summaryrefslogtreecommitdiff
path: root/svx/source/svdraw
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/svdraw')
-rw-r--r--svx/source/svdraw/ActionDescriptionProvider.cxx82
-rw-r--r--svx/source/svdraw/clonelist.cxx134
-rw-r--r--svx/source/svdraw/gradtrns.cxx538
-rw-r--r--svx/source/svdraw/gradtrns.hxx64
-rw-r--r--svx/source/svdraw/impgrfll.cxx255
-rw-r--r--svx/source/svdraw/makefile.mk124
-rw-r--r--svx/source/svdraw/polypolygoneditor.cxx190
-rw-r--r--svx/source/svdraw/sdrcomment.cxx98
-rw-r--r--svx/source/svdraw/sdrhittesthelper.cxx173
-rw-r--r--svx/source/svdraw/sdrmasterpagedescriptor.cxx119
-rw-r--r--svx/source/svdraw/sdrpagewindow.cxx464
-rw-r--r--svx/source/svdraw/sdrpaintwindow.cxx312
-rw-r--r--svx/source/svdraw/selectioncontroller.cxx114
-rw-r--r--svx/source/svdraw/svdattr.cxx2429
-rw-r--r--svx/source/svdraw/svdcrtv.cxx964
-rw-r--r--svx/source/svdraw/svddrag.cxx153
-rw-r--r--svx/source/svdraw/svddrgm1.hxx277
-rw-r--r--svx/source/svdraw/svddrgmt.cxx3652
-rw-r--r--svx/source/svdraw/svddrgv.cxx1006
-rw-r--r--svx/source/svdraw/svdedtv.cxx1086
-rw-r--r--svx/source/svdraw/svdedtv1.cxx1784
-rw-r--r--svx/source/svdraw/svdedtv2.cxx2139
-rw-r--r--svx/source/svdraw/svdedxv.cxx2146
-rw-r--r--svx/source/svdraw/svdetc.cxx1118
-rw-r--r--svx/source/svdraw/svdfmtf.cxx1028
-rw-r--r--svx/source/svdraw/svdfmtf.hxx166
-rw-r--r--svx/source/svdraw/svdglev.cxx422
-rw-r--r--svx/source/svdraw/svdglue.cxx450
-rw-r--r--svx/source/svdraw/svdhdl.cxx2417
-rw-r--r--svx/source/svdraw/svdhlpln.cxx149
-rw-r--r--svx/source/svdraw/svdibrow.cxx1299
-rw-r--r--svx/source/svdraw/svditer.cxx110
-rw-r--r--svx/source/svdraw/svditext.hxx37
-rw-r--r--svx/source/svdraw/svdlayer.cxx458
-rw-r--r--svx/source/svdraw/svdmark.cxx1040
-rw-r--r--svx/source/svdraw/svdmodel.cxx2250
-rw-r--r--svx/source/svdraw/svdmrkv.cxx2176
-rw-r--r--svx/source/svdraw/svdmrkv1.cxx724
-rw-r--r--svx/source/svdraw/svdoashp.cxx3504
-rw-r--r--svx/source/svdraw/svdoattr.cxx180
-rw-r--r--svx/source/svdraw/svdobj.cxx3310
-rw-r--r--svx/source/svdraw/svdocapt.cxx851
-rw-r--r--svx/source/svdraw/svdocirc.cxx1171
-rw-r--r--svx/source/svdraw/svdoedge.cxx2497
-rw-r--r--svx/source/svdraw/svdograf.cxx1282
-rw-r--r--svx/source/svdraw/svdogrp.cxx801
-rw-r--r--svx/source/svdraw/svdomeas.cxx1494
-rw-r--r--svx/source/svdraw/svdomedia.cxx285
-rw-r--r--svx/source/svdraw/svdoole2.cxx2242
-rw-r--r--svx/source/svdraw/svdopage.cxx195
-rw-r--r--svx/source/svdraw/svdopath.cxx3117
-rw-r--r--svx/source/svdraw/svdorect.cxx620
-rw-r--r--svx/source/svdraw/svdotext.cxx2132
-rw-r--r--svx/source/svdraw/svdotextdecomposition.cxx1258
-rw-r--r--svx/source/svdraw/svdotextpathdecomposition.cxx824
-rw-r--r--svx/source/svdraw/svdotxat.cxx462
-rw-r--r--svx/source/svdraw/svdotxdr.cxx285
-rw-r--r--svx/source/svdraw/svdotxed.cxx350
-rw-r--r--svx/source/svdraw/svdotxfl.cxx58
-rw-r--r--svx/source/svdraw/svdotxln.cxx350
-rw-r--r--svx/source/svdraw/svdotxtr.cxx558
-rw-r--r--svx/source/svdraw/svdouno.cxx665
-rw-r--r--svx/source/svdraw/svdoutl.cxx132
-rw-r--r--svx/source/svdraw/svdoutlinercache.cxx115
-rw-r--r--svx/source/svdraw/svdovirt.cxx659
-rw-r--r--svx/source/svdraw/svdpage.cxx2020
-rw-r--r--svx/source/svdraw/svdpagv.cxx1122
-rwxr-xr-xsvx/source/svdraw/svdpntv.cxx1540
-rw-r--r--svx/source/svdraw/svdpoev.cxx745
-rw-r--r--svx/source/svdraw/svdsnpv.cxx730
-rw-r--r--svx/source/svdraw/svdstr.src2935
-rw-r--r--svx/source/svdraw/svdtext.cxx224
-rw-r--r--svx/source/svdraw/svdtrans.cxx1271
-rw-r--r--svx/source/svdraw/svdundo.cxx1871
-rw-r--r--svx/source/svdraw/svdview.cxx1606
-rw-r--r--svx/source/svdraw/svdviter.cxx351
-rw-r--r--svx/source/svdraw/svdxcgv.cxx894
77 files changed, 76853 insertions, 0 deletions
diff --git a/svx/source/svdraw/ActionDescriptionProvider.cxx b/svx/source/svdraw/ActionDescriptionProvider.cxx
new file mode 100644
index 000000000000..acd60e27680b
--- /dev/null
+++ b/svx/source/svdraw/ActionDescriptionProvider.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "ActionDescriptionProvider.hxx"
+#include "svdglob.hxx"
+#include "svdstr.hrc"
+
+::rtl::OUString ActionDescriptionProvider::createDescription( ActionType eActionType
+ , const ::rtl::OUString& rObjectName )
+{
+ USHORT nResID=0;
+ switch( eActionType )
+ {
+ case INSERT:
+ nResID=STR_UndoInsertObj;
+ break;
+ case DELETE:
+ nResID= STR_EditDelete;
+ break;
+ case CUT:
+ nResID= STR_ExchangeClpCut;
+ break;
+ case MOVE:
+ nResID= STR_EditMove;
+ break;
+ case RESIZE:
+ nResID= STR_EditResize;
+ break;
+ case ROTATE:
+ nResID= STR_EditRotate;
+ break;
+ case TRANSFORM:
+ nResID= STR_EditTransform;
+ break;
+ case FORMAT:
+ nResID= STR_EditSetAttributes;
+ break;
+ case MOVE_TOTOP:
+ nResID= STR_EditMovToTop;
+ break;
+ case MOVE_TOBOTTOM:
+ nResID= STR_EditMovToBtm;
+ break;
+ case POS_SIZE:
+ nResID = STR_EditPosSize;
+ break;
+ }
+ if(!nResID)
+ return rtl::OUString();
+
+ XubString aStr(ImpGetResStr(nResID));
+ XubString aName(rObjectName);
+ aStr.SearchAndReplaceAscii("%1", aName);
+ return rtl::OUString(aStr);
+}
diff --git a/svx/source/svdraw/clonelist.cxx b/svx/source/svdraw/clonelist.cxx
new file mode 100644
index 000000000000..bae8ca9c188c
--- /dev/null
+++ b/svx/source/svdraw/clonelist.cxx
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+// #i13033#
+// New mechanism to hold a ist of all original and cloned objects for later
+// re-creating the connections for contained connectors
+#include <clonelist.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/scene3d.hxx>
+
+CloneList::CloneList()
+{
+}
+
+CloneList::~CloneList()
+{
+}
+
+void CloneList::AddPair(const SdrObject* pOriginal, SdrObject* pClone)
+{
+ maOriginalList.Insert((SdrObject*)pOriginal, LIST_APPEND);
+ maCloneList.Insert(pClone, LIST_APPEND);
+
+ // look for subobjects, too.
+ sal_Bool bOriginalIsGroup(pOriginal->IsGroupObject());
+ sal_Bool bCloneIsGroup(pClone->IsGroupObject());
+
+ if(bOriginalIsGroup && pOriginal->ISA(E3dObject) && !pOriginal->ISA(E3dScene))
+ bOriginalIsGroup = sal_False;
+
+ if(bCloneIsGroup && pClone->ISA(E3dObject) && !pClone->ISA(E3dScene))
+ bCloneIsGroup = sal_False;
+
+ if(bOriginalIsGroup && bCloneIsGroup)
+ {
+ const SdrObjList* pOriginalList = pOriginal->GetSubList();
+ SdrObjList* pCloneList = pClone->GetSubList();
+
+ if(pOriginalList && pCloneList
+ && pOriginalList->GetObjCount() == pCloneList->GetObjCount())
+ {
+ for(sal_uInt32 a(0); a < pOriginalList->GetObjCount(); a++)
+ {
+ // recursive call
+ AddPair(pOriginalList->GetObj(a), pCloneList->GetObj(a));
+ }
+ }
+ }
+}
+
+sal_uInt32 CloneList::Count() const
+{
+ return maOriginalList.Count();
+}
+
+const SdrObject* CloneList::GetOriginal(sal_uInt32 nIndex) const
+{
+ return (SdrObject*)maOriginalList.GetObject(nIndex);
+}
+
+SdrObject* CloneList::GetClone(sal_uInt32 nIndex) const
+{
+ return (SdrObject*)maCloneList.GetObject(nIndex);
+}
+
+void CloneList::CopyConnections() const
+{
+ for(sal_uInt32 a(0); a < maOriginalList.Count(); a++)
+ {
+ const SdrEdgeObj* pOriginalEdge = PTR_CAST(SdrEdgeObj, GetOriginal(a));
+ SdrEdgeObj* pCloneEdge = PTR_CAST(SdrEdgeObj, GetClone(a));
+
+ if(pOriginalEdge && pCloneEdge)
+ {
+ SdrObject* pOriginalNode1 = pOriginalEdge->GetConnectedNode(sal_True);
+ SdrObject* pOriginalNode2 = pOriginalEdge->GetConnectedNode(sal_False);
+
+ if(pOriginalNode1)
+ {
+ ULONG nPos(maOriginalList.GetPos(pOriginalNode1));
+
+ if(LIST_ENTRY_NOTFOUND != nPos)
+ {
+ if(pOriginalEdge->GetConnectedNode(sal_True) != GetClone(nPos))
+ {
+ pCloneEdge->ConnectToNode(sal_True, GetClone(nPos));
+ }
+ }
+ }
+
+ if(pOriginalNode2)
+ {
+ ULONG nPos(maOriginalList.GetPos(pOriginalNode2));
+
+ if(LIST_ENTRY_NOTFOUND != nPos)
+ {
+ if(pOriginalEdge->GetConnectedNode(sal_False) != GetClone(nPos))
+ {
+ pCloneEdge->ConnectToNode(sal_False, GetClone(nPos));
+ }
+ }
+ }
+ }
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/gradtrns.cxx b/svx/source/svdraw/gradtrns.cxx
new file mode 100644
index 000000000000..57f6270c4f91
--- /dev/null
+++ b/svx/source/svdraw/gradtrns.cxx
@@ -0,0 +1,538 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "gradtrns.hxx"
+#include <svx/svdobj.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <vcl/salbtype.hxx> // FRound
+
+//////////////////////////////////////////////////////////////////////////////
+
+void GradTransformer::GradToVec(GradTransGradient& rG, GradTransVector& rV, const SdrObject* pObj)
+{
+ // handle start color
+ rV.aCol1 = rG.aGradient.GetStartColor();
+ if(100 != rG.aGradient.GetStartIntens())
+ {
+ const double fFact((double)rG.aGradient.GetStartIntens() / 100.0);
+ rV.aCol1 = Color(rV.aCol1.getBColor() * fFact);
+ }
+
+ // handle end color
+ rV.aCol2 = rG.aGradient.GetEndColor();
+ if(100 != rG.aGradient.GetEndIntens())
+ {
+ const double fFact((double)rG.aGradient.GetEndIntens() / 100.0);
+ rV.aCol2 = Color(rV.aCol2.getBColor() * fFact);
+ }
+
+ // calc the basic positions
+ const Rectangle aObjectSnapRectangle(pObj->GetSnapRect());
+ const basegfx::B2DRange aRange(aObjectSnapRectangle.Left(), aObjectSnapRectangle.Top(), aObjectSnapRectangle.Right(), aObjectSnapRectangle.Bottom());
+ const basegfx::B2DPoint aCenter(aRange.getCenter());
+ basegfx::B2DPoint aStartPos, aEndPos;
+
+ switch(rG.aGradient.GetGradientStyle())
+ {
+ case XGRAD_LINEAR :
+ {
+ aStartPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMinY());
+ aEndPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY());
+
+ if(rG.aGradient.GetBorder())
+ {
+ basegfx::B2DVector aFullVec(aStartPos - aEndPos);
+ const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
+ aFullVec.normalize();
+ aStartPos = aEndPos + (aFullVec * fLen);
+ }
+
+ if(rG.aGradient.GetAngle())
+ {
+ const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
+ const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aCenter, -fAngle));
+
+ aStartPos *= aTransformation;
+ aEndPos *= aTransformation;
+ }
+ break;
+ }
+ case XGRAD_AXIAL :
+ {
+ aStartPos = aCenter;
+ aEndPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY());
+
+ if(rG.aGradient.GetBorder())
+ {
+ basegfx::B2DVector aFullVec(aEndPos - aStartPos);
+ const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
+ aFullVec.normalize();
+ aEndPos = aStartPos + (aFullVec * fLen);
+ }
+
+ if(rG.aGradient.GetAngle())
+ {
+ const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
+ const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aCenter, -fAngle));
+
+ aStartPos *= aTransformation;
+ aEndPos *= aTransformation;
+ }
+ break;
+ }
+ case XGRAD_RADIAL :
+ case XGRAD_SQUARE :
+ {
+ aStartPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMaximum().getY());
+ aEndPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY());
+
+ if(rG.aGradient.GetBorder())
+ {
+ basegfx::B2DVector aFullVec(aStartPos - aEndPos);
+ const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
+ aFullVec.normalize();
+ aStartPos = aEndPos + (aFullVec * fLen);
+ }
+
+ if(rG.aGradient.GetAngle())
+ {
+ const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
+ const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aEndPos, -fAngle));
+
+ aStartPos *= aTransformation;
+ aEndPos *= aTransformation;
+ }
+
+ if(rG.aGradient.GetXOffset() || rG.aGradient.GetYOffset())
+ {
+ basegfx::B2DPoint aOffset(
+ (aRange.getWidth() * rG.aGradient.GetXOffset()) / 100.0,
+ (aRange.getHeight() * rG.aGradient.GetYOffset()) / 100.0);
+
+ aStartPos += aOffset;
+ aEndPos += aOffset;
+ }
+
+ break;
+ }
+ case XGRAD_ELLIPTICAL :
+ case XGRAD_RECT :
+ {
+ aStartPos = basegfx::B2DPoint(aRange.getMinX(), aCenter.getY());
+ aEndPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY());
+
+ if(rG.aGradient.GetBorder())
+ {
+ basegfx::B2DVector aFullVec(aStartPos - aEndPos);
+ const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
+ aFullVec.normalize();
+ aStartPos = aEndPos + (aFullVec * fLen);
+ }
+
+ if(rG.aGradient.GetAngle())
+ {
+ const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
+ const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aEndPos, -fAngle));
+
+ aStartPos *= aTransformation;
+ aEndPos *= aTransformation;
+ }
+
+ if(rG.aGradient.GetXOffset() || rG.aGradient.GetYOffset())
+ {
+ basegfx::B2DPoint aOffset(
+ (aRange.getWidth() * rG.aGradient.GetXOffset()) / 100.0,
+ (aRange.getHeight() * rG.aGradient.GetYOffset()) / 100.0);
+
+ aStartPos += aOffset;
+ aEndPos += aOffset;
+ }
+
+ break;
+ }
+ }
+
+ // set values for vector positions now
+ rV.maPositionA = aStartPos;
+ rV.maPositionB = aEndPos;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void GradTransformer::VecToGrad(GradTransVector& rV, GradTransGradient& rG, GradTransGradient& rGOld, const SdrObject* pObj,
+ sal_Bool bMoveSingle, sal_Bool bMoveFirst)
+{
+ // fill old gradient to new gradient to have a base
+ rG = rGOld;
+
+ // handle color changes
+ if(rV.aCol1 != rGOld.aGradient.GetStartColor())
+ {
+ rG.aGradient.SetStartColor(rV.aCol1);
+ rG.aGradient.SetStartIntens(100);
+ }
+ if(rV.aCol2 != rGOld.aGradient.GetEndColor())
+ {
+ rG.aGradient.SetEndColor(rV.aCol2);
+ rG.aGradient.SetEndIntens(100);
+ }
+
+ // calc the basic positions
+ const Rectangle aObjectSnapRectangle(pObj->GetSnapRect());
+ const basegfx::B2DRange aRange(aObjectSnapRectangle.Left(), aObjectSnapRectangle.Top(), aObjectSnapRectangle.Right(), aObjectSnapRectangle.Bottom());
+ const basegfx::B2DPoint aCenter(aRange.getCenter());
+ basegfx::B2DPoint aStartPos(rV.maPositionA);
+ basegfx::B2DPoint aEndPos(rV.maPositionB);
+
+ switch(rG.aGradient.GetGradientStyle())
+ {
+ case XGRAD_LINEAR :
+ {
+ if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
+ {
+ basegfx::B2DVector aFullVec(aEndPos - aStartPos);
+
+ if(bMoveSingle)
+ {
+ aFullVec = aEndPos - aCenter;
+ }
+
+ aFullVec.normalize();
+
+ double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
+ fNewFullAngle /= F_PI180;
+ fNewFullAngle *= -10.0;
+ fNewFullAngle += 900.0;
+
+ // clip
+ while(fNewFullAngle < 0.0)
+ {
+ fNewFullAngle += 3600.0;
+ }
+
+ while(fNewFullAngle >= 3600.0)
+ {
+ fNewFullAngle -= 3600.0;
+ }
+
+ // to int and set
+ sal_Int32 nNewAngle = FRound(fNewFullAngle);
+
+ if(nNewAngle != rGOld.aGradient.GetAngle())
+ {
+ rG.aGradient.SetAngle(nNewAngle);
+ }
+ }
+
+ if(!bMoveSingle || (bMoveSingle && bMoveFirst))
+ {
+ const basegfx::B2DVector aFullVec(aEndPos - aStartPos);
+ const basegfx::B2DPoint aBottomLeft(aRange.getMinX(), aRange.getMaximum().getY());
+ const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
+ const basegfx::B2DVector aOldVec(aBottomLeft - aTopLeft);
+ const double fFullLen(aFullVec.getLength());
+ const double fOldLen(aOldVec.getLength());
+ const double fNewBorder((fFullLen * 100.0) / fOldLen);
+ sal_Int32 nNewBorder(100L - FRound(fNewBorder));
+
+ // clip
+ if(nNewBorder < 0L)
+ {
+ nNewBorder = 0L;
+ }
+
+ if(nNewBorder > 100L)
+ {
+ nNewBorder = 100L;
+ }
+
+ // set
+ if(nNewBorder != rG.aGradient.GetBorder())
+ {
+ rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
+ }
+ }
+
+ break;
+ }
+ case XGRAD_AXIAL :
+ {
+ if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
+ {
+ basegfx::B2DVector aFullVec(aEndPos - aCenter);
+ const basegfx::B2DVector aOldVec(basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY()) - aCenter);
+ const double fFullLen(aFullVec.getLength());
+ const double fOldLen(aOldVec.getLength());
+ const double fNewBorder((fFullLen * 100.0) / fOldLen);
+ sal_Int32 nNewBorder = 100 - FRound(fNewBorder);
+
+ // clip
+ if(nNewBorder < 0L)
+ {
+ nNewBorder = 0L;
+ }
+
+ if(nNewBorder > 100L)
+ {
+ nNewBorder = 100L;
+ }
+
+ // set
+ if(nNewBorder != rG.aGradient.GetBorder())
+ {
+ rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
+ }
+
+ aFullVec.normalize();
+ double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
+ fNewFullAngle /= F_PI180;
+ fNewFullAngle *= -10.0;
+ fNewFullAngle += 900.0;
+
+ // clip
+ while(fNewFullAngle < 0.0)
+ {
+ fNewFullAngle += 3600.0;
+ }
+
+ while(fNewFullAngle >= 3600.0)
+ {
+ fNewFullAngle -= 3600.0;
+ }
+
+ // to int and set
+ const sal_Int32 nNewAngle(FRound(fNewFullAngle));
+
+ if(nNewAngle != rGOld.aGradient.GetAngle())
+ {
+ rG.aGradient.SetAngle(nNewAngle);
+ }
+ }
+
+ break;
+ }
+ case XGRAD_RADIAL :
+ case XGRAD_SQUARE :
+ {
+ if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
+ {
+ const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
+ const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
+ sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth()));
+ sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight()));
+
+ // clip
+ if(nNewXOffset < 0L)
+ {
+ nNewXOffset = 0L;
+ }
+
+ if(nNewXOffset > 100L)
+ {
+ nNewXOffset = 100L;
+ }
+
+ if(nNewYOffset < 0L)
+ {
+ nNewYOffset = 0L;
+ }
+
+ if(nNewYOffset > 100L)
+ {
+ nNewYOffset = 100L;
+ }
+
+ rG.aGradient.SetXOffset((sal_uInt16)nNewXOffset);
+ rG.aGradient.SetYOffset((sal_uInt16)nNewYOffset);
+
+ aStartPos -= aOffset;
+ aEndPos -= aOffset;
+ }
+
+ if(!bMoveSingle || (bMoveSingle && bMoveFirst))
+ {
+ basegfx::B2DVector aFullVec(aStartPos - aEndPos);
+ const basegfx::B2DPoint aBottomLeft(aRange.getMinX(), aRange.getMaximum().getY());
+ const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
+ const basegfx::B2DVector aOldVec(aBottomLeft - aTopLeft);
+ const double fFullLen(aFullVec.getLength());
+ const double fOldLen(aOldVec.getLength());
+ const double fNewBorder((fFullLen * 100.0) / fOldLen);
+ sal_Int32 nNewBorder(100L - FRound(fNewBorder));
+
+ // clip
+ if(nNewBorder < 0L)
+ {
+ nNewBorder = 0L;
+ }
+
+ if(nNewBorder > 100L)
+ {
+ nNewBorder = 100L;
+ }
+
+ // set
+ if(nNewBorder != rG.aGradient.GetBorder())
+ {
+ rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
+ }
+
+ // angle is not definitely necessary for these modes, but it makes
+ // controlling more fun for the user
+ aFullVec.normalize();
+ double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
+ fNewFullAngle /= F_PI180;
+ fNewFullAngle *= -10.0;
+ fNewFullAngle += 900.0;
+
+ // clip
+ while(fNewFullAngle < 0.0)
+ {
+ fNewFullAngle += 3600.0;
+ }
+
+ while(fNewFullAngle >= 3600.0)
+ {
+ fNewFullAngle -= 3600.0;
+ }
+
+ // to int and set
+ const sal_Int32 nNewAngle(FRound(fNewFullAngle));
+
+ if(nNewAngle != rGOld.aGradient.GetAngle())
+ {
+ rG.aGradient.SetAngle(nNewAngle);
+ }
+ }
+
+ break;
+ }
+ case XGRAD_ELLIPTICAL :
+ case XGRAD_RECT :
+ {
+ if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
+ {
+ const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
+ const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
+ sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth()));
+ sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight()));
+
+ // clip
+ if(nNewXOffset < 0L)
+ {
+ nNewXOffset = 0L;
+ }
+
+ if(nNewXOffset > 100L)
+ {
+ nNewXOffset = 100L;
+ }
+
+ if(nNewYOffset < 0L)
+ {
+ nNewYOffset = 0L;
+ }
+
+ if(nNewYOffset > 100L)
+ {
+ nNewYOffset = 100L;
+ }
+
+ rG.aGradient.SetXOffset((sal_uInt16)nNewXOffset);
+ rG.aGradient.SetYOffset((sal_uInt16)nNewYOffset);
+
+ aStartPos -= aOffset;
+ aEndPos -= aOffset;
+ }
+
+ if(!bMoveSingle || (bMoveSingle && bMoveFirst))
+ {
+ basegfx::B2DVector aFullVec(aStartPos - aEndPos);
+ const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
+ const basegfx::B2DPoint aCenterLeft(aRange.getMinX(), aRange.getHeight());
+ const basegfx::B2DVector aOldVec(aCenterLeft - aTopLeft);
+ const double fFullLen(aFullVec.getLength());
+ const double fOldLen(aOldVec.getLength());
+ const double fNewBorder((fFullLen * 100.0) / fOldLen);
+ sal_Int32 nNewBorder(100L - FRound(fNewBorder));
+
+ // clip
+ if(nNewBorder < 0L)
+ {
+ nNewBorder = 0L;
+ }
+
+ if(nNewBorder > 100L)
+ {
+ nNewBorder = 100L;
+ }
+
+ // set
+ if(nNewBorder != rG.aGradient.GetBorder())
+ {
+ rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
+ }
+
+ // angle is not definitely necessary for these modes, but it makes
+ // controlling more fun for the user
+ aFullVec.normalize();
+ double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
+ fNewFullAngle /= F_PI180;
+ fNewFullAngle *= -10.0;
+ fNewFullAngle += 900.0;
+
+ // clip
+ while(fNewFullAngle < 0.0)
+ {
+ fNewFullAngle += 3600.0;
+ }
+
+ while(fNewFullAngle >= 3600.0)
+ {
+ fNewFullAngle -= 3600.0;
+ }
+
+ // to int and set
+ const sal_Int32 nNewAngle(FRound(fNewFullAngle));
+
+ if(nNewAngle != rGOld.aGradient.GetAngle())
+ {
+ rG.aGradient.SetAngle(nNewAngle);
+ }
+ }
+
+ break;
+ }
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/gradtrns.hxx b/svx/source/svdraw/gradtrns.hxx
new file mode 100644
index 000000000000..bf5352632f40
--- /dev/null
+++ b/svx/source/svdraw/gradtrns.hxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _GRADTRANS_HXX
+#define _GRADTRANS_HXX
+
+#include <svx/xgrad.hxx>
+#include <tools/gen.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+
+class SdrObject;
+
+class GradTransVector
+{
+public:
+ basegfx::B2DPoint maPositionA;
+ basegfx::B2DPoint maPositionB;
+ Color aCol1;
+ Color aCol2;
+};
+
+class GradTransGradient
+{
+public:
+ XGradient aGradient;
+};
+
+class GradTransformer
+{
+public:
+ GradTransformer() {}
+
+ void GradToVec(GradTransGradient& rG, GradTransVector& rV,
+ const SdrObject* pObj);
+ void VecToGrad(GradTransVector& rV, GradTransGradient& rG,
+ GradTransGradient& rGOld, const SdrObject* pObj, sal_Bool bMoveSingle, sal_Bool bMoveFirst);
+};
+
+#endif // _GRADTRANS_HXX
+
diff --git a/svx/source/svdraw/impgrfll.cxx b/svx/source/svdraw/impgrfll.cxx
new file mode 100644
index 000000000000..be2fc907d173
--- /dev/null
+++ b/svx/source/svdraw/impgrfll.cxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/rectenum.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/bitmap.hxx>
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ImpCalcBmpFillSizes( Size& rStartOffset,
+ Size& rBmpOutputSize,
+ const Rectangle& rOutputRect,
+ const MapMode& rOutputMapMode,
+ const Bitmap& rFillBitmap,
+ const Size& rBmpSize,
+ const Size& rBmpPerCent,
+ const Size& rBmpOffPerCent,
+ BOOL bBmpLogSize,
+ BOOL bBmpTile,
+ BOOL bBmpStretch,
+ RECT_POINT eBmpRectPoint )
+{
+ BOOL bOriginalSize = FALSE, bScaleSize = FALSE;
+
+ // Falls keine Groessen gegeben sind ( z.B. alte Dokumente )
+ // berechnen wir uns die Groesse selber aus der Bitmap
+ // ==> altes Verhalten;
+ // wenn nur eine Groesse gegeben ist, wird die andere
+ // Groesse angepasst berechnet
+ if( bBmpLogSize )
+ {
+ if( !rBmpSize.Width() && !rBmpSize.Height() )
+ bOriginalSize = TRUE;
+ else if( !rBmpSize.Width() || !rBmpSize.Height() )
+ bScaleSize = TRUE;
+ }
+ else
+ {
+ if( !rBmpPerCent.Width() && !rBmpPerCent.Height() )
+ bOriginalSize = TRUE;
+ else if( !rBmpPerCent.Width() || !rBmpPerCent.Height() )
+ bScaleSize = TRUE;
+ }
+
+ // entweder Originalgroesse oder angepasste Groesse
+ if( bOriginalSize || bScaleSize )
+ {
+ MapMode aBmpPrefMapMode( rFillBitmap.GetPrefMapMode() );
+ Size aBmpPrefSize( rFillBitmap.GetPrefSize() );
+
+ // Falls keine gesetzt ist, nehmen wir Pixel
+ if( !aBmpPrefSize.Width() || !aBmpPrefSize.Height() )
+ {
+ aBmpPrefSize = rFillBitmap.GetSizePixel();
+ aBmpPrefMapMode = MAP_PIXEL;
+ }
+
+ if( bOriginalSize )
+ {
+ if( MAP_PIXEL == aBmpPrefMapMode.GetMapUnit() )
+ rBmpOutputSize = Application::GetDefaultDevice()->PixelToLogic( aBmpPrefSize, rOutputMapMode );
+ else
+ rBmpOutputSize = OutputDevice::LogicToLogic( aBmpPrefSize, aBmpPrefMapMode, rOutputMapMode );
+ }
+ else
+ {
+ if( bBmpLogSize )
+ {
+ rBmpOutputSize = rBmpSize;
+
+ if( !rBmpSize.Width() )
+ rBmpOutputSize.Width() = basegfx::fround( (double) rBmpSize.Height() * aBmpPrefSize.Width() / aBmpPrefSize.Height() );
+ else
+ rBmpOutputSize.Height() = basegfx::fround( (double) rBmpSize.Width() * aBmpPrefSize.Height() / aBmpPrefSize.Width() );
+ }
+ else
+ {
+ if( !rBmpPerCent.Width() )
+ {
+ rBmpOutputSize.Height() = basegfx::fround( (double) rOutputRect.GetHeight() * rBmpPerCent.Height() / 100. );
+ rBmpOutputSize.Width() = basegfx::fround( (double) rBmpOutputSize.Height() * aBmpPrefSize.Width() / aBmpPrefSize.Height() );
+ }
+ else
+ {
+ rBmpOutputSize.Width() = basegfx::fround( (double) rOutputRect.GetWidth() * rBmpPerCent.Width() / 100. );
+ rBmpOutputSize.Height() = basegfx::fround( (double) rBmpOutputSize.Width() * aBmpPrefSize.Height() / aBmpPrefSize.Width() );
+ }
+ }
+ }
+ }
+ // ansonsten koennen wir die Groesse leicht selber berechnen
+ else
+ {
+ if( bBmpLogSize )
+ rBmpOutputSize = rBmpSize;
+ else
+ {
+ rBmpOutputSize.Width() = basegfx::fround( (double) rOutputRect.GetWidth() * rBmpPerCent.Width() / 100. );
+ rBmpOutputSize.Height() = basegfx::fround( (double) rOutputRect.GetHeight() * rBmpPerCent.Height() / 100. );
+ }
+ }
+
+ // nur bei Kachelung die anderen Positionen berechnen
+ if( bBmpTile )
+ {
+ Point aStartPoint;
+
+ // Grundposition der ersten Kachel berechen;
+ // Diese Position wird spaeter zur Berechnung der absoluten
+ // Startposition links oberhalb des Objektes benutzt
+ switch( eBmpRectPoint )
+ {
+ case( RP_MT ):
+ {
+ aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
+ aStartPoint.Y() = rOutputRect.Top();
+ }
+ break;
+
+ case( RP_RT ):
+ {
+ aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
+ aStartPoint.Y() = rOutputRect.Top();
+ }
+ break;
+
+ case( RP_LM ):
+ {
+ aStartPoint.X() = rOutputRect.Left();
+ aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
+ }
+ break;
+
+ case( RP_MM ):
+ {
+ aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
+ aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
+ }
+ break;
+
+ case( RP_RM ):
+ {
+ aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
+ aStartPoint.Y() = rOutputRect.Top() + ( ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
+ }
+ break;
+
+ case( RP_LB ):
+ {
+ aStartPoint.X() = rOutputRect.Left();
+ aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
+ }
+ break;
+
+ case( RP_MB ):
+ {
+ aStartPoint.X() = rOutputRect.Left() + ( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1 );
+ aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
+ }
+ break;
+
+ case( RP_RB ):
+ {
+ aStartPoint.X() = rOutputRect.Right() - rBmpOutputSize.Width();
+ aStartPoint.Y() = rOutputRect.Bottom() - rBmpOutputSize.Height();
+ }
+ break;
+
+ // default linke obere Ecke
+ default:
+ aStartPoint = rOutputRect.TopLeft();
+ break;
+ }
+
+ // X- oder Y-Positionsoffset beruecksichtigen
+ if( rBmpOffPerCent.Width() )
+ aStartPoint.X() += ( rBmpOutputSize.Width() * rBmpOffPerCent.Width() / 100 );
+
+ if( rBmpOffPerCent.Height() )
+ aStartPoint.Y() += ( rBmpOutputSize.Height() * rBmpOffPerCent.Height() / 100 );
+
+ // echten Startpunkt berechnen ( links oben )
+ if( rBmpOutputSize.Width() && rBmpOutputSize.Height() )
+ {
+ const long nDiffX = aStartPoint.X() - rOutputRect.Left();
+ const long nDiffY = aStartPoint.Y() - rOutputRect.Top();
+
+ if ( nDiffX )
+ {
+ long nCount = nDiffX / rBmpOutputSize.Width() + 1;
+
+ if ( rBmpOffPerCent.Height() && ( nCount & 1L ) )
+ nCount++;
+
+ aStartPoint.X() -= ( nCount * rBmpOutputSize.Width() );
+ }
+
+ if ( nDiffY )
+ {
+ long nCount = nDiffY / rBmpOutputSize.Height() + 1;
+
+ if ( rBmpOffPerCent.Width() && ( nCount & 1L ) )
+ nCount++;
+
+ aStartPoint.Y() -= ( nCount * rBmpOutputSize.Height() );
+ }
+ }
+
+ rStartOffset = Size( aStartPoint.X() - rOutputRect.Left(),
+ aStartPoint.Y() - rOutputRect.Top() );
+ }
+ else
+ {
+ if( bBmpStretch )
+ {
+ rStartOffset = Size(0, 0);
+ rBmpOutputSize = rOutputRect.GetSize();
+ }
+ else
+ {
+ rStartOffset = Size( ( rOutputRect.GetWidth() - rBmpOutputSize.Width() ) >> 1,
+ ( rOutputRect.GetHeight() - rBmpOutputSize.Height() ) >> 1 );
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/makefile.mk b/svx/source/svdraw/makefile.mk
new file mode 100644
index 000000000000..514c5b6d2cbc
--- /dev/null
+++ b/svx/source/svdraw/makefile.mk
@@ -0,0 +1,124 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=svx
+TARGET=svdraw
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Files --------------------------------------------------------
+
+LIB1TARGET= $(SLB)$/$(TARGET)-core.lib
+LIB1OBJFILES= \
+ $(SLO)$/svdxcgv.obj \
+ $(SLO)$/svdmodel.obj \
+ $(SLO)$/svdpage.obj \
+ $(SLO)$/svdobj.obj \
+ $(SLO)$/svdedtv1.obj \
+ $(SLO)$/svdcrtv.obj \
+ $(SLO)$/svdograf.obj \
+ $(SLO)$/svdoole2.obj \
+ $(SLO)$/svdhdl.obj \
+ $(SLO)$/svdmrkv.obj \
+ $(SLO)$/svdogrp.obj \
+ $(SLO)$/svdotxln.obj \
+ $(SLO)$/svdotextdecomposition.obj \
+ $(SLO)$/svdotextpathdecomposition.obj \
+ $(SLO)$/svdouno.obj \
+ $(SLO)$/svdpagv.obj \
+ $(SLO)$/svddrgmt.obj \
+ $(SLO)$/svdpntv.obj \
+ $(SLO)$/svdsnpv.obj \
+ $(SLO)$/svdview.obj \
+ $(SLO)$/svdtext.obj \
+ $(SLO)$/svdoashp.obj \
+ $(SLO)$/svdoattr.obj \
+ $(SLO)$/svdotext.obj \
+ $(SLO)$/svdotxat.obj \
+ $(SLO)$/svdotxdr.obj \
+ $(SLO)$/svdotxed.obj \
+ $(SLO)$/svdotxfl.obj \
+ $(SLO)$/svdotxtr.obj \
+ $(SLO)$/svdorect.obj \
+ $(SLO)$/svdoedge.obj \
+ $(SLO)$/svdomeas.obj \
+ $(SLO)$/svdopath.obj \
+ $(SLO)$/svdocapt.obj \
+ $(SLO)$/svdocirc.obj \
+ $(SLO)$/svdopage.obj \
+ $(SLO)$/svdoutl.obj \
+ $(SLO)$/svdovirt.obj \
+ $(SLO)$/svdoutlinercache.obj \
+ $(SLO)$/gradtrns.obj \
+ $(SLO)$/svdattr.obj \
+ $(SLO)$/svddrag.obj \
+ $(SLO)$/svddrgv.obj \
+ $(SLO)$/svdedtv2.obj \
+ $(SLO)$/svdedxv.obj \
+ $(SLO)$/svdetc.obj \
+ $(SLO)$/sdrhittesthelper.obj \
+ $(SLO)$/svdfmtf.obj \
+ $(SLO)$/svdglev.obj \
+ $(SLO)$/svdglue.obj \
+ $(SLO)$/svdhlpln.obj \
+ $(SLO)$/svditer.obj \
+ $(SLO)$/svdlayer.obj \
+ $(SLO)$/svdmark.obj \
+ $(SLO)$/svdmrkv1.obj \
+ $(SLO)$/sdrcomment.obj \
+ $(SLO)$/sdrmasterpagedescriptor.obj \
+ $(SLO)$/sdrpagewindow.obj \
+ $(SLO)$/sdrpaintwindow.obj \
+ $(SLO)$/svdpoev.obj \
+ $(SLO)$/svdtrans.obj \
+ $(SLO)$/svdundo.obj \
+ $(SLO)$/svdviter.obj \
+ $(SLO)$/clonelist.obj \
+ $(SLO)$/svdedtv.obj \
+ $(SLO)$/selectioncontroller.obj \
+ $(SLO)$/polypolygoneditor.obj \
+ $(SLO)$/svdibrow.obj \
+ $(SLO)$/svdomedia.obj
+
+LIB2TARGET= $(SLB)$/$(TARGET).lib
+LIB2OBJFILES= \
+ $(SLO)$/ActionDescriptionProvider.obj \
+ $(SLO)$/impgrfll.obj
+
+SLOFILES = $(LIB1OBJFILES) $(LIB2OBJFILES)
+
+SRS1NAME=svdstr
+SRC1FILES= svdstr.src
+
+.INCLUDE : target.mk
diff --git a/svx/source/svdraw/polypolygoneditor.cxx b/svx/source/svdraw/polypolygoneditor.cxx
new file mode 100644
index 000000000000..804f39957938
--- /dev/null
+++ b/svx/source/svdraw/polypolygoneditor.cxx
@@ -0,0 +1,190 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#include "svx/polypolygoneditor.hxx"
+
+namespace sdr {
+
+PolyPolygonEditor::PolyPolygonEditor( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bClosed )
+: maPolyPolygon( rPolyPolygon )
+, mbIsClosed( bClosed )
+{
+}
+
+bool PolyPolygonEditor::DeletePoints( const std::set< sal_uInt16 >& rAbsPoints )
+{
+ bool bPolyPolyChanged = false;
+
+ std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() );
+ for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ )
+ {
+ sal_uInt32 nPoly, nPnt;
+ if( GetRelativePolyPoint(maPolyPolygon,(*aIter), nPoly, nPnt) )
+ {
+ // remove point
+ basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPoly));
+
+ aCandidate.remove(nPnt);
+
+ if( ( mbIsClosed && aCandidate.count() < 3L) || (aCandidate.count() < 2L) )
+ {
+ maPolyPolygon.remove(nPoly);
+ }
+ else
+ {
+ maPolyPolygon.setB2DPolygon(nPoly, aCandidate);
+ }
+
+ bPolyPolyChanged = true;
+ }
+ }
+
+ return bPolyPolyChanged;
+}
+
+bool PolyPolygonEditor::SetSegmentsKind(SdrPathSegmentKind eKind, const std::set< sal_uInt16 >& rAbsPoints )
+{
+ bool bPolyPolyChanged = false;
+
+ std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() );
+ for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ )
+ {
+ sal_uInt32 nPolyNum, nPntNum;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum))
+ {
+ // do change at aNewPolyPolygon. Take a look at edge.
+ basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum));
+ bool bCandidateChanged(false);
+ const sal_uInt32 nCount(aCandidate.count());
+
+ if(nCount && (nPntNum + 1 < nCount || aCandidate.isClosed()))
+ {
+ // it's a valid edge, check control point usage
+ const sal_uInt32 nNextIndex((nPntNum + 1) % nCount);
+ const bool bContolUsed(aCandidate.areControlPointsUsed()
+ && (aCandidate.isNextControlPointUsed(nPntNum) || aCandidate.isPrevControlPointUsed(nNextIndex)));
+
+ if(bContolUsed)
+ {
+ if(SDRPATHSEGMENT_TOGGLE == eKind || SDRPATHSEGMENT_LINE == eKind)
+ {
+ // remove control
+ aCandidate.resetNextControlPoint(nPntNum);
+ aCandidate.resetPrevControlPoint(nNextIndex);
+ bCandidateChanged = true;
+ }
+ }
+ else
+ {
+ if(SDRPATHSEGMENT_TOGGLE == eKind || SDRPATHSEGMENT_CURVE == eKind)
+ {
+ // add control
+ const basegfx::B2DPoint aStart(aCandidate.getB2DPoint(nPntNum));
+ const basegfx::B2DPoint aEnd(aCandidate.getB2DPoint(nNextIndex));
+
+ aCandidate.setNextControlPoint(nPntNum, interpolate(aStart, aEnd, (1.0 / 3.0)));
+ aCandidate.setPrevControlPoint(nNextIndex, interpolate(aStart, aEnd, (2.0 / 3.0)));
+ bCandidateChanged = true;
+ }
+ }
+
+ if(bCandidateChanged)
+ {
+ maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate);
+ bPolyPolyChanged = true;
+ }
+ }
+ }
+ }
+
+ return bPolyPolyChanged;
+}
+
+bool PolyPolygonEditor::SetPointsSmooth( basegfx::B2VectorContinuity eFlags, const std::set< sal_uInt16 >& rAbsPoints)
+{
+ bool bPolyPolygonChanged(false);
+
+ std::set< sal_uInt16 >::const_reverse_iterator aIter;( rAbsPoints.rbegin() );
+ for( aIter = rAbsPoints.rbegin(); aIter != rAbsPoints.rend(); aIter++ )
+ {
+ sal_uInt32 nPolyNum, nPntNum;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(maPolyPolygon, (*aIter), nPolyNum, nPntNum))
+ {
+ // do change at aNewPolyPolygon...
+ basegfx::B2DPolygon aCandidate(maPolyPolygon.getB2DPolygon(nPolyNum));
+
+ // set continuity in point, make sure there is a curve
+ bool bPolygonChanged(false);
+ bPolygonChanged = basegfx::tools::expandToCurveInPoint(aCandidate, nPntNum);
+ bPolygonChanged |= basegfx::tools::setContinuityInPoint(aCandidate, nPntNum, eFlags);
+
+ if(bPolygonChanged)
+ {
+ maPolyPolygon.setB2DPolygon(nPolyNum, aCandidate);
+ bPolyPolygonChanged = true;
+ }
+ }
+ }
+
+ return bPolyPolygonChanged;
+}
+
+bool PolyPolygonEditor::GetRelativePolyPoint( const basegfx::B2DPolyPolygon& rPoly, sal_uInt32 nAbsPnt, sal_uInt32& rPolyNum, sal_uInt32& rPointNum )
+{
+ const sal_uInt32 nPolyCount(rPoly.count());
+ sal_uInt32 nPolyNum(0L);
+
+ while(nPolyNum < nPolyCount)
+ {
+ const sal_uInt32 nPointCount(rPoly.getB2DPolygon(nPolyNum).count());
+
+ if(nAbsPnt < nPointCount)
+ {
+ rPolyNum = nPolyNum;
+ rPointNum = nAbsPnt;
+
+ return true;
+ }
+ else
+ {
+ nPolyNum++;
+ nAbsPnt -= nPointCount;
+ }
+ }
+
+ return false;
+}
+
+} // end of namespace sdr
diff --git a/svx/source/svdraw/sdrcomment.cxx b/svx/source/svdraw/sdrcomment.cxx
new file mode 100644
index 000000000000..9f68b3e806ff
--- /dev/null
+++ b/svx/source/svdraw/sdrcomment.cxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/sdrcomment.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+ Comment::Comment(
+ sal_uInt32 nID,
+ Date aCreationDate,
+ const ::rtl::OUString& rUserName,
+ const ::rtl::OUString& rText,
+ const basegfx::B2DPoint& rPosition)
+ : mnID(nID),
+ maCreationDate(aCreationDate),
+ maUserName(rUserName),
+ maText(rText),
+ maPosition(rPosition)
+ {
+ }
+
+ Comment::~Comment()
+ {
+ }
+
+ sal_Bool Comment::operator==(const Comment& rCandidate) const
+ {
+ return (
+ mnID == rCandidate.mnID
+ && maCreationDate == rCandidate.maCreationDate
+ && maUserName == rCandidate.maUserName
+ && maText == rCandidate.maText
+ && maPosition == rCandidate.maPosition);
+ }
+
+ void Comment::SetCreationDate(Date aNewDate)
+ {
+ if(aNewDate != maCreationDate)
+ {
+ maCreationDate = aNewDate;
+ }
+ }
+
+ void Comment::SetUserName(const ::rtl::OUString& rNewName)
+ {
+ if(rNewName != maUserName)
+ {
+ maUserName = rNewName;
+ }
+ }
+
+ void Comment::SetText(const ::rtl::OUString& rNewText)
+ {
+ if(rNewText != maText)
+ {
+ maText = rNewText;
+ }
+ }
+
+ void Comment::SetPosition(const basegfx::B2DPoint& rNewPos)
+ {
+ if(rNewPos != maPosition)
+ {
+ maPosition = rNewPos;
+ }
+ }
+} // end of namespace sdr
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/sdrhittesthelper.cxx b/svx/source/svdraw/sdrhittesthelper.cxx
new file mode 100644
index 000000000000..58eef58a9fd6
--- /dev/null
+++ b/svx/source/svdraw/sdrhittesthelper.cxx
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/sdrhittesthelper.hxx>
+#include <svx/obj3d.hxx>
+#include <svx/helperhittest3d.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <drawinglayer/processor2d/hittestprocessor2d.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i101872# new Object HitTest as View-tooling
+
+SdrObject* SdrObjectPrimitiveHit(
+ const SdrObject& rObject,
+ const Point& rPnt,
+ sal_uInt16 nTol,
+ const SdrPageView& rSdrPageView,
+ const SetOfByte* pVisiLayer,
+ bool bTextOnly)
+{
+ SdrObject* pResult = 0;
+
+ if(rObject.GetSubList() && rObject.GetSubList()->GetObjCount())
+ {
+ // group or scene with content. Single 3D objects also have a
+ // true == rObject.GetSubList(), but no content
+ pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly);
+ }
+ else
+ {
+ if( rObject.IsVisible() && (!pVisiLayer || pVisiLayer->IsSet(rObject.GetLayer())))
+ {
+ // single object, 3d object, empty scene or empty group. Check if
+ // it's a single 3D object
+ const E3dCompoundObject* pE3dCompoundObject = dynamic_cast< const E3dCompoundObject* >(&rObject);
+
+ if(pE3dCompoundObject)
+ {
+ const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y());
+
+ if(checkHitSingle3DObject(aHitPosition, *pE3dCompoundObject))
+ {
+ pResult = const_cast< E3dCompoundObject* >(pE3dCompoundObject);
+ }
+ }
+ else
+ {
+ // not a single 3D object; Check in first PageWindow using prmitives (only SC
+ // with split views uses multiple PageWindows nowadays)
+ if(rSdrPageView.PageWindowCount())
+ {
+ const double fLogicTolerance(nTol);
+ const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y());
+ const sdr::contact::ViewObjectContact& rVOC = rObject.GetViewContact().GetViewObjectContact(
+ rSdrPageView.GetPageWindow(0)->GetObjectContact());
+
+ if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, fLogicTolerance, bTextOnly))
+ {
+ pResult = const_cast< SdrObject* >(&rObject);
+ }
+ }
+ }
+ }
+ }
+
+ return pResult;
+}
+
+/////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrObjListPrimitiveHit(
+ const SdrObjList& rList,
+ const Point& rPnt,
+ sal_uInt16 nTol,
+ const SdrPageView& rSdrPageView,
+ const SetOfByte* pVisiLayer,
+ bool bTextOnly)
+{
+ sal_uInt32 nObjNum(rList.GetObjCount());
+ SdrObject* pRetval = 0;
+
+ while(!pRetval && nObjNum > 0)
+ {
+ nObjNum--;
+ SdrObject* pObj = rList.GetObj(nObjNum);
+
+ pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly);
+ }
+
+ return pRetval;
+}
+
+/////////////////////////////////////////////////////////////////////
+
+bool ViewObjectContactPrimitiveHit(
+ const sdr::contact::ViewObjectContact& rVOC,
+ const basegfx::B2DPoint& rHitPosition,
+ double fLogicHitTolerance,
+ bool bTextOnly)
+{
+ basegfx::B2DRange aObjectRange(rVOC.getObjectRange());
+
+ if(!aObjectRange.isEmpty())
+ {
+ // first do a rough B2DRange based HitTest; do not forget to
+ // include the HitTolerance if given
+ if(basegfx::fTools::more(fLogicHitTolerance, 0.0))
+ {
+ aObjectRange.grow(fLogicHitTolerance);
+ }
+
+ if(aObjectRange.isInside(rHitPosition))
+ {
+ // get primitive sequence
+ sdr::contact::DisplayInfo aDisplayInfo;
+ const drawinglayer::primitive2d::Primitive2DSequence& rSequence(rVOC.getPrimitive2DSequence(aDisplayInfo));
+
+ if(rSequence.hasElements())
+ {
+ // create a HitTest processor
+ const drawinglayer::geometry::ViewInformation2D& rViewInformation2D = rVOC.GetObjectContact().getViewInformation2D();
+ drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D(
+ rViewInformation2D,
+ rHitPosition,
+ fLogicHitTolerance,
+ bTextOnly);
+
+ // feed it with the primitives
+ aHitTestProcessor2D.process(rSequence);
+
+ // deliver result
+ return aHitTestProcessor2D.getHit();
+ }
+ }
+ }
+
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/sdrmasterpagedescriptor.cxx b/svx/source/svdraw/sdrmasterpagedescriptor.cxx
new file mode 100644
index 000000000000..67b2de8b693c
--- /dev/null
+++ b/svx/source/svdraw/sdrmasterpagedescriptor.cxx
@@ -0,0 +1,119 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/sdrmasterpagedescriptor.hxx>
+#include <svx/sdr/contact/viewcontactofmasterpagedescriptor.hxx>
+#include <svx/svdpage.hxx>
+
+// #i42075#
+#include <svx/svdobj.hxx>
+#include <svx/xfillit0.hxx>
+#include <svl/itemset.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+ // ViewContact part
+ sdr::contact::ViewContact* MasterPageDescriptor::CreateObjectSpecificViewContact()
+ {
+ return new sdr::contact::ViewContactOfMasterPageDescriptor(*this);
+ }
+
+ MasterPageDescriptor::MasterPageDescriptor(SdrPage& aOwnerPage, SdrPage& aUsedPage)
+ : maOwnerPage(aOwnerPage),
+ maUsedPage(aUsedPage),
+ mpViewContact(0L)
+ {
+ // all layers visible
+ maVisibleLayers.SetAll();
+
+ // register at used page
+ maUsedPage.AddPageUser(*this);
+ }
+
+ MasterPageDescriptor::~MasterPageDescriptor()
+ {
+ // de-register at used page
+ maUsedPage.RemovePageUser(*this);
+
+ if(mpViewContact)
+ {
+ delete mpViewContact;
+ mpViewContact = 0L;
+ }
+ }
+
+ // ViewContact part
+ sdr::contact::ViewContact& MasterPageDescriptor::GetViewContact() const
+ {
+ if(!mpViewContact)
+ {
+ const_cast< MasterPageDescriptor* >(this)->mpViewContact =
+ const_cast< MasterPageDescriptor* >(this)->CreateObjectSpecificViewContact();
+ }
+
+ return *mpViewContact;
+ }
+
+ // this method is called form the destructor of the referenced page.
+ // do all necessary action to forget the page. It is not necessary to call
+ // RemovePageUser(), that is done form the destructor.
+ void MasterPageDescriptor::PageInDestruction(const SdrPage& /*rPage*/)
+ {
+ maOwnerPage.TRG_ClearMasterPage();
+ }
+
+ void MasterPageDescriptor::SetVisibleLayers(const SetOfByte& rNew)
+ {
+ if(rNew != maVisibleLayers)
+ {
+ maVisibleLayers = rNew;
+ GetViewContact().ActionChanged();
+ }
+ }
+
+ // operators
+ sal_Bool MasterPageDescriptor::operator==(const MasterPageDescriptor& rCandidate) const
+ {
+ return (&maOwnerPage == &rCandidate.maOwnerPage
+ && &maUsedPage == &rCandidate.maUsedPage
+ && maVisibleLayers == rCandidate.maVisibleLayers);
+ }
+
+ sal_Bool MasterPageDescriptor::operator!=(const MasterPageDescriptor& rCandidate) const
+ {
+ return (&maOwnerPage != &rCandidate.maOwnerPage
+ || &maUsedPage != &rCandidate.maUsedPage
+ || maVisibleLayers != rCandidate.maVisibleLayers);
+ }
+} // end of namespace sdr
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/sdrpagewindow.cxx b/svx/source/svdraw/sdrpagewindow.cxx
new file mode 100644
index 000000000000..85513fb3b926
--- /dev/null
+++ b/svx/source/svdraw/sdrpagewindow.cxx
@@ -0,0 +1,464 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/sdrpagewindow.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/util/XModeChangeBroadcaster.hpp>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <sdrpaintwindow.hxx>
+#include <svx/sdr/contact/objectcontactofpageview.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <vos/mutex.hxx>
+#include <svx/fmview.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
+{
+ if ( !mxControlContainer.is() && _bCreateIfNecessary )
+ {
+ SdrView& rView = GetPageView().GetView();
+
+ const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
+ if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
+ {
+ Window& rWindow = dynamic_cast< Window& >( rPaintWindow.GetOutputDevice() );
+ const_cast< SdrPageWindow* >( this )->mxControlContainer = VCLUnoHelper::CreateControlContainer( &rWindow );
+
+ // #100394# xC->setVisible triggers window->Show() and this has
+ // problems when the view is not completely constructed which may
+ // happen when loading. This leads to accessibility broadcasts which
+ // throw asserts due to the not finished view. All this chan be avoided
+ // since xC->setVisible is here called only for the side effect in
+ // UnoControlContainer::setVisible(...) which calls createPeer(...).
+ // This will now be called directly from here.
+
+ // UnoContainerModel erzeugen
+ // uno::Reference< awt::XWindow > xC(mxControlContainer, uno::UNO_QUERY);
+ // CreateControlContainer() is only used from
+ // , thus it seems not necessary to make
+ // it visible her at all.
+ // #58917# Das Show darf nicht am VCL-Fenster landen, weil dann Assertion vom SFX
+ // BOOL bVis = pWindow->IsVisible();
+ // xC->setVisible(TRUE);
+ // if ( !bVis )
+ // pWindow->Hide();
+ // if( !mxContext.is() && bVisible )
+ // // Es ist ein TopWindow, also automatisch anzeigen
+ // createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (), ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
+
+ uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
+ if(xControl.is())
+ {
+ uno::Reference< uno::XInterface > xContext = xControl->getContext();
+ if(!xContext.is())
+ {
+ xControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (),
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
+ }
+ }
+ }
+ else
+ {
+ // Printer und VirtualDevice, bzw. kein OutDev
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ if( xFactory.is() )
+ {
+ const_cast< SdrPageWindow* >( this )->mxControlContainer = uno::Reference< awt::XControlContainer >(xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlContainer")), uno::UNO_QUERY);
+ uno::Reference< awt::XControlModel > xModel(xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlContainerModel")), uno::UNO_QUERY);
+ uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
+ if (xControl.is())
+ xControl->setModel(xModel);
+
+ OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
+ Point aPosPix = rOutDev.GetMapMode().GetOrigin();
+ Size aSizePix = rOutDev.GetOutputSizePixel();
+
+ uno::Reference< awt::XWindow > xContComp(mxControlContainer, uno::UNO_QUERY);
+ if( xContComp.is() )
+ xContComp->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
+ }
+ }
+
+ FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
+ if ( pViewAsFormView )
+ pViewAsFormView->InsertControlContainer(mxControlContainer);
+ }
+ return mxControlContainer;
+}
+
+SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow)
+: mpObjectContact(0L),
+ mrPageView(rPageView),
+ mpPaintWindow(&rPaintWindow),
+ mpOriginalPaintWindow(NULL)
+{
+}
+
+SdrPageWindow::~SdrPageWindow()
+{
+ // #110094#, #i26631#
+ ResetObjectContact();
+
+ if (mxControlContainer.is())
+ {
+ SdrView& rView = GetPageView().GetView();
+
+ // notify derived views
+ FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
+ if ( pViewAsFormView )
+ pViewAsFormView->RemoveControlContainer(mxControlContainer);
+
+ // dispose the control container
+ uno::Reference< lang::XComponent > xComponent(mxControlContainer, uno::UNO_QUERY);
+ xComponent->dispose();
+ }
+}
+
+// #110094# ObjectContact section
+sdr::contact::ObjectContact* SdrPageWindow::CreateViewSpecificObjectContact()
+{
+ return new sdr::contact::ObjectContactOfPageView(*this);
+}
+
+// OVERLAYMANAGER
+::sdr::overlay::OverlayManager* SdrPageWindow::GetOverlayManager() const
+{
+ return GetPaintWindow().GetOverlayManager();
+}
+
+void SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
+{
+ mpOriginalPaintWindow = mpPaintWindow;
+ mpPaintWindow = &rPaintWindow;
+}
+
+void SdrPageWindow::unpatchPaintWindow()
+{
+ DBG_ASSERT(mpOriginalPaintWindow, "SdrPageWindow::unpatchPaintWindow: paint window not patched!" );
+ if ( mpOriginalPaintWindow )
+ {
+ mpPaintWindow = mpOriginalPaintWindow;
+ mpOriginalPaintWindow = NULL;
+ }
+}
+
+void SdrPageWindow::PrePaint()
+{
+ // give OC the chance to do ProcessDisplay preparations
+ if(HasObjectContact())
+ {
+ GetObjectContact().PrepareProcessDisplay();
+ }
+}
+
+void SdrPageWindow::PrepareRedraw(const Region& rReg)
+{
+ // evtl. give OC the chance to do ProcessDisplay preparations
+ if(HasObjectContact())
+ {
+ GetObjectContact().PrepareProcessDisplay();
+ }
+
+ // remember eventually changed RedrawArea at PaintWindow for usage with
+ // overlay and PreRenderDevice stuff
+ GetPaintWindow().SetRedrawRegion(rReg);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// clip test
+#ifdef CLIPPER_TEST
+#include <svx/svdopath.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+
+// for ::std::sort
+#include <algorithm>
+
+namespace
+{
+ void impPaintStrokePolygon(const basegfx::B2DPolygon& rCandidate, OutputDevice& rOutDev, Color aColor)
+ {
+ basegfx::B2DPolygon aCandidate(rCandidate);
+
+ if(aCandidate.areControlPointsUsed())
+ {
+ aCandidate = basegfx::tools::adaptiveSubdivideByAngle(rCandidate);
+ }
+
+ if(aCandidate.count())
+ {
+ const sal_uInt32 nLoopCount(aCandidate.isClosed() ? aCandidate.count() : aCandidate.count() - 1L);
+ rOutDev.SetFillColor();
+ rOutDev.SetLineColor(aColor);
+
+ for(sal_uInt32 a(0L); a < nLoopCount; a++)
+ {
+ const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
+ const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count()));
+ const Point aStart(FRound(aBStart.getX()), FRound(aBStart.getY()));
+ const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY()));
+ rOutDev.DrawLine(aStart, aEnd);
+ }
+ }
+ }
+
+ void impTryTest(const SdrPageView& rPageView, OutputDevice& rOutDev)
+ {
+ if(rPageView.GetPage() && rPageView.GetPage()->GetObjCount() >= 2L)
+ {
+ SdrPage* pPage = rPageView.GetPage();
+ SdrObject* pObjA = pPage->GetObj(0L);
+
+ if(pObjA && pObjA->ISA(SdrPathObj))
+ {
+ basegfx::B2DPolyPolygon aPolyA(((SdrPathObj*)pObjA)->GetPathPoly());
+ aPolyA = basegfx::tools::correctOrientations(aPolyA);
+
+ basegfx::B2DPolyPolygon aPolyB;
+
+ for(sal_uInt32 a(1L); a < rPageView.GetPage()->GetObjCount(); a++)
+ {
+ SdrObject* pObjB = pPage->GetObj(a);
+
+ if(pObjB && pObjB->ISA(SdrPathObj))
+ {
+ basegfx::B2DPolyPolygon aCandidate(((SdrPathObj*)pObjB)->GetPathPoly());
+ aCandidate = basegfx::tools::correctOrientations(aCandidate);
+ aPolyB.append(aCandidate);
+ }
+ }
+
+ if(aPolyA.count() && aPolyA.isClosed() && aPolyB.count())
+ {
+ // poly A is the clipregion, clip poly b against it. Algo depends on
+ // poly b being closed.
+ basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolyPolygonOnPolyPolygon(aPolyB, aPolyA));
+
+ for(sal_uInt32 a(0L); a < aResult.count(); a++)
+ {
+ Color aColor(rand()%255, rand()%255, rand()%255);
+ impPaintStrokePolygon(aResult.getB2DPolygon(a), rOutDev, aColor);
+ }
+
+ bool bBla = true;
+ }
+ }
+ }
+ }
+} // end of anonymous namespace
+#endif // CLIPPER_TEST
+
+//////////////////////////////////////////////////////////////////////////////
+
+void SdrPageWindow::RedrawAll(sdr::contact::ViewObjectContactRedirector* pRedirector) const
+{
+ // set Redirector
+ GetObjectContact().SetViewObjectContactRedirector(pRedirector);
+
+ // set PaintingPageView
+ const SdrView& rView = mrPageView.GetView();
+ SdrModel& rModel = *((SdrModel*)rView.GetModel());
+
+ // get to be processed layers
+ const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
+ SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
+
+ // create PaintInfoRec, #114359# use Rectangle only temporarily
+ const Region& rRegion = GetPaintWindow().GetRedrawRegion();
+
+ // create processing data
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // Draw all layers. do NOT draw form layer from CompleteRedraw, this is done separate
+ // as a single layer paint
+ const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
+ const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
+ aProcessLayers.Clear(nControlLayerId);
+
+ // still something to paint?
+ if(!aProcessLayers.IsEmpty())
+ {
+ aDisplayInfo.SetProcessLayers(aProcessLayers);
+
+ // Set region as redraw area
+ aDisplayInfo.SetRedrawArea(rRegion);
+
+ // Draw/Impress
+ aDisplayInfo.SetPageProcessingActive(rView.IsPagePaintingAllowed()); // #i72889#
+
+ // paint page
+ GetObjectContact().ProcessDisplay(aDisplayInfo);
+ }
+
+ // reset redirector
+ GetObjectContact().SetViewObjectContactRedirector(0L);
+
+ // LineClip test
+#ifdef CLIPPER_TEST
+ if(true)
+ {
+ impTryTest(GetPageView(), GetPaintWindow().GetOutputDevice());
+ }
+#endif // CLIPPER_TEST
+}
+
+void SdrPageWindow::RedrawLayer(const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector) const
+{
+ // set redirector
+ GetObjectContact().SetViewObjectContactRedirector(pRedirector);
+
+ // set PaintingPageView
+ const SdrView& rView = mrPageView.GetView();
+ SdrModel& rModel = *((SdrModel*)rView.GetModel());
+
+ // get the layers to process
+ const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
+ SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
+
+ // is the given layer visible at all?
+ if(aProcessLayers.IsSet(*pId))
+ {
+ // find out if we are painting the ControlLayer
+ const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
+ const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
+ const sal_Bool bControlLayerProcessingActive(pId && nControlLayerId == *pId);
+
+ // create PaintInfoRec, use Rectangle only temporarily
+ const Region& rRegion = GetPaintWindow().GetRedrawRegion();
+
+ // create processing data
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // is it the control layer? If Yes, set flag
+ aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
+
+ // Draw just the one given layer
+ aProcessLayers.ClearAll();
+ aProcessLayers.Set(*pId);
+
+ aDisplayInfo.SetProcessLayers(aProcessLayers);
+
+ // Set region as redraw area
+ aDisplayInfo.SetRedrawArea(rRegion);
+
+ // Writer or calc, coming from original RedrawOneLayer.
+ // #i72889# no page painting for layer painting
+ aDisplayInfo.SetPageProcessingActive(false);
+
+ // paint page
+ GetObjectContact().ProcessDisplay(aDisplayInfo);
+ }
+
+ // reset redirector
+ GetObjectContact().SetViewObjectContactRedirector(0L);
+}
+
+// Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
+void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
+{
+ if(GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
+ {
+ const SvtOptionsDrawinglayer aDrawinglayerOpt;
+ Window& rWindow(static_cast< Window& >(GetPaintWindow().GetOutputDevice()));
+ basegfx::B2DRange aDiscreteRange(rRange);
+ aDiscreteRange.transform(rWindow.GetViewTransformation());
+
+ if(aDrawinglayerOpt.IsAntiAliasing())
+ {
+ // invalidate one discrete unit more under the assumption that AA
+ // needs one pixel more
+ aDiscreteRange.grow(1.0);
+ }
+
+ const Rectangle aVCLDiscreteRectangle(
+ (sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()),
+ (sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
+ const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
+
+ rWindow.EnableMapMode(false);
+ rWindow.Invalidate(aVCLDiscreteRectangle, INVALIDATE_NOERASE);
+ rWindow.EnableMapMode(bWasMapModeEnabled);
+ }
+}
+
+// #110094# ObjectContact section
+sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
+{
+ if(!mpObjectContact)
+ {
+ ((SdrPageWindow*)this)->mpObjectContact = ((SdrPageWindow*)this)->CreateViewSpecificObjectContact();
+ }
+
+ return *mpObjectContact;
+}
+
+bool SdrPageWindow::HasObjectContact() const
+{
+ return ( mpObjectContact != NULL );
+}
+
+// #i26631#
+void SdrPageWindow::ResetObjectContact()
+{
+ if(mpObjectContact)
+ {
+ delete mpObjectContact;
+ mpObjectContact = 0L;
+ }
+}
+
+void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
+{
+ const ::sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const ::sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
+ DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
+ if ( pOC )
+ pOC->SetUNOControlsDesignMode( _bDesignMode );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/sdrpaintwindow.cxx b/svx/source/svdraw/sdrpaintwindow.cxx
new file mode 100644
index 000000000000..d173c1eea4d5
--- /dev/null
+++ b/svx/source/svdraw/sdrpaintwindow.cxx
@@ -0,0 +1,312 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <sdrpaintwindow.hxx>
+#include <svx/sdr/overlay/overlaymanagerbuffered.hxx>
+#include <svx/svdpntv.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/svapp.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPreRenderDevice::SdrPreRenderDevice(OutputDevice& rOriginal)
+: mrOutputDevice(rOriginal)
+{
+}
+
+SdrPreRenderDevice::~SdrPreRenderDevice()
+{
+}
+
+void SdrPreRenderDevice::PreparePreRenderDevice()
+{
+ // compare size of maPreRenderDevice with size of visible area
+ if(maPreRenderDevice.GetOutputSizePixel() != mrOutputDevice.GetOutputSizePixel())
+ {
+ maPreRenderDevice.SetOutputSizePixel(mrOutputDevice.GetOutputSizePixel());
+ }
+
+ // Also compare the MapModes for zoom/scroll changes
+ if(maPreRenderDevice.GetMapMode() != mrOutputDevice.GetMapMode())
+ {
+ maPreRenderDevice.SetMapMode(mrOutputDevice.GetMapMode());
+ }
+
+ // #i29186#
+ maPreRenderDevice.SetDrawMode(mrOutputDevice.GetDrawMode());
+ maPreRenderDevice.SetSettings(mrOutputDevice.GetSettings());
+}
+
+void SdrPreRenderDevice::OutputPreRenderDevice(const Region& rExpandedRegion)
+{
+ // region to pixels
+ Region aRegionPixel(mrOutputDevice.LogicToPixel(rExpandedRegion));
+ RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects());
+ Rectangle aRegionRectanglePixel;
+
+ // MapModes off
+ sal_Bool bMapModeWasEnabledDest(mrOutputDevice.IsMapModeEnabled());
+ sal_Bool bMapModeWasEnabledSource(maPreRenderDevice.IsMapModeEnabled());
+ mrOutputDevice.EnableMapMode(sal_False);
+ maPreRenderDevice.EnableMapMode(sal_False);
+
+ while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel))
+ {
+ // for each rectangle, copy the area
+ const Point aTopLeft(aRegionRectanglePixel.TopLeft());
+ const Size aSize(aRegionRectanglePixel.GetSize());
+
+ mrOutputDevice.DrawOutDev(
+ aTopLeft, aSize,
+ aTopLeft, aSize,
+ maPreRenderDevice);
+
+#ifdef DBG_UTIL
+ // #i74769#
+ static bool bDoPaintForVisualControlRegion(false);
+ if(bDoPaintForVisualControlRegion)
+ {
+ Color aColor((((((rand()&0x7f)|0x80)<<8L)|((rand()&0x7f)|0x80))<<8L)|((rand()&0x7f)|0x80));
+ mrOutputDevice.SetLineColor(aColor);
+ mrOutputDevice.SetFillColor();
+ mrOutputDevice.DrawRect(aRegionRectanglePixel);
+ }
+#endif
+ }
+
+ aRegionPixel.EndEnumRects(aRegionHandle);
+
+ mrOutputDevice.EnableMapMode(bMapModeWasEnabledDest);
+ maPreRenderDevice.EnableMapMode(bMapModeWasEnabledSource);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPaintWindow::impCreateOverlayManager(const bool bUseBuffer)
+{
+ // When the buffer usage has changed then we have to create a new
+ // overlay manager. Save the current one so that later we can move its
+ // overlay objects to the new one.
+ sdr::overlay::OverlayManager* pOldOverlayManager = NULL;
+
+ if(mbUseBuffer != bUseBuffer)
+ {
+ mbUseBuffer = bUseBuffer;
+ pOldOverlayManager = mpOverlayManager;
+ mpOverlayManager = NULL;
+ }
+
+ // not yet one created?
+ if(!mpOverlayManager)
+ {
+ // is it a window?
+ if(OUTDEV_WINDOW == GetOutputDevice().GetOutDevType())
+ {
+ // decide which OverlayManager to use
+ if(GetPaintView().IsBufferedOverlayAllowed() && mbUseBuffer)
+ {
+ // buffered OverlayManager, buffers it's background and refreshes from there
+ // for pure overlay changes (no system redraw). The 3rd parameter specifies
+ // if that refresh itself will use a 2nd vdev to avoid flickering.
+ // Also hand over the evtl. existing old OverlayManager; this means to take over
+ // the registered OverlayObjects from it
+ mpOverlayManager = new ::sdr::overlay::OverlayManagerBuffered(GetOutputDevice(), pOldOverlayManager, true);
+ }
+ else
+ {
+ // unbuffered OverlayManager, just invalidates places where changes
+ // take place
+ // Also hand over the evtl. existing old OverlayManager; this means to take over
+ // the registered OverlayObjects from it
+ mpOverlayManager = new ::sdr::overlay::OverlayManager(GetOutputDevice(), pOldOverlayManager);
+ }
+
+ OSL_ENSURE(mpOverlayManager, "SdrPaintWindow::SdrPaintWindow: Could not allocate an overlayManager (!)");
+
+ // Request a repaint so that the buffered overlay manager fills
+ // its buffer properly. This is a workaround for missing buffer
+ // updates.
+ Window* pWindow = dynamic_cast<Window*>(&GetOutputDevice());
+ if (pWindow != NULL)
+ pWindow->Invalidate();
+
+ Color aColA(GetPaintView().getOptionsDrawinglayer().GetStripeColorA());
+ Color aColB(GetPaintView().getOptionsDrawinglayer().GetStripeColorB());
+
+ if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor();
+ aColB.Invert();
+ }
+
+ mpOverlayManager->setStripeColorA(aColA);
+ mpOverlayManager->setStripeColorB(aColB);
+ mpOverlayManager->setStripeLengthPixel(GetPaintView().getOptionsDrawinglayer().GetStripeLength());
+ }
+ }
+
+ // OverlayObjects are transfered for the evtl. newly created OverlayManager by handing over
+ // at construction time
+ if(pOldOverlayManager)
+ {
+ // The old overlay manager is not used anymore and can be (has to be) deleted.
+ delete pOldOverlayManager;
+ }
+}
+
+SdrPaintWindow::SdrPaintWindow(SdrPaintView& rNewPaintView, OutputDevice& rOut)
+: mrOutputDevice(rOut),
+ mrPaintView(rNewPaintView),
+ mpOverlayManager(0L),
+ mpPreRenderDevice(0L),
+ mbTemporaryTarget(false), // #i72889#
+ mbUseBuffer(true)
+{
+}
+
+SdrPaintWindow::~SdrPaintWindow()
+{
+ if(mpOverlayManager)
+ {
+ delete mpOverlayManager;
+ mpOverlayManager = 0L;
+ }
+
+ DestroyPreRenderDevice();
+}
+
+::sdr::overlay::OverlayManager* SdrPaintWindow::GetOverlayManager() const
+{
+ if(!mpOverlayManager)
+ {
+ // Create buffered overlay manager by default.
+ const_cast< SdrPaintWindow* >(this)->impCreateOverlayManager(true);
+ }
+
+ return mpOverlayManager;
+}
+
+Rectangle SdrPaintWindow::GetVisibleArea() const
+{
+ Size aVisSizePixel(GetOutputDevice().GetOutputSizePixel());
+ return Rectangle(GetOutputDevice().PixelToLogic(Rectangle(Point(0,0), aVisSizePixel)));
+}
+
+sal_Bool SdrPaintWindow::OutputToRecordingMetaFile() const
+{
+ GDIMetaFile* pMetaFile = mrOutputDevice.GetConnectMetaFile();
+ return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause());
+}
+
+void SdrPaintWindow::PreparePreRenderDevice()
+{
+ const sal_Bool bPrepareBufferedOutput(
+ mrPaintView.IsBufferedOutputAllowed()
+ && !OutputToPrinter()
+ && !OutputToVirtualDevice()
+ && !OutputToRecordingMetaFile());
+
+ if(bPrepareBufferedOutput)
+ {
+ if(!mpPreRenderDevice)
+ {
+ mpPreRenderDevice = new SdrPreRenderDevice(mrOutputDevice);
+ }
+ }
+ else
+ {
+ DestroyPreRenderDevice();
+ }
+
+ if(mpPreRenderDevice)
+ {
+ mpPreRenderDevice->PreparePreRenderDevice();
+ }
+}
+
+void SdrPaintWindow::DestroyPreRenderDevice()
+{
+ if(mpPreRenderDevice)
+ {
+ delete mpPreRenderDevice;
+ mpPreRenderDevice = 0L;
+ }
+}
+
+void SdrPaintWindow::OutputPreRenderDevice(const Region& rExpandedRegion)
+{
+ if(mpPreRenderDevice)
+ {
+ mpPreRenderDevice->OutputPreRenderDevice(rExpandedRegion);
+ }
+}
+
+// #i73602# add flag if buffer shall be used
+void SdrPaintWindow::DrawOverlay(const Region& rRegion, bool bUseBuffer)
+{
+ // ## force creation of OverlayManager since the first repaint needs to
+ // save the background to get a controlled start into overlay mechanism
+ impCreateOverlayManager(bUseBuffer);
+
+ if(mpOverlayManager && !OutputToPrinter())
+ {
+ if(mpPreRenderDevice && bUseBuffer)
+ {
+ mpOverlayManager->completeRedraw(rRegion, &mpPreRenderDevice->GetPreRenderDevice());
+ }
+ else
+ {
+ mpOverlayManager->completeRedraw(rRegion);
+ }
+ }
+}
+
+void SdrPaintWindow::HideOverlay(const Region& rRegion)
+{
+ if(mpOverlayManager && !OutputToPrinter())
+ {
+ if(!mpPreRenderDevice)
+ {
+ mpOverlayManager->restoreBackground(rRegion);
+ }
+ }
+}
+
+const Region& SdrPaintWindow::GetRedrawRegion() const
+{
+ return maRedrawRegion;
+}
+
+void SdrPaintWindow::SetRedrawRegion(const Region& rNew)
+{
+ maRedrawRegion = rNew;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/selectioncontroller.cxx b/svx/source/svdraw/selectioncontroller.cxx
new file mode 100644
index 000000000000..d76f95837441
--- /dev/null
+++ b/svx/source/svdraw/selectioncontroller.cxx
@@ -0,0 +1,114 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <tools/debug.hxx>
+#include <svx/selectioncontroller.hxx>
+
+namespace sdr
+{
+
+bool SelectionController::onKeyInput(const KeyEvent& /*rKEvt*/, Window* /*pWin*/)
+{
+ return false;
+}
+
+bool SelectionController::onMouseButtonDown(const MouseEvent& /*rMEvt*/, Window* /*pWin*/)
+{
+ return false;
+}
+
+bool SelectionController::onMouseButtonUp(const MouseEvent& /*rMEvt*/, Window* /*pWin*/)
+{
+ return false;
+}
+
+bool SelectionController::onMouseMove(const MouseEvent& /*rMEvt*/, Window* /*pWin*/)
+{
+ return false;
+}
+
+void SelectionController::onSelectionHasChanged()
+{
+}
+
+void SelectionController::GetState( SfxItemSet& /*rSet*/ )
+{
+}
+
+void SelectionController::Execute( SfxRequest& /*rReq*/ )
+{
+}
+
+bool SelectionController::DeleteMarked()
+{
+ return false;
+}
+
+bool SelectionController::GetAttributes(SfxItemSet& /*rTargetSet*/, bool /*bOnlyHardAttr*/) const
+{
+ return false;
+}
+
+bool SelectionController::SetAttributes(const SfxItemSet& /*rSet*/, bool /*bReplaceAll*/)
+{
+ return false;
+}
+
+bool SelectionController::GetStyleSheet( SfxStyleSheet* &/*rpStyleSheet*/ ) const
+{
+ return false;
+}
+
+bool SelectionController::SetStyleSheet( SfxStyleSheet* /*pStyleSheet*/, bool /*bDontRemoveHardAttr*/ )
+{
+ return false;
+}
+
+bool SelectionController::GetMarkedObjModel( SdrPage* /*pNewPage*/ )
+{
+ return false;
+}
+
+bool SelectionController::PasteObjModel( const SdrModel& /*rModel*/ )
+{
+ return false;
+}
+
+bool SelectionController::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& /*rFormatSet*/ )
+{
+ return false;
+}
+
+bool SelectionController::ApplyFormatPaintBrush( SfxItemSet& /*rFormatSet*/, bool /*bNoCharacterFormats*/, bool /*bNoParagraphFormats*/ )
+{
+ return false;
+}
+
+}
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
new file mode 100644
index 000000000000..3a3935f819f8
--- /dev/null
+++ b/svx/source/svdraw/svdattr.cxx
@@ -0,0 +1,2429 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+
+#include <com/sun/star/drawing/TextFitToSizeType.hpp>
+#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/TextAnimationKind.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/drawing/TextAnimationDirection.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <com/sun/star/drawing/MeasureKind.hpp>
+#include <com/sun/star/drawing/MeasureTextHorzPos.hpp>
+#include <com/sun/star/drawing/MeasureTextVertPos.hpp>
+#include <com/sun/star/drawing/CircleKind.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <unotools/intlwrapper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdpool.hxx>
+
+#include <svl/solar.hrc>
+#include "editeng/xmlcnitm.hxx"
+
+#include <svx/svxids.hrc>
+#include <svx/xtable.hxx> // fuer RGB_Color()
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx> // fuer DEGREE_CHAR
+#include <svx/svdtrans.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc"
+#include <svx/sdgcpitm.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/sdtfchim.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <tools/bigint.hxx>
+#include <tools/stream.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/svx3ditems.hxx>
+
+#define ITEMID_BOX SDRATTR_TABLE_BORDER
+#define ITEMID_BOXINFO SDRATTR_TABLE_BORDER_INNER
+#include "editeng/boxitem.hxx"
+
+#define ITEMID_SHADOW SDRATTR_TABLE_BORDER_SHADOW
+#include "editeng/shaditem.hxx"
+
+#define ITEMID_LINE 0
+#include "editeng/bolnitem.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* Konstruktor
+|*
+\************************************************************************/
+
+SdrItemPool::SdrItemPool(
+ SfxItemPool* _pMaster,
+ sal_Bool bLoadRefCounts)
+: XOutdevItemPool(_pMaster, SDRATTR_START, SDRATTR_END, bLoadRefCounts)
+{
+ // preapare some constants
+ const Color aNullCol(RGB_Color(COL_BLACK));
+ const XubString aEmptyStr;
+ const sal_Int32 nDefEdgeDist(500L); // Erstmal hart defaulted fuer Draw (100TH_MM). hier muss noch der MapMode beruecksichtigt werden.
+
+ // init the non-persistent items
+ for(sal_uInt16 i(SDRATTR_NOTPERSIST_FIRST); i <= SDRATTR_NOTPERSIST_LAST; i++)
+ {
+ mpLocalItemInfos[i - SDRATTR_START]._nFlags=0;
+ }
+
+ // init own PoolDefaults
+ mppLocalPoolDefaults[SDRATTR_SHADOW -SDRATTR_START]=new SdrShadowItem;
+ mppLocalPoolDefaults[SDRATTR_SHADOWCOLOR -SDRATTR_START]=new SdrShadowColorItem(aEmptyStr,aNullCol);
+ mppLocalPoolDefaults[SDRATTR_SHADOWXDIST -SDRATTR_START]=new SdrShadowXDistItem;
+ mppLocalPoolDefaults[SDRATTR_SHADOWYDIST -SDRATTR_START]=new SdrShadowYDistItem;
+ mppLocalPoolDefaults[SDRATTR_SHADOWTRANSPARENCE-SDRATTR_START]=new SdrShadowTransparenceItem;
+ mppLocalPoolDefaults[SDRATTR_SHADOW3D -SDRATTR_START]=new SfxVoidItem(SDRATTR_SHADOW3D );
+ mppLocalPoolDefaults[SDRATTR_SHADOWPERSP -SDRATTR_START]=new SfxVoidItem(SDRATTR_SHADOWPERSP );
+ mppLocalPoolDefaults[SDRATTR_CAPTIONTYPE -SDRATTR_START]=new SdrCaptionTypeItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONFIXEDANGLE-SDRATTR_START]=new SdrCaptionFixedAngleItem;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONANGLE -SDRATTR_START]=new SdrCaptionAngleItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONGAP -SDRATTR_START]=new SdrCaptionGapItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONESCDIR -SDRATTR_START]=new SdrCaptionEscDirItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONESCISREL -SDRATTR_START]=new SdrCaptionEscIsRelItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONESCREL -SDRATTR_START]=new SdrCaptionEscRelItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONESCABS -SDRATTR_START]=new SdrCaptionEscAbsItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONLINELEN -SDRATTR_START]=new SdrCaptionLineLenItem ;
+ mppLocalPoolDefaults[SDRATTR_CAPTIONFITLINELEN-SDRATTR_START]=new SdrCaptionFitLineLenItem;
+ mppLocalPoolDefaults[SDRATTR_ECKENRADIUS -SDRATTR_START]=new SdrEckenradiusItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_MINFRAMEHEIGHT -SDRATTR_START]=new SdrTextMinFrameHeightItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_AUTOGROWHEIGHT -SDRATTR_START]=new SdrTextAutoGrowHeightItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_FITTOSIZE -SDRATTR_START]=new SdrTextFitToSizeTypeItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_LEFTDIST -SDRATTR_START]=new SdrTextLeftDistItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_RIGHTDIST -SDRATTR_START]=new SdrTextRightDistItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_UPPERDIST -SDRATTR_START]=new SdrTextUpperDistItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_LOWERDIST -SDRATTR_START]=new SdrTextLowerDistItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_VERTADJUST -SDRATTR_START]=new SdrTextVertAdjustItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_MAXFRAMEHEIGHT -SDRATTR_START]=new SdrTextMaxFrameHeightItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_MINFRAMEWIDTH -SDRATTR_START]=new SdrTextMinFrameWidthItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_MAXFRAMEWIDTH -SDRATTR_START]=new SdrTextMaxFrameWidthItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_AUTOGROWWIDTH -SDRATTR_START]=new SdrTextAutoGrowWidthItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_HORZADJUST -SDRATTR_START]=new SdrTextHorzAdjustItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANIKIND -SDRATTR_START]=new SdrTextAniKindItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANIDIRECTION -SDRATTR_START]=new SdrTextAniDirectionItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANISTARTINSIDE -SDRATTR_START]=new SdrTextAniStartInsideItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANISTOPINSIDE -SDRATTR_START]=new SdrTextAniStopInsideItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANICOUNT -SDRATTR_START]=new SdrTextAniCountItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANIDELAY -SDRATTR_START]=new SdrTextAniDelayItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_ANIAMOUNT -SDRATTR_START]=new SdrTextAniAmountItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_CONTOURFRAME -SDRATTR_START]=new SdrTextContourFrameItem;
+ mppLocalPoolDefaults[SDRATTR_CUSTOMSHAPE_ADJUSTMENT -SDRATTR_START]=new SdrCustomShapeAdjustmentItem;
+ mppLocalPoolDefaults[SDRATTR_XMLATTRIBUTES -SDRATTR_START]=new SvXMLAttrContainerItem( SDRATTR_XMLATTRIBUTES );
+ mppLocalPoolDefaults[SDRATTR_TEXT_USEFIXEDCELLHEIGHT -SDRATTR_START]=new SdrTextFixedCellHeightItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_WORDWRAP -SDRATTR_START]=new SdrTextWordWrapItem;
+ mppLocalPoolDefaults[SDRATTR_TEXT_AUTOGROWSIZE -SDRATTR_START]=new SdrTextAutoGrowSizeItem;
+ mppLocalPoolDefaults[SDRATTR_EDGEKIND -SDRATTR_START]=new SdrEdgeKindItem;
+ mppLocalPoolDefaults[SDRATTR_EDGENODE1HORZDIST-SDRATTR_START]=new SdrEdgeNode1HorzDistItem(nDefEdgeDist);
+ mppLocalPoolDefaults[SDRATTR_EDGENODE1VERTDIST-SDRATTR_START]=new SdrEdgeNode1VertDistItem(nDefEdgeDist);
+ mppLocalPoolDefaults[SDRATTR_EDGENODE2HORZDIST-SDRATTR_START]=new SdrEdgeNode2HorzDistItem(nDefEdgeDist);
+ mppLocalPoolDefaults[SDRATTR_EDGENODE2VERTDIST-SDRATTR_START]=new SdrEdgeNode2VertDistItem(nDefEdgeDist);
+ mppLocalPoolDefaults[SDRATTR_EDGENODE1GLUEDIST-SDRATTR_START]=new SdrEdgeNode1GlueDistItem;
+ mppLocalPoolDefaults[SDRATTR_EDGENODE2GLUEDIST-SDRATTR_START]=new SdrEdgeNode2GlueDistItem;
+ mppLocalPoolDefaults[SDRATTR_EDGELINEDELTAANZ -SDRATTR_START]=new SdrEdgeLineDeltaAnzItem;
+ mppLocalPoolDefaults[SDRATTR_EDGELINE1DELTA -SDRATTR_START]=new SdrEdgeLine1DeltaItem;
+ mppLocalPoolDefaults[SDRATTR_EDGELINE2DELTA -SDRATTR_START]=new SdrEdgeLine2DeltaItem;
+ mppLocalPoolDefaults[SDRATTR_EDGELINE3DELTA -SDRATTR_START]=new SdrEdgeLine3DeltaItem;
+ mppLocalPoolDefaults[SDRATTR_MEASUREKIND -SDRATTR_START]=new SdrMeasureKindItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTHPOS -SDRATTR_START]=new SdrMeasureTextHPosItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTVPOS -SDRATTR_START]=new SdrMeasureTextVPosItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURELINEDIST -SDRATTR_START]=new SdrMeasureLineDistItem(800);
+ mppLocalPoolDefaults[SDRATTR_MEASUREHELPLINEOVERHANG -SDRATTR_START]=new SdrMeasureHelplineOverhangItem(200);
+ mppLocalPoolDefaults[SDRATTR_MEASUREHELPLINEDIST -SDRATTR_START]=new SdrMeasureHelplineDistItem(100);
+ mppLocalPoolDefaults[SDRATTR_MEASUREHELPLINE1LEN -SDRATTR_START]=new SdrMeasureHelpline1LenItem;
+ mppLocalPoolDefaults[SDRATTR_MEASUREHELPLINE2LEN -SDRATTR_START]=new SdrMeasureHelpline2LenItem;
+ mppLocalPoolDefaults[SDRATTR_MEASUREBELOWREFEDGE -SDRATTR_START]=new SdrMeasureBelowRefEdgeItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTROTA90 -SDRATTR_START]=new SdrMeasureTextRota90Item;
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTUPSIDEDOWN -SDRATTR_START]=new SdrMeasureTextUpsideDownItem;
+ mppLocalPoolDefaults[SDRATTR_MEASUREOVERHANG -SDRATTR_START]=new SdrMeasureOverhangItem(600);
+ mppLocalPoolDefaults[SDRATTR_MEASUREUNIT -SDRATTR_START]=new SdrMeasureUnitItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURESCALE -SDRATTR_START]=new SdrMeasureScaleItem;
+ mppLocalPoolDefaults[SDRATTR_MEASURESHOWUNIT -SDRATTR_START]=new SdrMeasureShowUnitItem;
+ mppLocalPoolDefaults[SDRATTR_MEASUREFORMATSTRING -SDRATTR_START]=new SdrMeasureFormatStringItem();
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTAUTOANGLE -SDRATTR_START]=new SdrMeasureTextAutoAngleItem();
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTAUTOANGLEVIEW-SDRATTR_START]=new SdrMeasureTextAutoAngleViewItem();
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTISFIXEDANGLE -SDRATTR_START]=new SdrMeasureTextIsFixedAngleItem();
+ mppLocalPoolDefaults[SDRATTR_MEASURETEXTFIXEDANGLE -SDRATTR_START]=new SdrMeasureTextFixedAngleItem();
+ mppLocalPoolDefaults[SDRATTR_MEASUREDECIMALPLACES -SDRATTR_START]=new SdrMeasureDecimalPlacesItem();
+ mppLocalPoolDefaults[SDRATTR_CIRCKIND -SDRATTR_START]=new SdrCircKindItem;
+ mppLocalPoolDefaults[SDRATTR_CIRCSTARTANGLE-SDRATTR_START]=new SdrCircStartAngleItem;
+ mppLocalPoolDefaults[SDRATTR_CIRCENDANGLE -SDRATTR_START]=new SdrCircEndAngleItem;
+ mppLocalPoolDefaults[SDRATTR_OBJMOVEPROTECT -SDRATTR_START]=new SdrObjMoveProtectItem;
+ mppLocalPoolDefaults[SDRATTR_OBJSIZEPROTECT -SDRATTR_START]=new SdrObjSizeProtectItem;
+ mppLocalPoolDefaults[SDRATTR_OBJPRINTABLE -SDRATTR_START]=new SdrObjPrintableItem;
+ mppLocalPoolDefaults[SDRATTR_OBJVISIBLE -SDRATTR_START]=new SdrObjVisibleItem;
+ mppLocalPoolDefaults[SDRATTR_LAYERID -SDRATTR_START]=new SdrLayerIdItem;
+ mppLocalPoolDefaults[SDRATTR_LAYERNAME -SDRATTR_START]=new SdrLayerNameItem;
+ mppLocalPoolDefaults[SDRATTR_OBJECTNAME -SDRATTR_START]=new SdrObjectNameItem;
+ mppLocalPoolDefaults[SDRATTR_ALLPOSITIONX -SDRATTR_START]=new SdrAllPositionXItem;
+ mppLocalPoolDefaults[SDRATTR_ALLPOSITIONY -SDRATTR_START]=new SdrAllPositionYItem;
+ mppLocalPoolDefaults[SDRATTR_ALLSIZEWIDTH -SDRATTR_START]=new SdrAllSizeWidthItem;
+ mppLocalPoolDefaults[SDRATTR_ALLSIZEHEIGHT -SDRATTR_START]=new SdrAllSizeHeightItem;
+ mppLocalPoolDefaults[SDRATTR_ONEPOSITIONX -SDRATTR_START]=new SdrOnePositionXItem;
+ mppLocalPoolDefaults[SDRATTR_ONEPOSITIONY -SDRATTR_START]=new SdrOnePositionYItem;
+ mppLocalPoolDefaults[SDRATTR_ONESIZEWIDTH -SDRATTR_START]=new SdrOneSizeWidthItem;
+ mppLocalPoolDefaults[SDRATTR_ONESIZEHEIGHT -SDRATTR_START]=new SdrOneSizeHeightItem;
+ mppLocalPoolDefaults[SDRATTR_LOGICSIZEWIDTH -SDRATTR_START]=new SdrLogicSizeWidthItem;
+ mppLocalPoolDefaults[SDRATTR_LOGICSIZEHEIGHT-SDRATTR_START]=new SdrLogicSizeHeightItem;
+ mppLocalPoolDefaults[SDRATTR_ROTATEANGLE -SDRATTR_START]=new SdrRotateAngleItem;
+ mppLocalPoolDefaults[SDRATTR_SHEARANGLE -SDRATTR_START]=new SdrShearAngleItem;
+ mppLocalPoolDefaults[SDRATTR_MOVEX -SDRATTR_START]=new SdrMoveXItem;
+ mppLocalPoolDefaults[SDRATTR_MOVEY -SDRATTR_START]=new SdrMoveYItem;
+ mppLocalPoolDefaults[SDRATTR_RESIZEXONE -SDRATTR_START]=new SdrResizeXOneItem;
+ mppLocalPoolDefaults[SDRATTR_RESIZEYONE -SDRATTR_START]=new SdrResizeYOneItem;
+ mppLocalPoolDefaults[SDRATTR_ROTATEONE -SDRATTR_START]=new SdrRotateOneItem;
+ mppLocalPoolDefaults[SDRATTR_HORZSHEARONE -SDRATTR_START]=new SdrHorzShearOneItem;
+ mppLocalPoolDefaults[SDRATTR_VERTSHEARONE -SDRATTR_START]=new SdrVertShearOneItem;
+ mppLocalPoolDefaults[SDRATTR_RESIZEXALL -SDRATTR_START]=new SdrResizeXAllItem;
+ mppLocalPoolDefaults[SDRATTR_RESIZEYALL -SDRATTR_START]=new SdrResizeYAllItem;
+ mppLocalPoolDefaults[SDRATTR_ROTATEALL -SDRATTR_START]=new SdrRotateAllItem;
+ mppLocalPoolDefaults[SDRATTR_HORZSHEARALL -SDRATTR_START]=new SdrHorzShearAllItem;
+ mppLocalPoolDefaults[SDRATTR_VERTSHEARALL -SDRATTR_START]=new SdrVertShearAllItem;
+ mppLocalPoolDefaults[SDRATTR_TRANSFORMREF1X -SDRATTR_START]=new SdrTransformRef1XItem;
+ mppLocalPoolDefaults[SDRATTR_TRANSFORMREF1Y -SDRATTR_START]=new SdrTransformRef1YItem;
+ mppLocalPoolDefaults[SDRATTR_TRANSFORMREF2X -SDRATTR_START]=new SdrTransformRef2XItem;
+ mppLocalPoolDefaults[SDRATTR_TRANSFORMREF2Y -SDRATTR_START]=new SdrTransformRef2YItem;
+ mppLocalPoolDefaults[SDRATTR_TEXTDIRECTION -SDRATTR_START]=new SvxWritingModeItem(com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION);
+ mppLocalPoolDefaults[ SDRATTR_GRAFRED - SDRATTR_START] = new SdrGrafRedItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFGREEN - SDRATTR_START] = new SdrGrafGreenItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFBLUE - SDRATTR_START] = new SdrGrafBlueItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFLUMINANCE - SDRATTR_START] = new SdrGrafLuminanceItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFCONTRAST - SDRATTR_START] = new SdrGrafContrastItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFGAMMA - SDRATTR_START] = new SdrGrafGamma100Item;
+ mppLocalPoolDefaults[ SDRATTR_GRAFTRANSPARENCE - SDRATTR_START] = new SdrGrafTransparenceItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFINVERT - SDRATTR_START] = new SdrGrafInvertItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFMODE - SDRATTR_START] = new SdrGrafModeItem;
+ mppLocalPoolDefaults[ SDRATTR_GRAFCROP - SDRATTR_START] = new SdrGrafCropItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_PERCENT_DIAGONAL - SDRATTR_START ] = new Svx3DPercentDiagonalItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_BACKSCALE - SDRATTR_START ] = new Svx3DBackscaleItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_DEPTH - SDRATTR_START ] = new Svx3DDepthItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_HORZ_SEGS - SDRATTR_START ] = new Svx3DHorizontalSegmentsItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_VERT_SEGS - SDRATTR_START ] = new Svx3DVerticalSegmentsItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_END_ANGLE - SDRATTR_START ] = new Svx3DEndAngleItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_DOUBLE_SIDED - SDRATTR_START ] = new Svx3DDoubleSidedItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_NORMALS_KIND - SDRATTR_START ] = new Svx3DNormalsKindItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_NORMALS_INVERT - SDRATTR_START ] = new Svx3DNormalsInvertItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_TEXTURE_PROJ_X - SDRATTR_START ] = new Svx3DTextureProjectionXItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_TEXTURE_PROJ_Y - SDRATTR_START ] = new Svx3DTextureProjectionYItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_SHADOW_3D - SDRATTR_START ] = new Svx3DShadow3DItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_MAT_COLOR - SDRATTR_START ] = new Svx3DMaterialColorItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_MAT_EMISSION - SDRATTR_START ] = new Svx3DMaterialEmissionItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_MAT_SPECULAR - SDRATTR_START ] = new Svx3DMaterialSpecularItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY - SDRATTR_START ] = new Svx3DMaterialSpecularIntensityItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_TEXTURE_KIND - SDRATTR_START ] = new Svx3DTextureKindItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_TEXTURE_MODE - SDRATTR_START ] = new Svx3DTextureModeItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_TEXTURE_FILTER - SDRATTR_START ] = new Svx3DTextureFilterItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_SMOOTH_NORMALS - SDRATTR_START ] = new Svx3DSmoothNormalsItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_SMOOTH_LIDS - SDRATTR_START ] = new Svx3DSmoothLidsItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_CHARACTER_MODE - SDRATTR_START ] = new Svx3DCharacterModeItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_CLOSE_FRONT - SDRATTR_START ] = new Svx3DCloseFrontItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_CLOSE_BACK - SDRATTR_START ] = new Svx3DCloseBackItem;
+ mppLocalPoolDefaults[ SDRATTR_3DOBJ_REDUCED_LINE_GEOMETRY - SDRATTR_START ] = new Svx3DReducedLineGeometryItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_PERSPECTIVE - SDRATTR_START ] = new Svx3DPerspectiveItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_DISTANCE - SDRATTR_START ] = new Svx3DDistanceItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_FOCAL_LENGTH - SDRATTR_START ] = new Svx3DFocalLengthItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_TWO_SIDED_LIGHTING - SDRATTR_START ] = new Svx3DTwoSidedLightingItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_1 - SDRATTR_START ] = new Svx3DLightcolor1Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_2 - SDRATTR_START ] = new Svx3DLightcolor2Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_3 - SDRATTR_START ] = new Svx3DLightcolor3Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_4 - SDRATTR_START ] = new Svx3DLightcolor4Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_5 - SDRATTR_START ] = new Svx3DLightcolor5Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_6 - SDRATTR_START ] = new Svx3DLightcolor6Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_7 - SDRATTR_START ] = new Svx3DLightcolor7Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTCOLOR_8 - SDRATTR_START ] = new Svx3DLightcolor8Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_AMBIENTCOLOR - SDRATTR_START ] = new Svx3DAmbientcolorItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_1 - SDRATTR_START ] = new Svx3DLightOnOff1Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_2 - SDRATTR_START ] = new Svx3DLightOnOff2Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_3 - SDRATTR_START ] = new Svx3DLightOnOff3Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_4 - SDRATTR_START ] = new Svx3DLightOnOff4Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_5 - SDRATTR_START ] = new Svx3DLightOnOff5Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_6 - SDRATTR_START ] = new Svx3DLightOnOff6Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_7 - SDRATTR_START ] = new Svx3DLightOnOff7Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTON_8 - SDRATTR_START ] = new Svx3DLightOnOff8Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_1 - SDRATTR_START ] = new Svx3DLightDirection1Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_2 - SDRATTR_START ] = new Svx3DLightDirection2Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_3 - SDRATTR_START ] = new Svx3DLightDirection3Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_4 - SDRATTR_START ] = new Svx3DLightDirection4Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_5 - SDRATTR_START ] = new Svx3DLightDirection5Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_6 - SDRATTR_START ] = new Svx3DLightDirection6Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_7 - SDRATTR_START ] = new Svx3DLightDirection7Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_LIGHTDIRECTION_8 - SDRATTR_START ] = new Svx3DLightDirection8Item;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_SHADOW_SLANT - SDRATTR_START ] = new Svx3DShadowSlantItem;
+ mppLocalPoolDefaults[ SDRATTR_3DSCENE_SHADE_MODE - SDRATTR_START ] = new Svx3DShadeModeItem;
+ mppLocalPoolDefaults[ SDRATTR_CUSTOMSHAPE_ENGINE - SDRATTR_START ] = new SdrCustomShapeEngineItem;
+ mppLocalPoolDefaults[ SDRATTR_CUSTOMSHAPE_DATA - SDRATTR_START ] = new SdrCustomShapeDataItem;
+ mppLocalPoolDefaults[ SDRATTR_CUSTOMSHAPE_GEOMETRY - SDRATTR_START ] = new SdrCustomShapeGeometryItem;
+ mppLocalPoolDefaults[ SDRATTR_CUSTOMSHAPE_REPLACEMENT_URL - SDRATTR_START ] = new SdrCustomShapeReplacementURLItem;
+
+ SvxBoxItem* pboxItem = new SvxBoxItem( SDRATTR_TABLE_BORDER );
+ pboxItem->SetDistance( 100 );
+ mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER - SDRATTR_START ] = pboxItem;
+
+ SvxBoxInfoItem* pBoxInfoItem = new SvxBoxInfoItem( SDRATTR_TABLE_BORDER_INNER );
+
+ pBoxInfoItem->SetTable( TRUE );
+ pBoxInfoItem->SetDist( TRUE); // Abstandsfeld immer anzeigen
+// pBoxInfoItem->SetMinDist( TRUE );// Minimalgroesse in Tabellen und Absaetzen setzen
+// pBoxInfoItem->SetDefDist( MIN_BORDER_DIST );// Default-Abstand immer setzen
+ pBoxInfoItem->SetValid( VALID_DISABLE, TRUE ); // Einzelne Linien koennen nur in Tabellen DontCare-Status haben
+
+ mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_INNER - SDRATTR_START ] = pBoxInfoItem;
+// mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_SHADOW - SDRATTR_START ] = new SvxShadowItem( SDRATTR_TABLE_BORDER_SHADOW );
+ mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_TLBR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_TLBR );
+ mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_BLTR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_BLTR );
+
+ // set own ItemInfos
+ mpLocalItemInfos[SDRATTR_SHADOW-SDRATTR_START]._nSID=SID_ATTR_FILL_SHADOW;
+ mpLocalItemInfos[SDRATTR_TEXT_FITTOSIZE-SDRATTR_START]._nSID=SID_ATTR_TEXT_FITTOSIZE;
+ mpLocalItemInfos[SDRATTR_GRAFCROP-SDRATTR_START]._nSID=SID_ATTR_GRAF_CROP;
+
+ mpLocalItemInfos[SDRATTR_TABLE_BORDER - SDRATTR_START ]._nSID = SID_ATTR_BORDER_OUTER;
+ mpLocalItemInfos[SDRATTR_TABLE_BORDER_INNER - SDRATTR_START ]._nSID = SID_ATTR_BORDER_INNER;
+// mpLocalItemInfos[SDRATTR_TABLE_BORDER_SHADOW - SDRATTR_START ]._nSID = SID_ATTR_BORDER_SHADOW;
+ mpLocalItemInfos[SDRATTR_TABLE_BORDER_TLBR - SDRATTR_START ]._nSID = SID_ATTR_BORDER_DIAG_TLBR;
+ mpLocalItemInfos[SDRATTR_TABLE_BORDER_BLTR - SDRATTR_START ]._nSID = SID_ATTR_BORDER_DIAG_BLTR;
+
+ // it's my own creation level, set Defaults and ItemInfos
+ SetDefaults(mppLocalPoolDefaults);
+ SetItemInfos(mpLocalItemInfos);
+}
+
+/*************************************************************************
+|*
+|* copy ctor, sorgt dafuer, dass die static defaults gecloned werden
+|* (Parameter 2 = TRUE)
+|*
+\************************************************************************/
+
+SdrItemPool::SdrItemPool(const SdrItemPool& rPool)
+: XOutdevItemPool(rPool)
+{
+}
+
+/*************************************************************************
+|*
+|* Clone()
+|*
+\************************************************************************/
+
+SfxItemPool* __EXPORT SdrItemPool::Clone() const
+{
+ return new SdrItemPool(*this);
+}
+
+/*************************************************************************
+|*
+|* Destruktor
+|*
+\************************************************************************/
+
+SdrItemPool::~SdrItemPool()
+{
+ // dtor of SfxItemPool
+ Delete();
+
+ // clear own static Defaults
+ if(mppLocalPoolDefaults)
+ {
+ const sal_uInt16 nBeg(SDRATTR_SHADOW_FIRST - SDRATTR_START);
+ const sal_uInt16 nEnd2(SDRATTR_END - SDRATTR_START);
+
+ for(sal_uInt16 i(nBeg); i <= nEnd2; i++)
+ {
+ SetRefCount(*mppLocalPoolDefaults[i],0);
+ delete mppLocalPoolDefaults[i];
+ mppLocalPoolDefaults[i] = 0L;
+ }
+ }
+
+ // split pools before detroying
+ SetSecondaryPool(NULL);
+}
+
+SfxItemPresentation __EXPORT SdrItemPool::GetPresentation(
+ const SfxPoolItem& rItem, SfxItemPresentation ePresentation,
+ SfxMapUnit ePresentationMetric, XubString& rText,
+ const IntlWrapper * pIntlWrapper) const
+{
+ if (!IsInvalidItem(&rItem)) {
+ USHORT nWhich=rItem.Which();
+ if (nWhich>=SDRATTR_SHADOW_FIRST && nWhich<=SDRATTR_END) {
+ rItem.GetPresentation(SFX_ITEM_PRESENTATION_NAMELESS,
+ GetMetric(nWhich),ePresentationMetric,rText,
+ pIntlWrapper);
+ String aStr;
+
+ TakeItemName(nWhich, aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+
+ return ePresentation;
+ }
+ }
+ return XOutdevItemPool::GetPresentation(rItem,ePresentation,ePresentationMetric,rText,pIntlWrapper);
+}
+
+void SdrItemPool::TakeItemName(sal_uInt16 nWhich, String& rItemName)
+{
+ ResMgr* pResMgr = ImpGetResMgr();
+ USHORT nResId = SIP_UNKNOWN_ATTR;
+
+ switch (nWhich)
+ {
+ case XATTR_LINESTYLE : nResId = SIP_XA_LINESTYLE;break;
+ case XATTR_LINEDASH : nResId = SIP_XA_LINEDASH;break;
+ case XATTR_LINEWIDTH : nResId = SIP_XA_LINEWIDTH;break;
+ case XATTR_LINECOLOR : nResId = SIP_XA_LINECOLOR;break;
+ case XATTR_LINESTART : nResId = SIP_XA_LINESTART;break;
+ case XATTR_LINEEND : nResId = SIP_XA_LINEEND;break;
+ case XATTR_LINESTARTWIDTH : nResId = SIP_XA_LINESTARTWIDTH;break;
+ case XATTR_LINEENDWIDTH : nResId = SIP_XA_LINEENDWIDTH;break;
+ case XATTR_LINESTARTCENTER : nResId = SIP_XA_LINESTARTCENTER;break;
+ case XATTR_LINEENDCENTER : nResId = SIP_XA_LINEENDCENTER;break;
+ case XATTR_LINETRANSPARENCE : nResId = SIP_XA_LINETRANSPARENCE;break;
+ case XATTR_LINEJOINT : nResId = SIP_XA_LINEJOINT;break;
+ case XATTRSET_LINE : nResId = SIP_XATTRSET_LINE;break;
+
+ case XATTR_FILLSTYLE : nResId = SIP_XA_FILLSTYLE;break;
+ case XATTR_FILLCOLOR : nResId = SIP_XA_FILLCOLOR;break;
+ case XATTR_FILLGRADIENT : nResId = SIP_XA_FILLGRADIENT;break;
+ case XATTR_FILLHATCH : nResId = SIP_XA_FILLHATCH;break;
+ case XATTR_FILLBITMAP : nResId = SIP_XA_FILLBITMAP;break;
+ case XATTR_FILLTRANSPARENCE : nResId = SIP_XA_FILLTRANSPARENCE;break;
+ case XATTR_GRADIENTSTEPCOUNT : nResId = SIP_XA_GRADIENTSTEPCOUNT;break;
+ case XATTR_FILLBMP_TILE : nResId = SIP_XA_FILLBMP_TILE;break;
+ case XATTR_FILLBMP_POS : nResId = SIP_XA_FILLBMP_POS;break;
+ case XATTR_FILLBMP_SIZEX : nResId = SIP_XA_FILLBMP_SIZEX;break;
+ case XATTR_FILLBMP_SIZEY : nResId = SIP_XA_FILLBMP_SIZEY;break;
+ case XATTR_FILLFLOATTRANSPARENCE: nResId = SIP_XA_FILLFLOATTRANSPARENCE;break;
+ case XATTR_SECONDARYFILLCOLOR : nResId = SIP_XA_SECONDARYFILLCOLOR;break;
+ case XATTR_FILLBMP_SIZELOG : nResId = SIP_XA_FILLBMP_SIZELOG;break;
+ case XATTR_FILLBMP_TILEOFFSETX : nResId = SIP_XA_FILLBMP_TILEOFFSETX;break;
+ case XATTR_FILLBMP_TILEOFFSETY : nResId = SIP_XA_FILLBMP_TILEOFFSETY;break;
+ case XATTR_FILLBMP_STRETCH : nResId = SIP_XA_FILLBMP_STRETCH;break;
+ case XATTR_FILLBMP_POSOFFSETX : nResId = SIP_XA_FILLBMP_POSOFFSETX;break;
+ case XATTR_FILLBMP_POSOFFSETY : nResId = SIP_XA_FILLBMP_POSOFFSETY;break;
+ case XATTR_FILLBACKGROUND : nResId = SIP_XA_FILLBACKGROUND;break;
+
+ case XATTRSET_FILL : nResId = SIP_XATTRSET_FILL;break;
+
+ case XATTR_FORMTXTSTYLE : nResId = SIP_XA_FORMTXTSTYLE;break;
+ case XATTR_FORMTXTADJUST : nResId = SIP_XA_FORMTXTADJUST;break;
+ case XATTR_FORMTXTDISTANCE : nResId = SIP_XA_FORMTXTDISTANCE;break;
+ case XATTR_FORMTXTSTART : nResId = SIP_XA_FORMTXTSTART;break;
+ case XATTR_FORMTXTMIRROR : nResId = SIP_XA_FORMTXTMIRROR;break;
+ case XATTR_FORMTXTOUTLINE : nResId = SIP_XA_FORMTXTOUTLINE;break;
+ case XATTR_FORMTXTSHADOW : nResId = SIP_XA_FORMTXTSHADOW;break;
+ case XATTR_FORMTXTSHDWCOLOR : nResId = SIP_XA_FORMTXTSHDWCOLOR;break;
+ case XATTR_FORMTXTSHDWXVAL : nResId = SIP_XA_FORMTXTSHDWXVAL;break;
+ case XATTR_FORMTXTSHDWYVAL : nResId = SIP_XA_FORMTXTSHDWYVAL;break;
+ case XATTR_FORMTXTSTDFORM : nResId = SIP_XA_FORMTXTSTDFORM;break;
+ case XATTR_FORMTXTHIDEFORM : nResId = SIP_XA_FORMTXTHIDEFORM;break;
+ case XATTR_FORMTXTSHDWTRANSP: nResId = SIP_XA_FORMTXTSHDWTRANSP;break;
+
+ case SDRATTR_SHADOW : nResId = SIP_SA_SHADOW;break;
+ case SDRATTR_SHADOWCOLOR : nResId = SIP_SA_SHADOWCOLOR;break;
+ case SDRATTR_SHADOWXDIST : nResId = SIP_SA_SHADOWXDIST;break;
+ case SDRATTR_SHADOWYDIST : nResId = SIP_SA_SHADOWYDIST;break;
+ case SDRATTR_SHADOWTRANSPARENCE: nResId = SIP_SA_SHADOWTRANSPARENCE;break;
+ case SDRATTR_SHADOW3D : nResId = SIP_SA_SHADOW3D;break;
+ case SDRATTR_SHADOWPERSP : nResId = SIP_SA_SHADOWPERSP;break;
+
+ case SDRATTR_CAPTIONTYPE : nResId = SIP_SA_CAPTIONTYPE;break;
+ case SDRATTR_CAPTIONFIXEDANGLE: nResId = SIP_SA_CAPTIONFIXEDANGLE;break;
+ case SDRATTR_CAPTIONANGLE : nResId = SIP_SA_CAPTIONANGLE;break;
+ case SDRATTR_CAPTIONGAP : nResId = SIP_SA_CAPTIONGAP;break;
+ case SDRATTR_CAPTIONESCDIR : nResId = SIP_SA_CAPTIONESCDIR;break;
+ case SDRATTR_CAPTIONESCISREL : nResId = SIP_SA_CAPTIONESCISREL;break;
+ case SDRATTR_CAPTIONESCREL : nResId = SIP_SA_CAPTIONESCREL;break;
+ case SDRATTR_CAPTIONESCABS : nResId = SIP_SA_CAPTIONESCABS;break;
+ case SDRATTR_CAPTIONLINELEN : nResId = SIP_SA_CAPTIONLINELEN;break;
+ case SDRATTR_CAPTIONFITLINELEN: nResId = SIP_SA_CAPTIONFITLINELEN;break;
+
+ case SDRATTR_ECKENRADIUS : nResId = SIP_SA_ECKENRADIUS;break;
+ case SDRATTR_TEXT_MINFRAMEHEIGHT : nResId = SIP_SA_TEXT_MINFRAMEHEIGHT;break;
+ case SDRATTR_TEXT_AUTOGROWHEIGHT : nResId = SIP_SA_TEXT_AUTOGROWHEIGHT;break;
+ case SDRATTR_TEXT_FITTOSIZE : nResId = SIP_SA_TEXT_FITTOSIZE;break;
+ case SDRATTR_TEXT_LEFTDIST : nResId = SIP_SA_TEXT_LEFTDIST;break;
+ case SDRATTR_TEXT_RIGHTDIST : nResId = SIP_SA_TEXT_RIGHTDIST;break;
+ case SDRATTR_TEXT_UPPERDIST : nResId = SIP_SA_TEXT_UPPERDIST;break;
+ case SDRATTR_TEXT_LOWERDIST : nResId = SIP_SA_TEXT_LOWERDIST;break;
+ case SDRATTR_TEXT_VERTADJUST : nResId = SIP_SA_TEXT_VERTADJUST;break;
+ case SDRATTR_TEXT_MAXFRAMEHEIGHT : nResId = SIP_SA_TEXT_MAXFRAMEHEIGHT;break;
+ case SDRATTR_TEXT_MINFRAMEWIDTH : nResId = SIP_SA_TEXT_MINFRAMEWIDTH;break;
+ case SDRATTR_TEXT_MAXFRAMEWIDTH : nResId = SIP_SA_TEXT_MAXFRAMEWIDTH;break;
+ case SDRATTR_TEXT_AUTOGROWWIDTH : nResId = SIP_SA_TEXT_AUTOGROWWIDTH;break;
+ case SDRATTR_TEXT_HORZADJUST : nResId = SIP_SA_TEXT_HORZADJUST;break;
+ case SDRATTR_TEXT_ANIKIND : nResId = SIP_SA_TEXT_ANIKIND;break;
+ case SDRATTR_TEXT_ANIDIRECTION : nResId = SIP_SA_TEXT_ANIDIRECTION;break;
+ case SDRATTR_TEXT_ANISTARTINSIDE : nResId = SIP_SA_TEXT_ANISTARTINSIDE;break;
+ case SDRATTR_TEXT_ANISTOPINSIDE : nResId = SIP_SA_TEXT_ANISTOPINSIDE;break;
+ case SDRATTR_TEXT_ANICOUNT : nResId = SIP_SA_TEXT_ANICOUNT;break;
+ case SDRATTR_TEXT_ANIDELAY : nResId = SIP_SA_TEXT_ANIDELAY;break;
+ case SDRATTR_TEXT_ANIAMOUNT : nResId = SIP_SA_TEXT_ANIAMOUNT;break;
+ case SDRATTR_TEXT_CONTOURFRAME : nResId = SIP_SA_TEXT_CONTOURFRAME;break;
+ case SDRATTR_CUSTOMSHAPE_ADJUSTMENT : nResId = SIP_SA_CUSTOMSHAPE_ADJUSTMENT;break;
+ case SDRATTR_XMLATTRIBUTES : nResId = SIP_SA_XMLATTRIBUTES;break;
+ case SDRATTR_TEXT_USEFIXEDCELLHEIGHT: nResId = SIP_SA_TEXT_USEFIXEDCELLHEIGHT;break;
+ case SDRATTR_TEXT_WORDWRAP : nResId = SIP_SA_WORDWRAP;break;
+ case SDRATTR_TEXT_AUTOGROWSIZE : nResId = SIP_SA_AUTOGROWSIZE;break;
+
+ case SDRATTR_EDGEKIND : nResId = SIP_SA_EDGEKIND;break;
+ case SDRATTR_EDGENODE1HORZDIST : nResId = SIP_SA_EDGENODE1HORZDIST;break;
+ case SDRATTR_EDGENODE1VERTDIST : nResId = SIP_SA_EDGENODE1VERTDIST;break;
+ case SDRATTR_EDGENODE2HORZDIST : nResId = SIP_SA_EDGENODE2HORZDIST;break;
+ case SDRATTR_EDGENODE2VERTDIST : nResId = SIP_SA_EDGENODE2VERTDIST;break;
+ case SDRATTR_EDGENODE1GLUEDIST : nResId = SIP_SA_EDGENODE1GLUEDIST;break;
+ case SDRATTR_EDGENODE2GLUEDIST : nResId = SIP_SA_EDGENODE2GLUEDIST;break;
+ case SDRATTR_EDGELINEDELTAANZ : nResId = SIP_SA_EDGELINEDELTAANZ;break;
+ case SDRATTR_EDGELINE1DELTA : nResId = SIP_SA_EDGELINE1DELTA;break;
+ case SDRATTR_EDGELINE2DELTA : nResId = SIP_SA_EDGELINE2DELTA;break;
+ case SDRATTR_EDGELINE3DELTA : nResId = SIP_SA_EDGELINE3DELTA;break;
+
+ case SDRATTR_MEASUREKIND : nResId = SIP_SA_MEASUREKIND;break;
+ case SDRATTR_MEASURETEXTHPOS : nResId = SIP_SA_MEASURETEXTHPOS;break;
+ case SDRATTR_MEASURETEXTVPOS : nResId = SIP_SA_MEASURETEXTVPOS;break;
+ case SDRATTR_MEASURELINEDIST : nResId = SIP_SA_MEASURELINEDIST;break;
+ case SDRATTR_MEASUREHELPLINEOVERHANG : nResId = SIP_SA_MEASUREHELPLINEOVERHANG;break;
+ case SDRATTR_MEASUREHELPLINEDIST : nResId = SIP_SA_MEASUREHELPLINEDIST;break;
+ case SDRATTR_MEASUREHELPLINE1LEN : nResId = SIP_SA_MEASUREHELPLINE1LEN;break;
+ case SDRATTR_MEASUREHELPLINE2LEN : nResId = SIP_SA_MEASUREHELPLINE2LEN;break;
+ case SDRATTR_MEASUREBELOWREFEDGE : nResId = SIP_SA_MEASUREBELOWREFEDGE;break;
+ case SDRATTR_MEASURETEXTROTA90 : nResId = SIP_SA_MEASURETEXTROTA90;break;
+ case SDRATTR_MEASURETEXTUPSIDEDOWN : nResId = SIP_SA_MEASURETEXTUPSIDEDOWN;break;
+ case SDRATTR_MEASUREOVERHANG : nResId = SIP_SA_MEASUREOVERHANG;break;
+ case SDRATTR_MEASUREUNIT : nResId = SIP_SA_MEASUREUNIT;break;
+ case SDRATTR_MEASURESCALE : nResId = SIP_SA_MEASURESCALE;break;
+ case SDRATTR_MEASURESHOWUNIT : nResId = SIP_SA_MEASURESHOWUNIT;break;
+ case SDRATTR_MEASUREFORMATSTRING : nResId = SIP_SA_MEASUREFORMATSTRING;break;
+ case SDRATTR_MEASURETEXTAUTOANGLE : nResId = SIP_SA_MEASURETEXTAUTOANGLE;break;
+ case SDRATTR_MEASURETEXTAUTOANGLEVIEW: nResId = SIP_SA_MEASURETEXTAUTOANGLEVIEW;break;
+ case SDRATTR_MEASURETEXTISFIXEDANGLE : nResId = SIP_SA_MEASURETEXTISFIXEDANGLE;break;
+ case SDRATTR_MEASURETEXTFIXEDANGLE : nResId = SIP_SA_MEASURETEXTFIXEDANGLE;break;
+ case SDRATTR_MEASUREDECIMALPLACES : nResId = SIP_SA_MEASUREDECIMALPLACES;break;
+
+ case SDRATTR_CIRCKIND : nResId = SIP_SA_CIRCKIND;break;
+ case SDRATTR_CIRCSTARTANGLE: nResId = SIP_SA_CIRCSTARTANGLE;break;
+ case SDRATTR_CIRCENDANGLE : nResId = SIP_SA_CIRCENDANGLE;break;
+
+ case SDRATTR_OBJMOVEPROTECT : nResId = SIP_SA_OBJMOVEPROTECT;break;
+ case SDRATTR_OBJSIZEPROTECT : nResId = SIP_SA_OBJSIZEPROTECT;break;
+ case SDRATTR_OBJPRINTABLE : nResId = SIP_SA_OBJPRINTABLE;break;
+ case SDRATTR_OBJVISIBLE : nResId = SIP_SA_OBJVISIBLE;break;
+ case SDRATTR_LAYERID : nResId = SIP_SA_LAYERID;break;
+ case SDRATTR_LAYERNAME : nResId = SIP_SA_LAYERNAME;break;
+ case SDRATTR_OBJECTNAME : nResId = SIP_SA_OBJECTNAME;break;
+ case SDRATTR_ALLPOSITIONX : nResId = SIP_SA_ALLPOSITIONX;break;
+ case SDRATTR_ALLPOSITIONY : nResId = SIP_SA_ALLPOSITIONY;break;
+ case SDRATTR_ALLSIZEWIDTH : nResId = SIP_SA_ALLSIZEWIDTH;break;
+ case SDRATTR_ALLSIZEHEIGHT : nResId = SIP_SA_ALLSIZEHEIGHT;break;
+ case SDRATTR_ONEPOSITIONX : nResId = SIP_SA_ONEPOSITIONX;break;
+ case SDRATTR_ONEPOSITIONY : nResId = SIP_SA_ONEPOSITIONY;break;
+ case SDRATTR_ONESIZEWIDTH : nResId = SIP_SA_ONESIZEWIDTH;break;
+ case SDRATTR_ONESIZEHEIGHT : nResId = SIP_SA_ONESIZEHEIGHT;break;
+ case SDRATTR_LOGICSIZEWIDTH : nResId = SIP_SA_LOGICSIZEWIDTH;break;
+ case SDRATTR_LOGICSIZEHEIGHT: nResId = SIP_SA_LOGICSIZEHEIGHT;break;
+ case SDRATTR_ROTATEANGLE : nResId = SIP_SA_ROTATEANGLE;break;
+ case SDRATTR_SHEARANGLE : nResId = SIP_SA_SHEARANGLE;break;
+ case SDRATTR_MOVEX : nResId = SIP_SA_MOVEX;break;
+ case SDRATTR_MOVEY : nResId = SIP_SA_MOVEY;break;
+ case SDRATTR_RESIZEXONE : nResId = SIP_SA_RESIZEXONE;break;
+ case SDRATTR_RESIZEYONE : nResId = SIP_SA_RESIZEYONE;break;
+ case SDRATTR_ROTATEONE : nResId = SIP_SA_ROTATEONE;break;
+ case SDRATTR_HORZSHEARONE : nResId = SIP_SA_HORZSHEARONE;break;
+ case SDRATTR_VERTSHEARONE : nResId = SIP_SA_VERTSHEARONE;break;
+ case SDRATTR_RESIZEXALL : nResId = SIP_SA_RESIZEXALL;break;
+ case SDRATTR_RESIZEYALL : nResId = SIP_SA_RESIZEYALL;break;
+ case SDRATTR_ROTATEALL : nResId = SIP_SA_ROTATEALL;break;
+ case SDRATTR_HORZSHEARALL : nResId = SIP_SA_HORZSHEARALL;break;
+ case SDRATTR_VERTSHEARALL : nResId = SIP_SA_VERTSHEARALL;break;
+ case SDRATTR_TRANSFORMREF1X : nResId = SIP_SA_TRANSFORMREF1X;break;
+ case SDRATTR_TRANSFORMREF1Y : nResId = SIP_SA_TRANSFORMREF1Y;break;
+ case SDRATTR_TRANSFORMREF2X : nResId = SIP_SA_TRANSFORMREF2X;break;
+ case SDRATTR_TRANSFORMREF2Y : nResId = SIP_SA_TRANSFORMREF2Y;break;
+
+ case SDRATTR_GRAFRED : nResId = SIP_SA_GRAFRED;break;
+ case SDRATTR_GRAFGREEN : nResId = SIP_SA_GRAFGREEN;break;
+ case SDRATTR_GRAFBLUE : nResId = SIP_SA_GRAFBLUE;break;
+ case SDRATTR_GRAFLUMINANCE : nResId = SIP_SA_GRAFLUMINANCE;break;
+ case SDRATTR_GRAFCONTRAST : nResId = SIP_SA_GRAFCONTRAST;break;
+ case SDRATTR_GRAFGAMMA : nResId = SIP_SA_GRAFGAMMA;break;
+ case SDRATTR_GRAFTRANSPARENCE : nResId = SIP_SA_GRAFTRANSPARENCE;break;
+ case SDRATTR_GRAFINVERT : nResId = SIP_SA_GRAFINVERT;break;
+ case SDRATTR_GRAFMODE : nResId = SIP_SA_GRAFMODE;break;
+ case SDRATTR_GRAFCROP : nResId = SIP_SA_GRAFCROP;break;
+
+ case EE_PARA_HYPHENATE : nResId = SIP_EE_PARA_HYPHENATE;break;
+ case EE_PARA_BULLETSTATE: nResId = SIP_EE_PARA_BULLETSTATE;break;
+ case EE_PARA_OUTLLRSPACE: nResId = SIP_EE_PARA_OUTLLRSPACE;break;
+ case EE_PARA_OUTLLEVEL : nResId = SIP_EE_PARA_OUTLLEVEL;break;
+ case EE_PARA_BULLET : nResId = SIP_EE_PARA_BULLET;break;
+ case EE_PARA_LRSPACE : nResId = SIP_EE_PARA_LRSPACE;break;
+ case EE_PARA_ULSPACE : nResId = SIP_EE_PARA_ULSPACE;break;
+ case EE_PARA_SBL : nResId = SIP_EE_PARA_SBL;break;
+ case EE_PARA_JUST : nResId = SIP_EE_PARA_JUST;break;
+ case EE_PARA_TABS : nResId = SIP_EE_PARA_TABS;break;
+
+ case EE_CHAR_COLOR : nResId = SIP_EE_CHAR_COLOR;break;
+ case EE_CHAR_FONTINFO : nResId = SIP_EE_CHAR_FONTINFO;break;
+ case EE_CHAR_FONTHEIGHT : nResId = SIP_EE_CHAR_FONTHEIGHT;break;
+ case EE_CHAR_FONTWIDTH : nResId = SIP_EE_CHAR_FONTWIDTH;break;
+ case EE_CHAR_WEIGHT : nResId = SIP_EE_CHAR_WEIGHT;break;
+ case EE_CHAR_UNDERLINE : nResId = SIP_EE_CHAR_UNDERLINE;break;
+ case EE_CHAR_OVERLINE : nResId = SIP_EE_CHAR_OVERLINE;break;
+ case EE_CHAR_STRIKEOUT : nResId = SIP_EE_CHAR_STRIKEOUT;break;
+ case EE_CHAR_ITALIC : nResId = SIP_EE_CHAR_ITALIC;break;
+ case EE_CHAR_OUTLINE : nResId = SIP_EE_CHAR_OUTLINE;break;
+ case EE_CHAR_SHADOW : nResId = SIP_EE_CHAR_SHADOW;break;
+ case EE_CHAR_ESCAPEMENT : nResId = SIP_EE_CHAR_ESCAPEMENT;break;
+ case EE_CHAR_PAIRKERNING: nResId = SIP_EE_CHAR_PAIRKERNING;break;
+ case EE_CHAR_KERNING : nResId = SIP_EE_CHAR_KERNING;break;
+ case EE_CHAR_WLM : nResId = SIP_EE_CHAR_WLM;break;
+ case EE_FEATURE_TAB : nResId = SIP_EE_FEATURE_TAB;break;
+ case EE_FEATURE_LINEBR : nResId = SIP_EE_FEATURE_LINEBR;break;
+ case EE_FEATURE_NOTCONV : nResId = SIP_EE_FEATURE_NOTCONV;break;
+ case EE_FEATURE_FIELD : nResId = SIP_EE_FEATURE_FIELD;break;
+ } // switch
+
+ rItemName = String( ResId( nResId, *pResMgr ) );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FractionItem
+////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1_AUTOFACTORY(SdrFractionItem,SfxPoolItem);
+
+SdrFractionItem::SdrFractionItem(USHORT nId, SvStream& rIn):
+ SfxPoolItem(nId)
+{
+ INT32 nMul,nDiv;
+ rIn>>nMul;
+ rIn>>nDiv;
+ nValue=Fraction(nMul,nDiv);
+}
+
+int __EXPORT SdrFractionItem::operator==(const SfxPoolItem& rCmp) const
+{
+ return SfxPoolItem::operator==(rCmp) &&
+ ((SdrFractionItem&)rCmp).GetValue()==nValue;
+}
+
+SfxItemPresentation __EXPORT SdrFractionItem::GetPresentation(
+ SfxItemPresentation ePresentation, SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresentationMetric*/, XubString &rText, const IntlWrapper *) const
+{
+ if(nValue.IsValid())
+ {
+ INT32 nDiv = nValue.GetDenominator();
+ rText = UniString::CreateFromInt32(nValue.GetNumerator());
+
+ if(nDiv != 1)
+ {
+ rText += sal_Unicode('/');
+ rText += UniString::CreateFromInt32(nDiv);
+ }
+ }
+ else
+ {
+ rText = UniString();
+ rText += sal_Unicode('?');
+ }
+
+ if(ePresentation == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePresentation;
+}
+
+SfxPoolItem* __EXPORT SdrFractionItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrFractionItem(Which(),rIn);
+}
+
+SvStream& __EXPORT SdrFractionItem::Store(SvStream& rOut, USHORT /*nItemVers*/) const
+{
+ rOut<<INT32(nValue.GetNumerator());
+ rOut<<INT32(nValue.GetDenominator());
+ return rOut;
+}
+
+SfxPoolItem* __EXPORT SdrFractionItem::Clone(SfxItemPool * /*pPool*/) const
+{
+ return new SdrFractionItem(Which(),GetValue());
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrFractionItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// ScaleItem
+////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1_AUTOFACTORY(SdrScaleItem,SdrFractionItem);
+
+SfxItemPresentation __EXPORT SdrScaleItem::GetPresentation(
+ SfxItemPresentation ePresentation, SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresentationMetric*/, XubString &rText, const IntlWrapper *) const
+{
+ if(GetValue().IsValid())
+ {
+ INT32 nDiv = GetValue().GetDenominator();
+
+ rText = UniString::CreateFromInt32(GetValue().GetNumerator());
+ rText += sal_Unicode(':');
+ rText += UniString::CreateFromInt32(nDiv);
+ }
+ else
+ {
+ rText = UniString();
+ rText += sal_Unicode('?');
+ }
+
+ if(ePresentation == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePresentation;
+}
+
+SfxPoolItem* __EXPORT SdrScaleItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrScaleItem(Which(),rIn);
+}
+
+SfxPoolItem* __EXPORT SdrScaleItem::Clone(SfxItemPool * /*pPool*/) const
+{
+ return new SdrScaleItem(Which(),GetValue());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// OnOffItem
+////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1_AUTOFACTORY(SdrOnOffItem,SfxBoolItem);
+
+SfxPoolItem* __EXPORT SdrOnOffItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrOnOffItem(Which(),GetValue());
+}
+
+SfxPoolItem* __EXPORT SdrOnOffItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrOnOffItem(Which(),rIn);
+}
+
+XubString __EXPORT SdrOnOffItem::GetValueTextByVal(BOOL bVal) const
+{
+ if (bVal) return ImpGetResStr(STR_ItemValON);
+ else return ImpGetResStr(STR_ItemValOFF);
+}
+
+SfxItemPresentation __EXPORT SdrOnOffItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByVal(GetValue());
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrOnOffItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+TYPEINIT1_AUTOFACTORY(SdrYesNoItem,SfxBoolItem);
+
+SfxPoolItem* __EXPORT SdrYesNoItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrYesNoItem(Which(),GetValue());
+}
+
+SfxPoolItem* __EXPORT SdrYesNoItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrYesNoItem(Which(),rIn);
+}
+
+XubString __EXPORT SdrYesNoItem::GetValueTextByVal(BOOL bVal) const
+{
+ if (bVal) return ImpGetResStr(STR_ItemValYES);
+ else return ImpGetResStr(STR_ItemValNO);
+}
+
+SfxItemPresentation __EXPORT SdrYesNoItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByVal(GetValue());
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrYesNoItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+//------------------------------------------------------------
+// class SdrPercentItem
+//------------------------------------------------------------
+
+TYPEINIT1_AUTOFACTORY(SdrPercentItem,SfxUInt16Item);
+
+SfxPoolItem* __EXPORT SdrPercentItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrPercentItem(Which(),GetValue());
+}
+
+SfxPoolItem* __EXPORT SdrPercentItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrPercentItem(Which(),rIn);
+}
+
+SfxItemPresentation __EXPORT SdrPercentItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText = UniString::CreateFromInt32(GetValue());
+ rText += sal_Unicode('%');
+
+ if(ePres == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrPercentItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+//------------------------------------------------------------
+// class SdrAngleItem
+//------------------------------------------------------------
+
+TYPEINIT1_AUTOFACTORY(SdrAngleItem,SfxInt32Item);
+
+SfxPoolItem* __EXPORT SdrAngleItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrAngleItem(Which(),GetValue());
+}
+
+SfxPoolItem* __EXPORT SdrAngleItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrAngleItem(Which(),rIn);
+}
+
+SfxItemPresentation __EXPORT SdrAngleItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ XubString& rText, const IntlWrapper * pIntlWrapper) const
+{
+ INT32 nValue(GetValue());
+ BOOL bNeg(nValue < 0);
+
+ if(bNeg)
+ nValue = -nValue;
+
+ rText = UniString::CreateFromInt32(nValue);
+
+ if(nValue)
+ {
+ sal_Unicode aUnicodeNull('0');
+ xub_StrLen nAnz(2);
+
+ const IntlWrapper* pMyIntlWrapper = NULL;
+// DBG_ASSERT( pIntlWrapper, "SdrAngleItem::GetPresentation: using default App-IntlWrapper" );
+ if(!pIntlWrapper)
+ pIntlWrapper = pMyIntlWrapper = new IntlWrapper(
+ ::comphelper::getProcessServiceFactory(),
+ Application::GetSettings().GetLanguage() );
+
+ if(pIntlWrapper->getLocaleData()->isNumLeadingZero())
+ nAnz++;
+
+ while(rText.Len() < nAnz)
+ rText.Insert(aUnicodeNull, 0);
+
+ xub_StrLen nLen = rText.Len();
+ BOOL bNull1(rText.GetChar(nLen-1) == aUnicodeNull);
+ BOOL bNull2(bNull1 && rText.GetChar(nLen-2) == aUnicodeNull);
+
+ if(bNull2)
+ {
+ // keine Nachkommastellen
+ rText.Erase(nLen-2);
+ }
+ else
+ {
+ sal_Unicode cDec =
+ pIntlWrapper->getLocaleData()->getNumDecimalSep().GetChar(0);
+ rText.Insert(cDec, nLen-2);
+
+ if(bNull1)
+ rText.Erase(nLen);
+ }
+
+ if(bNeg)
+ rText.Insert(sal_Unicode('-'), 0);
+
+ if ( pMyIntlWrapper )
+ {
+ delete pMyIntlWrapper;
+ pIntlWrapper = NULL;
+ }
+ }
+
+ rText += sal_Unicode(DEGREE_CHAR);
+
+ if(ePres == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrAngleItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+//------------------------------------------------------------
+// class SdrMetricItem
+//------------------------------------------------------------
+
+TYPEINIT1_AUTOFACTORY(SdrMetricItem,SfxInt32Item);
+
+SfxPoolItem* __EXPORT SdrMetricItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrMetricItem(Which(),GetValue());
+}
+
+SfxPoolItem* __EXPORT SdrMetricItem::Create(SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrMetricItem(Which(),rIn);
+}
+
+FASTBOOL __EXPORT SdrMetricItem::HasMetrics() const
+{
+ return TRUE;
+}
+
+FASTBOOL __EXPORT SdrMetricItem::ScaleMetrics(long nMul, long nDiv)
+{
+ if (GetValue()!=0) {
+ BigInt aVal(GetValue());
+ aVal*=nMul;
+ aVal+=nDiv/2; // fuer korrektes Runden
+ aVal/=nDiv;
+ SetValue(long(aVal));
+ }
+ return TRUE;
+}
+
+SfxItemPresentation __EXPORT SdrMetricItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric, XubString& rText, const IntlWrapper *) const
+{
+ long nValue=GetValue();
+ SdrFormatter aFmt((MapUnit)eCoreMetric,(MapUnit)ePresMetric);
+ aFmt.TakeStr(nValue,rText);
+ String aStr;
+ aFmt.TakeUnitStr((MapUnit)ePresMetric,aStr);
+ rText+=aStr;
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr2;
+
+ SdrItemPool::TakeItemName(Which(), aStr2);
+ aStr2 += sal_Unicode(' ');
+ rText.Insert(aStr2, 0);
+ }
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrMetricItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId<SDRATTR_NOTPERSIST_FIRST || nId>SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Items des Legendenobjekts
+////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1_AUTOFACTORY(SdrCaptionTypeItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrCaptionTypeItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrCaptionTypeItem(*this); }
+
+SfxPoolItem* __EXPORT SdrCaptionTypeItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrCaptionTypeItem(rIn); }
+
+USHORT __EXPORT SdrCaptionTypeItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrCaptionTypeItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValCAPTIONTYPE1+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrCaptionTypeItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrCaptionEscDirItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrCaptionEscDirItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrCaptionEscDirItem(*this); }
+
+SfxPoolItem* __EXPORT SdrCaptionEscDirItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrCaptionEscDirItem(rIn); }
+
+USHORT __EXPORT SdrCaptionEscDirItem::GetValueCount() const { return 3; }
+
+XubString __EXPORT SdrCaptionEscDirItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValCAPTIONESCHORI+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrCaptionEscDirItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// MiscItems
+////////////////////////////////////////////////////////////////////////////////
+
+// FitToSize
+TYPEINIT1_AUTOFACTORY(SdrTextFitToSizeTypeItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrTextFitToSizeTypeItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextFitToSizeTypeItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextFitToSizeTypeItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextFitToSizeTypeItem(rIn); }
+
+USHORT __EXPORT SdrTextFitToSizeTypeItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrTextFitToSizeTypeItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValFITTOSIZENONE+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrTextFitToSizeTypeItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+int __EXPORT SdrTextFitToSizeTypeItem::HasBoolValue() const { return TRUE; }
+
+BOOL __EXPORT SdrTextFitToSizeTypeItem::GetBoolValue() const { return GetValue()!=SDRTEXTFIT_NONE; }
+
+void __EXPORT SdrTextFitToSizeTypeItem::SetBoolValue(BOOL bVal) { SetValue(sal::static_int_cast< USHORT >(bVal ? SDRTEXTFIT_PROPORTIONAL : SDRTEXTFIT_NONE)); }
+
+sal_Bool SdrTextFitToSizeTypeItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ drawing::TextFitToSizeType eFS = (drawing::TextFitToSizeType)GetValue();
+ rVal <<= eFS;
+
+ return sal_True;
+}
+
+sal_Bool SdrTextFitToSizeTypeItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::TextFitToSizeType eFS;
+ if(!(rVal >>= eFS))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eFS = (drawing::TextFitToSizeType) nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrFitToSizeType)eFS ) );
+
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextVertAdjustItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrTextVertAdjustItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextVertAdjustItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextVertAdjustItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextVertAdjustItem(rIn); }
+
+USHORT __EXPORT SdrTextVertAdjustItem::GetValueCount() const { return 5; }
+
+XubString __EXPORT SdrTextVertAdjustItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValTEXTVADJTOP+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrTextVertAdjustItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrTextVertAdjustItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::TextVerticalAdjust)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrTextVertAdjustItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::TextVerticalAdjust eAdj;
+ if(!(rVal >>= eAdj))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eAdj = (drawing::TextVerticalAdjust)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrTextVertAdjust)eAdj ) );
+
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextHorzAdjustItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrTextHorzAdjustItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextHorzAdjustItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextHorzAdjustItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextHorzAdjustItem(rIn); }
+
+USHORT __EXPORT SdrTextHorzAdjustItem::GetValueCount() const { return 5; }
+
+XubString __EXPORT SdrTextHorzAdjustItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValTEXTHADJLEFT+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrTextHorzAdjustItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrTextHorzAdjustItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::TextHorizontalAdjust)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrTextHorzAdjustItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::TextHorizontalAdjust eAdj;
+ if(!(rVal >>= eAdj))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eAdj = (drawing::TextHorizontalAdjust)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrTextHorzAdjust)eAdj ) );
+
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextAniKindItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrTextAniKindItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextAniKindItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextAniKindItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextAniKindItem(rIn); }
+
+USHORT __EXPORT SdrTextAniKindItem::GetValueCount() const { return 5; }
+
+XubString __EXPORT SdrTextAniKindItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValTEXTANI_NONE+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrTextAniKindItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrTextAniKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::TextAnimationKind)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrTextAniKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::TextAnimationKind eKind;
+ if(!(rVal >>= eKind))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+ eKind = (drawing::TextAnimationKind)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrTextAniKind)eKind ) );
+
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextAniDirectionItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrTextAniDirectionItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextAniDirectionItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextAniDirectionItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextAniDirectionItem(rIn); }
+
+USHORT __EXPORT SdrTextAniDirectionItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrTextAniDirectionItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValTEXTANI_LEFT+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrTextAniDirectionItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrTextAniDirectionItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::TextAnimationDirection)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrTextAniDirectionItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::TextAnimationDirection eDir;
+ if(!(rVal >>= eDir))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eDir = (drawing::TextAnimationDirection)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrTextAniDirection)eDir ) );
+
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextAniDelayItem,SfxUInt16Item);
+
+SfxPoolItem* __EXPORT SdrTextAniDelayItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextAniDelayItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextAniDelayItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextAniDelayItem(rIn); }
+
+SfxItemPresentation __EXPORT SdrTextAniDelayItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ XubString& rText, const IntlWrapper *) const
+{
+ rText = UniString::CreateFromInt32(GetValue());
+ rText += sal_Unicode('m');
+ rText += sal_Unicode('s');
+
+ if(ePres == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePres;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrTextAniAmountItem,SfxInt16Item);
+
+SfxPoolItem* __EXPORT SdrTextAniAmountItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrTextAniAmountItem(*this); }
+
+SfxPoolItem* __EXPORT SdrTextAniAmountItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrTextAniAmountItem(rIn); }
+
+FASTBOOL __EXPORT SdrTextAniAmountItem::HasMetrics() const
+{
+ return GetValue()>0;
+}
+
+FASTBOOL __EXPORT SdrTextAniAmountItem::ScaleMetrics(long nMul, long nDiv)
+{
+ if (GetValue()>0) {
+ BigInt aVal(GetValue());
+ aVal*=nMul;
+ aVal+=nDiv/2; // fuer korrektes Runden
+ aVal/=nDiv;
+ SetValue(short(aVal));
+ return TRUE;
+ } else return FALSE;
+}
+
+SfxItemPresentation __EXPORT SdrTextAniAmountItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit eCoreMetric, SfxMapUnit ePresMetric,
+ XubString& rText, const IntlWrapper *) const
+{
+ INT32 nValue(GetValue());
+
+ if(!nValue)
+ nValue = -1L;
+
+ if(nValue < 0)
+ {
+ sal_Char aText[] = "pixel";
+
+ rText = UniString::CreateFromInt32(-nValue);
+ rText += UniString(aText, sizeof(aText-1));
+ }
+ else
+ {
+ SdrFormatter aFmt((MapUnit)eCoreMetric, (MapUnit)ePresMetric);
+ XubString aStr;
+
+ aFmt.TakeStr(nValue, rText);
+ aFmt.TakeUnitStr((MapUnit)ePresMetric, aStr);
+ rText += aStr;
+ }
+
+ if(ePres == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePres;
+}
+
+TYPEINIT1_AUTOFACTORY( SdrTextFixedCellHeightItem, SfxBoolItem );
+SdrTextFixedCellHeightItem::SdrTextFixedCellHeightItem( BOOL bUseFixedCellHeight )
+ : SfxBoolItem( SDRATTR_TEXT_USEFIXEDCELLHEIGHT, bUseFixedCellHeight )
+{
+}
+SdrTextFixedCellHeightItem::SdrTextFixedCellHeightItem( SvStream & rStream, sal_uInt16 nVersion )
+ : SfxBoolItem( SDRATTR_TEXT_USEFIXEDCELLHEIGHT, FALSE )
+{
+ if ( nVersion )
+ {
+ sal_Bool bValue;
+ rStream >> bValue;
+ SetValue( bValue );
+ }
+}
+SfxItemPresentation __EXPORT SdrTextFixedCellHeightItem::GetPresentation( SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresentationMetric*/,
+ String &rText, const IntlWrapper * ) const
+{
+ rText = GetValueTextByVal( GetValue() );
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ String aStr;
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+SfxPoolItem* __EXPORT SdrTextFixedCellHeightItem::Create( SvStream& rIn, sal_uInt16 nItemVersion ) const
+{
+ return new SdrTextFixedCellHeightItem( rIn, nItemVersion );
+}
+SvStream& __EXPORT SdrTextFixedCellHeightItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
+{
+ if ( nItemVersion )
+ {
+ sal_Bool bValue = (sal_Bool)GetValue();
+ rOut << bValue;
+ }
+ return rOut;
+}
+SfxPoolItem* __EXPORT SdrTextFixedCellHeightItem::Clone( SfxItemPool * /*pPool*/) const
+{
+ return new SdrTextFixedCellHeightItem( GetValue() );
+}
+sal_uInt16 SdrTextFixedCellHeightItem::GetVersion( sal_uInt16 /*nFileFormatVersion*/) const
+{
+ return 1;
+}
+sal_Bool SdrTextFixedCellHeightItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ sal_Bool bValue = (sal_Bool)GetValue();
+ rVal <<= bValue;
+ return sal_True;
+}
+sal_Bool SdrTextFixedCellHeightItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Bool bValue = sal_Bool();
+ if( !( rVal >>= bValue ) )
+ return sal_False;
+ SetValue( bValue );
+ return sal_True;
+}
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrTextFixedCellHeightItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId < SDRATTR_NOTPERSIST_FIRST || nId > SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+TYPEINIT1_AUTOFACTORY( SdrCustomShapeAdjustmentItem, SfxPoolItem );
+
+SdrCustomShapeAdjustmentItem::SdrCustomShapeAdjustmentItem() : SfxPoolItem( SDRATTR_CUSTOMSHAPE_ADJUSTMENT )
+{
+}
+
+SdrCustomShapeAdjustmentItem::SdrCustomShapeAdjustmentItem( SvStream& rIn, sal_uInt16 nVersion ):
+ SfxPoolItem( SDRATTR_CUSTOMSHAPE_ADJUSTMENT )
+{
+ if ( nVersion )
+ {
+ SdrCustomShapeAdjustmentValue aVal;
+ sal_uInt32 i, nCount;
+ rIn >> nCount;
+ for ( i = 0; i < nCount; i++ )
+ {
+ rIn >> aVal.nValue;
+ SetValue( i, aVal );
+ }
+ }
+}
+
+SdrCustomShapeAdjustmentItem::~SdrCustomShapeAdjustmentItem()
+{
+ void* pPtr;
+ for ( pPtr = aAdjustmentValueList.First(); pPtr; pPtr = aAdjustmentValueList.Next() )
+ delete (SdrCustomShapeAdjustmentValue*)pPtr;
+}
+
+int __EXPORT SdrCustomShapeAdjustmentItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ int bRet = SfxPoolItem::operator==( rCmp );
+ if ( bRet )
+ {
+ bRet = ((SdrCustomShapeAdjustmentItem&)rCmp).GetCount() == GetCount();
+ if ( bRet )
+ {
+ sal_uInt32 i;
+ for ( i = 0; i < GetCount(); i++ )
+ {
+ if ( ((SdrCustomShapeAdjustmentItem&)rCmp).GetValue( i ).nValue != GetValue( i ).nValue )
+ {
+ bRet = 0;
+ break;
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+SfxItemPresentation __EXPORT SdrCustomShapeAdjustmentItem::GetPresentation(
+ SfxItemPresentation ePresentation, SfxMapUnit /*eCoreMetric*/,
+ SfxMapUnit /*ePresentationMetric*/, XubString &rText, const IntlWrapper *) const
+{
+ sal_uInt32 i, nCount = GetCount();
+ rText.Append( UniString::CreateFromInt32( nCount ) );
+ for ( i = 0; i < nCount; i++ )
+ {
+ rText += sal_Unicode( ' ' );
+ rText.Append( UniString::CreateFromInt32( GetValue( i ).nValue ) );
+ }
+ if ( ePresentation == SFX_ITEM_PRESENTATION_COMPLETE )
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName( Which(), aStr );
+ aStr += sal_Unicode( ' ' );
+ rText.Insert( aStr, 0 );
+ }
+ return ePresentation;
+}
+
+SfxPoolItem* __EXPORT SdrCustomShapeAdjustmentItem::Create( SvStream& rIn, sal_uInt16 nItemVersion ) const
+{
+ return new SdrCustomShapeAdjustmentItem( rIn, nItemVersion );
+}
+
+SvStream& __EXPORT SdrCustomShapeAdjustmentItem::Store( SvStream& rOut, sal_uInt16 nItemVersion ) const
+{
+ if ( nItemVersion )
+ {
+ sal_uInt32 i, nCount = GetCount();
+ rOut << nCount;
+ for ( i = 0; i < nCount; i++ )
+ rOut << GetValue( i ).nValue;
+ }
+ return rOut;
+}
+
+SfxPoolItem* __EXPORT SdrCustomShapeAdjustmentItem::Clone( SfxItemPool * /*pPool*/) const
+{
+ sal_uInt32 i;
+ SdrCustomShapeAdjustmentItem* pItem = new SdrCustomShapeAdjustmentItem;
+ for ( i = 0; i < GetCount(); i++ )
+ {
+ const SdrCustomShapeAdjustmentValue& rVal = GetValue( i );
+ pItem->SetValue( i, rVal );
+ }
+ return pItem;
+}
+
+#ifdef SDR_ISPOOLABLE
+int __EXPORT SdrCustomShapeAdjustmentItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId < SDRATTR_NOTPERSIST_FIRST || nId > SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+const SdrCustomShapeAdjustmentValue& SdrCustomShapeAdjustmentItem::GetValue( sal_uInt32 nIndex ) const
+{
+#ifdef DBG_UTIL
+ if ( aAdjustmentValueList.Count() <= nIndex )
+ DBG_ERROR( "SdrCustomShapeAdjustemntItem::GetValue - nIndex out of range (SJ)" );
+#endif
+ return *(SdrCustomShapeAdjustmentValue*)aAdjustmentValueList.GetObject( nIndex );
+}
+
+void SdrCustomShapeAdjustmentItem::SetValue( sal_uInt32 nIndex, const SdrCustomShapeAdjustmentValue& rVal )
+{
+ sal_uInt32 i;
+ for ( i = GetCount(); i <= nIndex; i++ )
+ {
+ SdrCustomShapeAdjustmentValue* pItem = new SdrCustomShapeAdjustmentValue;
+ aAdjustmentValueList.Insert( pItem, LIST_APPEND );
+ }
+ SdrCustomShapeAdjustmentValue& rValue = *(SdrCustomShapeAdjustmentValue*)aAdjustmentValueList.GetObject( nIndex );
+ rValue.nValue = rVal.nValue;
+}
+
+sal_uInt16 SdrCustomShapeAdjustmentItem::GetVersion( sal_uInt16 /*nFileFormatVersion*/) const
+{
+ return 1;
+}
+
+sal_Bool SdrCustomShapeAdjustmentItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ sal_uInt32 i, nCount = GetCount();
+ uno::Sequence< sal_Int32 > aSequence( nCount );
+ if ( nCount )
+ {
+ sal_Int32* pPtr = aSequence.getArray();
+ for ( i = 0; i < nCount; i++ )
+ *pPtr++ = GetValue( i ).nValue;
+ }
+ rVal <<= aSequence;
+ return sal_True;
+}
+
+sal_Bool SdrCustomShapeAdjustmentItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ uno::Sequence< sal_Int32 > aSequence;
+ if( !( rVal >>= aSequence ) )
+ return sal_False;
+
+ void* pPtr;
+ for ( pPtr = aAdjustmentValueList.First(); pPtr; pPtr = aAdjustmentValueList.Next() )
+ delete (SdrCustomShapeAdjustmentValue*)pPtr;
+
+ sal_uInt32 i, nCount = aSequence.getLength();
+ if ( nCount )
+ {
+ const sal_Int32* pPtr2 = aSequence.getConstArray();
+ for ( i = 0; i < nCount; i++ )
+ {
+ SdrCustomShapeAdjustmentValue* pItem = new SdrCustomShapeAdjustmentValue;
+ pItem->nValue = *pPtr2++;
+ aAdjustmentValueList.Insert( pItem, LIST_APPEND );
+ }
+ }
+ return sal_True;
+}
+
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Edge
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// EdgeKind
+TYPEINIT1_AUTOFACTORY(SdrEdgeKindItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrEdgeKindItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrEdgeKindItem(*this); }
+
+SfxPoolItem* __EXPORT SdrEdgeKindItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrEdgeKindItem(rIn); }
+
+USHORT __EXPORT SdrEdgeKindItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrEdgeKindItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValEDGE_ORTHOLINES+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrEdgeKindItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrEdgeKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ drawing::ConnectorType eCT = drawing::ConnectorType_STANDARD;
+
+ switch( GetValue() )
+ {
+ case SDREDGE_ORTHOLINES : eCT = drawing::ConnectorType_STANDARD; break;
+ case SDREDGE_THREELINES : eCT = drawing::ConnectorType_LINES; break;
+ case SDREDGE_ONELINE : eCT = drawing::ConnectorType_LINE; break;
+ case SDREDGE_BEZIER : eCT = drawing::ConnectorType_CURVE; break;
+ case SDREDGE_ARC : eCT = drawing::ConnectorType_CURVE; break;
+ default:
+ DBG_ERROR( "SdrEdgeKindItem::QueryValue : unknown enum" );
+ }
+
+ rVal <<= eCT;
+
+ return sal_True;
+}
+
+sal_Bool SdrEdgeKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::ConnectorType eCT;
+ if(!(rVal >>= eCT))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eCT = (drawing::ConnectorType)nEnum;
+ }
+
+ SdrEdgeKind eEK = SDREDGE_ORTHOLINES;
+ switch( eCT )
+ {
+ case drawing::ConnectorType_STANDARD : eEK = SDREDGE_ORTHOLINES; break;
+ case drawing::ConnectorType_CURVE : eEK = SDREDGE_BEZIER; break;
+ case drawing::ConnectorType_LINE : eEK = SDREDGE_ONELINE; break;
+ case drawing::ConnectorType_LINES : eEK = SDREDGE_THREELINES; break;
+ default:
+ DBG_ERROR( "SdrEdgeKindItem::PuValue : unknown enum" );
+ }
+ SetValue( sal::static_int_cast< USHORT >( eEK ) );
+
+ return sal_True;
+}
+
+sal_Bool SdrEdgeNode1HorzDistItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrEdgeNode1HorzDistItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeNode1VertDistItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeNode1VertDistItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeNode2HorzDistItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeNode2HorzDistItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeNode2VertDistItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeNode2VertDistItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeLine1DeltaItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeLine1DeltaItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeLine2DeltaItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeLine2DeltaItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+BOOL SdrEdgeLine3DeltaItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+BOOL SdrEdgeLine3DeltaItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nValue = 0;
+ if(!(rVal >>= nValue))
+ return sal_False;
+
+ SetValue( nValue );
+ return sal_True;
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Measure
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// MeasureKind
+TYPEINIT1_AUTOFACTORY(SdrMeasureKindItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrMeasureKindItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrMeasureKindItem(*this); }
+
+SfxPoolItem* __EXPORT SdrMeasureKindItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrMeasureKindItem(rIn); }
+
+USHORT __EXPORT SdrMeasureKindItem::GetValueCount() const { return 2; }
+
+XubString __EXPORT SdrMeasureKindItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValMEASURE_STD+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrMeasureKindItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrMeasureKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::MeasureKind)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrMeasureKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::MeasureKind eKind;
+ if(!(rVal >>= eKind))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eKind = (drawing::MeasureKind)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrMeasureKind)eKind ) );
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrMeasureTextHPosItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrMeasureTextHPosItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrMeasureTextHPosItem(*this); }
+
+SfxPoolItem* __EXPORT SdrMeasureTextHPosItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrMeasureTextHPosItem(rIn); }
+
+USHORT __EXPORT SdrMeasureTextHPosItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrMeasureTextHPosItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValMEASURE_TEXTHAUTO+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrMeasureTextHPosItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrMeasureTextHPosItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::MeasureTextHorzPos)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrMeasureTextHPosItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::MeasureTextHorzPos ePos;
+ if(!(rVal >>= ePos))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ ePos = (drawing::MeasureTextHorzPos)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrMeasureTextHPos)ePos ) );
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrMeasureTextVPosItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrMeasureTextVPosItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrMeasureTextVPosItem(*this); }
+
+SfxPoolItem* __EXPORT SdrMeasureTextVPosItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrMeasureTextVPosItem(rIn); }
+
+USHORT __EXPORT SdrMeasureTextVPosItem::GetValueCount() const { return 5; }
+
+XubString __EXPORT SdrMeasureTextVPosItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValMEASURE_TEXTVAUTO+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrMeasureTextVPosItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrMeasureTextVPosItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::MeasureTextVertPos)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrMeasureTextVPosItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::MeasureTextVertPos ePos;
+ if(!(rVal >>= ePos))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ ePos = (drawing::MeasureTextVertPos)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrMeasureTextHPos)ePos ) );
+ return sal_True;
+}
+
+TYPEINIT1_AUTOFACTORY(SdrMeasureUnitItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrMeasureUnitItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrMeasureUnitItem(*this); }
+
+SfxPoolItem* __EXPORT SdrMeasureUnitItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrMeasureUnitItem(rIn); }
+
+USHORT __EXPORT SdrMeasureUnitItem::GetValueCount() const { return 14; }
+
+XubString __EXPORT SdrMeasureUnitItem::GetValueTextByPos(USHORT nPos) const
+{
+ XubString aRetval;
+
+ if((FieldUnit)nPos == FUNIT_NONE)
+ {
+ sal_Char aText[] = "default";
+ aRetval += UniString(aText, sizeof(aText-1));
+ }
+ else
+ {
+ SdrFormatter::TakeUnitStr((FieldUnit)nPos, aRetval);
+ }
+
+ return aRetval;
+}
+
+SfxItemPresentation __EXPORT SdrMeasureUnitItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrMeasureUnitItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (sal_Int32)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrMeasureUnitItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ sal_Int32 nMeasure = 0;
+ if(!(rVal >>= nMeasure))
+ return sal_False;
+
+ SetValue( sal::static_int_cast< USHORT >( (FieldUnit)nMeasure ) );
+ return sal_True;
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Circ
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// CircKind
+TYPEINIT1_AUTOFACTORY(SdrCircKindItem,SfxEnumItem);
+
+SfxPoolItem* __EXPORT SdrCircKindItem::Clone(SfxItemPool* /*pPool*/) const { return new SdrCircKindItem(*this); }
+
+SfxPoolItem* __EXPORT SdrCircKindItem::Create(SvStream& rIn, USHORT /*nVer*/) const { return new SdrCircKindItem(rIn); }
+
+USHORT __EXPORT SdrCircKindItem::GetValueCount() const { return 4; }
+
+XubString __EXPORT SdrCircKindItem::GetValueTextByPos(USHORT nPos) const
+{
+ return ImpGetResStr(STR_ItemValCIRC_FULL+nPos);
+}
+
+SfxItemPresentation __EXPORT SdrCircKindItem::GetPresentation(SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/, XubString& rText, const IntlWrapper *) const
+{
+ rText=GetValueTextByPos(sal::static_int_cast< USHORT >(GetValue()));
+ if (ePres==SFX_ITEM_PRESENTATION_COMPLETE) {
+ String aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+ return ePres;
+}
+
+sal_Bool SdrCircKindItem::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= (drawing::CircleKind)GetValue();
+ return sal_True;
+}
+
+sal_Bool SdrCircKindItem::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ drawing::CircleKind eKind;
+ if(!(rVal >>= eKind))
+ {
+ sal_Int32 nEnum = 0;
+ if(!(rVal >>= nEnum))
+ return sal_False;
+
+ eKind = (drawing::CircleKind)nEnum;
+ }
+
+ SetValue( sal::static_int_cast< USHORT >( (SdrCircKind)eKind ) );
+ return sal_True;
+}
+
+//------------------------------------------------------------
+// class SdrSignedPercentItem
+//------------------------------------------------------------
+
+TYPEINIT1_AUTOFACTORY( SdrSignedPercentItem, SfxInt16Item );
+
+
+SfxPoolItem* __EXPORT SdrSignedPercentItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrSignedPercentItem( Which(), GetValue() );
+}
+
+SfxPoolItem* __EXPORT SdrSignedPercentItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrSignedPercentItem( Which(), rIn );
+}
+
+SfxItemPresentation __EXPORT SdrSignedPercentItem::GetPresentation(
+ SfxItemPresentation ePres, SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ XubString& rText, const IntlWrapper *) const
+{
+ rText = UniString::CreateFromInt32(GetValue());
+ rText += sal_Unicode('%');
+
+ if(ePres == SFX_ITEM_PRESENTATION_COMPLETE)
+ {
+ XubString aStr;
+
+ SdrItemPool::TakeItemName(Which(), aStr);
+ aStr += sal_Unicode(' ');
+ rText.Insert(aStr, 0);
+ }
+
+ return ePres;
+}
+
+#ifdef SDR_ISPOOLABLE
+
+int __EXPORT SdrSignedPercentItem::IsPoolable() const
+{
+ USHORT nId=Which();
+ return nId < SDRATTR_NOTPERSIST_FIRST || nId > SDRATTR_NOTPERSIST_LAST;
+}
+#endif
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafRedItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafRedItem, SdrSignedPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafRedItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafRedItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafRedItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafRedItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafGreenItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafGreenItem, SdrSignedPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafGreenItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafGreenItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafGreenItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafGreenItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafBlueItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafBlueItem, SdrSignedPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafBlueItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafBlueItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafBlueItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafBlueItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafLuminanceItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafLuminanceItem, SdrSignedPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafLuminanceItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafLuminanceItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafLuminanceItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafLuminanceItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafContrastItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafContrastItem, SdrSignedPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafContrastItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafContrastItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafContrastItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafContrastItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafGamma100Item
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafGamma100Item, SfxUInt32Item );
+
+SfxPoolItem* __EXPORT SdrGrafGamma100Item::Clone( SfxItemPool* /*pPool */) const
+{
+ return new SdrGrafGamma100Item( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafGamma100Item::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafGamma100Item( rIn );
+}
+
+sal_Bool SdrGrafGamma100Item::QueryValue( uno::Any& rVal, BYTE /*nMemberId*/) const
+{
+ rVal <<= ((double)GetValue()) / 100.0;
+ return sal_True;
+}
+
+sal_Bool SdrGrafGamma100Item::PutValue( const uno::Any& rVal, BYTE /*nMemberId*/)
+{
+ double nGamma = 0;
+ if(!(rVal >>= nGamma))
+ return sal_False;
+
+ SetValue( (UINT32)(nGamma * 100.0 ) );
+ return sal_True;
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafInvertItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafInvertItem, SdrOnOffItem );
+
+SfxPoolItem* __EXPORT SdrGrafInvertItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafInvertItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafInvertItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafInvertItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafTransparenceItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafTransparenceItem, SdrPercentItem );
+
+SfxPoolItem* __EXPORT SdrGrafTransparenceItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafTransparenceItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafTransparenceItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafTransparenceItem( rIn );
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafModeItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafModeItem, SfxEnumItem );
+
+SfxPoolItem* __EXPORT SdrGrafModeItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafModeItem( *this );
+}
+
+SfxPoolItem* __EXPORT SdrGrafModeItem::Create( SvStream& rIn, USHORT /*nVer*/) const
+{
+ return new SdrGrafModeItem( rIn );
+}
+
+USHORT __EXPORT SdrGrafModeItem::GetValueCount() const
+{
+ return 4;
+}
+
+XubString __EXPORT SdrGrafModeItem::GetValueTextByPos(UINT16 nPos) const
+{
+ XubString aStr;
+
+ switch(nPos)
+ {
+ case 1:
+ {
+ sal_Char aTextGreys[] = "Greys";
+ aStr += UniString(aTextGreys, sizeof(aTextGreys-1));
+ break;
+ }
+ case 2:
+ {
+ sal_Char aTextBlackWhite[] = "Black/White";
+ aStr += UniString(aTextBlackWhite, sizeof(aTextBlackWhite-1));
+ break;
+ }
+ case 3:
+ {
+ sal_Char aTextWatermark[] = "Watermark";
+ aStr += UniString(aTextWatermark, sizeof(aTextWatermark-1));
+ break;
+ }
+ default:
+ {
+ sal_Char aTextStandard[] = "Standard";
+ aStr += UniString(aTextStandard, sizeof(aTextStandard-1));
+ break;
+ }
+ }
+
+ return aStr;
+}
+
+SfxItemPresentation __EXPORT SdrGrafModeItem::GetPresentation( SfxItemPresentation ePres,
+ SfxMapUnit /*eCoreMetric*/, SfxMapUnit /*ePresMetric*/,
+ XubString& rText, const IntlWrapper *) const
+{
+ rText = GetValueTextByPos( sal::static_int_cast< USHORT >( GetValue() ) );
+
+ if( ePres == SFX_ITEM_PRESENTATION_COMPLETE )
+ {
+ String aStr;
+
+ SdrItemPool::TakeItemName( Which(), aStr );
+ aStr += sal_Unicode(' ');
+ rText.Insert( aStr, 0 );
+ }
+
+ return ePres;
+}
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SdrGrafCropItem
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TYPEINIT1( SdrGrafCropItem, SvxGrfCrop );
+
+SfxPoolItem* SdrGrafCropItem::Clone( SfxItemPool* /*pPool*/) const
+{
+ return new SdrGrafCropItem( *this );
+}
+
+SfxPoolItem* SdrGrafCropItem::Create( SvStream& rIn, USHORT nVer ) const
+{
+ return( ( 0 == nVer ) ? Clone( NULL ) : SvxGrfCrop::Create( rIn, nVer ) );
+}
+
+USHORT SdrGrafCropItem::GetVersion( USHORT /*nFileVersion*/) const
+{
+ // GRFCROP_VERSION_MOVETOSVX is 1
+ return GRFCROP_VERSION_MOVETOSVX;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx
new file mode 100644
index 000000000000..9fd0edd3aac0
--- /dev/null
+++ b/svx/source/svdraw/svdcrtv.cxx
@@ -0,0 +1,964 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdcrtv.hxx>
+#include "xattr.hxx"
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx> // Spezialbehandlung: Nach dem Create transparente Fuellung
+#include <svx/svdoedge.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/scene3d.hxx>
+#include <svx/view3d.hxx>
+#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <svx/svdouno.hxx>
+#define XOR_CREATE_PEN PEN_SOLID
+#include <svx/svdopath.hxx>
+#include <svx/sdr/overlay/overlaypolypolygon.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <sdrpaintwindow.hxx>
+#include "fmobj.hxx"
+#include <svx/svdocirc.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImplConnectMarkerOverlay
+{
+ // The OverlayObjects
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+ // The remembered target object
+ const SdrObject& mrObject;
+
+public:
+ ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject& rObject);
+ ~ImplConnectMarkerOverlay();
+
+ const SdrObject& GetTargetObject() const { return mrObject; }
+};
+
+ImplConnectMarkerOverlay::ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject& rObject)
+: mrObject(rObject)
+{
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rObject.TakeXorPoly());
+
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ Size aHalfLogicSize(pTargetOverlay->getOutputDevice().PixelToLogic(Size(4, 4)));
+
+ // object
+ ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aB2DPolyPolygon);
+ pTargetOverlay->add(*pNew);
+ maObjects.append(*pNew);
+
+ // gluepoints
+ if(rView.IsAutoVertexConnectors())
+ {
+ for(sal_uInt16 i(0); i < 4; i++)
+ {
+ SdrGluePoint aGluePoint(rObject.GetVertexGluePoint(i));
+ const Point& rPosition = aGluePoint.GetAbsolutePos(rObject);
+
+ basegfx::B2DPoint aTopLeft(rPosition.X() - aHalfLogicSize.Width(), rPosition.Y() - aHalfLogicSize.Height());
+ basegfx::B2DPoint aBottomRight(rPosition.X() + aHalfLogicSize.Width(), rPosition.Y() + aHalfLogicSize.Height());
+
+ basegfx::B2DPolygon aTempPoly;
+ aTempPoly.append(aTopLeft);
+ aTempPoly.append(basegfx::B2DPoint(aBottomRight.getX(), aTopLeft.getY()));
+ aTempPoly.append(aBottomRight);
+ aTempPoly.append(basegfx::B2DPoint(aTopLeft.getX(), aBottomRight.getY()));
+ aTempPoly.setClosed(true);
+
+ basegfx::B2DPolyPolygon aTempPolyPoly;
+ aTempPolyPoly.append(aTempPoly);
+
+ pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aTempPolyPoly);
+ pTargetOverlay->add(*pNew);
+ maObjects.append(*pNew);
+ }
+ }
+ }
+ }
+}
+
+ImplConnectMarkerOverlay::~ImplConnectMarkerOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpSdrCreateViewExtraData
+{
+ // The OverlayObjects for XOR replacement
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+public:
+ ImpSdrCreateViewExtraData();
+ ~ImpSdrCreateViewExtraData();
+
+ void CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly);
+ void HideOverlay();
+};
+
+ImpSdrCreateViewExtraData::ImpSdrCreateViewExtraData()
+{
+}
+
+ImpSdrCreateViewExtraData::~ImpSdrCreateViewExtraData()
+{
+ HideOverlay();
+}
+
+void ImpSdrCreateViewExtraData::CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
+
+ if(pOverlayManager)
+ {
+ if(pObject)
+ {
+ const sdr::contact::ViewContact& rVC = pObject->GetViewContact();
+ const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence();
+ sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
+
+ pOverlayManager->add(*pNew);
+ maObjects.append(*pNew);
+ }
+
+ if(rPolyPoly.count())
+ {
+ ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(rPolyPoly);
+ pOverlayManager->add(*pNew);
+ maObjects.append(*pNew);
+ }
+ }
+ }
+}
+
+void ImpSdrCreateViewExtraData::HideOverlay()
+{
+ // the clear() call at the list removes all objects from the
+ // OverlayManager and deletes them.
+ maObjects.clear();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@ @@@@ @@@@@@ @@@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@ @@@@@ @@@@ @@@@@@ @@ @@@@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrCreateView::ImpClearConnectMarker()
+{
+ if(mpCoMaOverlay)
+ {
+ delete mpCoMaOverlay;
+ mpCoMaOverlay = 0L;
+ }
+}
+
+void SdrCreateView::ImpClearVars()
+{
+ nAktInvent=SdrInventor;
+ nAktIdent=OBJ_NONE;
+ pAktCreate=NULL;
+ pCreatePV=NULL;
+ bAutoTextEdit=FALSE;
+ b1stPointAsCenter=FALSE;
+ aAktCreatePointer=Pointer(POINTER_CROSS);
+ bUseIncompatiblePathCreateInterface=FALSE;
+ bAutoClosePolys=TRUE;
+ nAutoCloseDistPix=5;
+ nFreeHandMinDistPix=10;
+
+ ImpClearConnectMarker();
+}
+
+void SdrCreateView::ImpMakeCreateAttr()
+{
+}
+
+SdrCreateView::SdrCreateView(SdrModel* pModel1, OutputDevice* pOut)
+: SdrDragView(pModel1,pOut),
+ mpCoMaOverlay(0L),
+ mpCreateViewExtraData(new ImpSdrCreateViewExtraData())
+{
+ ImpClearVars();
+ ImpMakeCreateAttr();
+}
+
+SdrCreateView::~SdrCreateView()
+{
+ ImpClearConnectMarker();
+ delete mpCreateViewExtraData;
+ SdrObject::Free( pAktCreate );
+}
+
+void SdrCreateView::ImpDelCreateAttr()
+{
+}
+
+BOOL SdrCreateView::IsAction() const
+{
+ return SdrDragView::IsAction() || pAktCreate!=NULL;
+}
+
+void SdrCreateView::MovAction(const Point& rPnt)
+{
+ SdrDragView::MovAction(rPnt);
+ if (pAktCreate!=NULL) {
+ MovCreateObj(rPnt);
+ }
+}
+
+void SdrCreateView::EndAction()
+{
+ if (pAktCreate!=NULL) EndCreateObj(SDRCREATE_FORCEEND);
+ SdrDragView::EndAction();
+}
+
+void SdrCreateView::BckAction()
+{
+ if (pAktCreate!=NULL) BckCreateObj();
+ SdrDragView::BckAction();
+}
+
+void SdrCreateView::BrkAction()
+{
+ SdrDragView::BrkAction();
+ BrkCreateObj();
+}
+
+void SdrCreateView::TakeActionRect(Rectangle& rRect) const
+{
+ if (pAktCreate!=NULL)
+ {
+ rRect=aDragStat.GetActionRect();
+ if (rRect.IsEmpty())
+ {
+ rRect=Rectangle(aDragStat.GetPrev(),aDragStat.GetNow());
+ }
+ }
+ else
+ {
+ SdrDragView::TakeActionRect(rRect);
+ }
+}
+
+BOOL SdrCreateView::CheckEdgeMode()
+{
+ UINT32 nInv=nAktInvent;
+ UINT16 nIdn=nAktIdent;
+ if (pAktCreate!=NULL)
+ {
+ nInv=pAktCreate->GetObjInventor();
+ nIdn=pAktCreate->GetObjIdentifier();
+ // wird vom EdgeObj gemanaged
+ if (nAktInvent==SdrInventor && nAktIdent==OBJ_EDGE) return FALSE;
+ }
+
+ if (!IsCreateMode() || nAktInvent!=SdrInventor || nAktIdent!=OBJ_EDGE)
+ {
+ ImpClearConnectMarker();
+ return FALSE;
+ }
+ else
+ {
+ // TRUE heisst: MouseMove soll Connect checken
+ return !IsAction();
+ }
+}
+
+void SdrCreateView::SetConnectMarker(const SdrObjConnection& rCon, const SdrPageView& /*rPV*/)
+{
+ SdrObject* pTargetObject = rCon.pObj;
+
+ if(pTargetObject)
+ {
+ // if target object changes, throw away overlay object to make room for changes
+ if(mpCoMaOverlay && pTargetObject != &mpCoMaOverlay->GetTargetObject())
+ {
+ ImpClearConnectMarker();
+ }
+
+ if(!mpCoMaOverlay)
+ {
+ mpCoMaOverlay = new ImplConnectMarkerOverlay(*this, *pTargetObject);
+ }
+ }
+ else
+ {
+ ImpClearConnectMarker();
+ }
+}
+
+void SdrCreateView::HideConnectMarker()
+{
+ ImpClearConnectMarker();
+}
+
+BOOL SdrCreateView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
+{
+ if(CheckEdgeMode() && pWin)
+ {
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ // Defaultete Hit-Toleranz bei IsMarkedHit() mal aendern !!!!
+ Point aPos(pWin->PixelToLogic(rMEvt.GetPosPixel()));
+ BOOL bMarkHit=PickHandle(aPos)!=NULL || IsMarkedObjHit(aPos);
+ SdrObjConnection aCon;
+ if (!bMarkHit) SdrEdgeObj::ImpFindConnector(aPos,*pPV,aCon,NULL,pWin);
+ SetConnectMarker(aCon,*pPV);
+ }
+ }
+ return SdrDragView::MouseMove(rMEvt,pWin);
+}
+
+BOOL SdrCreateView::IsTextTool() const
+{
+ return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_TEXT || nAktIdent==OBJ_TEXTEXT || nAktIdent==OBJ_TITLETEXT || nAktIdent==OBJ_OUTLINETEXT);
+}
+
+BOOL SdrCreateView::IsEdgeTool() const
+{
+ return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_EDGE);
+}
+
+BOOL SdrCreateView::IsMeasureTool() const
+{
+ return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_MEASURE);
+}
+
+void SdrCreateView::SetCurrentObj(UINT16 nIdent, UINT32 nInvent)
+{
+ if (nAktInvent!=nInvent || nAktIdent!=nIdent)
+ {
+ nAktInvent=nInvent;
+ nAktIdent=nIdent;
+ SdrObject* pObj = SdrObjFactory::MakeNewObject(nInvent,nIdent,NULL,NULL);
+
+ if(pObj)
+ {
+ // Auf pers. Wunsch von Marco:
+ // Mauszeiger bei Textwerkzeug immer I-Beam. Fadenkreuz
+ // mit kleinem I-Beam erst bai MouseButtonDown
+ if(IsTextTool())
+ {
+ // #81944# AW: Here the correct pointer needs to be used
+ // if the default is set to vertical writing
+ aAktCreatePointer = POINTER_TEXT;
+ }
+ else
+ aAktCreatePointer = pObj->GetCreatePointer();
+
+ SdrObject::Free( pObj );
+ }
+ else
+ {
+ aAktCreatePointer = Pointer(POINTER_CROSS);
+ }
+ }
+
+ CheckEdgeMode();
+ ImpSetGlueVisible3(IsEdgeTool());
+}
+
+BOOL SdrCreateView::ImpBegCreateObj(UINT32 nInvent, UINT16 nIdent, const Point& rPnt, OutputDevice* pOut,
+ short nMinMov, SdrPageView* pPV, const Rectangle& rLogRect, SdrObject* pPreparedFactoryObject)
+{
+ BOOL bRet=FALSE;
+ UnmarkAllObj();
+ BrkAction();
+
+ ImpClearConnectMarker();
+
+ if (pPV!=NULL)
+ {
+ pCreatePV=pPV;
+ }
+ else
+ {
+ pCreatePV = GetSdrPageView();
+ }
+ if (pCreatePV!=NULL)
+ { // ansonsten keine Seite angemeldet!
+ String aLay(aAktLayer);
+
+ if(nInvent == SdrInventor && nIdent == OBJ_MEASURE && aMeasureLayer.Len())
+ {
+ aLay = aMeasureLayer;
+ }
+
+ SdrLayerID nLayer=pCreatePV->GetPage()->GetLayerAdmin().GetLayerID(aLay,TRUE);
+ if (nLayer==SDRLAYER_NOTFOUND) nLayer=0;
+ if (!pCreatePV->GetLockedLayers().IsSet(nLayer) && pCreatePV->GetVisibleLayers().IsSet(nLayer))
+ {
+ if(pPreparedFactoryObject)
+ {
+ pAktCreate = pPreparedFactoryObject;
+
+ if(pCreatePV->GetPage())
+ {
+ pAktCreate->SetPage(pCreatePV->GetPage());
+ }
+ else if (pMod)
+ {
+ pAktCreate->SetModel(pMod);
+ }
+ }
+ else
+ {
+ pAktCreate = SdrObjFactory::MakeNewObject(nInvent, nIdent, pCreatePV->GetPage(), pMod);
+ }
+
+ Point aPnt(rPnt);
+ if (nAktInvent!=SdrInventor || (nAktIdent!=USHORT(OBJ_EDGE) &&
+ nAktIdent!=USHORT(OBJ_FREELINE) &&
+ nAktIdent!=USHORT(OBJ_FREEFILL) )) { // Kein Fang fuer Edge und Freihand!
+ aPnt=GetSnapPos(aPnt,pCreatePV);
+ }
+ if (pAktCreate!=NULL)
+ {
+ BOOL bStartEdit=FALSE; // nach Ende von Create automatisch TextEdit starten
+ if (pDefaultStyleSheet!=NULL) pAktCreate->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
+
+ // #101618# SW uses a naked SdrObject for frame construction. Normally, such an
+ // object should not be created. Since it is possible to use it as a helper
+ // object (e.g. in letting the user define an area with the interactive
+ // construction) at least no items should be set at that object.
+ if(nInvent != SdrInventor || nIdent != OBJ_NONE)
+ {
+ pAktCreate->SetMergedItemSet(aDefaultAttr);
+ }
+
+ if (HAS_BASE(SdrCaptionObj,pAktCreate))
+ {
+ SfxItemSet aSet(pMod->GetItemPool());
+ aSet.Put(XFillColorItem(String(),Color(COL_WHITE))); // Falls einer auf Solid umschaltet
+ aSet.Put(XFillStyleItem(XFILL_NONE));
+
+ pAktCreate->SetMergedItemSet(aSet);
+
+ bStartEdit=TRUE;
+ }
+ if (nInvent==SdrInventor && (nIdent==OBJ_TEXT || nIdent==OBJ_TEXTEXT ||
+ nIdent==OBJ_TITLETEXT || nIdent==OBJ_OUTLINETEXT))
+ {
+ // Fuer alle Textrahmen default keinen Hintergrund und keine Umrandung
+ SfxItemSet aSet(pMod->GetItemPool());
+ aSet.Put(XFillColorItem(String(),Color(COL_WHITE))); // Falls einer auf Solid umschaltet
+ aSet.Put(XFillStyleItem(XFILL_NONE));
+ aSet.Put(XLineColorItem(String(),Color(COL_BLACK))); // Falls einer auf Solid umschaltet
+ aSet.Put(XLineStyleItem(XLINE_NONE));
+
+ pAktCreate->SetMergedItemSet(aSet);
+
+ bStartEdit=TRUE;
+ }
+ if (!rLogRect.IsEmpty()) pAktCreate->NbcSetLogicRect(rLogRect);
+
+ // #90129# make sure drag start point is inside WorkArea
+ const Rectangle& rWorkArea = ((SdrDragView*)this)->GetWorkArea();
+
+ if(!rWorkArea.IsEmpty())
+ {
+ if(aPnt.X() < rWorkArea.Left())
+ {
+ aPnt.X() = rWorkArea.Left();
+ }
+
+ if(aPnt.X() > rWorkArea.Right())
+ {
+ aPnt.X() = rWorkArea.Right();
+ }
+
+ if(aPnt.Y() < rWorkArea.Top())
+ {
+ aPnt.Y() = rWorkArea.Top();
+ }
+
+ if(aPnt.Y() > rWorkArea.Bottom())
+ {
+ aPnt.Y() = rWorkArea.Bottom();
+ }
+ }
+
+ aDragStat.Reset(aPnt);
+ aDragStat.SetView((SdrView*)this);
+ aDragStat.SetPageView(pCreatePV);
+ aDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
+ pDragWin=pOut;
+ if (pAktCreate->BegCreate(aDragStat))
+ {
+ ShowCreateObj(/*pOut,TRUE*/);
+ bRet=TRUE;
+ }
+ else
+ {
+ SdrObject::Free( pAktCreate );
+ pAktCreate=NULL;
+ pCreatePV=NULL;
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+BOOL SdrCreateView::BegCreateObj(const Point& rPnt, OutputDevice* pOut, short nMinMov, SdrPageView* pPV)
+{
+ return ImpBegCreateObj(nAktInvent,nAktIdent,rPnt,pOut,nMinMov,pPV,Rectangle(), 0L);
+}
+
+sal_Bool SdrCreateView::BegCreatePreparedObject(const Point& rPnt, sal_Int16 nMinMov, SdrObject* pPreparedFactoryObject)
+{
+ sal_uInt32 nInvent(nAktInvent);
+ sal_uInt16 nIdent(nAktIdent);
+
+ if(pPreparedFactoryObject)
+ {
+ nInvent = pPreparedFactoryObject->GetObjInventor();
+ nIdent = pPreparedFactoryObject->GetObjIdentifier();
+ }
+
+ return ImpBegCreateObj(nInvent, nIdent, rPnt, 0L, nMinMov, 0L, Rectangle(), pPreparedFactoryObject);
+}
+
+BOOL SdrCreateView::BegCreateCaptionObj(const Point& rPnt, const Size& rObjSiz,
+ OutputDevice* pOut, short nMinMov, SdrPageView* pPV)
+{
+ return ImpBegCreateObj(SdrInventor,OBJ_CAPTION,rPnt,pOut,nMinMov,pPV,
+ Rectangle(rPnt,Size(rObjSiz.Width()+1,rObjSiz.Height()+1)), 0L);
+}
+
+void SdrCreateView::MovCreateObj(const Point& rPnt)
+{
+ if (pAktCreate!=NULL) {
+ Point aPnt(rPnt);
+ if (!aDragStat.IsNoSnap())
+ {
+ aPnt=GetSnapPos(aPnt,pCreatePV);
+ }
+ if (IsOrtho())
+ {
+ if (aDragStat.IsOrtho8Possible()) OrthoDistance8(aDragStat.GetPrev(),aPnt,IsBigOrtho());
+ else if (aDragStat.IsOrtho4Possible()) OrthoDistance4(aDragStat.GetPrev(),aPnt,IsBigOrtho());
+ }
+
+ // #77734# If the drag point was limited and Ortho is active, do
+ // the small ortho correction (reduction) -> last parameter to FALSE.
+ sal_Bool bDidLimit(ImpLimitToWorkArea(aPnt));
+ if(bDidLimit && IsOrtho())
+ {
+ if(aDragStat.IsOrtho8Possible())
+ OrthoDistance8(aDragStat.GetPrev(), aPnt, FALSE);
+ else if(aDragStat.IsOrtho4Possible())
+ OrthoDistance4(aDragStat.GetPrev(), aPnt, FALSE);
+ }
+
+ if (aPnt==aDragStat.GetNow()) return;
+ bool bMerk(aDragStat.IsMinMoved());
+ if (aDragStat.CheckMinMoved(aPnt))
+ {
+ Rectangle aBound;
+ if (!bMerk) aDragStat.NextPoint();
+ aDragStat.NextMove(aPnt);
+ pAktCreate->MovCreate(aDragStat);
+
+ // MovCreate changes the object, so use ActionChanged() on it
+ pAktCreate->ActionChanged();
+
+ // replace for DrawCreateObjDiff
+ HideCreateObj();
+ ShowCreateObj();
+ }
+ }
+}
+
+BOOL SdrCreateView::EndCreateObj(SdrCreateCmd eCmd)
+{
+ BOOL bRet=FALSE;
+ SdrObject* pObjMerk=pAktCreate;
+ SdrPageView* pPVMerk=pCreatePV;
+
+ if (pAktCreate!=NULL)
+ {
+ ULONG nAnz=aDragStat.GetPointAnz();
+
+ if (nAnz<=1 && eCmd==SDRCREATE_FORCEEND)
+ {
+ BrkCreateObj(); // Objekte mit nur einem Punkt gibt's nicht (zumindest noch nicht)
+ return FALSE; // FALSE=Event nicht ausgewertet
+ }
+
+ BOOL bPntsEq=nAnz>1;
+ ULONG i=1;
+ Point aP0=aDragStat.GetPoint(0);
+ while (bPntsEq && i<nAnz) { bPntsEq=aP0==aDragStat.GetPoint(i); i++; }
+
+ if (pAktCreate->EndCreate(aDragStat,eCmd))
+ {
+ HideCreateObj();
+
+ if (!bPntsEq)
+ {
+ // sonst Brk, weil alle Punkte gleich sind.
+ SdrObject* pObj=pAktCreate;
+ pAktCreate=NULL;
+
+ const SdrLayerAdmin& rAd = pCreatePV->GetPage()->GetLayerAdmin();
+ SdrLayerID nLayer(0);
+
+ // #i72535#
+ if(pObj->ISA(FmFormObj))
+ {
+ // for FormControls, force to form layer
+ nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
+ }
+ else
+ {
+ nLayer = rAd.GetLayerID(aAktLayer, TRUE);
+ }
+
+ if(SDRLAYER_NOTFOUND == nLayer)
+ {
+ nLayer=0;
+ }
+
+ pObj->SetLayer(nLayer);
+
+ // #83403# recognize creation of a new 3D object inside a 3D scene
+ BOOL bSceneIntoScene(FALSE);
+
+ if(pObjMerk
+ && pObjMerk->ISA(E3dScene)
+ && pCreatePV
+ && pCreatePV->GetAktGroup()
+ && pCreatePV->GetAktGroup()->ISA(E3dScene))
+ {
+ BOOL bDidInsert = ((E3dView*)this)->ImpCloneAll3DObjectsToDestScene(
+ (E3dScene*)pObjMerk, (E3dScene*)pCreatePV->GetAktGroup(), Point(0, 0));
+
+ if(bDidInsert)
+ {
+ // delete object, it's content is cloned and inserted
+ SdrObject::Free( pObjMerk );
+ pObjMerk = 0L;
+ bRet = FALSE;
+ bSceneIntoScene = TRUE;
+ }
+ }
+
+ if(!bSceneIntoScene)
+ {
+ // do the same as before
+ InsertObjectAtView(pObj, *pCreatePV);
+ }
+
+ pCreatePV=NULL;
+ bRet=TRUE; // TRUE=Event ausgewertet
+ }
+ else
+ {
+ BrkCreateObj();
+ }
+ }
+ else
+ { // Mehr Punkte
+ if (eCmd==SDRCREATE_FORCEEND || // nix da, Ende erzwungen
+ nAnz==0 || // keine Punkte da (kann eigentlich nicht vorkommen)
+ (nAnz<=1 && !aDragStat.IsMinMoved())) { // MinMove nicht erfuellt
+ BrkCreateObj();
+ }
+ else
+ {
+ // replace for DrawCreateObjDiff
+ HideCreateObj();
+ ShowCreateObj();
+ aDragStat.ResetMinMoved(); // NextPoint gibt's bei MovCreateObj()
+ bRet=TRUE;
+ }
+ }
+ if (bRet && pObjMerk!=NULL && IsTextEditAfterCreate())
+ {
+ SdrTextObj* pText=PTR_CAST(SdrTextObj,pObjMerk);
+ if (pText!=NULL && pText->IsTextFrame())
+ {
+ SdrBeginTextEdit(pText, pPVMerk, (Window*)0L, sal_True, (SdrOutliner*)0L, (OutlinerView*)0L);
+ }
+ }
+ }
+ return bRet;
+}
+
+void SdrCreateView::BckCreateObj()
+{
+ if (pAktCreate!=NULL)
+ {
+ if (aDragStat.GetPointAnz()<=2 )
+ {
+ BrkCreateObj();
+ }
+ else
+ {
+ HideCreateObj();
+ aDragStat.PrevPoint();
+ if (pAktCreate->BckCreate(aDragStat))
+ {
+ ShowCreateObj();
+ }
+ else
+ {
+ BrkCreateObj();
+ }
+ }
+ }
+}
+
+void SdrCreateView::BrkCreateObj()
+{
+ if (pAktCreate!=NULL)
+ {
+ HideCreateObj();
+ pAktCreate->BrkCreate(aDragStat);
+ SdrObject::Free( pAktCreate );
+ pAktCreate=NULL;
+ pCreatePV=NULL;
+ }
+}
+
+void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, BOOL bFull*/)
+{
+ if(IsCreateObj() && !aDragStat.IsShown())
+ {
+ if(pAktCreate)
+ {
+ // for migration from XOR, replace DrawDragObj here to create
+ // overlay objects instead.
+ sal_Bool bUseSolidDragging(IsSolidDragging());
+
+ // #i101648# check if dragged object is a naked SdrObject (no
+ // derivation of). This is e.g. used in SW Frame construction
+ // as placeholder. Do not use SolidDragging for naked SDrObjects,
+ // they cannot have a valid optical representation
+ if(bUseSolidDragging && OBJ_NONE == pAktCreate->GetObjIdentifier())
+ {
+ bUseSolidDragging = false;
+ }
+
+ // check for objects with no fill and no line
+ if(bUseSolidDragging)
+ {
+ const SfxItemSet& rSet = pAktCreate->GetMergedItemSet();
+ const XFillStyle eFill(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue());
+ const XLineStyle eLine(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue());
+
+ if(XLINE_NONE == eLine && XFILL_NONE == eFill)
+ {
+ bUseSolidDragging = sal_False;
+ }
+ }
+
+ // check for form controls
+ if(bUseSolidDragging)
+ {
+ if(pAktCreate->ISA(SdrUnoObj))
+ {
+ bUseSolidDragging = sal_False;
+ }
+ }
+
+ // #i101781# force to non-solid dragging when not creating a full circle
+ if(bUseSolidDragging)
+ {
+ SdrCircObj* pCircObj = dynamic_cast< SdrCircObj* >(pAktCreate);
+
+ if(pCircObj && OBJ_CIRC != pCircObj->GetObjIdentifier())
+ {
+ // #i103058# Allow SolidDragging with four points
+ if(aDragStat.GetPointAnz() < 4)
+ {
+ bUseSolidDragging = false;
+ }
+ }
+ }
+
+ if(bUseSolidDragging)
+ {
+ basegfx::B2DPolyPolygon aDragPolyPolygon;
+
+ if(pAktCreate->ISA(SdrRectObj))
+ {
+ // ensure object has some size, necessary for SdrTextObj because
+ // there are still untested divisions by that sizes
+ Rectangle aCurrentSnapRect(pAktCreate->GetSnapRect());
+
+ if(!(aCurrentSnapRect.GetWidth() > 1 && aCurrentSnapRect.GetHeight() > 1))
+ {
+ Rectangle aNewRect(aDragStat.GetStart(), aDragStat.GetStart() + Point(2, 2));
+ pAktCreate->NbcSetSnapRect(aNewRect);
+ }
+ }
+
+ if(pAktCreate->ISA(SdrPathObj))
+ {
+ // The up-to-now created path needs to be set at the object to have something
+ // that can be visualized
+ SdrPathObj& rPathObj((SdrPathObj&)(*pAktCreate));
+ const basegfx::B2DPolyPolygon aCurrentPolyPolygon(rPathObj.getObjectPolyPolygon(aDragStat));
+
+ if(aCurrentPolyPolygon.count())
+ {
+ rPathObj.NbcSetPathPoly(aCurrentPolyPolygon);
+ }
+
+ aDragPolyPolygon = rPathObj.getDragPolyPolygon(aDragStat);
+ }
+
+ // use directly the SdrObject for overlay
+ mpCreateViewExtraData->CreateAndShowOverlay(*this, pAktCreate, aDragPolyPolygon);
+ }
+ else
+ {
+ mpCreateViewExtraData->CreateAndShowOverlay(*this, 0, pAktCreate->TakeCreatePoly(aDragStat));
+ }
+
+ // #i101679# Force changed overlay to be shown
+ for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = GetPaintWindow(a);
+ sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
+
+ if(pOverlayManager)
+ {
+ pOverlayManager->flush();
+ }
+ }
+ }
+
+ aDragStat.SetShown(TRUE);
+ }
+}
+
+void SdrCreateView::HideCreateObj()
+{
+ if(IsCreateObj() && aDragStat.IsShown())
+ {
+ // for migration from XOR, replace DrawDragObj here to create
+ // overlay objects instead.
+ mpCreateViewExtraData->HideOverlay();
+
+ //DrawCreateObj(pOut,bFull);
+ aDragStat.SetShown(FALSE);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* new interface src537 */
+BOOL SdrCreateView::GetAttributes(SfxItemSet& rTargetSet, BOOL bOnlyHardAttr) const
+{
+ if(pAktCreate)
+ {
+ rTargetSet.Put(pAktCreate->GetMergedItemSet());
+ return TRUE;
+ }
+ else
+ {
+ return SdrDragView::GetAttributes(rTargetSet, bOnlyHardAttr);
+ }
+}
+
+BOOL SdrCreateView::SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll)
+{
+ if(pAktCreate)
+ {
+ pAktCreate->SetMergedItemSetAndBroadcast(rSet, bReplaceAll);
+
+ return TRUE;
+ }
+ else
+ {
+ return SdrDragView::SetAttributes(rSet,bReplaceAll);
+ }
+}
+
+SfxStyleSheet* SdrCreateView::GetStyleSheet() const // SfxStyleSheet* SdrCreateView::GetStyleSheet(BOOL& rOk) const
+{
+ if (pAktCreate!=NULL)
+ {
+ //rOk=TRUE;
+ return pAktCreate->GetStyleSheet();
+ }
+ else
+ {
+ return SdrDragView::GetStyleSheet(); // SdrDragView::GetStyleSheet(rOk);
+ }
+}
+
+BOOL SdrCreateView::SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ if (pAktCreate!=NULL)
+ {
+ pAktCreate->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ return TRUE;
+ }
+ else
+ {
+ return SdrDragView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ }
+}
+
diff --git a/svx/source/svdraw/svddrag.cxx b/svx/source/svdraw/svddrag.cxx
new file mode 100644
index 000000000000..74d8fd10a402
--- /dev/null
+++ b/svx/source/svdraw/svddrag.cxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/svdview.hxx>
+#include <svx/svddrag.hxx>
+
+void SdrDragStat::Clear(FASTBOOL bLeaveOne)
+{
+ void* pP=aPnts.First();
+ while (pP!=NULL) {
+ delete (Point*)pP;
+ pP=aPnts.Next();
+ }
+ if (pUser!=NULL) delete pUser;
+ pUser=NULL;
+ aPnts.Clear();
+ if (bLeaveOne) {
+ aPnts.Insert(new Point,CONTAINER_APPEND);
+ }
+}
+
+void SdrDragStat::Reset()
+{
+ pView=NULL;
+ pPageView=NULL;
+ bShown=FALSE;
+ nMinMov=1;
+ bMinMoved=FALSE;
+ bHorFixed=FALSE;
+ bVerFixed=FALSE;
+ bWantNoSnap=FALSE;
+ pHdl=NULL;
+ bOrtho4=FALSE;
+ bOrtho8=FALSE;
+ pDragMethod=NULL;
+ bEndDragChangesAttributes=FALSE;
+ bEndDragChangesGeoAndAttributes=FALSE;
+ bMouseIsUp=FALSE;
+ Clear(TRUE);
+ aActionRect=Rectangle();
+}
+
+void SdrDragStat::Reset(const Point& rPnt)
+{
+ Reset();
+ Start()=rPnt;
+ aPos0=rPnt;
+ aRealPos0=rPnt;
+ RealNow()=rPnt;
+}
+
+void SdrDragStat::NextMove(const Point& rPnt)
+{
+ aRealPos0=GetRealNow();
+ aPos0=GetNow();
+ RealNow()=rPnt;
+ Point aBla=KorregPos(GetRealNow(),GetPrev());
+ Now()=aBla;
+}
+
+void SdrDragStat::NextPoint(FASTBOOL bSaveReal)
+{
+ Point aPnt(GetNow());
+ if (bSaveReal) aPnt=aRealNow;
+ aPnts.Insert(new Point(KorregPos(GetRealNow(),aPnt)),CONTAINER_APPEND);
+ Prev()=aPnt;
+}
+
+void SdrDragStat::PrevPoint()
+{
+ if (aPnts.Count()>=2) { // einer muss immer da bleiben
+ Point* pPnt=(Point*)(aPnts.GetObject(aPnts.Count()-2));
+ aPnts.Remove(aPnts.Count()-2);
+ delete pPnt;
+ Now()=KorregPos(GetRealNow(),GetPrev());
+ }
+}
+
+Point SdrDragStat::KorregPos(const Point& rNow, const Point& /*rPrev*/) const
+{
+ Point aRet(rNow);
+ return aRet;
+}
+
+FASTBOOL SdrDragStat::CheckMinMoved(const Point& rPnt)
+{
+ if (!bMinMoved) {
+ long dx=rPnt.X()-GetPrev().X(); if (dx<0) dx=-dx;
+ long dy=rPnt.Y()-GetPrev().Y(); if (dy<0) dy=-dy;
+ if (dx>=long(nMinMov) || dy>=long(nMinMov))
+ bMinMoved=TRUE;
+ }
+ return bMinMoved;
+}
+
+Fraction SdrDragStat::GetXFact() const
+{
+ long nMul=GetNow().X()-aRef1.X();
+ long nDiv=GetPrev().X()-aRef1.X();
+ if (nDiv==0) nDiv=1;
+ if (bHorFixed) { nMul=1; nDiv=1; }
+ return Fraction(nMul,nDiv);
+}
+
+Fraction SdrDragStat::GetYFact() const
+{
+ long nMul=GetNow().Y()-aRef1.Y();
+ long nDiv=GetPrev().Y()-aRef1.Y();
+ if (nDiv==0) nDiv=1;
+ if (bVerFixed) { nMul=1; nDiv=1; }
+ return Fraction(nMul,nDiv);
+}
+
+void SdrDragStat::TakeCreateRect(Rectangle& rRect) const
+{
+ rRect=Rectangle(GetStart(),GetNow());
+ if (GetPointAnz()>=2) {
+ Point aBtmRgt(GetPoint(1));
+ rRect.Right()=aBtmRgt.X();
+ rRect.Bottom()=aBtmRgt.Y();
+ }
+ if (pView!=NULL && pView->IsCreate1stPointAsCenter()) {
+ rRect.Top()+=rRect.Top()-rRect.Bottom();
+ rRect.Left()+=rRect.Left()-rRect.Right();
+ }
+}
+
diff --git a/svx/source/svdraw/svddrgm1.hxx b/svx/source/svdraw/svddrgm1.hxx
new file mode 100644
index 000000000000..201d02e7b9f3
--- /dev/null
+++ b/svx/source/svdraw/svddrgm1.hxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVDDRGM1_HXX
+#define _SVDDRGM1_HXX
+
+#include <svx/xpoly.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svddrgv.hxx>
+#include <svx/svddrgmt.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+class SdrDragView;
+class SdrDragStat;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragMovHdl
+
+class SdrDragMovHdl : public SdrDragMethod
+{
+private:
+ bool bMirrObjShown;
+
+protected:
+ // define nothing, overload to do so
+ virtual void createSdrDragEntries();
+
+public:
+ TYPEINFO();
+ SdrDragMovHdl(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual void CancelSdrDrag();
+ virtual Pointer GetSdrDragPointer() const;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragRotate
+
+class SdrDragRotate : public SdrDragMethod
+{
+private:
+ double nSin;
+ double nCos;
+ long nWink0;
+ long nWink;
+ bool bRight;
+
+public:
+ TYPEINFO();
+ SdrDragRotate(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+
+ virtual basegfx::B2DHomMatrix getCurrentTransformation();
+ virtual void applyCurrentTransformationToSdrObject(SdrObject& rTarget);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragShear
+
+class SdrDragShear : public SdrDragMethod
+{
+private:
+ Fraction aFact;
+ long nWink0;
+ long nWink;
+ double nTan;
+ bool bVertical; // Vertikales verzerren
+ bool bResize; // Shear mit Resize
+ bool bUpSideDown; // Beim Shear/Slant gespiegelt
+ bool bSlant;
+
+public:
+ TYPEINFO();
+ SdrDragShear(SdrDragView& rNewView,bool bSlant1);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+
+ virtual basegfx::B2DHomMatrix getCurrentTransformation();
+ virtual void applyCurrentTransformationToSdrObject(SdrObject& rTarget);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragMirror
+
+class SdrDragMirror : public SdrDragMethod
+{
+private:
+ Point aDif;
+ long nWink;
+ bool bMirrored;
+ bool bSide0;
+
+ bool ImpCheckSide(const Point& rPnt) const;
+
+public:
+ TYPEINFO();
+ SdrDragMirror(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+
+ virtual basegfx::B2DHomMatrix getCurrentTransformation();
+ virtual void applyCurrentTransformationToSdrObject(SdrObject& rTarget);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragGradient
+
+class SdrDragGradient : public SdrDragMethod
+{
+private:
+ // Handles to work on
+ SdrHdlGradient* pIAOHandle;
+
+ // is this for gradient (or for transparence) ?
+ unsigned bIsGradient : 1;
+
+public:
+ TYPEINFO();
+ SdrDragGradient(SdrDragView& rNewView, bool bGrad = true);
+
+ bool IsGradient() const { return bIsGradient; }
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+ virtual void CancelSdrDrag();
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragCrook
+
+class SdrDragCrook : public SdrDragMethod
+{
+private:
+ Rectangle aMarkRect;
+ Point aMarkCenter;
+ Point aCenter;
+ Point aStart;
+ Fraction aFact;
+ Point aRad;
+ bool bContortionAllowed;
+ bool bNoContortionAllowed;
+ bool bContortion;
+ bool bResizeAllowed;
+ bool bResize;
+ bool bRotateAllowed;
+ bool bRotate;
+ bool bVertical;
+ bool bValid;
+ bool bLft;
+ bool bRgt;
+ bool bUpr;
+ bool bLwr;
+ bool bAtCenter;
+ long nWink;
+ long nMarkSize;
+ SdrCrookMode eMode;
+
+ // helpers for applyCurrentTransformationToPolyPolygon
+ void _MovAllPoints(basegfx::B2DPolyPolygon& rTarget);
+ void _MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2);
+
+protected:
+ // needs to add drag geometry to the default
+ virtual void createSdrDragEntries();
+
+public:
+ TYPEINFO();
+ SdrDragCrook(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+
+ virtual void applyCurrentTransformationToSdrObject(SdrObject& rTarget);
+ virtual void applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragDistort
+
+class SdrDragDistort : public SdrDragMethod
+{
+private:
+ Rectangle aMarkRect;
+ XPolygon aDistortedRect;
+ sal_uInt16 nPolyPt;
+ bool bContortionAllowed;
+ bool bNoContortionAllowed;
+ bool bContortion;
+
+ // helper for applyCurrentTransformationToPolyPolygon
+ void _MovAllPoints(basegfx::B2DPolyPolygon& rTarget);
+
+protected:
+ // needs to add drag geometry to the default
+ virtual void createSdrDragEntries();
+
+public:
+ TYPEINFO();
+ SdrDragDistort(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool BeginSdrDrag();
+ virtual void MoveSdrDrag(const Point& rPnt);
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+
+ virtual void applyCurrentTransformationToSdrObject(SdrObject& rTarget);
+ virtual void applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrDragCrop
+
+class SdrDragCrop : public SdrDragResize
+{
+public:
+ TYPEINFO();
+ SdrDragCrop(SdrDragView& rNewView);
+
+ virtual void TakeSdrDragComment(String& rStr) const;
+ virtual bool EndSdrDrag(bool bCopy);
+ virtual Pointer GetSdrDragPointer() const;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif //_SVDDRGM1_HXX
+
+// eof
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
new file mode 100644
index 000000000000..d04bf8851795
--- /dev/null
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -0,0 +1,3652 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svddrgm1.hxx"
+#include <math.h>
+
+#ifndef _MATH_H
+#define _MATH_H
+#endif
+#include <tools/bigint.hxx>
+#include <vcl/svapp.hxx>
+
+#include "xattr.hxx"
+#include <svx/xpoly.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpagv.hxx>
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/svddrgv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/sdgcpitm.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svx/sdr/overlay/overlaypolypolygon.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdr/overlay/overlayrollingrectangle.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <sdrpaintwindow.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include "svditer.hxx"
+#include <svx/svdopath.hxx>
+#include <svx/polypolygoneditor.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx>
+#include <svx/sdr/primitive2d/sdrattributecreator.hxx>
+#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdovirt.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/sdr/primitive2d/sdrprimitivetools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/attribute/sdrlineattribute.hxx>
+#include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrDragEntry::SdrDragEntry()
+: mbAddToTransparent(false)
+{
+}
+
+SdrDragEntry::~SdrDragEntry()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrDragEntryPolyPolygon::SdrDragEntryPolyPolygon(const basegfx::B2DPolyPolygon& rOriginalPolyPolygon)
+: SdrDragEntry(),
+ maOriginalPolyPolygon(rOriginalPolyPolygon)
+{
+}
+
+SdrDragEntryPolyPolygon::~SdrDragEntryPolyPolygon()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPolyPolygon::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+
+ if(maOriginalPolyPolygon.count())
+ {
+ basegfx::B2DPolyPolygon aCopy(maOriginalPolyPolygon);
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+
+ rDragMethod.applyCurrentTransformationToPolyPolygon(aCopy);
+ basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
+ basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
+ const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
+
+ if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
+ aColB.invert();
+ }
+
+ drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
+ new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(aCopy, aColA, aColB, fStripeLength));
+
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aPolyPolygonMarkerPrimitive2D, 1);
+ }
+
+ return aRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
+: SdrDragEntry(),
+ maOriginal(rOriginal),
+ mpClone(0),
+ mrObjectContact(rObjectContact),
+ mbModify(bModify)
+{
+ // add SdrObject parts to transparent overlay stuff
+ setAddToTransparent(true);
+}
+
+SdrDragEntrySdrObject::~SdrDragEntrySdrObject()
+{
+ if(mpClone)
+ {
+ SdrObject::Free(mpClone);
+ }
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragEntrySdrObject::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
+{
+ // for the moment, i need to re-create the clone in all cases. I need to figure
+ // out when clone and original have the same class, so that i can use operator=
+ // in those cases
+
+ // // copy all other needed stuff
+ // basegfx::B2DHomMatrix aMatrix;
+ // basegfx::B2DPolyPolygon aPolyPolygon;
+ // pOleObject->TRGetBaseGeometry(aMatrix, aPolyPolygon);
+ // pClone->TRSetBaseGeometry(aMatrix, aPolyPolygon);
+
+ const SdrObject* pSource = &maOriginal;
+
+ if(mpClone)
+ {
+ SdrObject::Free(mpClone);
+ mpClone = 0;
+ }
+
+ if(mbModify)
+ {
+ if(!mpClone)
+ {
+ mpClone = maOriginal.getFullDragClone();
+ }
+
+ // apply original transformation, implemented at the DragMethods
+ rDragMethod.applyCurrentTransformationToSdrObject(*mpClone);
+
+ // choose source for geometry data
+ pSource = mpClone;
+ }
+
+ // get VOC and Primitive2DSequence
+ sdr::contact::ViewContact& rVC = pSource->GetViewContact();
+ sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact);
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
+ // here we want the complete primitive sequence without visibility clippings
+ mrObjectContact.resetViewPort();
+
+ return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrDragEntryPrimitive2DSequence::SdrDragEntryPrimitive2DSequence(
+ const drawinglayer::primitive2d::Primitive2DSequence& rSequence,
+ bool bAddToTransparent)
+: SdrDragEntry(),
+ maPrimitive2DSequence(rSequence)
+{
+ // add parts to transparent overlay stuff eventually
+ setAddToTransparent(bAddToTransparent);
+}
+
+SdrDragEntryPrimitive2DSequence::~SdrDragEntryPrimitive2DSequence()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPrimitive2DSequence::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
+{
+ drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ rDragMethod.getCurrentTransformation(),
+ maPrimitive2DSequence));
+
+ return drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrDragEntryPointGlueDrag::SdrDragEntryPointGlueDrag(const std::vector< basegfx::B2DPoint >& rPositions, bool bIsPointDrag)
+: maPositions(rPositions),
+ mbIsPointDrag(bIsPointDrag)
+{
+ // add SdrObject parts to transparent overlay stuff
+ setAddToTransparent(true);
+}
+
+SdrDragEntryPointGlueDrag::~SdrDragEntryPointGlueDrag()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragEntryPointGlueDrag::createPrimitive2DSequenceInCurrentState(SdrDragMethod& rDragMethod)
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+
+ if(maPositions.size())
+ {
+ basegfx::B2DPolygon aPolygon;
+ sal_uInt32 a(0);
+
+ for(a = 0; a < maPositions.size(); a++)
+ {
+ aPolygon.append(maPositions[a]);
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon(aPolygon);
+
+ rDragMethod.applyCurrentTransformationToPolyPolygon(aPolyPolygon);
+
+ const basegfx::B2DPolygon aTransformed(aPolyPolygon.getB2DPolygon(0));
+ std::vector< basegfx::B2DPoint > aTransformedPositions;
+
+ aTransformedPositions.reserve(aTransformed.count());
+
+ for(a = 0; a < aTransformed.count(); a++)
+ {
+ aTransformedPositions.push_back(aTransformed.getB2DPoint(a));
+ }
+
+ if(mbIsPointDrag)
+ {
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ basegfx::BColor aColor(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
+
+ if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ aColor = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
+ }
+
+ drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
+ new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
+ drawinglayer::primitive2d::createDefaultCross_3x3(aColor)));
+
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
+ }
+ else
+ {
+ const basegfx::BColor aBackPen(1.0, 1.0, 1.0);
+ const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE
+ drawinglayer::primitive2d::Primitive2DReference aMarkerArrayPrimitive2D(
+ new drawinglayer::primitive2d::MarkerArrayPrimitive2D(aTransformedPositions,
+ drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor)));
+
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aMarkerArrayPrimitive2D, 1);
+ }
+ }
+
+ return aRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT0(SdrDragMethod);
+
+void SdrDragMethod::resetSdrDragEntries()
+{
+ // clear entries; creation is on demand
+ clearSdrDragEntries();
+}
+
+basegfx::B2DRange SdrDragMethod::getCurrentRange() const
+{
+ return getB2DRangeFromOverlayObjectList();
+}
+
+void SdrDragMethod::createSdrDragEntries()
+{
+ if(getSdrDragView().GetSdrPageView() && getSdrDragView().GetSdrPageView()->HasMarkedObjPageView())
+ {
+ if(getSdrDragView().IsDraggingPoints())
+ {
+ createSdrDragEntries_PointDrag();
+ }
+ else if(getSdrDragView().IsDraggingGluePoints())
+ {
+ createSdrDragEntries_GlueDrag();
+ }
+ else
+ {
+ if(getSolidDraggingActive())
+ {
+ createSdrDragEntries_SolidDrag();
+ }
+ else
+ {
+ createSdrDragEntries_PolygonDrag();
+ }
+ }
+ }
+}
+
+void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
+{
+ // add full obejct drag; Clone() at the object has to work
+ // for this
+ addSdrDragEntry(new SdrDragEntrySdrObject(rOriginal, rObjectContact, bModify));
+}
+
+void SdrDragMethod::createSdrDragEntries_SolidDrag()
+{
+ const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
+ SdrPageView* pPV = getSdrDragView().GetSdrPageView();
+
+ if(pPV)
+ {
+ for(sal_uInt32 a(0); a < nMarkAnz; a++)
+ {
+ SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
+
+ if(pM->GetPageView() == pPV)
+ {
+ const SdrObject* pObject = pM->GetMarkedSdrObj();
+
+ if(pObject)
+ {
+ if(pPV->PageWindowCount())
+ {
+ sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
+ SdrObjListIter aIter(*pObject);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pCandidate = aIter.Next();
+
+ if(pCandidate)
+ {
+ const bool bSuppressFullDrag(!pCandidate->supportsFullDrag());
+ bool bAddWireframe(bSuppressFullDrag);
+
+ if(!bAddWireframe && !pCandidate->HasLineStyle())
+ {
+ // add wireframe for objects without outline
+ bAddWireframe = true;
+ }
+
+ if(!bSuppressFullDrag)
+ {
+ // add full obejct drag; Clone() at the object has to work
+ // for this
+ createSdrDragEntryForSdrObject(*pCandidate, rOC, true);
+ }
+
+ if(bAddWireframe)
+ {
+ // when dragging a 50% transparent copy of a filled or not filled object without
+ // outline, this is normally hard to see. Add extra wireframe in that case. This
+ // works nice e.g. with thext frames etc.
+ addSdrDragEntry(new SdrDragEntryPolyPolygon(pCandidate->TakeXorPoly()));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void SdrDragMethod::createSdrDragEntries_PolygonDrag()
+{
+ const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
+ bool bNoPolygons(getSdrDragView().IsNoDragXorPolys() || nMarkAnz > getSdrDragView().GetDragXorPolyLimit());
+ basegfx::B2DPolyPolygon aResult;
+ sal_uInt32 nPointCount(0);
+
+ for(sal_uInt32 a(0); !bNoPolygons && a < nMarkAnz; a++)
+ {
+ SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(a);
+
+ if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
+ {
+ const basegfx::B2DPolyPolygon aNewPolyPolygon(pM->GetMarkedSdrObj()->TakeXorPoly());
+
+ for(sal_uInt32 b(0); b < aNewPolyPolygon.count(); b++)
+ {
+ nPointCount += aNewPolyPolygon.getB2DPolygon(b).count();
+ }
+
+ if(nPointCount > getSdrDragView().GetDragXorPointLimit())
+ {
+ bNoPolygons = true;
+ }
+
+ if(!bNoPolygons)
+ {
+ aResult.append(aNewPolyPolygon);
+ }
+ }
+ }
+
+ if(bNoPolygons)
+ {
+ const Rectangle aR(getSdrDragView().GetSdrPageView()->MarkSnap());
+ const basegfx::B2DRange aNewRectangle(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
+ basegfx::B2DPolygon aNewPolygon(basegfx::tools::createPolygonFromRect(aNewRectangle));
+
+ aResult = basegfx::B2DPolyPolygon(basegfx::tools::expandToCurve(aNewPolygon));
+ }
+
+ if(aResult.count())
+ {
+ addSdrDragEntry(new SdrDragEntryPolyPolygon(aResult));
+ }
+}
+
+void SdrDragMethod::createSdrDragEntries_PointDrag()
+{
+ const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
+ std::vector< basegfx::B2DPoint > aPositions;
+
+ for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
+ {
+ SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
+
+ if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
+ {
+ const SdrUShortCont* pPts = pM->GetMarkedPoints();
+
+ if(pPts && pPts->GetCount())
+ {
+ const SdrObject* pObj = pM->GetMarkedSdrObj();
+ const SdrPathObj* pPath = dynamic_cast< const SdrPathObj* >(pObj);
+
+ if(pPath)
+ {
+ const basegfx::B2DPolyPolygon aPathXPP = pPath->GetPathPoly();
+
+ if(aPathXPP.count())
+ {
+ const sal_uInt32 nPtAnz(pPts->GetCount());
+
+ for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
+ {
+ sal_uInt32 nPolyNum, nPointNum;
+ const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
+
+ if(sdr::PolyPolygonEditor::GetRelativePolyPoint(aPathXPP, nObjPt, nPolyNum, nPointNum))
+ {
+ aPositions.push_back(aPathXPP.getB2DPolygon(nPolyNum).getB2DPoint(nPointNum));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(aPositions.size())
+ {
+ addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, true));
+ }
+}
+
+void SdrDragMethod::createSdrDragEntries_GlueDrag()
+{
+ const sal_uInt32 nMarkAnz(getSdrDragView().GetMarkedObjectCount());
+ std::vector< basegfx::B2DPoint > aPositions;
+
+ for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
+ {
+ SdrMark* pM = getSdrDragView().GetSdrMarkByIndex(nm);
+
+ if(pM->GetPageView() == getSdrDragView().GetSdrPageView())
+ {
+ const SdrUShortCont* pPts = pM->GetMarkedGluePoints();
+
+ if(pPts && pPts->GetCount())
+ {
+ const SdrObject* pObj = pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL = pObj->GetGluePointList();
+
+ if(pGPL)
+ {
+ const sal_uInt32 nPtAnz(pPts->GetCount());
+
+ for(sal_uInt32 nPtNum(0); nPtNum < nPtAnz; nPtNum++)
+ {
+ const sal_uInt16 nObjPt(pPts->GetObject(nPtNum));
+ const sal_uInt16 nGlueNum(pGPL->FindGluePoint(nObjPt));
+
+ if(SDRGLUEPOINT_NOTFOUND != nGlueNum)
+ {
+ const Point aPoint((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
+ aPositions.push_back(basegfx::B2DPoint(aPoint.X(), aPoint.Y()));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(aPositions.size())
+ {
+ addSdrDragEntry(new SdrDragEntryPointGlueDrag(aPositions, false));
+ }
+}
+
+void SdrDragMethod::ImpTakeDescriptionStr(sal_uInt16 nStrCacheID, XubString& rStr, sal_uInt16 nVal) const
+{
+ sal_uInt16 nOpt=0;
+ if (IsDraggingPoints()) {
+ nOpt=IMPSDR_POINTSDESCRIPTION;
+ } else if (IsDraggingGluePoints()) {
+ nOpt=IMPSDR_GLUEPOINTSDESCRIPTION;
+ }
+ getSdrDragView().ImpTakeDescriptionStr(nStrCacheID,rStr,nVal,nOpt);
+}
+
+SdrObject* SdrDragMethod::GetDragObj() const
+{
+ SdrObject* pObj=NULL;
+ if (getSdrDragView().pDragHdl!=NULL) pObj=getSdrDragView().pDragHdl->GetObj();
+ if (pObj==NULL) pObj=getSdrDragView().pMarkedObj;
+ return pObj;
+}
+
+SdrPageView* SdrDragMethod::GetDragPV() const
+{
+ SdrPageView* pPV=NULL;
+ if (getSdrDragView().pDragHdl!=NULL) pPV=getSdrDragView().pDragHdl->GetPageView();
+ if (pPV==NULL) pPV=getSdrDragView().pMarkedPV;
+ return pPV;
+}
+
+void SdrDragMethod::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ // the original applies the transformation using TRGetBaseGeometry/TRSetBaseGeometry.
+ // Later this should be the only needed one for linear transforms (not for SdrDragCrook and
+ // SdrDragDistort, those are NOT linear). Currently, this can not yet be used since the
+ // special handling of rotate/mirror due to the not-being-able to handle it in the old
+ // drawinglayer stuff. Text would currently not correctly be mirrored in the preview.
+ basegfx::B2DHomMatrix aObjectTransform;
+ basegfx::B2DPolyPolygon aObjectPolyPolygon;
+ bool bPolyUsed(rTarget.TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon));
+
+ // apply transform to object transform
+ aObjectTransform *= getCurrentTransformation();
+
+ if(bPolyUsed)
+ {
+ // do something special since the object size is in the polygon
+ // break up matrix to get the scale
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate, fShearX;
+ aObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // get polygon's pos and size
+ const basegfx::B2DRange aPolyRange(aObjectPolyPolygon.getB2DRange());
+
+ // get the scaling factors (do not mirror, this is in the object transformation)
+ const double fScaleX(fabs(aScale.getX()) / (basegfx::fTools::equalZero(aPolyRange.getWidth()) ? 1.0 : aPolyRange.getWidth()));
+ const double fScaleY(fabs(aScale.getY()) / (basegfx::fTools::equalZero(aPolyRange.getHeight()) ? 1.0 : aPolyRange.getHeight()));
+
+ // prepare transform matrix for polygon
+ basegfx::B2DHomMatrix aPolyTransform(basegfx::tools::createTranslateB2DHomMatrix(
+ -aPolyRange.getMinX(), -aPolyRange.getMinY()));
+ aPolyTransform.scale(fScaleX, fScaleY);
+
+ // normally the poly should be moved back, but the translation is in the object
+ // transformation and thus does not need to be done
+ // aPolyTransform.translate(-aPolyRange.getMinX(), -aPolyRange.getMinY());
+
+ // transform the polygon
+ aObjectPolyPolygon.transform(aPolyTransform);
+ }
+
+ rTarget.TRSetBaseGeometry(getCurrentTransformation() * aObjectTransform, aObjectPolyPolygon);
+}
+
+void SdrDragMethod::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
+{
+ // original uses CurrentTransformation
+ rTarget.transform(getCurrentTransformation());
+}
+
+SdrDragMethod::SdrDragMethod(SdrDragView& rNewView)
+: maSdrDragEntries(),
+ maOverlayObjectList(),
+ mrSdrDragView(rNewView),
+ mbMoveOnly(false),
+ mbSolidDraggingActive(getSdrDragView().IsSolidDragging())
+{
+ if(mbSolidDraggingActive && Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ // fallback to wireframe when high contrast is used
+ mbSolidDraggingActive = false;
+ }
+}
+
+SdrDragMethod::~SdrDragMethod()
+{
+ clearSdrDragEntries();
+}
+
+void SdrDragMethod::Show()
+{
+ getSdrDragView().ShowDragObj();
+}
+
+void SdrDragMethod::Hide()
+{
+ getSdrDragView().HideDragObj();
+}
+
+basegfx::B2DHomMatrix SdrDragMethod::getCurrentTransformation()
+{
+ return basegfx::B2DHomMatrix();
+}
+
+void SdrDragMethod::CancelSdrDrag()
+{
+ Hide();
+}
+
+void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
+{
+ // create SdrDragEntries on demand
+ if(!maSdrDragEntries.size())
+ {
+ createSdrDragEntries();
+ }
+
+ // if there are entries, derive OverlayObjects from the entries, including
+ // modification from current interactive state
+ if(maSdrDragEntries.size())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aResult;
+ drawinglayer::primitive2d::Primitive2DSequence aResultTransparent;
+
+ for(sal_uInt32 a(0); a < maSdrDragEntries.size(); a++)
+ {
+ SdrDragEntry* pCandidate = maSdrDragEntries[a];
+
+ if(pCandidate)
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence aCandidateResult(pCandidate->createPrimitive2DSequenceInCurrentState(*this));
+
+ if(aCandidateResult.hasElements())
+ {
+ if(pCandidate->getAddToTransparent())
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aCandidateResult);
+ }
+ else
+ {
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResult, aCandidateResult);
+ }
+ }
+ }
+ }
+
+ if(DoAddConnectorOverlays())
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence aConnectorOverlays(AddConnectorOverlays());
+
+ if(aConnectorOverlays.hasElements())
+ {
+ // add connector overlays to transparent part
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aResultTransparent, aConnectorOverlays);
+ }
+ }
+
+ if(aResult.hasElements())
+ {
+ sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult);
+ rOverlayManager.add(*pNewOverlayObject);
+ addToOverlayObjectList(*pNewOverlayObject);
+ }
+
+ if(aResultTransparent.hasElements())
+ {
+ drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5));
+ aResultTransparent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);
+
+ sdr::overlay::OverlayObject* pNewOverlayObject = new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent);
+ rOverlayManager.add(*pNewOverlayObject);
+ addToOverlayObjectList(*pNewOverlayObject);
+ }
+ }
+
+ // evtl add DragStripes (help lines cross the page when dragging)
+ if(getSdrDragView().IsDragStripes())
+ {
+ Rectangle aActionRectangle;
+ getSdrDragView().TakeActionRect(aActionRectangle);
+
+ const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top());
+ const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom());
+ sdr::overlay::OverlayRollingRectangleStriped* pNew = new sdr::overlay::OverlayRollingRectangleStriped(
+ aTopLeft, aBottomRight, true, false);
+
+ rOverlayManager.add(*pNew);
+ addToOverlayObjectList(*pNew);
+ }
+}
+
+void SdrDragMethod::destroyOverlayGeometry()
+{
+ clearOverlayObjectList();
+}
+
+bool SdrDragMethod::DoAddConnectorOverlays()
+{
+ // these conditions are translated from SdrDragView::ImpDrawEdgeXor
+ const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
+
+ if(!rMarkedNodes.GetMarkCount())
+ {
+ return false;
+ }
+
+ if(!getSdrDragView().IsRubberEdgeDragging() && !getSdrDragView().IsDetailedEdgeDragging())
+ {
+ return false;
+ }
+
+ if(getSdrDragView().IsDraggingPoints() || getSdrDragView().IsDraggingGluePoints())
+ {
+ return false;
+ }
+
+ if(!getMoveOnly() && !(
+ IS_TYPE(SdrDragMove, this) || IS_TYPE(SdrDragResize, this) ||
+ IS_TYPE(SdrDragRotate,this) || IS_TYPE(SdrDragMirror,this)))
+ {
+ return false;
+ }
+
+ const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
+
+ if(!bDetail && !getSdrDragView().IsRubberEdgeDragging())
+ {
+ return false;
+ }
+
+ // one more migrated from SdrEdgeObj::NspToggleEdgeXor
+ if(IS_TYPE(SdrDragObjOwn, this) || IS_TYPE(SdrDragMovHdl, this))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+drawinglayer::primitive2d::Primitive2DSequence SdrDragMethod::AddConnectorOverlays()
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+ const bool bDetail(getSdrDragView().IsDetailedEdgeDragging() && getMoveOnly());
+ const SdrMarkList& rMarkedNodes = getSdrDragView().GetEdgesOfMarkedNodes();
+
+ for(sal_uInt16 a(0); a < rMarkedNodes.GetMarkCount(); a++)
+ {
+ SdrMark* pEM = rMarkedNodes.GetMark(a);
+
+ if(pEM && pEM->GetMarkedSdrObj())
+ {
+ SdrEdgeObj* pEdge = dynamic_cast< SdrEdgeObj* >(pEM->GetMarkedSdrObj());
+
+ if(pEdge)
+ {
+ const basegfx::B2DPolygon aEdgePolygon(pEdge->ImplAddConnectorOverlay(*this, pEM->IsCon1(), pEM->IsCon2(), bDetail));
+
+ if(aEdgePolygon.count())
+ {
+ // this polygon is a temporary calculated connector path, so it is not possible to fetch
+ // the needed primitives directly from the pEdge object which does not get changed. If full
+ // drag is on, use the SdrObjects ItemSet to create a adequate representation
+ bool bUseSolidDragging(getSolidDraggingActive());
+
+ if(bUseSolidDragging)
+ {
+ // switch off solid dragging if connector is not visible
+ if(!pEdge->HasLineStyle())
+ {
+ bUseSolidDragging = false;
+ }
+ }
+
+ if(bUseSolidDragging)
+ {
+ const SfxItemSet& rItemSet = pEdge->GetMergedItemSet();
+ const drawinglayer::attribute::SdrLineAttribute aLine(
+ drawinglayer::primitive2d::createNewSdrLineAttribute(rItemSet));
+
+ if(!aLine.isDefault())
+ {
+ const drawinglayer::attribute::SdrLineStartEndAttribute aLineStartEnd(
+ drawinglayer::primitive2d::createNewSdrLineStartEndAttribute(
+ rItemSet,
+ aLine.getWidth()));
+
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
+ aRetval, drawinglayer::primitive2d::createPolygonLinePrimitive(
+ aEdgePolygon,
+ basegfx::B2DHomMatrix(),
+ aLine,
+ aLineStartEnd));
+ }
+ }
+ else
+ {
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ basegfx::BColor aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
+ basegfx::BColor aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
+ const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
+
+ if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ aColA = aColB = Application::GetSettings().GetStyleSettings().GetHighlightColor().getBColor();
+ aColB.invert();
+ }
+
+ drawinglayer::primitive2d::Primitive2DReference aPolyPolygonMarkerPrimitive2D(
+ new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D(
+ basegfx::B2DPolyPolygon(aEdgePolygon), aColA, aColB, fStripeLength));
+ drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aPolyPolygonMarkerPrimitive2D);
+ }
+ }
+ }
+ }
+ }
+
+ return aRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragMovHdl,SdrDragMethod);
+
+SdrDragMovHdl::SdrDragMovHdl(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ bMirrObjShown(false)
+{
+}
+
+void SdrDragMovHdl::createSdrDragEntries()
+{
+ // SdrDragMovHdl does not use the default drags,
+ // but creates nothing
+}
+
+void SdrDragMovHdl::TakeSdrDragComment(XubString& rStr) const
+{
+ rStr=ImpGetResStr(STR_DragMethMovHdl);
+ if (getSdrDragView().IsDragWithCopy()) rStr+=ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragMovHdl::BeginSdrDrag()
+{
+ DragStat().Ref1()=GetDragHdl()->GetPos();
+ DragStat().SetShown(!DragStat().IsShown());
+ SdrHdlKind eKind=GetDragHdl()->GetKind();
+ SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
+ SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
+
+ if (eKind==HDL_MIRX)
+ {
+ if (pH1==NULL || pH2==NULL)
+ {
+ DBG_ERROR("SdrDragMovHdl::BeginSdrDrag(): Verschieben der Spiegelachse: Referenzhandles nicht gefunden");
+ return false;
+ }
+
+ DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
+ }
+ else
+ {
+ Point aPt(GetDragHdl()->GetPos());
+ DragStat().SetActionRect(Rectangle(aPt,aPt));
+ }
+
+ return true;
+}
+
+void SdrDragMovHdl::MoveSdrDrag(const Point& rNoSnapPnt)
+{
+ Point aPnt(rNoSnapPnt);
+
+ if (DragStat().CheckMinMoved(rNoSnapPnt))
+ {
+ if (GetDragHdl()->GetKind()==HDL_MIRX)
+ {
+ SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
+ SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
+
+ if (pH1==NULL || pH2==NULL)
+ return;
+
+ if (!DragStat().IsNoSnap())
+ {
+ long nBestXSnap=0;
+ long nBestYSnap=0;
+ bool bXSnapped=false;
+ bool bYSnapped=false;
+ Point aDif(aPnt-DragStat().GetStart());
+ getSdrDragView().CheckSnap(Ref1()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ getSdrDragView().CheckSnap(Ref2()+aDif,NULL,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ aPnt.X()+=nBestXSnap;
+ aPnt.Y()+=nBestYSnap;
+ }
+
+ if (aPnt!=DragStat().GetNow())
+ {
+ Hide();
+ DragStat().NextMove(aPnt);
+ Point aDif(DragStat().GetNow()-DragStat().GetStart());
+ pH1->SetPos(Ref1()+aDif);
+ pH2->SetPos(Ref2()+aDif);
+
+ SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
+
+ if(pHM)
+ pHM->Touch();
+
+ Show();
+ DragStat().SetActionRect(Rectangle(pH1->GetPos(),pH2->GetPos()));
+ }
+ }
+ else
+ {
+ if (!DragStat().IsNoSnap()) SnapPos(aPnt);
+ long nSA=0;
+
+ if (getSdrDragView().IsAngleSnapEnabled())
+ nSA=getSdrDragView().GetSnapAngle();
+
+ if (getSdrDragView().IsMirrorAllowed(true,true))
+ { // eingeschraenkt
+ if (!getSdrDragView().IsMirrorAllowed(false,false)) nSA=4500;
+ if (!getSdrDragView().IsMirrorAllowed(true,false)) nSA=9000;
+ }
+
+ if (getSdrDragView().IsOrtho() && nSA!=9000)
+ nSA=4500;
+
+ if (nSA!=0)
+ { // Winkelfang
+ SdrHdlKind eRef=HDL_REF1;
+
+ if (GetDragHdl()->GetKind()==HDL_REF1)
+ eRef=HDL_REF2;
+
+ SdrHdl* pH=GetHdlList().GetHdl(eRef);
+
+ if (pH!=NULL)
+ {
+ Point aRef(pH->GetPos());
+ long nWink=NormAngle360(GetAngle(aPnt-aRef));
+ long nNeuWink=nWink;
+ nNeuWink+=nSA/2;
+ nNeuWink/=nSA;
+ nNeuWink*=nSA;
+ nNeuWink=NormAngle360(nNeuWink);
+ double a=(nNeuWink-nWink)*nPi180;
+ double nSin=sin(a);
+ double nCos=cos(a);
+ RotatePoint(aPnt,aRef,nSin,nCos);
+
+ // Bei bestimmten Werten Rundungsfehler ausschliessen:
+ if (nSA==9000)
+ {
+ if (nNeuWink==0 || nNeuWink==18000) aPnt.Y()=aRef.Y();
+ if (nNeuWink==9000 || nNeuWink==27000) aPnt.X()=aRef.X();
+ }
+
+ if (nSA==4500)
+ OrthoDistance8(aRef,aPnt,true);
+ }
+ }
+
+ if (aPnt!=DragStat().GetNow())
+ {
+ Hide();
+ DragStat().NextMove(aPnt);
+ GetDragHdl()->SetPos(DragStat().GetNow());
+ SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
+
+ if(pHM)
+ pHM->Touch();
+
+ Show();
+ DragStat().SetActionRect(Rectangle(aPnt,aPnt));
+ }
+ }
+ }
+}
+
+bool SdrDragMovHdl::EndSdrDrag(bool /*bCopy*/)
+{
+ switch (GetDragHdl()->GetKind())
+ {
+ case HDL_REF1:
+ Ref1()=DragStat().GetNow();
+ break;
+
+ case HDL_REF2:
+ Ref2()=DragStat().GetNow();
+ break;
+
+ case HDL_MIRX:
+ Ref1()+=DragStat().GetNow()-DragStat().GetStart();
+ Ref2()+=DragStat().GetNow()-DragStat().GetStart();
+ break;
+
+ default: break;
+ }
+
+ return true;
+}
+
+void SdrDragMovHdl::CancelSdrDrag()
+{
+ Hide();
+ GetDragHdl()->SetPos(DragStat().GetRef1());
+ SdrHdl* pHM = GetHdlList().GetHdl(HDL_MIRX);
+
+ if(pHM)
+ pHM->Touch();
+}
+
+Pointer SdrDragMovHdl::GetSdrDragPointer() const
+{
+ const SdrHdl* pHdl = GetDragHdl();
+
+ if (pHdl!=NULL)
+ {
+ return pHdl->GetPointer();
+ }
+
+ return Pointer(POINTER_REFHAND);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragObjOwn,SdrDragMethod);
+
+SdrDragObjOwn::SdrDragObjOwn(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ mpClone(0)
+{
+ const SdrObject* pObj = GetDragObj();
+
+ if(pObj)
+ {
+ // suppress full drag for some object types
+ setSolidDraggingActive(pObj->supportsFullDrag());
+ }
+}
+
+SdrDragObjOwn::~SdrDragObjOwn()
+{
+ if(mpClone)
+ {
+ SdrObject::Free(mpClone);
+ }
+}
+
+void SdrDragObjOwn::createSdrDragEntries()
+{
+ if(mpClone)
+ {
+ basegfx::B2DPolyPolygon aDragPolyPolygon;
+ bool bAddWireframe(true);
+
+ if(getSolidDraggingActive())
+ {
+ SdrPageView* pPV = getSdrDragView().GetSdrPageView();
+
+ if(pPV && pPV->PageWindowCount())
+ {
+ sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
+ addSdrDragEntry(new SdrDragEntrySdrObject(*mpClone, rOC, false));
+
+ // potentially no wireframe needed, full drag works
+ bAddWireframe = false;
+ }
+ }
+
+ if(!bAddWireframe)
+ {
+ // check for extra conditions for wireframe, e.g. no border at
+ // objects
+ if(!mpClone->HasLineStyle())
+ {
+ bAddWireframe = true;
+ }
+ }
+
+ if(bAddWireframe)
+ {
+ // use wireframe poly when full drag is off or did not work
+ aDragPolyPolygon = mpClone->TakeXorPoly();
+ }
+
+ // add evtl. extra DragPolyPolygon
+ const basegfx::B2DPolyPolygon aSpecialDragPolyPolygon(mpClone->getSpecialDragPoly(DragStat()));
+
+ if(aSpecialDragPolyPolygon.count())
+ {
+ aDragPolyPolygon.append(aSpecialDragPolyPolygon);
+ }
+
+ if(aDragPolyPolygon.count())
+ {
+ addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragPolyPolygon));
+ }
+ }
+}
+
+void SdrDragObjOwn::TakeSdrDragComment(XubString& rStr) const
+{
+ // #i103058# get info string from the clone preferred, the original will
+ // not be changed. For security, use original as fallback
+ if(mpClone)
+ {
+ rStr = mpClone->getSpecialDragComment(DragStat());
+ }
+ else
+ {
+ const SdrObject* pObj = GetDragObj();
+
+ if(pObj)
+ {
+ rStr = pObj->getSpecialDragComment(DragStat());
+ }
+ }
+}
+
+bool SdrDragObjOwn::BeginSdrDrag()
+{
+ if(!mpClone)
+ {
+ const SdrObject* pObj = GetDragObj();
+
+ if(pObj && !pObj->IsResizeProtect())
+ {
+ if(pObj->beginSpecialDrag(DragStat()))
+ {
+ // create nitial clone to have a start visualisation
+ mpClone = pObj->getFullDragClone();
+ mpClone->applySpecialDrag(DragStat());
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void SdrDragObjOwn::MoveSdrDrag(const Point& rNoSnapPnt)
+{
+ const SdrObject* pObj = GetDragObj();
+
+ if(pObj)
+ {
+ Point aPnt(rNoSnapPnt);
+ SdrPageView* pPV = GetDragPV();
+
+ if(pPV)
+ {
+ if(!DragStat().IsNoSnap())
+ {
+ SnapPos(aPnt);
+ }
+
+ if(getSdrDragView().IsOrtho())
+ {
+ if (DragStat().IsOrtho8Possible())
+ {
+ OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
+ }
+ else if (DragStat().IsOrtho4Possible())
+ {
+ OrthoDistance4(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
+ }
+ }
+
+ if(DragStat().CheckMinMoved(rNoSnapPnt))
+ {
+ if(aPnt != DragStat().GetNow())
+ {
+ Hide();
+ DragStat().NextMove(aPnt);
+
+ // since SdrDragObjOwn currently supports no transformation of
+ // existing SdrDragEntries but only their recreation, a recreation
+ // after every move is needed in this mode. Delete existing
+ // SdrDragEntries here to force their recreation in the following Show().
+ clearSdrDragEntries();
+
+ // delete current clone (after the last reference to it is deleted above)
+ if(mpClone)
+ {
+ SdrObject::Free(mpClone);
+ mpClone = 0;
+ }
+
+ // create a new clone and modify to current drag state
+ if(!mpClone)
+ {
+ mpClone = pObj->getFullDragClone();
+ mpClone->applySpecialDrag(DragStat());
+ }
+
+ Show();
+ }
+ }
+ }
+ }
+}
+
+bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
+{
+ Hide();
+ SdrUndoAction* pUndo = NULL;
+ SdrUndoAction* pUndo2 = NULL;
+ std::vector< SdrUndoAction* > vConnectorUndoActions;
+ bool bRet = false;
+ SdrObject* pObj = GetDragObj();
+
+ if(pObj)
+ {
+ const bool bUndo = getSdrDragView().IsUndoEnabled();
+
+ if( bUndo )
+ {
+ if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
+ {
+ if (DragStat().IsEndDragChangesAttributes())
+ {
+ pUndo=getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj);
+
+ if (DragStat().IsEndDragChangesGeoAndAttributes())
+ {
+ vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
+ pUndo2 = getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
+ }
+ }
+ else
+ {
+ vConnectorUndoActions = getSdrDragView().CreateConnectorUndo( *pObj );
+ pUndo= getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj);
+ }
+ }
+
+ if( pUndo )
+ {
+ getSdrDragView().BegUndo( pUndo->GetComment() );
+ }
+ else
+ {
+ getSdrDragView().BegUndo();
+ }
+ }
+
+ // evtl. use opertator= for setting changed object data (do not change selection in
+ // view, this will destroy the interactor). This is possible since a clone is now
+ // directly modified by the modifiers. Only SdrTableObj is adding own UNDOs
+ // in it's SdrTableObj::endSpecialDrag, so currently not possible. OTOH it uses
+ // a CreateUndoGeoObject() so maybe setting SetEndDragChangesAttributes is okay. I
+ // will test this now
+ Rectangle aBoundRect0;
+
+ if(pObj->GetUserCall())
+ {
+ aBoundRect0 = pObj->GetLastBoundRect();
+ }
+
+ bRet = pObj->applySpecialDrag(DragStat());
+
+ if(bRet)
+ {
+ pObj->SetChanged();
+ pObj->BroadcastObjectChange();
+ pObj->SendUserCall( SDRUSERCALL_RESIZE, aBoundRect0 );
+ }
+
+ if(bRet)
+ {
+ if( bUndo )
+ {
+ getSdrDragView().AddUndoActions( vConnectorUndoActions );
+
+ if ( pUndo )
+ {
+ getSdrDragView().AddUndo(pUndo);
+ }
+
+ if ( pUndo2 )
+ {
+ getSdrDragView().AddUndo(pUndo2);
+ }
+ }
+ }
+ else
+ {
+ if( bUndo )
+ {
+ std::vector< SdrUndoAction* >::iterator vConnectorUndoIter( vConnectorUndoActions.begin() );
+
+ while( vConnectorUndoIter != vConnectorUndoActions.end() )
+ {
+ delete *vConnectorUndoIter++;
+ }
+
+ delete pUndo;
+ delete pUndo2;
+ }
+ }
+
+ if( bUndo )
+ getSdrDragView().EndUndo();
+ }
+
+ return bRet;
+}
+
+Pointer SdrDragObjOwn::GetSdrDragPointer() const
+{
+ const SdrHdl* pHdl=GetDragHdl();
+
+ if (pHdl)
+ {
+ return pHdl->GetPointer();
+ }
+
+ return Pointer(POINTER_MOVE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragMove,SdrDragMethod);
+
+void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool /*bModify*/)
+{
+ // for SdrDragMove, use current Primitive2DSequence of SdrObject visualisation
+ // in given ObjectContact directly
+ sdr::contact::ViewContact& rVC = rOriginal.GetViewContact();
+ sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact);
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
+ // here we want the complete primitive sequence without visibility clippings
+ rObjectContact.resetViewPort();
+
+ addSdrDragEntry(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo), true));
+}
+
+void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ rTarget.Move(Size(DragStat().GetDX(), DragStat().GetDY()));
+}
+
+SdrDragMove::SdrDragMove(SdrDragView& rNewView)
+: SdrDragMethod(rNewView)
+{
+ setMoveOnly(true);
+}
+
+void SdrDragMove::TakeSdrDragComment(XubString& rStr) const
+{
+ XubString aStr;
+
+ ImpTakeDescriptionStr(STR_DragMethMove, rStr);
+ rStr.AppendAscii(" (x=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
+ rStr += aStr;
+ rStr.AppendAscii(" y=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+
+ if(getSdrDragView().IsDragWithCopy())
+ {
+ if(!getSdrDragView().IsInsObjPoint() && !getSdrDragView().IsInsGluePoint())
+ {
+ rStr += ImpGetResStr(STR_EditWithCopy);
+ }
+ }
+}
+
+bool SdrDragMove::BeginSdrDrag()
+{
+ DragStat().SetActionRect(GetMarkedRect());
+ Show();
+
+ return true;
+}
+
+basegfx::B2DHomMatrix SdrDragMove::getCurrentTransformation()
+{
+ return basegfx::tools::createTranslateB2DHomMatrix(DragStat().GetDX(), DragStat().GetDY());
+}
+
+void SdrDragMove::ImpCheckSnap(const Point& rPt)
+{
+ Point aPt(rPt);
+ sal_uInt16 nRet=SnapPos(aPt);
+ aPt-=rPt;
+
+ if ((nRet & SDRSNAP_XSNAPPED) !=0)
+ {
+ if (bXSnapped)
+ {
+ if (Abs(aPt.X())<Abs(nBestXSnap))
+ {
+ nBestXSnap=aPt.X();
+ }
+ }
+ else
+ {
+ nBestXSnap=aPt.X();
+ bXSnapped=true;
+ }
+ }
+
+ if ((nRet & SDRSNAP_YSNAPPED) !=0)
+ {
+ if (bYSnapped)
+ {
+ if (Abs(aPt.Y())<Abs(nBestYSnap))
+ {
+ nBestYSnap=aPt.Y();
+ }
+ }
+ else
+ {
+ nBestYSnap=aPt.Y();
+ bYSnapped=true;
+ }
+ }
+}
+
+void SdrDragMove::MoveSdrDrag(const Point& rNoSnapPnt_)
+{
+ nBestXSnap=0;
+ nBestYSnap=0;
+ bXSnapped=false;
+ bYSnapped=false;
+ Point aNoSnapPnt(rNoSnapPnt_);
+ const Rectangle& aSR=GetMarkedRect();
+ long nMovedx=aNoSnapPnt.X()-DragStat().GetStart().X();
+ long nMovedy=aNoSnapPnt.Y()-DragStat().GetStart().Y();
+ Point aLO(aSR.TopLeft()); aLO.X()+=nMovedx; aLO.Y()+=nMovedy;
+ Point aRU(aSR.BottomRight()); aRU.X()+=nMovedx; aRU.Y()+=nMovedy;
+ Point aLU(aLO.X(),aRU.Y());
+ Point aRO(aRU.X(),aLO.Y());
+ ImpCheckSnap(aLO);
+
+ if (!getSdrDragView().IsMoveSnapOnlyTopLeft())
+ {
+ ImpCheckSnap(aRO);
+ ImpCheckSnap(aLU);
+ ImpCheckSnap(aRU);
+ }
+
+ Point aPnt(aNoSnapPnt.X()+nBestXSnap,aNoSnapPnt.Y()+nBestYSnap);
+ bool bOrtho=getSdrDragView().IsOrtho();
+
+ if (bOrtho)
+ OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
+
+ if (DragStat().CheckMinMoved(aNoSnapPnt))
+ {
+ Point aPt1(aPnt);
+ Rectangle aLR(getSdrDragView().GetWorkArea());
+ bool bWorkArea=!aLR.IsEmpty();
+ bool bDragLimit=IsDragLimit();
+
+ if (bDragLimit || bWorkArea)
+ {
+ Rectangle aSR2(GetMarkedRect());
+ Point aD(aPt1-DragStat().GetStart());
+
+ if (bDragLimit)
+ {
+ Rectangle aR2(GetDragLimitRect());
+
+ if (bWorkArea)
+ aLR.Intersection(aR2);
+ else
+ aLR=aR2;
+ }
+
+ if (aSR2.Left()>aLR.Left() || aSR2.Right()<aLR.Right())
+ { // ist ueberhaupt Platz zum verschieben?
+ aSR2.Move(aD.X(),0);
+
+ if (aSR2.Left()<aLR.Left())
+ {
+ aPt1.X()-=aSR2.Left()-aLR.Left();
+ }
+ else if (aSR2.Right()>aLR.Right())
+ {
+ aPt1.X()-=aSR2.Right()-aLR.Right();
+ }
+ }
+ else
+ aPt1.X()=DragStat().GetStart().X(); // kein Platz zum verschieben
+
+ if (aSR2.Top()>aLR.Top() || aSR2.Bottom()<aLR.Bottom())
+ { // ist ueberhaupt Platz zum verschieben?
+ aSR2.Move(0,aD.Y());
+
+ if (aSR2.Top()<aLR.Top())
+ {
+ aPt1.Y()-=aSR2.Top()-aLR.Top();
+ }
+ else if (aSR2.Bottom()>aLR.Bottom())
+ {
+ aPt1.Y()-=aSR2.Bottom()-aLR.Bottom();
+ }
+ }
+ else
+ aPt1.Y()=DragStat().GetStart().Y(); // kein Platz zum verschieben
+ }
+
+ if (getSdrDragView().IsDraggingGluePoints())
+ { // Klebepunkte aufs BoundRect des Obj limitieren
+ aPt1-=DragStat().GetStart();
+ const SdrMarkList& rML=GetMarkedObjectList();
+ ULONG nMarkAnz=rML.GetMarkCount();
+
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
+ {
+ const SdrMark* pM=rML.GetMark(nMarkNum);
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+
+ if (nPtAnz!=0)
+ {
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ Rectangle aBound(pObj->GetCurrentBoundRect());
+
+ for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
+ {
+ sal_uInt16 nId=pPts->GetObject(nPtNum);
+ sal_uInt16 nGlueNum=pGPL->FindGluePoint(nId);
+
+ if (nGlueNum!=SDRGLUEPOINT_NOTFOUND)
+ {
+ Point aPt((*pGPL)[nGlueNum].GetAbsolutePos(*pObj));
+ aPt+=aPt1; // soviel soll verschoben werden
+ if (aPt.X()<aBound.Left() ) aPt1.X()-=aPt.X()-aBound.Left() ;
+ if (aPt.X()>aBound.Right() ) aPt1.X()-=aPt.X()-aBound.Right() ;
+ if (aPt.Y()<aBound.Top() ) aPt1.Y()-=aPt.Y()-aBound.Top() ;
+ if (aPt.Y()>aBound.Bottom()) aPt1.Y()-=aPt.Y()-aBound.Bottom();
+ }
+ }
+ }
+ }
+
+ aPt1+=DragStat().GetStart();
+ }
+
+ if (bOrtho)
+ OrthoDistance8(DragStat().GetStart(),aPt1,false);
+
+ if (aPt1!=DragStat().GetNow())
+ {
+ Hide();
+ DragStat().NextMove(aPt1);
+ Rectangle aAction(GetMarkedRect());
+ aAction.Move(DragStat().GetDX(),DragStat().GetDY());
+ DragStat().SetActionRect(aAction);
+ Show();
+ }
+ }
+}
+
+bool SdrDragMove::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (getSdrDragView().IsInsObjPoint() || getSdrDragView().IsInsGluePoint())
+ bCopy=false;
+
+ if (IsDraggingPoints())
+ {
+ getSdrDragView().MoveMarkedPoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
+ }
+ else if (IsDraggingGluePoints())
+ {
+ getSdrDragView().MoveMarkedGluePoints(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
+ }
+ else
+ {
+ getSdrDragView().MoveMarkedObj(Size(DragStat().GetDX(),DragStat().GetDY()),bCopy);
+ }
+
+ return true;
+}
+
+Pointer SdrDragMove::GetSdrDragPointer() const
+{
+ if (IsDraggingPoints() || IsDraggingGluePoints())
+ {
+ return Pointer(POINTER_MOVEPOINT);
+ }
+ else
+ {
+ return Pointer(POINTER_MOVE);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragResize,SdrDragMethod);
+
+SdrDragResize::SdrDragResize(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ aXFact(1,1),
+ aYFact(1,1)
+{
+}
+
+void SdrDragResize::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(STR_DragMethResize, rStr);
+ bool bEqual(aXFact == aYFact);
+ Fraction aFact1(1,1);
+ Point aStart(DragStat().GetStart());
+ Point aRef(DragStat().GetRef1());
+ INT32 nXDiv(aStart.X() - aRef.X());
+
+ if(!nXDiv)
+ nXDiv = 1;
+
+ INT32 nYDiv(aStart.Y() - aRef.Y());
+
+ if(!nYDiv)
+ nYDiv = 1;
+
+ bool bX(aXFact != aFact1 && Abs(nXDiv) > 1);
+ bool bY(aYFact != aFact1 && Abs(nYDiv) > 1);
+
+ if(bX || bY)
+ {
+ XubString aStr;
+
+ rStr.AppendAscii(" (");
+
+ if(bX)
+ {
+ if(!bEqual)
+ rStr.AppendAscii("x=");
+
+ getSdrDragView().GetModel()->TakePercentStr(aXFact, aStr);
+ rStr += aStr;
+ }
+
+ if(bY && !bEqual)
+ {
+ if(bX)
+ rStr += sal_Unicode(' ');
+
+ rStr.AppendAscii("y=");
+ getSdrDragView().GetModel()->TakePercentStr(aYFact, aStr);
+ rStr += aStr;
+ }
+
+ rStr += sal_Unicode(')');
+ }
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragResize::BeginSdrDrag()
+{
+ SdrHdlKind eRefHdl=HDL_MOVE;
+ SdrHdl* pRefHdl=NULL;
+
+ switch (GetDragHdlKind())
+ {
+ case HDL_UPLFT: eRefHdl=HDL_LWRGT; break;
+ case HDL_UPPER: eRefHdl=HDL_LOWER; DragStat().SetHorFixed(true); break;
+ case HDL_UPRGT: eRefHdl=HDL_LWLFT; break;
+ case HDL_LEFT : eRefHdl=HDL_RIGHT; DragStat().SetVerFixed(true); break;
+ case HDL_RIGHT: eRefHdl=HDL_LEFT ; DragStat().SetVerFixed(true); break;
+ case HDL_LWLFT: eRefHdl=HDL_UPRGT; break;
+ case HDL_LOWER: eRefHdl=HDL_UPPER; DragStat().SetHorFixed(true); break;
+ case HDL_LWRGT: eRefHdl=HDL_UPLFT; break;
+ default: break;
+ }
+
+ if (eRefHdl!=HDL_MOVE)
+ pRefHdl=GetHdlList().GetHdl(eRefHdl);
+
+ if (pRefHdl!=NULL && !getSdrDragView().IsResizeAtCenter())
+ {
+ DragStat().Ref1()=pRefHdl->GetPos();
+ }
+ else
+ {
+ SdrHdl* pRef1=GetHdlList().GetHdl(HDL_UPLFT);
+ SdrHdl* pRef2=GetHdlList().GetHdl(HDL_LWRGT);
+
+ if (pRef1!=NULL && pRef2!=NULL)
+ {
+ DragStat().Ref1()=Rectangle(pRef1->GetPos(),pRef2->GetPos()).Center();
+ }
+ else
+ {
+ DragStat().Ref1()=GetMarkedRect().Center();
+ }
+ }
+
+ Show();
+
+ return true;
+}
+
+basegfx::B2DHomMatrix SdrDragResize::getCurrentTransformation()
+{
+ basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
+ -DragStat().Ref1().X(), -DragStat().Ref1().Y()));
+ aRetval.scale(aXFact, aYFact);
+ aRetval.translate(DragStat().Ref1().X(), DragStat().Ref1().Y());
+
+ return aRetval;
+}
+
+void SdrDragResize::MoveSdrDrag(const Point& rNoSnapPnt)
+{
+ Point aPnt(GetSnapPos(rNoSnapPnt));
+ Point aStart(DragStat().GetStart());
+ Point aRef(DragStat().GetRef1());
+ Fraction aMaxFact(0x7FFFFFFF,1);
+ Rectangle aLR(getSdrDragView().GetWorkArea());
+ bool bWorkArea=!aLR.IsEmpty();
+ bool bDragLimit=IsDragLimit();
+
+ if (bDragLimit || bWorkArea)
+ {
+ Rectangle aSR(GetMarkedRect());
+
+ if (bDragLimit)
+ {
+ Rectangle aR2(GetDragLimitRect());
+
+ if (bWorkArea)
+ aLR.Intersection(aR2);
+ else
+ aLR=aR2;
+ }
+
+ if (aPnt.X()<aLR.Left())
+ aPnt.X()=aLR.Left();
+ else if (aPnt.X()>aLR.Right())
+ aPnt.X()=aLR.Right();
+
+ if (aPnt.Y()<aLR.Top())
+ aPnt.Y()=aLR.Top();
+ else if (aPnt.Y()>aLR.Bottom())
+ aPnt.Y()=aLR.Bottom();
+
+ if (aRef.X()>aSR.Left())
+ {
+ Fraction aMax(aRef.X()-aLR.Left(),aRef.X()-aSR.Left());
+
+ if (aMax<aMaxFact)
+ aMaxFact=aMax;
+ }
+
+ if (aRef.X()<aSR.Right())
+ {
+ Fraction aMax(aLR.Right()-aRef.X(),aSR.Right()-aRef.X());
+
+ if (aMax<aMaxFact)
+ aMaxFact=aMax;
+ }
+
+ if (aRef.Y()>aSR.Top())
+ {
+ Fraction aMax(aRef.Y()-aLR.Top(),aRef.Y()-aSR.Top());
+
+ if (aMax<aMaxFact)
+ aMaxFact=aMax;
+ }
+
+ if (aRef.Y()<aSR.Bottom())
+ {
+ Fraction aMax(aLR.Bottom()-aRef.Y(),aSR.Bottom()-aRef.Y());
+
+ if (aMax<aMaxFact)
+ aMaxFact=aMax;
+ }
+ }
+
+ long nXDiv=aStart.X()-aRef.X(); if (nXDiv==0) nXDiv=1;
+ long nYDiv=aStart.Y()-aRef.Y(); if (nYDiv==0) nYDiv=1;
+ long nXMul=aPnt.X()-aRef.X();
+ long nYMul=aPnt.Y()-aRef.Y();
+
+ if (nXDiv<0)
+ {
+ nXDiv=-nXDiv;
+ nXMul=-nXMul;
+ }
+
+ if (nYDiv<0)
+ {
+ nYDiv=-nYDiv;
+ nYMul=-nYMul;
+ }
+
+ bool bXNeg=nXMul<0; if (bXNeg) nXMul=-nXMul;
+ bool bYNeg=nYMul<0; if (bYNeg) nYMul=-nYMul;
+ bool bOrtho=getSdrDragView().IsOrtho() || !getSdrDragView().IsResizeAllowed(false);
+
+ if (!DragStat().IsHorFixed() && !DragStat().IsVerFixed())
+ {
+ if (Abs(nXDiv)<=1 || Abs(nYDiv)<=1)
+ bOrtho=false;
+
+ if (bOrtho)
+ {
+ if ((Fraction(nXMul,nXDiv)>Fraction(nYMul,nYDiv)) !=getSdrDragView().IsBigOrtho())
+ {
+ nXMul=nYMul;
+ nXDiv=nYDiv;
+ }
+ else
+ {
+ nYMul=nXMul;
+ nYDiv=nXDiv;
+ }
+ }
+ }
+ else
+ {
+ if (bOrtho)
+ {
+ if (DragStat().IsHorFixed())
+ {
+ bXNeg=false;
+ nXMul=nYMul;
+ nXDiv=nYDiv;
+ }
+
+ if (DragStat().IsVerFixed())
+ {
+ bYNeg=false;
+ nYMul=nXMul;
+ nYDiv=nXDiv;
+ }
+ }
+ else
+ {
+ if (DragStat().IsHorFixed())
+ {
+ bXNeg=false;
+ nXMul=1;
+ nXDiv=1;
+ }
+
+ if (DragStat().IsVerFixed())
+ {
+ bYNeg=false;
+ nYMul=1;
+ nYDiv=1;
+ }
+ }
+ }
+
+ Fraction aNeuXFact(nXMul,nXDiv);
+ Fraction aNeuYFact(nYMul,nYDiv);
+
+ if (bOrtho)
+ {
+ if (aNeuXFact>aMaxFact)
+ {
+ aNeuXFact=aMaxFact;
+ aNeuYFact=aMaxFact;
+ }
+
+ if (aNeuYFact>aMaxFact)
+ {
+ aNeuXFact=aMaxFact;
+ aNeuYFact=aMaxFact;
+ }
+ }
+
+ if (bXNeg)
+ aNeuXFact=Fraction(-aNeuXFact.GetNumerator(),aNeuXFact.GetDenominator());
+
+ if (bYNeg)
+ aNeuYFact=Fraction(-aNeuYFact.GetNumerator(),aNeuYFact.GetDenominator());
+
+ if (DragStat().CheckMinMoved(aPnt))
+ {
+ if ((!DragStat().IsHorFixed() && aPnt.X()!=DragStat().GetNow().X()) ||
+ (!DragStat().IsVerFixed() && aPnt.Y()!=DragStat().GetNow().Y()))
+ {
+ Hide();
+ DragStat().NextMove(aPnt);
+ aXFact=aNeuXFact;
+ aYFact=aNeuYFact;
+ Show();
+ }
+ }
+}
+
+void SdrDragResize::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ rTarget.Resize(DragStat().Ref1(),aXFact,aYFact);
+}
+
+bool SdrDragResize::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (IsDraggingPoints())
+ {
+ getSdrDragView().ResizeMarkedPoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
+ }
+ else if (IsDraggingGluePoints())
+ {
+ getSdrDragView().ResizeMarkedGluePoints(DragStat().Ref1(),aXFact,aYFact,bCopy);
+ }
+ else
+ {
+ getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
+ }
+
+ return true;
+}
+
+Pointer SdrDragResize::GetSdrDragPointer() const
+{
+ const SdrHdl* pHdl=GetDragHdl();
+
+ if (pHdl!=NULL)
+ {
+ return pHdl->GetPointer();
+ }
+
+ return Pointer(POINTER_MOVE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragRotate,SdrDragMethod);
+
+void SdrDragRotate::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ rTarget.Rotate(DragStat().GetRef1(), nWink, sin(nWink*nPi180), cos(nWink*nPi180));
+}
+
+SdrDragRotate::SdrDragRotate(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ nSin(0.0),
+ nCos(1.0),
+ nWink0(0),
+ nWink(0),
+ bRight(false)
+{
+}
+
+void SdrDragRotate::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(STR_DragMethRotate, rStr);
+ rStr.AppendAscii(" (");
+ XubString aStr;
+ INT32 nTmpWink(NormAngle360(nWink));
+
+ if(bRight && nWink)
+ {
+ nTmpWink -= 36000;
+ }
+
+ getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragRotate::BeginSdrDrag()
+{
+ SdrHdl* pH=GetHdlList().GetHdl(HDL_REF1);
+
+ if (pH!=NULL)
+ {
+ Show();
+ DragStat().Ref1()=pH->GetPos();
+ nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
+ return true;
+ }
+ else
+ {
+ DBG_ERROR("SdrDragRotate::BeginSdrDrag(): Kein Referenzpunkt-Handle gefunden");
+ return false;
+ }
+}
+
+basegfx::B2DHomMatrix SdrDragRotate::getCurrentTransformation()
+{
+ return basegfx::tools::createRotateAroundPoint(
+ DragStat().GetRef1().X(), DragStat().GetRef1().Y(),
+ -atan2(nSin, nCos));
+}
+
+void SdrDragRotate::MoveSdrDrag(const Point& rPnt_)
+{
+ Point aPnt(rPnt_);
+ if (DragStat().CheckMinMoved(aPnt))
+ {
+ long nNeuWink=NormAngle360(GetAngle(aPnt-DragStat().GetRef1())-nWink0);
+ long nSA=0;
+
+ if (getSdrDragView().IsAngleSnapEnabled())
+ nSA=getSdrDragView().GetSnapAngle();
+
+ if (!getSdrDragView().IsRotateAllowed(false))
+ nSA=9000;
+
+ if (nSA!=0)
+ { // Winkelfang
+ nNeuWink+=nSA/2;
+ nNeuWink/=nSA;
+ nNeuWink*=nSA;
+ }
+
+ nNeuWink=NormAngle180(nNeuWink);
+
+ if (nWink!=nNeuWink)
+ {
+ sal_uInt16 nSekt0=GetAngleSector(nWink);
+ sal_uInt16 nSekt1=GetAngleSector(nNeuWink);
+
+ if (nSekt0==0 && nSekt1==3)
+ bRight=true;
+
+ if (nSekt0==3 && nSekt1==0)
+ bRight=false;
+
+ nWink=nNeuWink;
+ double a=nWink*nPi180;
+ double nSin1=sin(a); // schonmal berechnen, damit mgl. wenig Zeit
+ double nCos1=cos(a); // zwischen Hide() und Show() vergeht
+ Hide();
+ nSin=nSin1;
+ nCos=nCos1;
+ DragStat().NextMove(aPnt);
+ Show();
+ }
+ }
+}
+
+bool SdrDragRotate::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (nWink!=0)
+ {
+ if (IsDraggingPoints())
+ {
+ getSdrDragView().RotateMarkedPoints(DragStat().GetRef1(),nWink,bCopy);
+ }
+ else if (IsDraggingGluePoints())
+ {
+ getSdrDragView().RotateMarkedGluePoints(DragStat().GetRef1(),nWink,bCopy);
+ }
+ else
+ {
+ getSdrDragView().RotateMarkedObj(DragStat().GetRef1(),nWink,bCopy);
+ }
+ }
+ return true;
+}
+
+Pointer SdrDragRotate::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_ROTATE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragShear,SdrDragMethod);
+
+SdrDragShear::SdrDragShear(SdrDragView& rNewView, bool bSlant1)
+: SdrDragMethod(rNewView),
+ aFact(1,1),
+ nWink0(0),
+ nWink(0),
+ nTan(0.0),
+ bVertical(false),
+ bResize(false),
+ bUpSideDown(false),
+ bSlant(bSlant1)
+{
+}
+
+void SdrDragShear::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(STR_DragMethShear, rStr);
+ rStr.AppendAscii(" (");
+
+ INT32 nTmpWink(nWink);
+
+ if(bUpSideDown)
+ nTmpWink += 18000;
+
+ nTmpWink = NormAngle180(nTmpWink);
+
+ XubString aStr;
+
+ getSdrDragView().GetModel()->TakeWinkStr(nTmpWink, aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragShear::BeginSdrDrag()
+{
+ SdrHdlKind eRefHdl=HDL_MOVE;
+ SdrHdl* pRefHdl=NULL;
+
+ switch (GetDragHdlKind())
+ {
+ case HDL_UPPER: eRefHdl=HDL_LOWER; break;
+ case HDL_LOWER: eRefHdl=HDL_UPPER; break;
+ case HDL_LEFT : eRefHdl=HDL_RIGHT; bVertical=true; break;
+ case HDL_RIGHT: eRefHdl=HDL_LEFT ; bVertical=true; break;
+ default: break;
+ }
+
+ if (eRefHdl!=HDL_MOVE)
+ pRefHdl=GetHdlList().GetHdl(eRefHdl);
+
+ if (pRefHdl!=NULL)
+ {
+ DragStat().Ref1()=pRefHdl->GetPos();
+ nWink0=GetAngle(DragStat().GetStart()-DragStat().GetRef1());
+ }
+ else
+ {
+ DBG_ERROR("SdrDragShear::BeginSdrDrag(): Kein Referenzpunkt-Handle fuer Shear gefunden");
+ return false;
+ }
+
+ Show();
+ return true;
+}
+
+basegfx::B2DHomMatrix SdrDragShear::getCurrentTransformation()
+{
+ basegfx::B2DHomMatrix aRetval(basegfx::tools::createTranslateB2DHomMatrix(
+ -DragStat().GetRef1().X(), -DragStat().GetRef1().Y()));
+
+ if (bResize)
+ {
+ if (bVertical)
+ {
+ aRetval.scale(aFact, 1.0);
+ aRetval.shearY(-nTan);
+ }
+ else
+ {
+ aRetval.scale(1.0, aFact);
+ aRetval.shearX(-nTan);
+ }
+ }
+
+ aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
+
+ return aRetval;
+}
+
+void SdrDragShear::MoveSdrDrag(const Point& rPnt)
+{
+ if (DragStat().CheckMinMoved(rPnt))
+ {
+ bResize=!getSdrDragView().IsOrtho();
+ long nSA=0;
+
+ if (getSdrDragView().IsAngleSnapEnabled())
+ nSA=getSdrDragView().GetSnapAngle();
+
+ Point aP0(DragStat().GetStart());
+ Point aPnt(rPnt);
+ Fraction aNeuFact(1,1);
+
+ // Wenn kein Winkelfang, dann ggf. Rasterfang (ausser bei Slant)
+ if (nSA==0 && !bSlant)
+ aPnt=GetSnapPos(aPnt);
+
+ if (!bSlant && !bResize)
+ { // Shear ohne Resize
+ if (bVertical)
+ aPnt.X()=aP0.X();
+ else
+ aPnt.Y()=aP0.Y();
+ }
+
+ Point aRef(DragStat().GetRef1());
+ Point aDif(aPnt-aRef);
+
+ long nNeuWink=0;
+
+ if (bSlant)
+ {
+ nNeuWink=NormAngle180(-(GetAngle(aDif)-nWink0));
+
+ if (bVertical)
+ nNeuWink=NormAngle180(-nNeuWink);
+ }
+ else
+ {
+ if (bVertical)
+ nNeuWink=NormAngle180(GetAngle(aDif));
+ else
+ nNeuWink=NormAngle180(-(GetAngle(aDif)-9000));
+
+ if (nNeuWink<-9000 || nNeuWink>9000)
+ nNeuWink=NormAngle180(nNeuWink+18000);
+
+ if (bResize)
+ {
+ Point aPt2(aPnt);
+
+ if (nSA!=0)
+ aPt2=GetSnapPos(aPnt); // den also in jedem Falle fangen
+
+ if (bVertical)
+ {
+ aNeuFact=Fraction(aPt2.X()-aRef.X(),aP0.X()-aRef.X());
+ }
+ else
+ {
+ aNeuFact=Fraction(aPt2.Y()-aRef.Y(),aP0.Y()-aRef.Y());
+ }
+ }
+ }
+
+ bool bNeg=nNeuWink<0;
+
+ if (bNeg)
+ nNeuWink=-nNeuWink;
+
+ if (nSA!=0)
+ { // Winkelfang
+ nNeuWink+=nSA/2;
+ nNeuWink/=nSA;
+ nNeuWink*=nSA;
+ }
+
+ nNeuWink=NormAngle360(nNeuWink);
+ bUpSideDown=nNeuWink>9000 && nNeuWink<27000;
+
+ if (bSlant)
+ { // Resize fuer Slant berechnen
+ // Mit Winkelfang jedoch ohne 89deg Begrenzung
+ long nTmpWink=nNeuWink;
+ if (bUpSideDown) nNeuWink-=18000;
+ if (bNeg) nTmpWink=-nTmpWink;
+ bResize=true;
+ double nCos=cos(nTmpWink*nPi180);
+ aNeuFact=nCos;
+ Kuerzen(aFact,10); // 3 Dezimalstellen sollten reichen
+ }
+
+ if (nNeuWink>8900)
+ nNeuWink=8900;
+
+ if (bNeg)
+ nNeuWink=-nNeuWink;
+
+ if (nWink!=nNeuWink || aFact!=aNeuFact)
+ {
+ nWink=nNeuWink;
+ aFact=aNeuFact;
+ double a=nWink*nPi180;
+ double nTan1=0.0;
+ nTan1=tan(a); // schonmal berechnen, damit mgl. wenig Zeit zwischen Hide() und Show() vergeht
+ Hide();
+ nTan=nTan1;
+ DragStat().NextMove(rPnt);
+ Show();
+ }
+ }
+}
+
+void SdrDragShear::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ if (bResize)
+ {
+ if (bVertical)
+ {
+ rTarget.Resize(DragStat().GetRef1(),aFact,Fraction(1,1));
+ }
+ else
+ {
+ rTarget.Resize(DragStat().GetRef1(),Fraction(1,1),aFact);
+ }
+ }
+
+ if (nWink!=0)
+ {
+ rTarget.Shear(DragStat().GetRef1(),nWink,tan(nWink*nPi180),bVertical);
+ }
+}
+
+bool SdrDragShear::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (bResize && aFact==Fraction(1,1))
+ bResize=false;
+
+ if (nWink!=0 || bResize)
+ {
+ if (nWink!=0 && bResize)
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditShear,aStr);
+
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+
+ getSdrDragView().BegUndo(aStr);
+ }
+
+ if (bResize)
+ {
+ if (bVertical)
+ {
+ getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),aFact,Fraction(1,1),bCopy);
+ }
+ else
+ {
+ getSdrDragView().ResizeMarkedObj(DragStat().GetRef1(),Fraction(1,1),aFact,bCopy);
+ }
+
+ bCopy=false;
+ }
+
+ if (nWink!=0)
+ {
+ getSdrDragView().ShearMarkedObj(DragStat().GetRef1(),nWink,bVertical,bCopy);
+ }
+
+ if (nWink!=0 && bResize)
+ getSdrDragView().EndUndo();
+
+ return true;
+ }
+
+ return false;
+}
+
+Pointer SdrDragShear::GetSdrDragPointer() const
+{
+ if (bVertical)
+ return Pointer(POINTER_VSHEAR);
+ else
+ return Pointer(POINTER_HSHEAR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragMirror,SdrDragMethod);
+
+void SdrDragMirror::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ if(bMirrored)
+ {
+ rTarget.Mirror(DragStat().GetRef1(), DragStat().GetRef2());
+ }
+}
+
+SdrDragMirror::SdrDragMirror(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ nWink(0),
+ bMirrored(false),
+ bSide0(false)
+{
+}
+
+bool SdrDragMirror::ImpCheckSide(const Point& rPnt) const
+{
+ long nWink1=GetAngle(rPnt-DragStat().GetRef1());
+ nWink1-=nWink;
+ nWink1=NormAngle360(nWink1);
+
+ return nWink1<18000;
+}
+
+void SdrDragMirror::TakeSdrDragComment(XubString& rStr) const
+{
+ if (aDif.X()==0)
+ ImpTakeDescriptionStr(STR_DragMethMirrorHori,rStr);
+ else if (aDif.Y()==0)
+ ImpTakeDescriptionStr(STR_DragMethMirrorVert,rStr);
+ else if (Abs(aDif.X())==Abs(aDif.Y()))
+ ImpTakeDescriptionStr(STR_DragMethMirrorDiag,rStr);
+ else
+ ImpTakeDescriptionStr(STR_DragMethMirrorFree,rStr);
+
+ if (getSdrDragView().IsDragWithCopy())
+ rStr+=ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragMirror::BeginSdrDrag()
+{
+ SdrHdl* pH1=GetHdlList().GetHdl(HDL_REF1);
+ SdrHdl* pH2=GetHdlList().GetHdl(HDL_REF2);
+
+ if (pH1!=NULL && pH2!=NULL)
+ {
+ DragStat().Ref1()=pH1->GetPos();
+ DragStat().Ref2()=pH2->GetPos();
+ Ref1()=pH1->GetPos();
+ Ref2()=pH2->GetPos();
+ aDif=pH2->GetPos()-pH1->GetPos();
+ bool b90=(aDif.X()==0) || aDif.Y()==0;
+ bool b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
+ nWink=NormAngle360(GetAngle(aDif));
+
+ if (!getSdrDragView().IsMirrorAllowed(false,false) && !b45)
+ return false; // freier Achsenwinkel nicht erlaubt
+
+ if (!getSdrDragView().IsMirrorAllowed(true,false) && !b90)
+ return false; // 45deg auch nicht erlaubt
+
+ bSide0=ImpCheckSide(DragStat().GetStart());
+ Show();
+ return true;
+ }
+ else
+ {
+ DBG_ERROR("SdrDragMirror::BeginSdrDrag(): Spiegelachse nicht gefunden");
+ return false;
+ }
+}
+
+basegfx::B2DHomMatrix SdrDragMirror::getCurrentTransformation()
+{
+ basegfx::B2DHomMatrix aRetval;
+
+ if (bMirrored)
+ {
+ const double fDeltaX(DragStat().GetRef2().X() - DragStat().GetRef1().X());
+ const double fDeltaY(DragStat().GetRef2().Y() - DragStat().GetRef1().Y());
+ const double fRotation(atan2(fDeltaY, fDeltaX));
+
+ aRetval = basegfx::tools::createTranslateB2DHomMatrix(-DragStat().GetRef1().X(), -DragStat().GetRef1().Y());
+ aRetval.rotate(-fRotation);
+ aRetval.scale(1.0, -1.0);
+ aRetval.rotate(fRotation);
+ aRetval.translate(DragStat().GetRef1().X(), DragStat().GetRef1().Y());
+ }
+
+ return aRetval;
+}
+
+void SdrDragMirror::MoveSdrDrag(const Point& rPnt)
+{
+ if (DragStat().CheckMinMoved(rPnt))
+ {
+ bool bNeuSide=ImpCheckSide(rPnt);
+ bool bNeuMirr=bSide0!=bNeuSide;
+
+ if (bMirrored!=bNeuMirr)
+ {
+ Hide();
+ bMirrored=bNeuMirr;
+ DragStat().NextMove(rPnt);
+ Show();
+ }
+ }
+}
+
+bool SdrDragMirror::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (bMirrored)
+ {
+ getSdrDragView().MirrorMarkedObj(DragStat().GetRef1(),DragStat().GetRef2(),bCopy);
+ }
+
+ return true;
+}
+
+Pointer SdrDragMirror::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_MIRROR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragGradient, SdrDragMethod);
+
+SdrDragGradient::SdrDragGradient(SdrDragView& rNewView, bool bGrad)
+: SdrDragMethod(rNewView),
+ pIAOHandle(NULL),
+ bIsGradient(bGrad)
+{
+}
+
+void SdrDragGradient::TakeSdrDragComment(XubString& rStr) const
+{
+ if(IsGradient())
+ ImpTakeDescriptionStr(STR_DragMethGradient, rStr);
+ else
+ ImpTakeDescriptionStr(STR_DragMethTransparence, rStr);
+}
+
+bool SdrDragGradient::BeginSdrDrag()
+{
+ bool bRetval(false);
+
+ pIAOHandle = (SdrHdlGradient*)GetHdlList().GetHdl(IsGradient() ? HDL_GRAD : HDL_TRNS);
+
+ if(pIAOHandle)
+ {
+ // save old values
+ DragStat().Ref1() = pIAOHandle->GetPos();
+ DragStat().Ref2() = pIAOHandle->Get2ndPos();
+
+ // what was hit?
+ bool bHit(false);
+ SdrHdlColor* pColHdl = pIAOHandle->GetColorHdl1();
+
+ // init handling flags
+ pIAOHandle->SetMoveSingleHandle(false);
+ pIAOHandle->SetMoveFirstHandle(false);
+
+ // test first color handle
+ if(pColHdl)
+ {
+ basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
+
+ if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
+ {
+ bHit = true;
+ pIAOHandle->SetMoveSingleHandle(true);
+ pIAOHandle->SetMoveFirstHandle(true);
+ }
+ }
+
+ // test second color handle
+ pColHdl = pIAOHandle->GetColorHdl2();
+
+ if(!bHit && pColHdl)
+ {
+ basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
+
+ if(pColHdl->getOverlayObjectList().isHitLogic(aPosition))
+ {
+ bHit = true;
+ pIAOHandle->SetMoveSingleHandle(true);
+ }
+ }
+
+ // test gradient handle itself
+ if(!bHit)
+ {
+ basegfx::B2DPoint aPosition(DragStat().GetStart().X(), DragStat().GetStart().Y());
+
+ if(pIAOHandle->getOverlayObjectList().isHitLogic(aPosition))
+ {
+ bHit = true;
+ }
+ }
+
+ // everything up and running :o}
+ bRetval = bHit;
+ }
+ else
+ {
+ DBG_ERROR("SdrDragGradient::BeginSdrDrag(): IAOGradient nicht gefunden");
+ }
+
+ return bRetval;
+}
+
+void SdrDragGradient::MoveSdrDrag(const Point& rPnt)
+{
+ if(pIAOHandle && DragStat().CheckMinMoved(rPnt))
+ {
+ DragStat().NextMove(rPnt);
+
+ // Do the Move here!!! DragStat().GetStart()
+ Point aMoveDiff = rPnt - DragStat().GetStart();
+
+ if(pIAOHandle->IsMoveSingleHandle())
+ {
+ if(pIAOHandle->IsMoveFirstHandle())
+ {
+ pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
+ if(pIAOHandle->GetColorHdl1())
+ pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
+ }
+ else
+ {
+ pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
+ if(pIAOHandle->GetColorHdl2())
+ pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
+ }
+ }
+ else
+ {
+ pIAOHandle->SetPos(DragStat().Ref1() + aMoveDiff);
+ pIAOHandle->Set2ndPos(DragStat().Ref2() + aMoveDiff);
+
+ if(pIAOHandle->GetColorHdl1())
+ pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1() + aMoveDiff);
+
+ if(pIAOHandle->GetColorHdl2())
+ pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2() + aMoveDiff);
+ }
+
+ // new state
+ pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), false, false);
+ }
+}
+
+bool SdrDragGradient::EndSdrDrag(bool /*bCopy*/)
+{
+ // here the result is clear, do something with the values
+ Ref1() = pIAOHandle->GetPos();
+ Ref2() = pIAOHandle->Get2ndPos();
+
+ // new state
+ pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, true);
+
+ return true;
+}
+
+void SdrDragGradient::CancelSdrDrag()
+{
+ // restore old values
+ pIAOHandle->SetPos(DragStat().Ref1());
+ pIAOHandle->Set2ndPos(DragStat().Ref2());
+
+ if(pIAOHandle->GetColorHdl1())
+ pIAOHandle->GetColorHdl1()->SetPos(DragStat().Ref1());
+
+ if(pIAOHandle->GetColorHdl2())
+ pIAOHandle->GetColorHdl2()->SetPos(DragStat().Ref2());
+
+ // new state
+ pIAOHandle->FromIAOToItem(getSdrDragView().GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(), true, false);
+}
+
+Pointer SdrDragGradient::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_REFHAND);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragCrook,SdrDragMethod);
+
+SdrDragCrook::SdrDragCrook(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ aFact(1,1),
+ bContortionAllowed(false),
+ bNoContortionAllowed(false),
+ bContortion(false),
+ bResizeAllowed(false),
+ bResize(false),
+ bRotateAllowed(false),
+ bRotate(false),
+ bVertical(false),
+ bValid(false),
+ bLft(false),
+ bRgt(false),
+ bUpr(false),
+ bLwr(false),
+ bAtCenter(false),
+ nWink(0),
+ nMarkSize(0),
+ eMode(SDRCROOK_ROTATE)
+{
+}
+
+void SdrDragCrook::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(!bContortion ? STR_DragMethCrook : STR_DragMethCrookContortion, rStr);
+
+ if(bValid)
+ {
+ rStr.AppendAscii(" (");
+
+ XubString aStr;
+ INT32 nVal(nWink);
+
+ if(bAtCenter)
+ nVal *= 2;
+
+ nVal = Abs(nVal);
+ getSdrDragView().GetModel()->TakeWinkStr(nVal, aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+ }
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+// #96920# These defines parametrise the created raster
+// for interactions
+#define DRAG_CROOK_RASTER_MINIMUM (4)
+#define DRAG_CROOK_RASTER_MAXIMUM (15)
+#define DRAG_CROOK_RASTER_DISTANCE (30)
+
+basegfx::B2DPolyPolygon impCreateDragRaster(SdrPageView& rPageView, const Rectangle& rMarkRect)
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ if(rPageView.PageWindowCount())
+ {
+ OutputDevice& rOut = (rPageView.GetPageWindow(0)->GetPaintWindow().GetOutputDevice());
+ Rectangle aPixelSize = rOut.LogicToPixel(rMarkRect);
+ sal_uInt32 nHorDiv(aPixelSize.GetWidth() / DRAG_CROOK_RASTER_DISTANCE);
+ sal_uInt32 nVerDiv(aPixelSize.GetHeight() / DRAG_CROOK_RASTER_DISTANCE);
+
+ if(nHorDiv > DRAG_CROOK_RASTER_MAXIMUM)
+ nHorDiv = DRAG_CROOK_RASTER_MAXIMUM;
+ if(nHorDiv < DRAG_CROOK_RASTER_MINIMUM)
+ nHorDiv = DRAG_CROOK_RASTER_MINIMUM;
+
+ if(nVerDiv > DRAG_CROOK_RASTER_MAXIMUM)
+ nVerDiv = DRAG_CROOK_RASTER_MAXIMUM;
+ if(nVerDiv < DRAG_CROOK_RASTER_MINIMUM)
+ nVerDiv = DRAG_CROOK_RASTER_MINIMUM;
+
+ const double fXLen(rMarkRect.GetWidth() / (double)nHorDiv);
+ const double fYLen(rMarkRect.GetHeight() / (double)nVerDiv);
+ double fYPos(rMarkRect.Top());
+ sal_uInt32 a, b;
+
+ for(a = 0; a <= nVerDiv; a++)
+ {
+ // hor lines
+ for(b = 0; b < nHorDiv; b++)
+ {
+ basegfx::B2DPolygon aHorLineSegment;
+
+ const double fNewX(rMarkRect.Left() + (b * fXLen));
+ aHorLineSegment.append(basegfx::B2DPoint(fNewX, fYPos));
+ aHorLineSegment.appendBezierSegment(
+ basegfx::B2DPoint(fNewX + (fXLen * (1.0 / 3.0)), fYPos),
+ basegfx::B2DPoint(fNewX + (fXLen * (2.0 / 3.0)), fYPos),
+ basegfx::B2DPoint(fNewX + fXLen, fYPos));
+ aRetval.append(aHorLineSegment);
+ }
+
+ // increments
+ fYPos += fYLen;
+ }
+
+ double fXPos(rMarkRect.Left());
+
+ for(a = 0; a <= nHorDiv; a++)
+ {
+ // ver lines
+ for(b = 0; b < nVerDiv; b++)
+ {
+ basegfx::B2DPolygon aVerLineSegment;
+
+ const double fNewY(rMarkRect.Top() + (b * fYLen));
+ aVerLineSegment.append(basegfx::B2DPoint(fXPos, fNewY));
+ aVerLineSegment.appendBezierSegment(
+ basegfx::B2DPoint(fXPos, fNewY + (fYLen * (1.0 / 3.0))),
+ basegfx::B2DPoint(fXPos, fNewY + (fYLen * (2.0 / 3.0))),
+ basegfx::B2DPoint(fXPos, fNewY + fYLen));
+ aRetval.append(aVerLineSegment);
+ }
+
+ // increments
+ fXPos += fXLen;
+ }
+ }
+
+ return aRetval;
+}
+
+void SdrDragCrook::createSdrDragEntries()
+{
+ // Add extended frame raster first, so it will be behind objects
+ if(getSdrDragView().GetSdrPageView())
+ {
+ const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
+
+ if(aDragRaster.count())
+ {
+ addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
+ }
+ }
+
+ // call parent
+ SdrDragMethod::createSdrDragEntries();
+}
+
+bool SdrDragCrook::BeginSdrDrag()
+{
+ bContortionAllowed=getSdrDragView().IsCrookAllowed(false);
+ bNoContortionAllowed=getSdrDragView().IsCrookAllowed(true);
+ bResizeAllowed=getSdrDragView().IsResizeAllowed(false);
+ bRotateAllowed=getSdrDragView().IsRotateAllowed(false);
+
+ if (bContortionAllowed || bNoContortionAllowed)
+ {
+ bVertical=(GetDragHdlKind()==HDL_LOWER || GetDragHdlKind()==HDL_UPPER);
+ aMarkRect=GetMarkedRect();
+ aMarkCenter=aMarkRect.Center();
+ nMarkSize=bVertical ? (aMarkRect.GetHeight()-1) : (aMarkRect.GetWidth()-1);
+ aCenter=aMarkCenter;
+ aStart=DragStat().GetStart();
+ Show();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void SdrDragCrook::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
+{
+ SdrPageView* pPV = getSdrDragView().GetSdrPageView();
+
+ if(pPV)
+ {
+ XPolyPolygon aTempPolyPoly(rTarget);
+
+ if (pPV->HasMarkedObjPageView())
+ {
+ sal_uInt16 nPolyAnz=aTempPolyPoly.Count();
+
+ if (!bContortion && !getSdrDragView().IsNoDragXorPolys())
+ {
+ sal_uInt16 n1st=0,nLast=0;
+ Point aC(aCenter);
+
+ while (n1st<nPolyAnz)
+ {
+ nLast=n1st;
+ while (nLast<nPolyAnz && aTempPolyPoly[nLast].GetPointCount()!=0) nLast++;
+ Rectangle aBound(aTempPolyPoly[n1st].GetBoundRect());
+ sal_uInt16 i;
+
+ for (i=n1st+1; i<nLast; i++)
+ {
+ aBound.Union(aTempPolyPoly[n1st].GetBoundRect());
+ }
+
+ Point aCtr0(aBound.Center());
+ Point aCtr1(aCtr0);
+
+ if (bResize)
+ {
+ Fraction aFact1(1,1);
+
+ if (bVertical)
+ {
+ ResizePoint(aCtr1,aC,aFact1,aFact);
+ }
+ else
+ {
+ ResizePoint(aCtr1,aC,aFact,aFact1);
+ }
+ }
+
+ bool bRotOk=false;
+ double nSin=0,nCos=0;
+
+ if (aRad.X()!=0 && aRad.Y()!=0)
+ {
+ bRotOk=bRotate;
+
+ switch (eMode)
+ {
+ case SDRCROOK_ROTATE : CrookRotateXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
+ case SDRCROOK_SLANT : CrookSlantXPoint (aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical); break;
+ case SDRCROOK_STRETCH: CrookStretchXPoint(aCtr1,NULL,NULL,aC,aRad,nSin,nCos,bVertical,aMarkRect); break;
+ } // switch
+ }
+
+ aCtr1-=aCtr0;
+
+ for (i=n1st; i<nLast; i++)
+ {
+ if (bRotOk)
+ {
+ RotateXPoly(aTempPolyPoly[i],aCtr0,nSin,nCos);
+ }
+
+ aTempPolyPoly[i].Move(aCtr1.X(),aCtr1.Y());
+ }
+
+ n1st=nLast+1;
+ }
+ }
+ else
+ {
+ sal_uInt16 i,j;
+
+ for (j=0; j<nPolyAnz; j++)
+ {
+ XPolygon& aPol=aTempPolyPoly[j];
+ sal_uInt16 nPtAnz=aPol.GetPointCount();
+ i=0;
+
+ while (i<nPtAnz)
+ {
+ Point* pPnt=&aPol[i];
+ Point* pC1=NULL;
+ Point* pC2=NULL;
+
+ if (i+1<nPtAnz && aPol.IsControl(i))
+ { // Kontrollpunkt links
+ pC1=pPnt;
+ i++;
+ pPnt=&aPol[i];
+ }
+
+ i++;
+
+ if (i<nPtAnz && aPol.IsControl(i))
+ { // Kontrollpunkt rechts
+ pC2=&aPol[i];
+ i++;
+ }
+
+ _MovCrookPoint(*pPnt,pC1,pC2);
+ }
+ }
+ }
+ }
+
+ rTarget = aTempPolyPoly.getB2DPolyPolygon();
+ }
+}
+
+void SdrDragCrook::_MovCrookPoint(Point& rPnt, Point* pC1, Point* pC2)
+{
+ bool bVert=bVertical;
+ bool bC1=pC1!=NULL;
+ bool bC2=pC2!=NULL;
+ Point aC(aCenter);
+
+ if (bResize)
+ {
+ Fraction aFact1(1,1);
+
+ if (bVert)
+ {
+ ResizePoint(rPnt,aC,aFact1,aFact);
+
+ if (bC1)
+ ResizePoint(*pC1,aC,aFact1,aFact);
+
+ if (bC2)
+ ResizePoint(*pC2,aC,aFact1,aFact);
+ }
+ else
+ {
+ ResizePoint(rPnt,aC,aFact,aFact1);
+
+ if (bC1)
+ ResizePoint(*pC1,aC,aFact,aFact1);
+
+ if (bC2)
+ ResizePoint(*pC2,aC,aFact,aFact1);
+ }
+ }
+
+ if (aRad.X()!=0 && aRad.Y()!=0)
+ {
+ double nSin,nCos;
+
+ switch (eMode)
+ {
+ case SDRCROOK_ROTATE : CrookRotateXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
+ case SDRCROOK_SLANT : CrookSlantXPoint (rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert); break;
+ case SDRCROOK_STRETCH: CrookStretchXPoint(rPnt,pC1,pC2,aC,aRad,nSin,nCos,bVert,aMarkRect); break;
+ } // switch
+ }
+}
+
+void SdrDragCrook::MoveSdrDrag(const Point& rPnt)
+{
+ if (DragStat().CheckMinMoved(rPnt))
+ {
+ Point aPnt(rPnt);
+ bool bNeuMoveOnly=getSdrDragView().IsMoveOnlyDragging();
+ bAtCenter=false;
+ SdrCrookMode eNeuMode=getSdrDragView().GetCrookMode();
+ bool bNeuContortion=!bNeuMoveOnly && ((bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed);
+ bResize=!getSdrDragView().IsOrtho() && bResizeAllowed && !bNeuMoveOnly;
+ bool bNeuRotate=bRotateAllowed && !bNeuContortion && !bNeuMoveOnly && eNeuMode==SDRCROOK_ROTATE;
+ long nSA=0;
+
+ if (nSA==0)
+ aPnt=GetSnapPos(aPnt);
+
+ Point aNeuCenter(aMarkCenter.X(),aStart.Y());
+
+ if (bVertical)
+ {
+ aNeuCenter.X()=aStart.X();
+ aNeuCenter.Y()=aMarkCenter.Y();
+ }
+
+ if (!getSdrDragView().IsCrookAtCenter())
+ {
+ switch (GetDragHdlKind())
+ {
+ case HDL_UPLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
+ case HDL_UPPER: aNeuCenter.Y()=aMarkRect.Bottom(); bUpr=true; break;
+ case HDL_UPRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
+ case HDL_LEFT : aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
+ case HDL_RIGHT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
+ case HDL_LWLFT: aNeuCenter.X()=aMarkRect.Right(); bLft=true; break;
+ case HDL_LOWER: aNeuCenter.Y()=aMarkRect.Top(); bLwr=true; break;
+ case HDL_LWRGT: aNeuCenter.X()=aMarkRect.Left(); bRgt=true; break;
+ default: bAtCenter=true;
+ }
+ }
+ else
+ bAtCenter=true;
+
+ Fraction aNeuFact(1,1);
+ long dx1=aPnt.X()-aNeuCenter.X();
+ long dy1=aPnt.Y()-aNeuCenter.Y();
+ bValid=bVertical ? dx1!=0 : dy1!=0;
+
+ if (bValid)
+ {
+ if (bVertical)
+ bValid=Abs(dx1)*100>Abs(dy1);
+ else
+ bValid=Abs(dy1)*100>Abs(dx1);
+ }
+
+ long nNeuRad=0;
+ nWink=0;
+
+ if (bValid)
+ {
+ double a=0; // Steigung des Radius
+ long nPntWink=0;
+
+ if (bVertical)
+ {
+ a=((double)dy1)/((double)dx1); // Steigung des Radius
+ nNeuRad=((long)(dy1*a)+dx1) /2;
+ aNeuCenter.X()+=nNeuRad;
+ nPntWink=GetAngle(aPnt-aNeuCenter);
+ }
+ else
+ {
+ a=((double)dx1)/((double)dy1); // Steigung des Radius
+ nNeuRad=((long)(dx1*a)+dy1) /2;
+ aNeuCenter.Y()+=nNeuRad;
+ nPntWink=GetAngle(aPnt-aNeuCenter)-9000;
+ }
+
+ if (!bAtCenter)
+ {
+ if (nNeuRad<0)
+ {
+ if (bRgt) nPntWink+=18000;
+ if (bLft) nPntWink=18000-nPntWink;
+ if (bLwr) nPntWink=-nPntWink;
+ }
+ else
+ {
+ if (bRgt) nPntWink=-nPntWink;
+ if (bUpr) nPntWink=18000-nPntWink;
+ if (bLwr) nPntWink+=18000;
+ }
+
+ nPntWink=NormAngle360(nPntWink);
+ }
+ else
+ {
+ if (nNeuRad<0) nPntWink+=18000;
+ if (bVertical) nPntWink=18000-nPntWink;
+ nPntWink=NormAngle180(nPntWink);
+ nPntWink=Abs(nPntWink);
+ }
+
+ double nUmfang=2*Abs(nNeuRad)*nPi;
+
+ if (bResize)
+ {
+ if (nSA!=0)
+ { // Winkelfang
+ long nWink0=nPntWink;
+ nPntWink+=nSA/2;
+ nPntWink/=nSA;
+ nPntWink*=nSA;
+ BigInt a2(nNeuRad);
+ a2*=BigInt(nWink);
+ a2/=BigInt(nWink0);
+ nNeuRad=long(a2);
+
+ if (bVertical)
+ aNeuCenter.X()=aStart.X()+nNeuRad;
+ else
+ aNeuCenter.Y()=aStart.Y()+nNeuRad;
+ }
+
+ long nMul=(long)(nUmfang*NormAngle360(nPntWink)/36000);
+
+ if (bAtCenter)
+ nMul*=2;
+
+ aNeuFact=Fraction(nMul,nMarkSize);
+ nWink=nPntWink;
+ }
+ else
+ {
+ nWink=(long)((nMarkSize*360/nUmfang)*100)/2;
+
+ if (nWink==0)
+ bValid=false;
+
+ if (bValid && nSA!=0)
+ { // Winkelfang
+ long nWink0=nWink;
+ nWink+=nSA/2;
+ nWink/=nSA;
+ nWink*=nSA;
+ BigInt a2(nNeuRad);
+ a2*=BigInt(nWink);
+ a2/=BigInt(nWink0);
+ nNeuRad=long(a2);
+
+ if (bVertical)
+ aNeuCenter.X()=aStart.X()+nNeuRad;
+ else
+ aNeuCenter.Y()=aStart.Y()+nNeuRad;
+ }
+ }
+ }
+
+ if (nWink==0 || nNeuRad==0)
+ bValid=false;
+
+ if (!bValid)
+ nNeuRad=0;
+
+ if (!bValid && bResize)
+ {
+ long nMul=bVertical ? dy1 : dx1;
+
+ if (bLft || bUpr)
+ nMul=-nMul;
+
+ long nDiv=nMarkSize;
+
+ if (bAtCenter)
+ {
+ nMul*=2;
+ nMul=Abs(nMul);
+ }
+
+ aNeuFact=Fraction(nMul,nDiv);
+ }
+
+ if (aNeuCenter!=aCenter || bNeuContortion!=bContortion || aNeuFact!=aFact ||
+ bNeuMoveOnly != getMoveOnly() || bNeuRotate!=bRotate || eNeuMode!=eMode)
+ {
+ Hide();
+ setMoveOnly(bNeuMoveOnly);
+ bRotate=bNeuRotate;
+ eMode=eNeuMode;
+ bContortion=bNeuContortion;
+ aCenter=aNeuCenter;
+ aFact=aNeuFact;
+ aRad=Point(nNeuRad,nNeuRad);
+ bResize=aFact!=Fraction(1,1) && aFact.GetDenominator()!=0 && aFact.IsValid();
+ DragStat().NextMove(aPnt);
+ Show();
+ }
+ }
+}
+
+void SdrDragCrook::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ const bool bDoResize(aFact!=Fraction(1,1));
+ const bool bDoCrook(aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0);
+
+ if (bDoCrook || bDoResize)
+ {
+ if (bDoResize)
+ {
+ Fraction aFact1(1,1);
+
+ if (bContortion)
+ {
+ if (bVertical)
+ {
+ rTarget.Resize(aCenter,aFact1,aFact);
+ }
+ else
+ {
+ rTarget.Resize(aCenter,aFact,aFact1);
+ }
+ }
+ else
+ {
+ Point aCtr0(rTarget.GetSnapRect().Center());
+ Point aCtr1(aCtr0);
+
+ if (bVertical)
+ {
+ ResizePoint(aCtr1,aCenter,aFact1,aFact);
+ }
+ else
+ {
+ ResizePoint(aCtr1,aCenter,aFact,aFact1);
+ }
+
+ Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
+
+ rTarget.Move(aSiz);
+ }
+ }
+
+ if (bDoCrook)
+ {
+ const Rectangle aLocalMarkRect(getSdrDragView().GetMarkedObjRect());
+ const bool bLocalRotate(!bContortion && eMode == SDRCROOK_ROTATE && getSdrDragView().IsRotateAllowed(false));
+
+ getSdrDragView().ImpCrookObj(&rTarget,aCenter,aRad,eMode,bVertical,!bContortion,bLocalRotate,aLocalMarkRect);
+ }
+ }
+}
+
+void SdrDragCrook::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
+{
+ // use helper derived from old stuff
+ _MovAllPoints(rTarget);
+}
+
+bool SdrDragCrook::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if (bResize && aFact==Fraction(1,1))
+ bResize=false;
+
+ const bool bUndo = getSdrDragView().IsUndoEnabled();
+
+ bool bDoCrook=aCenter!=aMarkCenter && aRad.X()!=0 && aRad.Y()!=0;
+
+ if (bDoCrook || bResize)
+ {
+ if (bResize && bUndo)
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(!bContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
+
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+
+ getSdrDragView().BegUndo(aStr);
+ }
+
+ if (bResize)
+ {
+ Fraction aFact1(1,1);
+
+ if (bContortion)
+ {
+ if (bVertical)
+ getSdrDragView().ResizeMarkedObj(aCenter,aFact1,aFact,bCopy);
+ else
+ getSdrDragView().ResizeMarkedObj(aCenter,aFact,aFact1,bCopy);
+ }
+ else
+ {
+ if (bCopy)
+ getSdrDragView().CopyMarkedObj();
+
+ ULONG nMarkAnz=getSdrDragView().GetMarkedObjectList().GetMarkCount();
+
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=getSdrDragView().GetMarkedObjectList().GetMark(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ Point aCtr0(pO->GetSnapRect().Center());
+ Point aCtr1(aCtr0);
+
+ if (bVertical)
+ ResizePoint(aCtr1,aCenter,aFact1,aFact);
+ else
+ ResizePoint(aCtr1,aCenter,aFact,aFact1);
+
+ Size aSiz(aCtr1.X()-aCtr0.X(),aCtr1.Y()-aCtr0.Y());
+ if( bUndo )
+ AddUndo(getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,aSiz));
+ pO->Move(aSiz);
+ }
+ }
+
+ bCopy=false;
+ }
+
+ if (bDoCrook)
+ {
+ getSdrDragView().CrookMarkedObj(aCenter,aRad,eMode,bVertical,!bContortion,bCopy);
+ getSdrDragView().SetLastCrookCenter(aCenter);
+ }
+
+ if (bResize && bUndo)
+ getSdrDragView().EndUndo();
+
+ return true;
+ }
+
+ return false;
+}
+
+Pointer SdrDragCrook::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_CROOK);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragDistort,SdrDragMethod);
+
+SdrDragDistort::SdrDragDistort(SdrDragView& rNewView)
+: SdrDragMethod(rNewView),
+ nPolyPt(0),
+ bContortionAllowed(false),
+ bNoContortionAllowed(false),
+ bContortion(false)
+{
+}
+
+void SdrDragDistort::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(STR_DragMethDistort, rStr);
+
+ XubString aStr;
+
+ rStr.AppendAscii(" (x=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
+ rStr += aStr;
+ rStr.AppendAscii(" y=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+void SdrDragDistort::createSdrDragEntries()
+{
+ // Add extended frame raster first, so it will be behind objects
+ if(getSdrDragView().GetSdrPageView())
+ {
+ const basegfx::B2DPolyPolygon aDragRaster(impCreateDragRaster(*getSdrDragView().GetSdrPageView(), GetMarkedRect()));
+
+ if(aDragRaster.count())
+ {
+ addSdrDragEntry(new SdrDragEntryPolyPolygon(aDragRaster));
+ }
+ }
+
+ // call parent
+ SdrDragMethod::createSdrDragEntries();
+}
+
+bool SdrDragDistort::BeginSdrDrag()
+{
+ bContortionAllowed=getSdrDragView().IsDistortAllowed(false);
+ bNoContortionAllowed=getSdrDragView().IsDistortAllowed(true);
+
+ if (bContortionAllowed || bNoContortionAllowed)
+ {
+ SdrHdlKind eKind=GetDragHdlKind();
+ nPolyPt=0xFFFF;
+
+ if (eKind==HDL_UPLFT) nPolyPt=0;
+ if (eKind==HDL_UPRGT) nPolyPt=1;
+ if (eKind==HDL_LWRGT) nPolyPt=2;
+ if (eKind==HDL_LWLFT) nPolyPt=3;
+ if (nPolyPt>3) return false;
+
+ aMarkRect=GetMarkedRect();
+ aDistortedRect=XPolygon(aMarkRect);
+ Show();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void SdrDragDistort::_MovAllPoints(basegfx::B2DPolyPolygon& rTarget)
+{
+ if (bContortion)
+ {
+ SdrPageView* pPV = getSdrDragView().GetSdrPageView();
+
+ if(pPV)
+ {
+ if (pPV->HasMarkedObjPageView())
+ {
+ basegfx::B2DPolyPolygon aDragPolygon(rTarget);
+ const basegfx::B2DRange aOriginalRange(aMarkRect.Left(), aMarkRect.Top(), aMarkRect.Right(), aMarkRect.Bottom());
+ const basegfx::B2DPoint aTopLeft(aDistortedRect[0].X(), aDistortedRect[0].Y());
+ const basegfx::B2DPoint aTopRight(aDistortedRect[1].X(), aDistortedRect[1].Y());
+ const basegfx::B2DPoint aBottomLeft(aDistortedRect[3].X(), aDistortedRect[3].Y());
+ const basegfx::B2DPoint aBottomRight(aDistortedRect[2].X(), aDistortedRect[2].Y());
+
+ aDragPolygon = basegfx::tools::distort(aDragPolygon, aOriginalRange, aTopLeft, aTopRight, aBottomLeft, aBottomRight);
+ rTarget = aDragPolygon;
+ }
+ }
+ }
+}
+
+void SdrDragDistort::MoveSdrDrag(const Point& rPnt)
+{
+ if (DragStat().CheckMinMoved(rPnt))
+ {
+ Point aPnt(GetSnapPos(rPnt));
+
+ if (getSdrDragView().IsOrtho())
+ OrthoDistance8(DragStat().GetStart(),aPnt,getSdrDragView().IsBigOrtho());
+
+ bool bNeuContortion=(bContortionAllowed && !getSdrDragView().IsCrookNoContortion()) || !bNoContortionAllowed;
+
+ if (bNeuContortion!=bContortion || aDistortedRect[nPolyPt]!=aPnt)
+ {
+ Hide();
+ aDistortedRect[nPolyPt]=aPnt;
+ bContortion=bNeuContortion;
+ DragStat().NextMove(aPnt);
+ Show();
+ }
+ }
+}
+
+bool SdrDragDistort::EndSdrDrag(bool bCopy)
+{
+ Hide();
+ bool bDoDistort=DragStat().GetDX()!=0 || DragStat().GetDY()!=0;
+
+ if (bDoDistort)
+ {
+ getSdrDragView().DistortMarkedObj(aMarkRect,aDistortedRect,!bContortion,bCopy);
+ return true;
+ }
+
+ return false;
+}
+
+Pointer SdrDragDistort::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_REFHAND);
+}
+
+void SdrDragDistort::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
+{
+ const bool bDoDistort(DragStat().GetDX()!=0 || DragStat().GetDY()!=0);
+
+ if (bDoDistort)
+ {
+ getSdrDragView().ImpDistortObj(&rTarget, aMarkRect, aDistortedRect, !bContortion);
+ }
+}
+
+void SdrDragDistort::applyCurrentTransformationToPolyPolygon(basegfx::B2DPolyPolygon& rTarget)
+{
+ // use helper derived from old stuff
+ _MovAllPoints(rTarget);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrDragCrop,SdrDragResize);
+
+SdrDragCrop::SdrDragCrop(SdrDragView& rNewView)
+: SdrDragResize(rNewView)
+{
+ // switch off solid dragging for crop; it just makes no sense since showing
+ // a 50% transparent object above the original will not be visible
+ setSolidDraggingActive(false);
+}
+
+void SdrDragCrop::TakeSdrDragComment(XubString& rStr) const
+{
+ ImpTakeDescriptionStr(STR_DragMethCrop, rStr);
+
+ XubString aStr;
+
+ rStr.AppendAscii(" (x=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDX(), aStr);
+ rStr += aStr;
+ rStr.AppendAscii(" y=");
+ getSdrDragView().GetModel()->TakeMetricStr(DragStat().GetDY(), aStr);
+ rStr += aStr;
+ rStr += sal_Unicode(')');
+
+ if(getSdrDragView().IsDragWithCopy())
+ rStr += ImpGetResStr(STR_EditWithCopy);
+}
+
+bool SdrDragCrop::EndSdrDrag(bool bCopy)
+{
+ Hide();
+
+ if( DragStat().GetDX()==0 && DragStat().GetDY()==0 )
+ return false;
+
+ const SdrMarkList& rMarkList = getSdrDragView().GetMarkedObjectList();
+
+ if( rMarkList.GetMarkCount() != 1 )
+ return false;
+
+ SdrGrafObj* pObj = dynamic_cast<SdrGrafObj*>( rMarkList.GetMark( 0 )->GetMarkedSdrObj() );
+
+ if( !pObj || (pObj->GetGraphicType() == GRAPHIC_NONE) || (pObj->GetGraphicType() == GRAPHIC_DEFAULT) )
+ return false;
+
+ const GraphicObject& rGraphicObject = pObj->GetGraphicObject();
+ const MapMode aMapMode100thmm(MAP_100TH_MM);
+ Size aGraphicSize(rGraphicObject.GetPrefSize());
+
+ if( MAP_PIXEL == rGraphicObject.GetPrefMapMode().GetMapUnit() )
+ aGraphicSize = Application::GetDefaultDevice()->PixelToLogic( aGraphicSize, aMapMode100thmm );
+ else
+ aGraphicSize = Application::GetDefaultDevice()->LogicToLogic( aGraphicSize, rGraphicObject.GetPrefMapMode(), aMapMode100thmm);
+
+ if( aGraphicSize.nA == 0 || aGraphicSize.nB == 0 )
+ return false;
+
+ const SdrGrafCropItem& rOldCrop = (const SdrGrafCropItem&)pObj->GetMergedItem(SDRATTR_GRAFCROP);
+
+ const bool bUndo = getSdrDragView().IsUndoEnabled();
+
+ if( bUndo )
+ {
+ String aUndoStr;
+ ImpTakeDescriptionStr(STR_DragMethCrop, aUndoStr);
+
+ getSdrDragView().BegUndo( aUndoStr );
+ getSdrDragView().AddUndo( getSdrDragView().GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
+ }
+
+ Rectangle aOldRect( pObj->GetLogicRect() );
+ getSdrDragView().ResizeMarkedObj(DragStat().Ref1(),aXFact,aYFact,bCopy);
+ Rectangle aNewRect( pObj->GetLogicRect() );
+
+ double fScaleX = ( aGraphicSize.Width() - rOldCrop.GetLeft() - rOldCrop.GetRight() ) / (double)aOldRect.GetWidth();
+ double fScaleY = ( aGraphicSize.Height() - rOldCrop.GetTop() - rOldCrop.GetBottom() ) / (double)aOldRect.GetHeight();
+
+ sal_Int32 nDiffLeft = aNewRect.nLeft - aOldRect.nLeft;
+ sal_Int32 nDiffTop = aNewRect.nTop - aOldRect.nTop;
+ sal_Int32 nDiffRight = aNewRect.nRight - aOldRect.nRight;
+ sal_Int32 nDiffBottom = aNewRect.nBottom - aOldRect.nBottom;
+
+ sal_Int32 nLeftCrop = static_cast<sal_Int32>( rOldCrop.GetLeft() + nDiffLeft * fScaleX );
+ sal_Int32 nTopCrop = static_cast<sal_Int32>( rOldCrop.GetTop() + nDiffTop * fScaleY );
+ sal_Int32 nRightCrop = static_cast<sal_Int32>( rOldCrop.GetRight() - nDiffRight * fScaleX );
+ sal_Int32 nBottomCrop = static_cast<sal_Int32>( rOldCrop.GetBottom() - nDiffBottom * fScaleY );
+
+ SfxItemPool& rPool = getSdrDragView().GetModel()->GetItemPool();
+ SfxItemSet aSet( rPool, SDRATTR_GRAFCROP, SDRATTR_GRAFCROP );
+ aSet.Put( SdrGrafCropItem( nLeftCrop, nTopCrop, nRightCrop, nBottomCrop ) );
+ getSdrDragView().SetAttributes( aSet, false );
+
+ if( bUndo )
+ getSdrDragView().EndUndo();
+
+ return true;
+}
+
+Pointer SdrDragCrop::GetSdrDragPointer() const
+{
+ return Pointer(POINTER_CROP);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx
new file mode 100644
index 000000000000..f1b84ac5f98e
--- /dev/null
+++ b/svx/source/svdraw/svddrgv.cxx
@@ -0,0 +1,1006 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svddrgv.hxx>
+#include "xattr.hxx"
+#include <svx/xpoly.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdoedge.hxx>
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+#include "svddrgm1.hxx"
+#include <svx/obj3d.hxx>
+#include <svx/svdoashp.hxx>
+#include <sdrpaintwindow.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svx/polypolygoneditor.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+
+using namespace sdr;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@@@@ @@@@ @@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@ @@ @@@@@ @@@@@@ @@ @@@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@@ @@ @@ @@ @@ @@@@@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrDragView::ImpClearVars()
+{
+ bFramDrag=FALSE;
+ eDragMode=SDRDRAG_MOVE;
+ bDragLimit=FALSE;
+ bMarkedHitMovesAlways=FALSE;
+ eDragHdl=HDL_MOVE;
+ pDragHdl=NULL;
+ bDragHdl=FALSE;
+ bDragSpecial=FALSE;
+ mpCurrentSdrDragMethod=NULL;
+ bDragStripes=FALSE;
+ bMirrRefDragObj=TRUE;
+ bDragWithCopy=FALSE;
+ pInsPointUndo=NULL;
+ bInsGluePoint=FALSE;
+ bInsObjPointMode=FALSE;
+ bInsGluePointMode=FALSE;
+ nDragXorPolyLimit=100;
+ nDragXorPointLimit=500;
+ bNoDragXorPolys=FALSE;
+ bAutoVertexCon=TRUE;
+ bAutoCornerCon=FALSE;
+ bRubberEdgeDragging=TRUE;
+ nRubberEdgeDraggingLimit=100;
+ bDetailedEdgeDragging=TRUE;
+ nDetailedEdgeDraggingLimit=10;
+ bResizeAtCenter=FALSE;
+ bCrookAtCenter=FALSE;
+ bMouseHideWhileDraggingPoints=FALSE;
+
+ // init using default
+ mbSolidDragging = getOptionsDrawinglayer().IsSolidDragCreate();
+}
+
+void SdrDragView::ImpMakeDragAttr()
+{
+ ImpDelDragAttr();
+}
+
+SdrDragView::SdrDragView(SdrModel* pModel1, OutputDevice* pOut)
+: SdrExchangeView(pModel1,pOut)
+{
+ ImpClearVars();
+ ImpMakeDragAttr();
+}
+
+SdrDragView::~SdrDragView()
+{
+ ImpDelDragAttr();
+}
+
+void SdrDragView::ImpDelDragAttr()
+{
+}
+
+BOOL SdrDragView::IsAction() const
+{
+ return (mpCurrentSdrDragMethod || SdrExchangeView::IsAction());
+}
+
+void SdrDragView::MovAction(const Point& rPnt)
+{
+ SdrExchangeView::MovAction(rPnt);
+ if (mpCurrentSdrDragMethod)
+ {
+ MovDragObj(rPnt);
+ }
+}
+
+void SdrDragView::EndAction()
+{
+ if (mpCurrentSdrDragMethod)
+ {
+ EndDragObj(FALSE);
+ }
+ SdrExchangeView::EndAction();
+}
+
+void SdrDragView::BckAction()
+{
+ SdrExchangeView::BckAction();
+ BrkDragObj();
+}
+
+void SdrDragView::BrkAction()
+{
+ SdrExchangeView::BrkAction();
+ BrkDragObj();
+}
+
+void SdrDragView::TakeActionRect(Rectangle& rRect) const
+{
+ if (mpCurrentSdrDragMethod)
+ {
+ rRect=aDragStat.GetActionRect();
+ if (rRect.IsEmpty())
+ {
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV&& pPV->HasMarkedObjPageView())
+ {
+ // #i95646# is this used..?
+ const basegfx::B2DRange aBoundRange(mpCurrentSdrDragMethod->getCurrentRange());
+ rRect = Rectangle(
+ basegfx::fround(aBoundRange.getMinX()), basegfx::fround(aBoundRange.getMinY()),
+ basegfx::fround(aBoundRange.getMaxX()), basegfx::fround(aBoundRange.getMaxY()));
+ }
+ }
+ if (rRect.IsEmpty())
+ {
+ rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow());
+ }
+ }
+ else
+ {
+ SdrExchangeView::TakeActionRect(rRect);
+ }
+}
+
+BOOL SdrDragView::TakeDragObjAnchorPos(Point& rPos, BOOL bTR ) const
+{
+ Rectangle aR;
+ TakeActionRect(aR);
+ rPos = bTR ? aR.TopRight() : aR.TopLeft();
+ if (GetMarkedObjectCount()==1 && IsDragObj() && // nur bei Einzelselektion
+ !IsDraggingPoints() && !IsDraggingGluePoints() && // nicht beim Punkteschieben
+ !mpCurrentSdrDragMethod->ISA(SdrDragMovHdl)) // nicht beim Handlesschieben
+ {
+ SdrObject* pObj=GetMarkedObjectByIndex(0);
+ if (pObj->ISA(SdrCaptionObj))
+ {
+ Point aPt(((SdrCaptionObj*)pObj)->GetTailPos());
+ BOOL bTail=eDragHdl==HDL_POLY; // Schwanz wird gedraggt (nicht so ganz feine Abfrage hier)
+ BOOL bOwn=mpCurrentSdrDragMethod->ISA(SdrDragObjOwn); // Objektspeziefisch
+ if (!bTail)
+ { // bei bTail liefert TakeActionRect schon das richtige
+ if (bOwn)
+ { // bOwn kann sein MoveTextFrame, ResizeTextFrame aber eben nicht mehr DragTail
+ rPos=aPt;
+ }
+ else
+ {
+ // drag the whole Object (Move, Resize, ...)
+ const basegfx::B2DPoint aTransformed(mpCurrentSdrDragMethod->getCurrentTransformation() * basegfx::B2DPoint(aPt.X(), aPt.Y()));
+ rPos.X() = basegfx::fround(aTransformed.getX());
+ rPos.Y() = basegfx::fround(aTransformed.getY());
+ }
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrDragView::TakeDragLimit(SdrDragMode /*eMode*/, Rectangle& /*rRect*/) const
+{
+ return FALSE;
+}
+
+BOOL SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl, short nMinMov, SdrDragMethod* pForcedMeth)
+{
+ BrkAction();
+
+ bool bRet=false;
+ {
+ SetDragWithCopy(FALSE);
+ //ForceEdgesOfMarkedNodes();
+ //TODO: aAni.Reset();
+ mpCurrentSdrDragMethod=NULL;
+ bDragSpecial=FALSE;
+ bDragLimit=FALSE;
+ SdrDragMode eTmpMode=eDragMode;
+ if (eTmpMode==SDRDRAG_MOVE && pHdl!=NULL && pHdl->GetKind()!=HDL_MOVE) {
+ eTmpMode=SDRDRAG_RESIZE;
+ }
+ bDragLimit=TakeDragLimit(eTmpMode,aDragLimit);
+ bFramDrag=ImpIsFrameHandles();
+ if (!bFramDrag &&
+ (pMarkedObj==NULL || !pMarkedObj->hasSpecialDrag()) &&
+ (pHdl==NULL || pHdl->GetObj()==NULL)) {
+ bFramDrag=TRUE;
+ }
+
+ Point aPnt(rPnt);
+ if(pHdl == NULL
+ || pHdl->GetKind() == HDL_MOVE
+ || pHdl->GetKind() == HDL_MIRX
+ || pHdl->GetKind() == HDL_TRNS
+ || pHdl->GetKind() == HDL_GRAD)
+ {
+ aDragStat.Reset(aPnt);
+ }
+ else
+ {
+ aDragStat.Reset(pHdl->GetPos());
+ }
+
+ aDragStat.SetView((SdrView*)this);
+ aDragStat.SetPageView(pMarkedPV); // <<-- hier muss die DragPV rein!!!
+ aDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
+ aDragStat.SetHdl(pHdl);
+ aDragStat.NextPoint();
+ pDragWin=pOut;
+ pDragHdl=pHdl;
+ eDragHdl= pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
+ bDragHdl=eDragHdl==HDL_REF1 || eDragHdl==HDL_REF2 || eDragHdl==HDL_MIRX;
+
+ // #103894# Expand test for HDL_ANCHOR_TR
+ BOOL bNotDraggable = (HDL_ANCHOR == eDragHdl || HDL_ANCHOR_TR == eDragHdl);
+
+ if(pHdl && (pHdl->GetKind() == HDL_SMARTTAG) && pForcedMeth )
+ {
+ // just use the forced method for smart tags
+ }
+ else if(bDragHdl)
+ {
+ mpCurrentSdrDragMethod = new SdrDragMovHdl(*this);
+ }
+ else if(!bNotDraggable)
+ {
+ switch (eDragMode)
+ {
+ case SDRDRAG_ROTATE: case SDRDRAG_SHEAR: case SDRDRAG_DISTORT:
+ {
+ switch (eDragHdl)
+ {
+ case HDL_LEFT: case HDL_RIGHT:
+ case HDL_UPPER: case HDL_LOWER:
+ {
+ // Sind 3D-Objekte selektiert?
+ BOOL b3DObjSelected = FALSE;
+ for(UINT32 a=0;!b3DObjSelected && a<GetMarkedObjectCount();a++)
+ {
+ SdrObject* pObj = GetMarkedObjectByIndex(a);
+ if(pObj && pObj->ISA(E3dObject))
+ b3DObjSelected = TRUE;
+ }
+ // Falls ja, Shear auch bei !IsShearAllowed zulassen,
+ // da es sich bei 3D-Objekten um eingeschraenkte
+ // Rotationen handelt
+ if (!b3DObjSelected && !IsShearAllowed())
+ return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragShear(*this,eDragMode==SDRDRAG_ROTATE);
+ } break;
+ case HDL_UPLFT: case HDL_UPRGT:
+ case HDL_LWLFT: case HDL_LWRGT:
+ {
+ if (eDragMode==SDRDRAG_SHEAR || eDragMode==SDRDRAG_DISTORT)
+ {
+ if (!IsDistortAllowed(TRUE) && !IsDistortAllowed(FALSE)) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragDistort(*this);
+ }
+ else
+ {
+ if (!IsRotateAllowed(TRUE)) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragRotate(*this);
+ }
+ } break;
+ default:
+ {
+ if (IsMarkedHitMovesAlways() && eDragHdl==HDL_MOVE)
+ { // HDL_MOVE ist auch wenn Obj direkt getroffen
+ if (!IsMoveAllowed()) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if (!IsRotateAllowed(TRUE)) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragRotate(*this);
+ }
+ }
+ }
+ } break;
+ case SDRDRAG_MIRROR:
+ {
+ if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
+ {
+ if (!IsMoveAllowed()) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if (!IsMirrorAllowed(TRUE,TRUE)) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMirror(*this);
+ }
+ } break;
+
+ case SDRDRAG_CROP:
+ {
+ if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
+ {
+ if (!IsMoveAllowed())
+ return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if (!IsCrookAllowed(TRUE) && !IsCrookAllowed(FALSE))
+ return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragCrop(*this);
+ }
+ }
+ break;
+
+ case SDRDRAG_TRANSPARENCE:
+ {
+ if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
+ {
+ if(!IsMoveAllowed())
+ return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if(!IsTransparenceAllowed())
+ return FALSE;
+
+ mpCurrentSdrDragMethod = new SdrDragGradient(*this, FALSE);
+ }
+ break;
+ }
+ case SDRDRAG_GRADIENT:
+ {
+ if(eDragHdl == HDL_MOVE && IsMarkedHitMovesAlways())
+ {
+ if(!IsMoveAllowed())
+ return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if(!IsGradientAllowed())
+ return FALSE;
+
+ mpCurrentSdrDragMethod = new SdrDragGradient(*this);
+ }
+ break;
+ }
+
+ case SDRDRAG_CROOK :
+ {
+ if (eDragHdl==HDL_MOVE && IsMarkedHitMovesAlways())
+ {
+ if (!IsMoveAllowed()) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if (!IsCrookAllowed(TRUE) && !IsCrookAllowed(FALSE)) return FALSE;
+ mpCurrentSdrDragMethod = new SdrDragCrook(*this);
+ }
+ } break;
+
+ default:
+ {
+ // SDRDRAG_MOVE
+ if((eDragHdl == HDL_MOVE) && !IsMoveAllowed())
+ {
+ return FALSE;
+ }
+ else if(eDragHdl == HDL_GLUE)
+ {
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if(bFramDrag)
+ {
+ if(eDragHdl == HDL_MOVE)
+ {
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ }
+ else
+ {
+ if(!IsResizeAllowed(TRUE))
+ {
+ return FALSE;
+ }
+
+ sal_Bool bSingleTextObjMark = sal_False; // SJ: #i100490#
+ if ( GetMarkedObjectCount() == 1 )
+ {
+ pMarkedObj=GetMarkedObjectByIndex(0);
+ if ( pMarkedObj &&
+ pMarkedObj->ISA( SdrTextObj ) &&
+ static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame() )
+ bSingleTextObjMark = sal_True;
+ }
+ if ( bSingleTextObjMark )
+ mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
+ else
+ mpCurrentSdrDragMethod = new SdrDragResize(*this);
+ }
+ }
+ else
+ {
+ if(HDL_MOVE == eDragHdl)
+ {
+ const bool bCustomShapeSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrObjCustomShape));
+
+ if(bCustomShapeSelected)
+ {
+ mpCurrentSdrDragMethod = new SdrDragMove( *this );
+ }
+ }
+ else if(HDL_POLY == eDragHdl)
+ {
+ const bool bConnectorSelected(1 == GetMarkedObjectCount() && GetMarkedObjectByIndex(0)->ISA(SdrEdgeObj));
+
+ if(bConnectorSelected)
+ {
+ // #i97784#
+ // fallback to old behaviour for connectors (see
+ // text in task description for more details)
+ }
+ else if(!IsMoveAllowed() || !IsResizeAllowed())
+ {
+ // #i77187#
+ // do not allow move of polygon points if object is move or size protected
+ return FALSE;
+ }
+ }
+
+ if(!mpCurrentSdrDragMethod)
+ {
+ // fallback to DragSpecial if no interaction defined
+ bDragSpecial = TRUE;
+ mpCurrentSdrDragMethod = new SdrDragObjOwn(*this);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (pForcedMeth!=NULL)
+ {
+ delete mpCurrentSdrDragMethod;
+ mpCurrentSdrDragMethod = pForcedMeth;
+ }
+ aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
+ if (mpCurrentSdrDragMethod)
+ {
+ bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
+ if (!bRet)
+ {
+ if (pHdl==NULL && IS_TYPE(SdrDragObjOwn,mpCurrentSdrDragMethod))
+ {
+ // Aha, Obj kann nicht Move SpecialDrag, also MoveFrameDrag versuchen
+ delete mpCurrentSdrDragMethod;
+ mpCurrentSdrDragMethod = 0;
+ bDragSpecial=FALSE;
+
+ if (!IsMoveAllowed())
+ return FALSE;
+
+ bFramDrag=TRUE;
+ mpCurrentSdrDragMethod = new SdrDragMove(*this);
+ aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
+ bRet = mpCurrentSdrDragMethod->BeginSdrDrag();
+ }
+ }
+ if (!bRet)
+ {
+ delete mpCurrentSdrDragMethod;
+ mpCurrentSdrDragMethod = 0;
+ aDragStat.SetDragMethod(mpCurrentSdrDragMethod);
+ }
+ }
+ }
+
+ return bRet;
+}
+
+void SdrDragView::MovDragObj(const Point& rPnt)
+{
+ if (mpCurrentSdrDragMethod)
+ {
+ Point aPnt(rPnt);
+ ImpLimitToWorkArea(aPnt);
+ mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
+ }
+}
+
+BOOL SdrDragView::EndDragObj(BOOL bCopy)
+{
+ bool bRet(false);
+
+ // #i73341# If insert GluePoint, do not insist on last points being different
+ if(mpCurrentSdrDragMethod && aDragStat.IsMinMoved() && (IsInsertGluePoint() || aDragStat.GetNow() != aDragStat.GetPrev()))
+ {
+ ULONG nHdlAnzMerk=0;
+
+ if (bEliminatePolyPoints)
+ { // IBM Special
+ nHdlAnzMerk=GetMarkablePointCount();
+ }
+
+ const bool bUndo = IsUndoEnabled();
+ if (IsInsertGluePoint() && bUndo)
+ {
+ BegUndo(aInsPointUndoStr);
+ AddUndo(pInsPointUndo);
+ }
+
+ bRet = mpCurrentSdrDragMethod->EndSdrDrag(bCopy);
+
+ if( IsInsertGluePoint() && bUndo)
+ EndUndo();
+
+ delete mpCurrentSdrDragMethod;
+ mpCurrentSdrDragMethod = 0;
+
+ if (bEliminatePolyPoints)
+ { // IBM Special
+ if (nHdlAnzMerk!=GetMarkablePointCount())
+ {
+ UnmarkAllPoints();
+ }
+ }
+
+ if (bInsPolyPoint)
+ {
+ SetMarkHandles();
+ bInsPolyPoint=FALSE;
+ if( bUndo )
+ {
+ BegUndo(aInsPointUndoStr);
+ AddUndo(pInsPointUndo);
+ EndUndo();
+ }
+ }
+
+ eDragHdl=HDL_MOVE;
+ pDragHdl=NULL;
+
+ if (!bSomeObjChgdFlag)
+ {
+ // Aha, Obj hat nicht gebroadcastet (z.B. Writer FlyFrames)
+ if(!bDragHdl)
+ {
+ AdjustMarkHdl();
+ }
+ }
+ }
+ else
+ {
+ BrkDragObj();
+ }
+
+ bInsPolyPoint=FALSE;
+ SetInsertGluePoint(FALSE);
+
+ return bRet;
+}
+
+void SdrDragView::BrkDragObj()
+{
+ if (mpCurrentSdrDragMethod)
+ {
+ mpCurrentSdrDragMethod->CancelSdrDrag();
+
+ delete mpCurrentSdrDragMethod;
+ mpCurrentSdrDragMethod = 0;
+
+ if (bInsPolyPoint)
+ {
+ pInsPointUndo->Undo(); // Den eingefuegten Punkt wieder raus
+ delete pInsPointUndo;
+ pInsPointUndo=NULL;
+ SetMarkHandles();
+ bInsPolyPoint=FALSE;
+ }
+
+ if (IsInsertGluePoint())
+ {
+ pInsPointUndo->Undo(); // Den eingefuegten Klebepunkt wieder raus
+ delete pInsPointUndo;
+ pInsPointUndo=NULL;
+ SetInsertGluePoint(FALSE);
+ }
+
+ eDragHdl=HDL_MOVE;
+ pDragHdl=NULL;
+ }
+}
+
+BOOL SdrDragView::IsInsObjPointPossible() const
+{
+ return pMarkedObj!=NULL && pMarkedObj->IsPolyObj();
+}
+
+sal_Bool SdrDragView::ImpBegInsObjPoint(sal_Bool bIdxZwang, sal_uInt32 nIdx, const Point& rPnt, sal_Bool bNewObj, OutputDevice* pOut)
+{
+ sal_Bool bRet(sal_False);
+
+ if(pMarkedObj && pMarkedObj->ISA(SdrPathObj))
+ {
+ SdrPathObj* pMarkedPath = (SdrPathObj*)pMarkedObj;
+ BrkAction();
+ pInsPointUndo = dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pMarkedObj) );
+ DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
+
+ XubString aStr(ImpGetResStr(STR_DragInsertPoint));
+ XubString aName;
+ pMarkedObj->TakeObjNameSingul(aName);
+ xub_StrLen nPos(aStr.SearchAscii("%1"));
+
+ if(STRING_NOTFOUND != nPos)
+ {
+ aStr.Erase(nPos, 2);
+ aStr.Insert(aName, nPos);
+ }
+
+ aInsPointUndoStr = aStr;
+ Point aPt(rPnt);
+
+ if(bNewObj)
+ aPt = GetSnapPos(aPt,pMarkedPV);
+
+ sal_Bool bClosed0(pMarkedPath->IsClosedObj());
+
+ if(bIdxZwang)
+ {
+ mnInsPointNum = pMarkedPath->NbcInsPoint(nIdx, aPt, bNewObj, sal_True);
+ }
+ else
+ {
+ mnInsPointNum = pMarkedPath->NbcInsPointOld(aPt, bNewObj, sal_True);
+ }
+
+ if(bClosed0 != pMarkedPath->IsClosedObj())
+ {
+ // Obj was closed implicit
+ // object changed
+ pMarkedPath->SetChanged();
+ pMarkedPath->BroadcastObjectChange();
+ }
+
+ if(0xffffffff != mnInsPointNum)
+ {
+ bInsPolyPoint = sal_True;
+ UnmarkAllPoints();
+ AdjustMarkHdl();
+
+ bRet = BegDragObj(rPnt, pOut, aHdl.GetHdl(mnInsPointNum), 0);
+
+ if (bRet)
+ {
+ aDragStat.SetMinMoved();
+ MovDragObj(rPnt);
+ }
+ }
+ else
+ {
+ delete pInsPointUndo;
+ pInsPointUndo = NULL;
+ }
+ }
+
+ return bRet;
+}
+
+BOOL SdrDragView::EndInsObjPoint(SdrCreateCmd eCmd)
+{
+ if(IsInsObjPoint())
+ {
+ sal_uInt32 nNextPnt(mnInsPointNum);
+ Point aPnt(aDragStat.GetNow());
+ BOOL bOk=EndDragObj(FALSE);
+ if (bOk==TRUE && eCmd!=SDRCREATE_FORCEEND)
+ {
+ // Ret=True bedeutet: Action ist vorbei.
+ bOk=!(ImpBegInsObjPoint(sal_True, nNextPnt, aPnt, eCmd == SDRCREATE_NEXTOBJECT, pDragWin));
+ }
+
+ return bOk;
+ } else return FALSE;
+}
+
+BOOL SdrDragView::IsInsGluePointPossible() const
+{
+ BOOL bRet=FALSE;
+ if (IsInsGluePointMode() && AreObjectsMarked())
+ {
+ if (GetMarkedObjectCount()==1)
+ {
+ // FALSE liefern, wenn 1 Objekt und dieses ein Verbinder ist.
+ const SdrObject* pObj=GetMarkedObjectByIndex(0);
+ if (!HAS_BASE(SdrEdgeObj,pObj))
+ {
+ bRet=TRUE;
+ }
+ }
+ else
+ {
+ bRet=TRUE;
+ }
+ }
+ return bRet;
+}
+
+BOOL SdrDragView::BegInsGluePoint(const Point& rPnt)
+{
+ BOOL bRet=FALSE;
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ ULONG nMarkNum;
+ if (PickMarkedObj(rPnt,pObj,pPV,&nMarkNum,SDRSEARCH_PASS2BOUND))
+ {
+ BrkAction();
+ UnmarkAllGluePoints();
+ pInsPointUndo= dynamic_cast< SdrUndoGeoObj* >( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj) );
+ DBG_ASSERT( pInsPointUndo, "svx::SdrDragView::BegInsObjPoint(), could not create correct undo object!" );
+ XubString aStr(ImpGetResStr(STR_DragInsertGluePoint));
+ XubString aName; pObj->TakeObjNameSingul(aName);
+
+ aStr.SearchAndReplaceAscii("%1", aName);
+
+ aInsPointUndoStr=aStr;
+ SdrGluePointList* pGPL=pObj->ForceGluePointList();
+ if (pGPL!=NULL)
+ {
+ USHORT nGlueIdx=pGPL->Insert(SdrGluePoint());
+ SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
+ USHORT nGlueId=rGP.GetId();
+ rGP.SetAbsolutePos(rPnt,*pObj);
+
+ SdrHdl* pHdl=NULL;
+ if (MarkGluePoint(pObj,nGlueId,pPV))
+ {
+ pHdl=GetGluePointHdl(pObj,nGlueId);
+ }
+ if (pHdl!=NULL && pHdl->GetKind()==HDL_GLUE && pHdl->GetObj()==pObj && pHdl->GetObjHdlNum()==nGlueId)
+ {
+ SetInsertGluePoint(TRUE);
+ bRet=BegDragObj(rPnt,NULL,pHdl,0);
+ if (bRet)
+ {
+ aDragStat.SetMinMoved();
+ MovDragObj(rPnt);
+ }
+ else
+ {
+ SetInsertGluePoint(FALSE);
+ delete pInsPointUndo;
+ pInsPointUndo=NULL;
+ }
+ }
+ else
+ {
+ DBG_ERROR("BegInsGluePoint(): GluePoint-Handle nicht gefunden");
+ }
+ }
+ else
+ {
+ // Keine Klebepunkte moeglich bei diesem Objekt (z.B. Edge)
+ SetInsertGluePoint(FALSE);
+ delete pInsPointUndo;
+ pInsPointUndo=NULL;
+ }
+ }
+
+ return bRet;
+}
+
+void SdrDragView::ShowDragObj()
+{
+ if(mpCurrentSdrDragMethod && !aDragStat.IsShown())
+ {
+ for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = GetPaintWindow(a);
+ sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
+
+ if(pOverlayManager)
+ {
+ mpCurrentSdrDragMethod->CreateOverlayGeometry(*pOverlayManager);
+
+ // #i101679# Force changed overlay to be shown
+ pOverlayManager->flush();
+ }
+ }
+
+ aDragStat.SetShown(TRUE);
+ }
+}
+
+void SdrDragView::HideDragObj()
+{
+ if(mpCurrentSdrDragMethod && aDragStat.IsShown())
+ {
+ mpCurrentSdrDragMethod->destroyOverlayGeometry();
+ aDragStat.SetShown(FALSE);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrDragView::SetNoDragXorPolys(BOOL bOn)
+{
+ if (IsNoDragXorPolys()!=bOn)
+ {
+ const bool bDragging(mpCurrentSdrDragMethod);
+ const bool bShown(bDragging && aDragStat.IsShown());
+
+ if(bShown)
+ {
+ HideDragObj();
+ }
+
+ bNoDragXorPolys = bOn;
+
+ if(bDragging)
+ {
+ // force recreation of drag content
+ mpCurrentSdrDragMethod->resetSdrDragEntries();
+ }
+
+ if(bShown)
+ {
+ ShowDragObj();
+ }
+ }
+}
+
+void SdrDragView::SetDragStripes(BOOL bOn)
+{
+ if (mpCurrentSdrDragMethod && aDragStat.IsShown())
+ {
+ HideDragObj();
+ bDragStripes=bOn;
+ ShowDragObj();
+ }
+ else
+ {
+ bDragStripes=bOn;
+ }
+}
+
+BOOL SdrDragView::IsOrthoDesired() const
+{
+ if(mpCurrentSdrDragMethod && (IS_TYPE(SdrDragObjOwn, mpCurrentSdrDragMethod) || IS_TYPE(SdrDragResize, mpCurrentSdrDragMethod)))
+ {
+ return bOrthoDesiredOnMarked;
+ }
+
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrDragView::SetRubberEdgeDragging(BOOL bOn)
+{
+ if (bOn!=IsRubberEdgeDragging())
+ {
+ ULONG nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
+ BOOL bShowHide=nAnz!=0 && IsDragObj() &&
+ (nRubberEdgeDraggingLimit>=nAnz);
+ if (bShowHide)
+ HideDragObj();
+ bRubberEdgeDragging=bOn;
+ if (bShowHide)
+ ShowDragObj();
+ }
+}
+
+void SdrDragView::SetRubberEdgeDraggingLimit(USHORT nEdgeObjAnz)
+{
+ if (nEdgeObjAnz!=nRubberEdgeDraggingLimit)
+ {
+ ULONG nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
+ BOOL bShowHide=IsRubberEdgeDragging() && nAnz!=0 && IsDragObj() &&
+ (nEdgeObjAnz>=nAnz)!=(nRubberEdgeDraggingLimit>=nAnz);
+ if (bShowHide)
+ HideDragObj();
+ nRubberEdgeDraggingLimit=nEdgeObjAnz;
+ if (bShowHide)
+ ShowDragObj();
+ }
+}
+
+void SdrDragView::SetDetailedEdgeDragging(BOOL bOn)
+{
+ if (bOn!=IsDetailedEdgeDragging())
+ {
+ ULONG nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
+ BOOL bShowHide=nAnz!=0 && IsDragObj() &&
+ (nDetailedEdgeDraggingLimit>=nAnz);
+ if (bShowHide)
+ HideDragObj();
+ bDetailedEdgeDragging=bOn;
+ if (bShowHide)
+ ShowDragObj();
+ }
+}
+
+void SdrDragView::SetDetailedEdgeDraggingLimit(USHORT nEdgeObjAnz)
+{
+ if (nEdgeObjAnz!=nDetailedEdgeDraggingLimit)
+ {
+ ULONG nAnz = GetEdgesOfMarkedNodes().GetMarkCount();
+ BOOL bShowHide=IsDetailedEdgeDragging() && nAnz!=0 && IsDragObj() &&
+ (nEdgeObjAnz>=nAnz)!=(nDetailedEdgeDraggingLimit>=nAnz);
+ if (bShowHide)
+ HideDragObj();
+ nDetailedEdgeDraggingLimit=nEdgeObjAnz;
+ if (bShowHide)
+ ShowDragObj();
+ }
+}
+
+void SdrDragView::SetMarkHandles()
+{
+ if( pDragHdl )
+ pDragHdl = 0;
+
+ SdrExchangeView::SetMarkHandles();
+}
+
+void SdrDragView::SetSolidDragging(bool bOn)
+{
+ if((bool)mbSolidDragging != bOn)
+ {
+ mbSolidDragging = bOn;
+ }
+}
+
+bool SdrDragView::IsSolidDragging() const
+{
+ // allow each user to disable by having a local setting, but using AND for
+ // checking allowance
+ return mbSolidDragging && getOptionsDrawinglayer().IsSolidDragCreate();
+}
+
+// eof
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
new file mode 100644
index 000000000000..5eae04dbbc87
--- /dev/null
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -0,0 +1,1086 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <vcl/metaact.hxx>
+#include <svx/svdedtv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdograf.hxx> // fuer Possibilities
+#include <svx/svdopath.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdopage.hxx>
+#include <svx/svdoedge.hxx>
+#include <svx/svdlayer.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpoev.hxx> // fuer die PolyPossiblities
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/e3dsceneupdater.hxx>
+
+// #i13033#
+#include <clonelist.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::ImpResetPossibilityFlags()
+{
+ bReadOnly =FALSE;
+
+ bGroupPossible =FALSE;
+ bUnGroupPossible =FALSE;
+ bGrpEnterPossible =FALSE;
+ bDeletePossible =FALSE;
+ bToTopPossible =FALSE;
+ bToBtmPossible =FALSE;
+ bReverseOrderPossible =FALSE;
+
+ bImportMtfPossible =FALSE;
+ bCombinePossible =FALSE;
+ bDismantlePossible =FALSE;
+ bCombineNoPolyPolyPossible =FALSE;
+ bDismantleMakeLinesPossible=FALSE;
+ bOrthoDesiredOnMarked =FALSE;
+
+ bMoreThanOneNotMovable =FALSE;
+ bOneOrMoreMovable =FALSE;
+ bMoreThanOneNoMovRot =FALSE;
+ bContortionPossible =FALSE;
+ bAllPolys =FALSE;
+ bOneOrMorePolys =FALSE;
+ bMoveAllowed =FALSE;
+ bResizeFreeAllowed =FALSE;
+ bResizePropAllowed =FALSE;
+ bRotateFreeAllowed =FALSE;
+ bRotate90Allowed =FALSE;
+ bMirrorFreeAllowed =FALSE;
+ bMirror45Allowed =FALSE;
+ bMirror90Allowed =FALSE;
+ bTransparenceAllowed =FALSE;
+ bGradientAllowed =FALSE;
+ bShearAllowed =FALSE;
+ bEdgeRadiusAllowed =FALSE;
+ bCanConvToPath =FALSE;
+ bCanConvToPoly =FALSE;
+ bCanConvToContour =FALSE;
+ bCanConvToPathLineToArea=FALSE;
+ bCanConvToPolyLineToArea=FALSE;
+ bMoveProtect =FALSE;
+ bResizeProtect =FALSE;
+}
+
+void SdrEditView::ImpClearVars()
+{
+ ImpResetPossibilityFlags();
+ bPossibilitiesDirty=TRUE; // << war von Purify angemeckert
+ bBundleVirtObj=FALSE;
+}
+
+SdrEditView::SdrEditView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrMarkView(pModel1,pOut)
+{
+ ImpClearVars();
+}
+
+SdrEditView::~SdrEditView()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrLayer* SdrEditView::InsertNewLayer(const XubString& rName, USHORT nPos)
+{
+ SdrLayerAdmin& rLA=pMod->GetLayerAdmin();
+ USHORT nMax=rLA.GetLayerCount();
+ if (nPos>nMax) nPos=nMax;
+ SdrLayer* pNewLayer=rLA.NewLayer(rName,nPos);
+
+ if( GetModel()->IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewLayer(nPos,rLA,*pMod));
+
+ pMod->SetChanged();
+ return pNewLayer;
+}
+
+#include <svx/svdogrp.hxx>
+#include <svx/scene3d.hxx>
+
+BOOL SdrEditView::ImpDelLayerCheck(SdrObjList* pOL, SdrLayerID nDelID) const
+{
+ sal_Bool bDelAll(sal_True);
+ sal_uInt32 nObjAnz(pOL->GetObjCount());
+
+ for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0 && bDelAll;)
+ {
+ nObjNum--;
+ SdrObject* pObj = pOL->GetObj(nObjNum);
+ SdrObjList* pSubOL = pObj->GetSubList();
+
+ // #104809# Test explicitely for group objects and 3d scenes
+ if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
+ {
+ if(!ImpDelLayerCheck(pSubOL, nDelID))
+ {
+ // Rekursion
+ bDelAll = sal_False;
+ }
+ }
+ else
+ {
+ if(pObj->GetLayer() != nDelID)
+ {
+ bDelAll = sal_False;
+ }
+ }
+ }
+
+ return bDelAll;
+}
+
+void SdrEditView::ImpDelLayerDelObjs(SdrObjList* pOL, SdrLayerID nDelID)
+{
+ sal_uInt32 nObjAnz(pOL->GetObjCount());
+ // make sure OrdNums are correct
+ pOL->GetObj(0)->GetOrdNum();
+
+ const bool bUndo = GetModel()->IsUndoEnabled();
+
+ for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0;)
+ {
+ nObjNum--;
+ SdrObject* pObj = pOL->GetObj(nObjNum);
+ SdrObjList* pSubOL = pObj->GetSubList();
+
+
+ // #104809# Test explicitely for group objects and 3d scenes
+ if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
+ {
+ if(ImpDelLayerCheck(pSubOL, nDelID))
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
+ pOL->RemoveObject(nObjNum);
+
+ if( !bUndo )
+ SdrObject::Free( pObj );
+ }
+ else
+ {
+ ImpDelLayerDelObjs(pSubOL, nDelID);
+ }
+ }
+ else
+ {
+ if(pObj->GetLayer() == nDelID)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
+ pOL->RemoveObject(nObjNum);
+ if( !bUndo )
+ SdrObject::Free( pObj );
+ }
+ }
+ }
+}
+
+void SdrEditView::DeleteLayer(const XubString& rName)
+{
+ SdrLayerAdmin& rLA = pMod->GetLayerAdmin();
+ SdrLayer* pLayer = rLA.GetLayer(rName, TRUE);
+ sal_uInt16 nLayerNum(rLA.GetLayerPos(pLayer));
+
+ if(SDRLAYER_NOTFOUND != nLayerNum)
+ {
+
+ SdrLayerID nDelID = pLayer->GetID();
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_UndoDelLayer));
+
+ sal_Bool bMaPg(sal_True);
+
+ for(sal_uInt16 nPageKind(0); nPageKind < 2; nPageKind++)
+ {
+ // MasterPages and DrawPages
+ sal_uInt16 nPgAnz(bMaPg ? pMod->GetMasterPageCount() : pMod->GetPageCount());
+
+ for(sal_uInt16 nPgNum(0); nPgNum < nPgAnz; nPgNum++)
+ {
+ // over all pages
+ SdrPage* pPage = (bMaPg) ? pMod->GetMasterPage(nPgNum) : pMod->GetPage(nPgNum);
+ sal_uInt32 nObjAnz(pPage->GetObjCount());
+
+ // make sure OrdNums are correct
+ if(nObjAnz)
+ pPage->GetObj(0)->GetOrdNum();
+
+ for(sal_uInt32 nObjNum(nObjAnz); nObjNum > 0;)
+ {
+ nObjNum--;
+ SdrObject* pObj = pPage->GetObj(nObjNum);
+ SdrObjList* pSubOL = pObj->GetSubList();
+
+ // #104809# Test explicitely for group objects and 3d scenes
+ if(pSubOL && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dScene)))
+ {
+ if(ImpDelLayerCheck(pSubOL, nDelID))
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
+ pPage->RemoveObject(nObjNum);
+ if( !bUndo )
+ SdrObject::Free(pObj);
+ }
+ else
+ {
+ ImpDelLayerDelObjs(pSubOL, nDelID);
+ }
+ }
+ else
+ {
+ if(pObj->GetLayer() == nDelID)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj, true));
+ pPage->RemoveObject(nObjNum);
+ if( !bUndo )
+ SdrObject::Free(pObj);
+ }
+ }
+ }
+ }
+ bMaPg = sal_False;
+ }
+
+ if( bUndo )
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteLayer(nLayerNum, rLA, *pMod));
+ rLA.RemoveLayer(nLayerNum);
+ EndUndo();
+ }
+ else
+ {
+ delete rLA.RemoveLayer(nLayerNum);
+ }
+
+ pMod->SetChanged();
+ }
+}
+
+void SdrEditView::MoveLayer(const XubString& rName, USHORT nNewPos)
+{
+ SdrLayerAdmin& rLA=pMod->GetLayerAdmin();
+ SdrLayer* pLayer=rLA.GetLayer(rName,TRUE);
+ USHORT nLayerNum=rLA.GetLayerPos(pLayer);
+ if (nLayerNum!=SDRLAYER_NOTFOUND)
+ {
+ if( IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveLayer(nLayerNum,rLA,*pMod,nNewPos));
+ rLA.MoveLayer(nLayerNum,nNewPos);
+ pMod->SetChanged();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::EndUndo()
+{
+ // #i13033#
+ // Comparison changed to 1L since EndUndo() is called later now
+ // and EndUndo WILL change count to count-1
+ if(1L == pMod->GetUndoBracketLevel())
+ {
+ ImpBroadcastEdgesOfMarkedNodes();
+ }
+
+ // #i13033#
+ // moved to bottom to still have access to UNDOs inside of
+ // ImpBroadcastEdgesOfMarkedNodes()
+ pMod->EndUndo();
+}
+
+void SdrEditView::ImpBroadcastEdgesOfMarkedNodes()
+{
+ const List& rAllMarkedObjects = GetTransitiveHullOfMarkedObjects();
+
+ // #i13033#
+ // New mechanism to search for necessary disconnections for
+ // changed connectors inside the transitive hull of all at
+ // the beginning of UNDO selected objects
+ for(sal_uInt32 a(0L); a < rAllMarkedObjects.Count(); a++)
+ {
+ SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, (SdrObject*)rAllMarkedObjects.GetObject(a));
+
+ if(pEdge)
+ {
+ SdrObject* pObj1 = pEdge->GetConnectedNode(sal_False);
+ SdrObject* pObj2 = pEdge->GetConnectedNode(sal_True);
+
+ if(pObj1
+ && LIST_ENTRY_NOTFOUND == rAllMarkedObjects.GetPos(pObj1)
+ && !pEdge->CheckNodeConnection(sal_False))
+ {
+ if( IsUndoEnabled() )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
+ pEdge->DisconnectFromNode(sal_False);
+ }
+
+ if(pObj2
+ && LIST_ENTRY_NOTFOUND == rAllMarkedObjects.GetPos(pObj2)
+ && !pEdge->CheckNodeConnection(sal_True))
+ {
+ if( IsUndoEnabled() )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pEdge));
+ pEdge->DisconnectFromNode(sal_True);
+ }
+ }
+ }
+
+ ULONG nMarkedEdgeAnz = GetMarkedEdgesOfMarkedNodes().GetMarkCount();
+ USHORT i;
+
+ for (i=0; i<nMarkedEdgeAnz; i++) {
+ SdrMark* pEM = GetMarkedEdgesOfMarkedNodes().GetMark(i);
+ SdrObject* pEdgeTmp=pEM->GetMarkedSdrObj();
+ SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pEdgeTmp);
+ if (pEdge!=NULL) {
+ pEdge->SetEdgeTrackDirty();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// #### ### #### #### # #### # # # ##### # ##### ####
+// # # # # # # # # # # # # # # # #
+// #### # # ### ### # #### # # # # # #### ###
+// # # # # # # # # # # # # # # #
+// # ### #### #### # #### # #### # # # ##### ####
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::MarkListHasChanged()
+{
+ SdrMarkView::MarkListHasChanged();
+ bPossibilitiesDirty=TRUE;
+}
+
+void SdrEditView::ModelHasChanged()
+{
+ SdrMarkView::ModelHasChanged();
+ bPossibilitiesDirty=TRUE;
+}
+
+BOOL SdrEditView::IsResizeAllowed(BOOL bProp) const
+{
+ ForcePossibilities();
+ if (bResizeProtect) return FALSE;
+ if (bProp) return bResizePropAllowed;
+ return bResizeFreeAllowed;
+}
+
+BOOL SdrEditView::IsRotateAllowed(BOOL b90Deg) const
+{
+ ForcePossibilities();
+ if (bMoveProtect) return FALSE;
+ if (b90Deg) return bRotate90Allowed;
+ return bRotateFreeAllowed;
+}
+
+BOOL SdrEditView::IsMirrorAllowed(BOOL b45Deg, BOOL b90Deg) const
+{
+ ForcePossibilities();
+ if (bMoveProtect) return FALSE;
+ if (b90Deg) return bMirror90Allowed;
+ if (b45Deg) return bMirror45Allowed;
+ return bMirrorFreeAllowed && !bMoveProtect;
+}
+
+BOOL SdrEditView::IsTransparenceAllowed() const
+{
+ ForcePossibilities();
+ return bTransparenceAllowed;
+}
+
+BOOL SdrEditView::IsGradientAllowed() const
+{
+ ForcePossibilities();
+ return bGradientAllowed;
+}
+
+BOOL SdrEditView::IsShearAllowed() const
+{
+ ForcePossibilities();
+ if (bResizeProtect) return FALSE;
+ return bShearAllowed;
+}
+
+BOOL SdrEditView::IsEdgeRadiusAllowed() const
+{
+ ForcePossibilities();
+ return bEdgeRadiusAllowed;
+}
+
+BOOL SdrEditView::IsCrookAllowed(BOOL bNoContortion) const
+{
+ // CrookMode fehlt hier (weil kein Rotate bei Shear ...)
+ ForcePossibilities();
+ if (bNoContortion) {
+ if (!bRotateFreeAllowed) return FALSE; // Crook is nich
+ return !bMoveProtect && bMoveAllowed;
+ } else {
+ return !bResizeProtect && bContortionPossible;
+ }
+}
+
+BOOL SdrEditView::IsDistortAllowed(BOOL bNoContortion) const
+{
+ ForcePossibilities();
+ if (bNoContortion) {
+ return FALSE;
+ } else {
+ return !bResizeProtect && bContortionPossible;
+ }
+}
+
+BOOL SdrEditView::IsCombinePossible(BOOL bNoPolyPoly) const
+{
+ ForcePossibilities();
+ if (bNoPolyPoly) return bCombineNoPolyPolyPossible;
+ else return bCombinePossible;
+}
+
+BOOL SdrEditView::IsDismantlePossible(BOOL bMakeLines) const
+{
+ ForcePossibilities();
+ if (bMakeLines) return bDismantleMakeLinesPossible;
+ else return bDismantlePossible;
+}
+
+void SdrEditView::CheckPossibilities()
+{
+ if (bSomeObjChgdFlag) bPossibilitiesDirty=TRUE;
+
+ if(bSomeObjChgdFlag)
+ {
+ // This call IS necessary to correct the MarkList, in which
+ // no longer to the model belonging objects still can reside.
+ // These ones nned to be removed.
+ CheckMarked();
+ }
+
+ if (bPossibilitiesDirty) {
+ ImpResetPossibilityFlags();
+ SortMarkedObjects();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz!=0) {
+ bReverseOrderPossible=nMarkAnz>=2;
+
+ ULONG nMovableCount=0;
+ bGroupPossible=nMarkAnz>=2;
+ bCombinePossible=nMarkAnz>=2;
+ if (nMarkAnz==1) {
+ // bCombinePossible gruendlicher checken
+ // fehlt noch ...
+ const SdrObject* pObj=GetMarkedObjectByIndex(0);
+ //const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
+ BOOL bGroup=pObj->GetSubList()!=NULL;
+ BOOL bHasText=pObj->GetOutlinerParaObject()!=NULL;
+ if (bGroup || bHasText) {
+ bCombinePossible=TRUE;
+ }
+ }
+ bCombineNoPolyPolyPossible=bCombinePossible;
+ bDeletePossible=TRUE;
+ // Zu den Transformationen erstmal ja sagen
+ bMoveAllowed =TRUE;
+ bResizeFreeAllowed=TRUE;
+ bResizePropAllowed=TRUE;
+ bRotateFreeAllowed=TRUE;
+ bRotate90Allowed =TRUE;
+ bMirrorFreeAllowed=TRUE;
+ bMirror45Allowed =TRUE;
+ bMirror90Allowed =TRUE;
+ bShearAllowed =TRUE;
+ bEdgeRadiusAllowed=FALSE;
+ bContortionPossible=TRUE;
+ bCanConvToContour = TRUE;
+
+ // these ones are only allowed when single object is selected
+ bTransparenceAllowed = (nMarkAnz == 1);
+ bGradientAllowed = (nMarkAnz == 1);
+ if(bGradientAllowed)
+ {
+ // gradient depends on fillstyle
+ const SdrMark* pM = GetSdrMarkByIndex(0);
+ const SdrObject* pObj = pM->GetMarkedSdrObj();
+
+ // maybe group object, so get merged ItemSet
+ const SfxItemSet& rSet = pObj->GetMergedItemSet();
+ SfxItemState eState = rSet.GetItemState(XATTR_FILLSTYLE, FALSE);
+
+ if(SFX_ITEM_DONTCARE != eState)
+ {
+ // If state is not DONTCARE, test the item
+ XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
+
+ if(eFillStyle != XFILL_GRADIENT)
+ {
+ bGradientAllowed = FALSE;
+ }
+ }
+ }
+
+ BOOL bNoMovRotFound=FALSE;
+ const SdrPageView* pPV0=NULL;
+
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nm);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrPageView* pPV=pM->GetPageView();
+ if (pPV!=pPV0) {
+ if (pPV->IsReadOnly()) bReadOnly=TRUE;
+ pPV0=pPV;
+ }
+
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+ BOOL bMovPrt=pObj->IsMoveProtect();
+ BOOL bSizPrt=pObj->IsResizeProtect();
+ if (!bMovPrt && aInfo.bMoveAllowed) nMovableCount++; // Menge der MovableObjs zaehlen
+ if (bMovPrt) bMoveProtect=TRUE;
+ if (bSizPrt) bResizeProtect=TRUE;
+
+ // not allowed when not allowed at one object
+ if(!aInfo.bTransparenceAllowed)
+ bTransparenceAllowed = FALSE;
+
+ // Wenn einer was nicht kann, duerfen's alle nicht
+ if (!aInfo.bMoveAllowed ) bMoveAllowed =FALSE;
+ if (!aInfo.bResizeFreeAllowed) bResizeFreeAllowed=FALSE;
+ if (!aInfo.bResizePropAllowed) bResizePropAllowed=FALSE;
+ if (!aInfo.bRotateFreeAllowed) bRotateFreeAllowed=FALSE;
+ if (!aInfo.bRotate90Allowed ) bRotate90Allowed =FALSE;
+ if (!aInfo.bMirrorFreeAllowed) bMirrorFreeAllowed=FALSE;
+ if (!aInfo.bMirror45Allowed ) bMirror45Allowed =FALSE;
+ if (!aInfo.bMirror90Allowed ) bMirror90Allowed =FALSE;
+ if (!aInfo.bShearAllowed ) bShearAllowed =FALSE;
+ if (aInfo.bEdgeRadiusAllowed) bEdgeRadiusAllowed=TRUE;
+ if (aInfo.bNoContortion ) bContortionPossible=FALSE;
+ // Fuer Crook mit Contortion: Alle Objekte muessen
+ // Movable und Rotatable sein, ausser maximal 1
+ if (!bMoreThanOneNoMovRot) {
+ if (!aInfo.bMoveAllowed || !aInfo.bResizeFreeAllowed) {
+ bMoreThanOneNoMovRot=bNoMovRotFound;
+ bNoMovRotFound=TRUE;
+ }
+ }
+
+ // when one member cannot be converted, no conversion is possible
+ if(!aInfo.bCanConvToContour)
+ bCanConvToContour = FALSE;
+
+ // Ungroup
+ if (!bUnGroupPossible) bUnGroupPossible=pObj->GetSubList()!=NULL;
+ // ConvertToCurve: Wenn mind. einer konvertiert werden kann ist das ok.
+ if (aInfo.bCanConvToPath ) bCanConvToPath =TRUE;
+ if (aInfo.bCanConvToPoly ) bCanConvToPoly =TRUE;
+ if (aInfo.bCanConvToPathLineToArea) bCanConvToPathLineToArea=TRUE;
+ if (aInfo.bCanConvToPolyLineToArea) bCanConvToPolyLineToArea=TRUE;
+
+ // Combine/Dismantle
+ if(bCombinePossible)
+ {
+ bCombinePossible = ImpCanConvertForCombine(pObj);
+ bCombineNoPolyPolyPossible = bCombinePossible;
+ }
+
+ if (!bDismantlePossible) bDismantlePossible = ImpCanDismantle(pObj, sal_False);
+ if (!bDismantleMakeLinesPossible) bDismantleMakeLinesPossible = ImpCanDismantle(pObj, sal_True);
+ // OrthoDesiredOnMarked checken
+ if (!bOrthoDesiredOnMarked && !aInfo.bNoOrthoDesired) bOrthoDesiredOnMarked=TRUE;
+ // ImportMtf checken
+
+ if (!bImportMtfPossible) {
+ BOOL bGraf=HAS_BASE(SdrGrafObj,pObj);
+ BOOL bOle2=HAS_BASE(SdrOle2Obj,pObj);
+
+ if( bGraf && ((SdrGrafObj*)pObj)->HasGDIMetaFile() && !((SdrGrafObj*)pObj)->IsEPS() )
+ bImportMtfPossible = TRUE;
+
+ if (bOle2)
+ bImportMtfPossible=((SdrOle2Obj*)pObj)->GetObjRef().is();
+ }
+ }
+
+ bMoreThanOneNotMovable=nMovableCount<nMarkAnz-1;
+ bOneOrMoreMovable=nMovableCount!=0;
+ bGrpEnterPossible=bUnGroupPossible;
+ }
+ ImpCheckToTopBtmPossible();
+ ((SdrPolyEditView*)this)->ImpCheckPolyPossibilities();
+ bPossibilitiesDirty=FALSE;
+
+ if (bReadOnly) {
+ BOOL bMerker1=bGrpEnterPossible;
+ ImpResetPossibilityFlags();
+ bReadOnly=TRUE;
+ bGrpEnterPossible=bMerker1;
+ }
+ if (bMoveAllowed) {
+ // Verschieben von angeklebten Verbindern unterbinden
+ // Derzeit nur fuer Einfachselektion implementiert.
+ if (nMarkAnz==1) {
+ SdrObject* pObj=GetMarkedObjectByIndex(0);
+ SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
+ if (pEdge!=NULL) {
+ SdrObject* pNode1=pEdge->GetConnectedNode(TRUE);
+ SdrObject* pNode2=pEdge->GetConnectedNode(FALSE);
+ if (pNode1!=NULL || pNode2!=NULL) bMoveAllowed=FALSE;
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::ForceMarkedObjToAnotherPage()
+{
+ BOOL bFlg=FALSE;
+ for (ULONG nm=0; nm<GetMarkedObjectCount(); nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ Rectangle aObjRect(pObj->GetCurrentBoundRect());
+ Rectangle aPgRect(pM->GetPageView()->GetPageRect());
+ if (!aObjRect.IsOver(aPgRect)) {
+ BOOL bFnd=FALSE;
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ bFnd = aObjRect.IsOver(pPV->GetPageRect());
+ }
+
+ if(bFnd)
+ {
+ pM->GetPageView()->GetObjList()->RemoveObject(pObj->GetOrdNum());
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pPV->GetObjList()->InsertObject(pObj,CONTAINER_APPEND,&aReason);
+ pM->SetPageView(pPV);
+ InvalidateAllWin(aObjRect);
+ bFlg=TRUE;
+ }
+ }
+ }
+ if (bFlg) {
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::DeleteMarkedList(const SdrMarkList& rMark)
+{
+ if (rMark.GetMarkCount()!=0)
+ {
+ rMark.ForceSort();
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo();
+ const sal_uInt32 nMarkAnz(rMark.GetMarkCount());
+
+ if(nMarkAnz)
+ {
+ sal_uInt32 nm(0);
+ std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
+
+ if( bUndo )
+ {
+ for(nm = nMarkAnz; nm > 0;)
+ {
+ nm--;
+ SdrMark* pM = rMark.GetMark(nm);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+
+ // extra undo actions for changed connector which now may hold it's layouted path (SJ)
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
+ AddUndoActions( vConnectorUndoActions );
+
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
+ }
+ }
+
+ // Sicherstellen, dass die OrderNums stimmen:
+ rMark.GetMark(0)->GetMarkedSdrObj()->GetOrdNum();
+
+ std::vector< SdrObject* > aRemoved3DObjects;
+
+ for(nm = nMarkAnz; nm > 0;)
+ {
+ nm--;
+ SdrMark* pM = rMark.GetMark(nm);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+ SdrObjList* pOL = pObj->GetObjList(); //#52680#
+ const sal_uInt32 nOrdNum(pObj->GetOrdNumDirect());
+
+ bool bIs3D = dynamic_cast< E3dObject* >(pObj);
+ // set up a scene updater if object is a 3d object
+ if(bIs3D)
+ {
+ aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
+ }
+
+ pOL->RemoveObject(nOrdNum);
+
+ if( !bUndo )
+ {
+ if( bIs3D )
+ aRemoved3DObjects.push_back( pObj ); // may be needed later
+ else
+ SdrObject::Free(pObj);
+ }
+ }
+
+ // fire scene updaters
+ while(aUpdaters.size())
+ {
+ delete aUpdaters.back();
+ aUpdaters.pop_back();
+ }
+
+ if( !bUndo )
+ {
+ // now delete removed scene objects
+ while(aRemoved3DObjects.size())
+ {
+ SdrObject::Free( aRemoved3DObjects.back() );
+ aRemoved3DObjects.pop_back();
+ }
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+ }
+}
+
+void SdrEditView::DeleteMarkedObj()
+{
+ // #i110981# return when nothing is to be done at all
+ if(!GetMarkedObjectCount())
+ {
+ return;
+ }
+
+ // moved breaking action and undo start outside loop
+ BrkAction();
+ BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_DELETE);
+
+ // remove as long as something is selected. This allows to schedule objects for
+ // removal for a next run as needed
+ while(GetMarkedObjectCount())
+ {
+ // vector to remember the parents which may be empty after object removal
+ std::vector< SdrObject* > aParents;
+
+ {
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ const sal_uInt32 nCount(rMarkList.GetMarkCount());
+ sal_uInt32 a(0);
+
+ for(a = 0; a < nCount; a++)
+ {
+ // in the first run, add all found parents, but only once
+ SdrMark* pMark = rMarkList.GetMark(a);
+ SdrObject* pObject = pMark->GetMarkedSdrObj();
+ SdrObject* pParent = pObject->GetObjList()->GetOwnerObj();
+
+ if(pParent)
+ {
+ if(aParents.size())
+ {
+ std::vector< SdrObject* >::iterator aFindResult =
+ std::find(aParents.begin(), aParents.end(), pParent);
+
+ if(aFindResult == aParents.end())
+ {
+ aParents.push_back(pParent);
+ }
+ }
+ else
+ {
+ aParents.push_back(pParent);
+ }
+ }
+ }
+
+ if(aParents.size())
+ {
+ // in a 2nd run, remove all objects which may already be scheduled for
+ // removal. I am not sure if this can happen, but theoretically
+ // a to-be-removed object may already be the group/3DScene itself
+ for(a = 0; a < nCount; a++)
+ {
+ SdrMark* pMark = rMarkList.GetMark(a);
+ SdrObject* pObject = pMark->GetMarkedSdrObj();
+
+ std::vector< SdrObject* >::iterator aFindResult =
+ std::find(aParents.begin(), aParents.end(), pObject);
+
+ if(aFindResult != aParents.end())
+ {
+ aParents.erase(aFindResult);
+ }
+ }
+ }
+ }
+
+ // original stuff: remove selected objects. Handle clear will
+ // do something only once
+ DeleteMarkedList(GetMarkedObjectList());
+ GetMarkedObjectListWriteAccess().Clear();
+ aHdl.Clear();
+
+ while(aParents.size() && !GetMarkedObjectCount())
+ {
+ // iterate over remembered parents
+ SdrObject* pParent = aParents.back();
+ aParents.pop_back();
+
+ if(pParent->GetSubList() && 0 == pParent->GetSubList()->GetObjCount())
+ {
+ // we detected an empty parent, a candidate to leave group/3DScene
+ // if entered
+ if(GetSdrPageView()->GetAktGroup()
+ && GetSdrPageView()->GetAktGroup() == pParent)
+ {
+ GetSdrPageView()->LeaveOneGroup();
+ }
+
+ // schedule empty parent for removal
+ GetMarkedObjectListWriteAccess().InsertEntry(
+ SdrMark(pParent, GetSdrPageView()));
+ }
+ }
+ }
+
+ // end undo and change messaging moved at the end
+ EndUndo();
+ MarkListHasChanged();
+}
+
+void SdrEditView::CopyMarkedObj()
+{
+ SortMarkedObjects();
+
+ SdrMarkList aSourceObjectsForCopy(GetMarkedObjectList());
+ // Folgende Schleife Anstatt MarkList::Merge(), damit
+ // ich jeweils mein Flag an die MarkEntries setzen kann.
+ ULONG nEdgeAnz = GetEdgesOfMarkedNodes().GetMarkCount();
+ for (ULONG nEdgeNum=0; nEdgeNum<nEdgeAnz; nEdgeNum++) {
+ SdrMark aM(*GetEdgesOfMarkedNodes().GetMark(nEdgeNum));
+ aM.SetUser(1);
+ aSourceObjectsForCopy.InsertEntry(aM);
+ }
+ aSourceObjectsForCopy.ForceSort();
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ CloneList aCloneList;
+
+ const bool bUndo = IsUndoEnabled();
+
+ GetMarkedObjectListWriteAccess().Clear();
+ ULONG nCloneErrCnt=0;
+ ULONG nMarkAnz=aSourceObjectsForCopy.GetMarkCount();
+ ULONG nm;
+ for (nm=0; nm<nMarkAnz; nm++) {
+ SdrMark* pM=aSourceObjectsForCopy.GetMark(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj()->Clone();
+ if (pO!=NULL) {
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pM->GetPageView()->GetObjList()->InsertObject(pO,CONTAINER_APPEND,&aReason);
+
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoCopyObject(*pO));
+
+ SdrMark aME(*pM);
+ aME.SetMarkedSdrObj(pO);
+ aCloneList.AddPair(pM->GetMarkedSdrObj(), pO);
+
+ if (pM->GetUser()==0)
+ {
+ // Sonst war's nur eine mitzukierende Edge
+ GetMarkedObjectListWriteAccess().InsertEntry(aME);
+ }
+ } else {
+ nCloneErrCnt++;
+ }
+ }
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ aCloneList.CopyConnections();
+
+ if(0L != nCloneErrCnt)
+ {
+#ifdef DBG_UTIL
+ ByteString aStr("SdrEditView::CopyMarkedObj(): Fehler beim Clonen ");
+
+ if(nCloneErrCnt == 1)
+ {
+ aStr += "eines Zeichenobjekts.";
+ }
+ else
+ {
+ aStr += "von ";
+ aStr += ByteString::CreateFromInt32( nCloneErrCnt );
+ aStr += " Zeichenobjekten.";
+ }
+
+ aStr += " Objektverbindungen werden nicht mitkopiert.";
+ DBG_ERROR(aStr.GetBuffer());
+#endif
+ }
+ MarkListHasChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrEditView::InsertObjectAtView(SdrObject* pObj, SdrPageView& rPV, ULONG nOptions)
+{
+ if ((nOptions & SDRINSERT_SETDEFLAYER)!=0) {
+ SdrLayerID nLayer=rPV.GetPage()->GetLayerAdmin().GetLayerID(aAktLayer,TRUE);
+ if (nLayer==SDRLAYER_NOTFOUND) nLayer=0;
+ if (rPV.GetLockedLayers().IsSet(nLayer) || !rPV.GetVisibleLayers().IsSet(nLayer)) {
+ SdrObject::Free( pObj ); // Layer gesperrt oder nicht sichtbar
+ return FALSE;
+ }
+ pObj->NbcSetLayer(nLayer);
+ }
+ if ((nOptions & SDRINSERT_SETDEFATTR)!=0) {
+ if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
+ pObj->SetMergedItemSet(aDefaultAttr);
+ }
+ if (!pObj->IsInserted()) {
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ if ((nOptions & SDRINSERT_NOBROADCAST)!=0) {
+ rPV.GetObjList()->NbcInsertObject(pObj,CONTAINER_APPEND,&aReason);
+ } else {
+ rPV.GetObjList()->InsertObject(pObj,CONTAINER_APPEND,&aReason);
+ }
+ }
+ if( IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
+
+ if ((nOptions & SDRINSERT_DONTMARK)==0) {
+ if ((nOptions & SDRINSERT_ADDMARK)==0) UnmarkAllObj();
+ MarkObj(pObj,&rPV);
+ }
+ return TRUE;
+}
+
+void SdrEditView::ReplaceObjectAtView(SdrObject* pOldObj, SdrPageView& rPV, SdrObject* pNewObj, BOOL bMark)
+{
+ SdrObjList* pOL=pOldObj->GetObjList();
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pOldObj,*pNewObj));
+
+ if( IsObjMarked( pOldObj ) )
+ MarkObj( pOldObj, &rPV, TRUE /*unmark!*/ );
+
+ pOL->ReplaceObject(pNewObj,pOldObj->GetOrdNum());
+
+ if( !bUndo )
+ SdrObject::Free( pOldObj );
+
+ if (bMark) MarkObj(pNewObj,&rPV);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef WIN
+void SdrEditView::BegUndo() // Undo-Klammerung auf
+{
+ pMod->BegUndo();
+}
+
+void SdrEditView::BegUndo(const String& rComment) // Undo-Klammerung auf
+{
+ pMod->BegUndo(rComment);
+}
+
+void SdrEditView::BegUndo(const String& rComment, const String& rObjDescr,
+ SdrRepeatFunc eFunc) // Undo-Klammerung auf
+{
+ pMod->BegUndo(rComment,rObjDescr,eFunc);
+}
+
+void SdrEditView::BegUndo(SdrUndoGroup* pUndoGrp) // Undo-Klammerung auf
+{
+ pMod->BegUndo(pUndoGrp);
+}
+
+void SdrEditView::AddUndo(SdrUndoAction* pUndo) // Action hinzufuegen
+{
+ pMod->AddUndo(pUndo);
+}
+ // nur nach dem 1. BegUndo oder vor dem letzten EndUndo:
+void SdrEditView::SetUndoComment(const String& rComment)
+{
+ pMod->SetUndoComment(rComment);
+}
+
+
+void SdrEditView::SetUndoComment(const String& rComment,
+ const String& rObjDescr)
+{
+ pMod->SetUndoComment(rComment,rObjDescr);
+}
+#endif
+
+bool SdrEditView::IsUndoEnabled() const
+{
+ return pMod->IsUndoEnabled();
+}
+
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
new file mode 100644
index 000000000000..1ac6d0b89945
--- /dev/null
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -0,0 +1,1784 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdedtv.hxx>
+#include <math.h>
+
+#ifndef _MATH_H
+#define _MATH_H
+#endif
+#include <tools/bigint.hxx>
+#include <svl/itemiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <svx/rectenum.hxx>
+#include <svx/svxids.hrc> // fuer SID_ATTR_TRANSFORM_...
+#include <svx/svdattr.hxx> // fuer Get/SetGeoAttr
+#include "svditext.hxx"
+#include "svditer.hxx"
+#include <svx/svdtrans.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdlayer.hxx> // fuer MergeNotPersistAttr
+#include <svx/svdattrx.hxx> // fuer MergeNotPersistAttr
+#include <svx/svdetc.hxx> // fuer SearchOutlinerItems
+#include <svx/svdopath.hxx> // fuer Crook
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <editeng/eeitem.hxx>
+#include <svl/aeitem.hxx>
+#include <svl/whiter.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/e3dsceneupdater.hxx>
+#include <svx/obj3d.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, BOOL bCopy)
+{
+ DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() mit leerem Rect mach keinen Sinn");
+ if (rRect.IsEmpty()) return;
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz==0) return;
+ Rectangle aR0(GetMarkedObjRect());
+ DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() ist leer");
+ if (aR0.IsEmpty()) return;
+ long x0=aR0.Left();
+ long y0=aR0.Top();
+ long w0=aR0.Right()-x0;
+ long h0=aR0.Bottom()-y0;
+ long x1=rRect.Left();
+ long y1=rRect.Top();
+ long w1=rRect.Right()-x1;
+ long h1=rRect.Bottom()-y1;
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditPosSize,aStr);
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(aStr);
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ for (ULONG nm=0; nm<nAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+
+ Rectangle aR1(pO->GetSnapRect());
+ if (!aR1.IsEmpty())
+ {
+ if (aR1==aR0)
+ {
+ aR1=rRect;
+ }
+ else
+ { // aR1 von aR0 nach rRect transformieren
+ aR1.Move(-x0,-y0);
+ BigInt l(aR1.Left());
+ BigInt r(aR1.Right());
+ BigInt t(aR1.Top());
+ BigInt b(aR1.Bottom());
+ if (w0!=0) {
+ l*=w1; l/=w0;
+ r*=w1; r/=w0;
+ } else {
+ l=0; r=w1;
+ }
+ if (h0!=0) {
+ t*=h1; t/=h0;
+ b*=h1; b/=h0;
+ } else {
+ t=0; b=h1;
+ }
+ aR1.Left ()=long(l);
+ aR1.Right ()=long(r);
+ aR1.Top ()=long(t);
+ aR1.Bottom()=long(b);
+ aR1.Move(x1,y1);
+ }
+ pO->SetSnapRect(aR1);
+ } else {
+ DBG_ERROR("SetMarkedObjRect(): pObj->GetSnapRect() liefert leeres Rect");
+ }
+ }
+ if( bUndo )
+ EndUndo();
+}
+
+std::vector< SdrUndoAction* > SdrEditView::CreateConnectorUndo( SdrObject& rO )
+{
+ std::vector< SdrUndoAction* > vUndoActions;
+
+ if ( rO.GetBroadcaster() )
+ {
+ const SdrPage* pPage = rO.GetPage();
+ if ( pPage )
+ {
+ SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pPartObj = aIter.Next();
+ if ( pPartObj->ISA( SdrEdgeObj ) )
+ {
+ if ( ( pPartObj->GetConnectedNode( sal_False ) == &rO ) ||
+ ( pPartObj->GetConnectedNode( sal_True ) == &rO ) )
+ {
+ vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) );
+ }
+ }
+ }
+ }
+ }
+ return vUndoActions;
+}
+
+void SdrEditView::AddUndoActions( std::vector< SdrUndoAction* >& rUndoActions )
+{
+ std::vector< SdrUndoAction* >::iterator aUndoActionIter( rUndoActions.begin() );
+ while( aUndoActionIter != rUndoActions.end() )
+ AddUndo( *aUndoActionIter++ );
+}
+
+void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr(ImpGetResStr(STR_EditMove));
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+ // benoetigt eigene UndoGroup wegen Parameter
+ BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ {
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
+ AddUndoActions( vConnectorUndoActions );
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz));
+ }
+ pO->Move(rSiz);
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditResize,aStr);
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ {
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
+ AddUndoActions( vConnectorUndoActions );
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+ }
+ pO->Resize(rRef,xFact,yFact);
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+long SdrEditView::GetMarkedObjRotate() const
+{
+ BOOL b1st=TRUE;
+ BOOL bOk=TRUE;
+ long nWink=0;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz && bOk; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ long nWink2=pO->GetRotateAngle();
+ if (b1st) nWink=nWink2;
+ else if (nWink2!=nWink) bOk=FALSE;
+ b1st=FALSE;
+ }
+ if (!bOk) nWink=0;
+ return nWink;
+}
+
+void SdrEditView::RotateMarkedObj(const Point& rRef, long nWink, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditRotate,aStr);
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ double nSin=sin(nWink*nPi180);
+ double nCos=cos(nWink*nPi180);
+ const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
+
+ if(nMarkAnz)
+ {
+ std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
+
+ for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
+ {
+ SdrMark* pM = GetSdrMarkByIndex(nm);
+ SdrObject* pO = pM->GetMarkedSdrObj();
+
+ if( bUndo )
+ {
+ // extra undo actions for changed connector which now may hold it's layouted path (SJ)
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
+ AddUndoActions( vConnectorUndoActions );
+
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+ }
+
+ // set up a scene updater if object is a 3d object
+ if(dynamic_cast< E3dObject* >(pO))
+ {
+ aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
+ }
+
+ pO->Rotate(rRef,nWink,nSin,nCos);
+ }
+
+ // fire scene updaters
+ while(aUpdaters.size())
+ {
+ delete aUpdaters.back();
+ aUpdaters.pop_back();
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr;
+ Point aDif(rRef2-rRef1);
+ if (aDif.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori,aStr);
+ else if (aDif.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert,aStr);
+ else if (Abs(aDif.X())==Abs(aDif.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag,aStr);
+ else ImpTakeDescriptionStr(STR_EditMirrorFree,aStr);
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
+
+ if(nMarkAnz)
+ {
+ std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
+
+ for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
+ {
+ SdrMark* pM = GetSdrMarkByIndex(nm);
+ SdrObject* pO = pM->GetMarkedSdrObj();
+
+ if( bUndo )
+ {
+ // extra undo actions for changed connector which now may hold it's layouted path (SJ)
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
+ AddUndoActions( vConnectorUndoActions );
+
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+ }
+
+ // set up a scene updater if object is a 3d object
+ if(dynamic_cast< E3dObject* >(pO))
+ {
+ aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
+ }
+
+ pO->Mirror(rRef1,rRef2);
+ }
+
+ // fire scene updaters
+ while(aUpdaters.size())
+ {
+ delete aUpdaters.back();
+ aUpdaters.pop_back();
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+void SdrEditView::MirrorMarkedObjHorizontal(BOOL bCopy)
+{
+ Point aCenter(GetMarkedObjRect().Center());
+ Point aPt2(aCenter);
+ aPt2.Y()++;
+ MirrorMarkedObj(aCenter,aPt2,bCopy);
+}
+
+void SdrEditView::MirrorMarkedObjVertical(BOOL bCopy)
+{
+ Point aCenter(GetMarkedObjRect().Center());
+ Point aPt2(aCenter);
+ aPt2.X()++;
+ MirrorMarkedObj(aCenter,aPt2,bCopy);
+}
+
+long SdrEditView::GetMarkedObjShear() const
+{
+ BOOL b1st=TRUE;
+ BOOL bOk=TRUE;
+ long nWink=0;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz && bOk; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ long nWink2=pO->GetShearAngle();
+ if (b1st) nWink=nWink2;
+ else if (nWink2!=nWink) bOk=FALSE;
+ b1st=FALSE;
+ }
+ if (nWink>SDRMAXSHEAR) nWink=SDRMAXSHEAR;
+ if (nWink<-SDRMAXSHEAR) nWink=-SDRMAXSHEAR;
+ if (!bOk) nWink=0;
+ return nWink;
+}
+
+void SdrEditView::ShearMarkedObj(const Point& rRef, long nWink, bool bVShear, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditShear,aStr);
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ double nTan=tan(nWink*nPi180);
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ {
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
+ AddUndoActions( vConnectorUndoActions );
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+ }
+ pO->Shear(rRef,nWink,nTan,bVShear);
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad,
+ SdrCrookMode eMode, BOOL bVertical, BOOL bNoContortion, BOOL bRotate, const Rectangle& rMarkRect)
+{
+ SdrPathObj* pPath=PTR_CAST(SdrPathObj,pO);
+ BOOL bDone = FALSE;
+
+ if(pPath!=NULL && !bNoContortion)
+ {
+ XPolyPolygon aXPP(pPath->GetPathPoly());
+ switch (eMode) {
+ case SDRCROOK_ROTATE : CrookRotatePoly (aXPP,rRef,rRad,bVertical); break;
+ case SDRCROOK_SLANT : CrookSlantPoly (aXPP,rRef,rRad,bVertical); break;
+ case SDRCROOK_STRETCH: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break;
+ } // switch
+ pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
+ bDone = TRUE;
+ }
+
+ if(!bDone && !pPath && pO->IsPolyObj() && 0L != pO->GetPointCount())
+ {
+ // FuerPolyObj's, aber NICHT fuer SdrPathObj's, z.B. fuer's Bemassungsobjekt
+ sal_uInt32 nPtAnz(pO->GetPointCount());
+ XPolygon aXP((sal_uInt16)nPtAnz);
+ sal_uInt32 nPtNum;
+
+ for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
+ {
+ Point aPt(pO->GetPoint(nPtNum));
+ aXP[(sal_uInt16)nPtNum]=aPt;
+ }
+
+ switch (eMode)
+ {
+ case SDRCROOK_ROTATE : CrookRotatePoly (aXP,rRef,rRad,bVertical); break;
+ case SDRCROOK_SLANT : CrookSlantPoly (aXP,rRef,rRad,bVertical); break;
+ case SDRCROOK_STRETCH: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break;
+ }
+
+ for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
+ {
+ // hier koennte man vieleicht auch mal das Broadcasting optimieren
+ // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch
+ pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
+ }
+
+ bDone = TRUE;
+ }
+
+ if(!bDone)
+ {
+ // Fuer alle anderen oder wenn bNoContortion
+ Point aCtr0(pO->GetSnapRect().Center());
+ Point aCtr1(aCtr0);
+ sal_Bool bRotOk(sal_False);
+ double nSin(0.0), nCos(1.0);
+ double nWink(0.0);
+
+ if(0 != rRad.X() && 0 != rRad.Y())
+ {
+ bRotOk = bRotate;
+
+ switch (eMode)
+ {
+ case SDRCROOK_ROTATE : nWink=CrookRotateXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break;
+ case SDRCROOK_SLANT : nWink=CrookSlantXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); break;
+ case SDRCROOK_STRETCH: nWink=CrookStretchXPoint(aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break;
+ }
+ }
+
+ aCtr1 -= aCtr0;
+
+ if(bRotOk)
+ pO->Rotate(aCtr0, Round(nWink/nPi180), nSin, nCos);
+
+ pO->Move(Size(aCtr1.X(),aCtr1.Y()));
+ }
+}
+
+void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode,
+ bool bVertical, bool bNoContortion, bool bCopy)
+{
+ Rectangle aMarkRect(GetMarkedObjRect());
+ const bool bUndo = IsUndoEnabled();
+
+ bool bRotate=bNoContortion && eMode==SDRCROOK_ROTATE && IsRotateAllowed(FALSE);
+
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(bNoContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+
+ const SdrObjList* pOL=pO->GetSubList();
+ if (bNoContortion || pOL==NULL) {
+ ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
+ } else {
+ SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
+ while (aIter.IsMore()) {
+ SdrObject* pO1=aIter.Next();
+ ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
+ }
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
+void SdrEditView::ImpDistortObj(SdrObject* pO, const Rectangle& rRef, const XPolygon& rDistortedRect, BOOL bNoContortion)
+{
+ SdrPathObj* pPath = PTR_CAST(SdrPathObj, pO);
+
+ if(!bNoContortion && pPath)
+ {
+ XPolyPolygon aXPP(pPath->GetPathPoly());
+ aXPP.Distort(rRef, rDistortedRect);
+ pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
+ }
+ else if(pO->IsPolyObj())
+ {
+ // z.B. fuer's Bemassungsobjekt
+ sal_uInt32 nPtAnz(pO->GetPointCount());
+ XPolygon aXP((sal_uInt16)nPtAnz);
+ sal_uInt32 nPtNum;
+
+ for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
+ {
+ Point aPt(pO->GetPoint(nPtNum));
+ aXP[(sal_uInt16)nPtNum]=aPt;
+ }
+
+ aXP.Distort(rRef, rDistortedRect);
+
+ for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
+ {
+ // hier koennte man vieleicht auch mal das Broadcasting optimieren
+ // ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch
+ pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
+ }
+ }
+}
+
+void SdrEditView::DistortMarkedObj(const Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditDistort,aStr);
+ if (bCopy)
+ aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr);
+ }
+
+ if (bCopy)
+ CopyMarkedObj();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ if( bUndo )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+
+ Rectangle aRefRect(rRef);
+ XPolygon aRefPoly(rDistortedRect);
+ const SdrObjList* pOL=pO->GetSubList();
+ if (bNoContortion || pOL==NULL) {
+ ImpDistortObj(pO,aRefRect,aRefPoly,bNoContortion);
+ } else {
+ SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
+ while (aIter.IsMore()) {
+ SdrObject* pO1=aIter.Next();
+ ImpDistortObj(pO1,aRefRect,aRefPoly,bNoContortion);
+ }
+ }
+ }
+ if( bUndo )
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, BOOL /*bReplaceAll*/)
+{
+ // bReplaceAll hat hier keinerlei Wirkung
+ Rectangle aAllSnapRect(GetMarkedObjRect());
+ const SfxPoolItem *pPoolItem=NULL;
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
+ SetRef1(Point(n,GetRef1().Y()));
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
+ SetRef1(Point(GetRef1().X(),n));
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
+ SetRef2(Point(n,GetRef2().Y()));
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
+ SetRef2(Point(GetRef2().X(),n));
+ }
+ long nAllPosX=0; BOOL bAllPosX=FALSE;
+ long nAllPosY=0; BOOL bAllPosY=FALSE;
+ long nAllWdt=0; BOOL bAllWdt=FALSE;
+ long nAllHgt=0; BOOL bAllHgt=FALSE;
+ BOOL bDoIt=FALSE;
+ if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ nAllPosX=((const SdrAllPositionXItem*)pPoolItem)->GetValue();
+ bAllPosX=TRUE; bDoIt=TRUE;
+ }
+ if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ nAllPosY=((const SdrAllPositionYItem*)pPoolItem)->GetValue();
+ bAllPosY=TRUE; bDoIt=TRUE;
+ }
+ if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ nAllWdt=((const SdrAllSizeWidthItem*)pPoolItem)->GetValue();
+ bAllWdt=TRUE; bDoIt=TRUE;
+ }
+ if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ nAllHgt=((const SdrAllSizeHeightItem*)pPoolItem)->GetValue();
+ bAllHgt=TRUE; bDoIt=TRUE;
+ }
+ if (bDoIt) {
+ Rectangle aRect(aAllSnapRect); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!!
+ if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0);
+ if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top());
+ if (bAllWdt) aRect.Right()=aAllSnapRect.Left()+nAllWdt;
+ if (bAllHgt) aRect.Bottom()=aAllSnapRect.Top()+nAllHgt;
+ SetMarkedObjRect(aRect);
+ }
+ if (rAttr.GetItemState(SDRATTR_RESIZEXALL,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ Fraction aXFact=((const SdrResizeXAllItem*)pPoolItem)->GetValue();
+ ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1));
+ }
+ if (rAttr.GetItemState(SDRATTR_RESIZEYALL,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ Fraction aYFact=((const SdrResizeYAllItem*)pPoolItem)->GetValue();
+ ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact);
+ }
+ if (rAttr.GetItemState(SDRATTR_ROTATEALL,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long nAngle=((const SdrRotateAllItem*)pPoolItem)->GetValue();
+ RotateMarkedObj(aAllSnapRect.Center(),nAngle);
+ }
+ if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long nAngle=((const SdrHorzShearAllItem*)pPoolItem)->GetValue();
+ ShearMarkedObj(aAllSnapRect.Center(),nAngle,FALSE);
+ }
+ if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long nAngle=((const SdrVertShearAllItem*)pPoolItem)->GetValue();
+ ShearMarkedObj(aAllSnapRect.Center(),nAngle,TRUE);
+ }
+
+ const bool bUndo = IsUndoEnabled();
+
+ // Todo: WhichRange nach Notwendigkeit ueberpruefen.
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ const SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ //const SdrPageView* pPV=pM->GetPageView();
+ if( bUndo )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ pObj->ApplyNotPersistAttr(rAttr);
+ }
+}
+
+void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, BOOL /*bOnlyHardAttr*/) const
+{
+ // bOnlyHardAttr hat hier keinerlei Wirkung
+ // Hier muss ausserdem noch der Nullpunkt und
+ // die PvPos berueksichtigt werden.
+ Rectangle aAllSnapRect(GetMarkedObjRect()); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!!
+ long nAllSnapPosX=aAllSnapRect.Left();
+ long nAllSnapPosY=aAllSnapRect.Top();
+ long nAllSnapWdt=aAllSnapRect.GetWidth()-1;
+ long nAllSnapHgt=aAllSnapRect.GetHeight()-1;
+ // koennte mal zu CheckPossibilities mit rein
+ BOOL bMovProtect=FALSE,bMovProtectDC=FALSE;
+ BOOL bSizProtect=FALSE,bSizProtectDC=FALSE;
+ BOOL bPrintable =TRUE ,bPrintableDC=FALSE;
+ BOOL bVisible = TRUE, bVisibleDC=FALSE;
+ SdrLayerID nLayerId=0; BOOL bLayerDC=FALSE;
+ XubString aObjName; BOOL bObjNameDC=FALSE,bObjNameSet=FALSE;
+ long nSnapPosX=0; BOOL bSnapPosXDC=FALSE;
+ long nSnapPosY=0; BOOL bSnapPosYDC=FALSE;
+ long nSnapWdt=0; BOOL bSnapWdtDC=FALSE;
+ long nSnapHgt=0; BOOL bSnapHgtDC=FALSE;
+ long nLogicWdt=0; BOOL bLogicWdtDC=FALSE,bLogicWdtDiff=FALSE;
+ long nLogicHgt=0; BOOL bLogicHgtDC=FALSE,bLogicHgtDiff=FALSE;
+ long nRotAngle=0; BOOL bRotAngleDC=FALSE;
+ long nShrAngle=0; BOOL bShrAngleDC=FALSE;
+ Rectangle aSnapRect;
+ Rectangle aLogicRect;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nm);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (nm==0) {
+ nLayerId=pObj->GetLayer();
+ bMovProtect=pObj->IsMoveProtect();
+ bSizProtect=pObj->IsResizeProtect();
+ bPrintable =pObj->IsPrintable();
+ bVisible = pObj->IsVisible();
+ Rectangle aSnapRect2(pObj->GetSnapRect());
+ Rectangle aLogicRect2(pObj->GetLogicRect());
+ nSnapPosX=aSnapRect2.Left();
+ nSnapPosY=aSnapRect2.Top();
+ nSnapWdt=aSnapRect2.GetWidth()-1;
+ nSnapHgt=aSnapRect2.GetHeight()-1;
+ nLogicWdt=aLogicRect2.GetWidth()-1;
+ nLogicHgt=aLogicRect2.GetHeight()-1;
+ bLogicWdtDiff=nLogicWdt!=nSnapWdt;
+ bLogicHgtDiff=nLogicHgt!=nSnapHgt;
+ nRotAngle=pObj->GetRotateAngle();
+ nShrAngle=pObj->GetShearAngle();
+ } else {
+ if (!bLayerDC && nLayerId !=pObj->GetLayer()) bLayerDC=TRUE;
+ if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC=TRUE;
+ if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC=TRUE;
+ if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC=TRUE;
+ if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=TRUE;
+ if (!bRotAngleDC && nRotAngle !=pObj->GetRotateAngle()) bRotAngleDC=TRUE;
+ if (!bShrAngleDC && nShrAngle !=pObj->GetShearAngle()) bShrAngleDC=TRUE;
+ if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) {
+ aSnapRect=pObj->GetSnapRect();
+ if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=TRUE;
+ if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=TRUE;
+ if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=TRUE;
+ if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=TRUE;
+ }
+ if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) {
+ aLogicRect=pObj->GetLogicRect();
+ if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=TRUE;
+ if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=TRUE;
+ if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=TRUE;
+ if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=TRUE;
+ }
+ }
+ if (!bObjNameDC ) {
+ if (!bObjNameSet) {
+ aObjName=pObj->GetName();
+ } else {
+ if (aObjName!=pObj->GetName()) bObjNameDC=TRUE;
+ }
+ }
+ }
+
+ if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX));
+ if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY));
+ if (bSnapWdtDC || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt));
+ if (bSnapHgtDC || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt));
+
+ // Items fuer reine Transformationen
+ rAttr.Put(SdrMoveXItem());
+ rAttr.Put(SdrMoveYItem());
+ rAttr.Put(SdrResizeXOneItem());
+ rAttr.Put(SdrResizeYOneItem());
+ rAttr.Put(SdrRotateOneItem());
+ rAttr.Put(SdrHorzShearOneItem());
+ rAttr.Put(SdrVertShearOneItem());
+
+ if (nMarkAnz>1) {
+ rAttr.Put(SdrResizeXAllItem());
+ rAttr.Put(SdrResizeYAllItem());
+ rAttr.Put(SdrRotateAllItem());
+ rAttr.Put(SdrHorzShearAllItem());
+ rAttr.Put(SdrVertShearAllItem());
+ }
+
+ if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
+ {
+ rAttr.Put(SdrTransformRef1XItem(GetRef1().X()));
+ rAttr.Put(SdrTransformRef1YItem(GetRef1().Y()));
+ }
+
+ if(eDragMode == SDRDRAG_MIRROR)
+ {
+ rAttr.Put(SdrTransformRef2XItem(GetRef2().X()));
+ rAttr.Put(SdrTransformRef2YItem(GetRef2().Y()));
+ }
+}
+
+SfxItemSet SdrEditView::GetAttrFromMarked(BOOL bOnlyHardAttr) const
+{
+ SfxItemSet aSet(pMod->GetItemPool());
+ MergeAttrFromMarked(aSet,bOnlyHardAttr);
+ //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
+ //so we do not set them here
+ // #i32448#
+ // Do not disable, but clear the items.
+ aSet.ClearItem(EE_FEATURE_TAB);
+ aSet.ClearItem(EE_FEATURE_LINEBR);
+ aSet.ClearItem(EE_FEATURE_NOTCONV);
+ aSet.ClearItem(EE_FEATURE_FIELD);
+ return aSet;
+}
+
+void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, BOOL bOnlyHardAttr) const
+{
+ sal_uInt32 nMarkAnz(GetMarkedObjectCount());
+
+ for(sal_uInt32 a(0); a < nMarkAnz; a++)
+ {
+ // #80277# merging was done wrong in the prev version
+ //const SfxItemSet& rSet = GetMarkedObjectByIndex()->GetItemSet();
+ const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet();
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+
+ while(nWhich)
+ {
+ if(!bOnlyHardAttr)
+ {
+ if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE))
+ rAttr.InvalidateItem(nWhich);
+ else
+ rAttr.MergeValue(rSet.Get(nWhich), TRUE);
+ }
+ else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, FALSE))
+ {
+ const SfxPoolItem& rItem = rSet.Get(nWhich);
+ rAttr.MergeValue(rItem, TRUE);
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+}
+
+void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, BOOL bReplaceAll)
+{
+ if (AreObjectsMarked())
+ {
+#ifdef DBG_UTIL
+ {
+ BOOL bHasEEFeatureItems=FALSE;
+ SfxItemIter aIter(rAttr);
+ const SfxPoolItem* pItem=aIter.FirstItem();
+ while (!bHasEEFeatureItems && pItem!=NULL) {
+ if (!IsInvalidItem(pItem)) {
+ USHORT nW=pItem->Which();
+ if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=TRUE;
+ }
+ pItem=aIter.NextItem();
+ }
+ if(bHasEEFeatureItems)
+ {
+ String aMessage;
+ aMessage.AppendAscii("SdrEditView::SetAttrToMarked(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten.");
+ InfoBox(NULL, aMessage).Execute();
+ }
+ }
+#endif
+
+ // #103836# if the user thets character attributes to the complete shape,
+ // we want to remove all hard set character attributes with same
+ // which ids from the text. We do that later but here we remember
+ // all character attribute which id's that are set.
+ std::vector<sal_uInt16> aCharWhichIds;
+ {
+ SfxItemIter aIter(rAttr);
+ const SfxPoolItem* pItem=aIter.FirstItem();
+ while( pItem!=NULL )
+ {
+ if (!IsInvalidItem(pItem))
+ {
+ sal_uInt16 nWhich = pItem->Which();
+ if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END)
+ aCharWhichIds.push_back( nWhich );
+ }
+ pItem=aIter.NextItem();
+ }
+ }
+
+ // Joe, 2.7.98: Damit Undo nach Format.Standard auch die Textattribute korrekt restauriert
+ BOOL bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll);
+
+ // AW 030100: save additional geom info when para or char attributes
+ // are changed and the geom form of the text object might be changed
+ BOOL bPossibleGeomChange(FALSE);
+ SfxWhichIter aIter(rAttr);
+ UINT16 nWhich = aIter.FirstWhich();
+ while(!bPossibleGeomChange && nWhich)
+ {
+ SfxItemState eState = rAttr.GetItemState(nWhich);
+ if(eState == SFX_ITEM_SET)
+ {
+ if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME)
+ || nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL
+ || nWhich == SDRATTR_3DOBJ_BACKSCALE
+ || nWhich == SDRATTR_3DOBJ_DEPTH
+ || nWhich == SDRATTR_3DOBJ_END_ANGLE
+ || nWhich == SDRATTR_3DSCENE_DISTANCE)
+ {
+ bPossibleGeomChange = TRUE;
+ }
+ }
+ nWhich = aIter.NextWhich();
+ }
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
+ BegUndo(aStr);
+ }
+
+ const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
+ std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
+
+ // create ItemSet without SFX_ITEM_DONTCARE. Put()
+ // uses it's second parameter (bInvalidAsDefault) to
+ // remove all such items to set them to default.
+ SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
+ aAttr.Put(rAttr, TRUE);
+
+ // #i38135#
+ bool bResetAnimationTimer(false);
+
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+
+ if( bUndo )
+ {
+ std::vector< SdrUndoAction* > vConnectorUndoActions;
+ SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj );
+ if ( pEdgeObj )
+ bPossibleGeomChange = TRUE;
+ else if( bUndo )
+ vConnectorUndoActions = CreateConnectorUndo( *pObj );
+
+ AddUndoActions( vConnectorUndoActions );
+ }
+
+ // new geometry undo
+ if(bPossibleGeomChange && bUndo)
+ {
+ // save position and size of obect, too
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+ }
+
+ if( bUndo )
+ {
+ // #i8508#
+ // If this is a text object also rescue the OutlinerParaObject since
+ // applying attributes to the object may change text layout when
+ // multiple portions exist with multiple formats. If a OutlinerParaObject
+ // really exists and needs to be rescued is evaluated in the undo
+ // implementation itself.
+ const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != 0;
+
+ // add attribute undo
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,FALSE,bHasEEItems || bPossibleGeomChange || bRescueText));
+ }
+
+ // set up a scxene updater if object is a 3d object
+ if(dynamic_cast< E3dObject* >(pObj))
+ {
+ aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
+ }
+
+ // set attributes at object
+ pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
+
+ if(pObj->ISA(SdrTextObj))
+ {
+ SdrTextObj* pTextObj = ((SdrTextObj*)pObj);
+
+ if(0 != aCharWhichIds.size())
+ {
+ Rectangle aOldBoundRect = pTextObj->GetLastBoundRect();
+
+ // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
+ pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds );
+
+ // object has changed, should be called form
+ // RemoveOutlinerCharacterAttribs. This will change when the text
+ // object implementation changes.
+ pTextObj->SetChanged();
+
+ pTextObj->BroadcastObjectChange();
+ pTextObj->SendUserCall(SDRUSERCALL_CHGATTR, aOldBoundRect);
+ }
+ }
+
+ // #i38495#
+ if(!bResetAnimationTimer)
+ {
+ if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact())
+ {
+ bResetAnimationTimer = true;
+ }
+ }
+ }
+
+ // fire scene updaters
+ while(aUpdaters.size())
+ {
+ delete aUpdaters.back();
+ aUpdaters.pop_back();
+ }
+
+ // #i38135#
+ if(bResetAnimationTimer)
+ {
+ SetAnimationTimer(0L);
+ }
+
+ // besser vorher checken, was gemacht werden soll:
+ // pObj->SetAttr() oder SetNotPersistAttr()
+ // !!! fehlende Implementation !!!
+ SetNotPersistAttrToMarked(rAttr,bReplaceAll);
+
+ if( bUndo )
+ EndUndo();
+ }
+}
+
+SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const
+{
+ SfxStyleSheet* pRet=NULL;
+ BOOL b1st=TRUE;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet();
+ if (b1st) pRet=pSS;
+ else if (pRet!=pSS) return NULL; // verschiedene StyleSheets
+ b1st=FALSE;
+ }
+ return pRet;
+}
+
+void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ if (AreObjectsMarked())
+ {
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ XubString aStr;
+ if (pStyleSheet!=NULL)
+ ImpTakeDescriptionStr(STR_EditSetStylesheet,aStr);
+ else
+ ImpTakeDescriptionStr(STR_EditDelStylesheet,aStr);
+ BegUndo(aStr);
+ }
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ if( bUndo )
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj()));
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true));
+ }
+ pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ }
+
+ if( bUndo )
+ EndUndo();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* new interface src537 */
+BOOL SdrEditView::GetAttributes(SfxItemSet& rTargetSet, BOOL bOnlyHardAttr) const
+{
+ if(GetMarkedObjectCount())
+ {
+ rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), FALSE);
+ return TRUE;
+ }
+ else
+ {
+ return SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr);
+ }
+}
+
+BOOL SdrEditView::SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll)
+{
+ if (GetMarkedObjectCount()!=0) {
+ SetAttrToMarked(rSet,bReplaceAll);
+ return TRUE;
+ } else {
+ return SdrMarkView::SetAttributes(rSet,bReplaceAll);
+ }
+}
+
+SfxStyleSheet* SdrEditView::GetStyleSheet() const // SfxStyleSheet* SdrEditView::GetStyleSheet(BOOL& rOk) const
+{
+ if (GetMarkedObjectCount()!=0) {
+ //rOk=TRUE;
+ return GetStyleSheetFromMarked();
+ } else {
+ return SdrMarkView::GetStyleSheet(); // SdrMarkView::GetStyleSheet(rOk);
+ }
+}
+
+BOOL SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ if (GetMarkedObjectCount()!=0) {
+ SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr);
+ return TRUE;
+ } else {
+ return SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SfxItemSet SdrEditView::GetGeoAttrFromMarked() const
+{
+ SfxItemSet aRetSet(pMod->GetItemPool(), // SID_ATTR_TRANSFORM_... aus s:svxids.hrc
+ SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE,
+ SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS,
+ 0);
+ if (AreObjectsMarked()) {
+ SfxItemSet aMarkAttr(GetAttrFromMarked(FALSE)); // wg. AutoGrowHeight und Eckenradius
+ Rectangle aRect(GetMarkedObjRect());
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->LogicToPagePos(aRect);
+ }
+
+ // Position
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X,aRect.Left()));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y,aRect.Top()));
+
+ // Groesse
+ long nResizeRefX=aRect.Left();
+ long nResizeRefY=aRect.Top();
+ if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Resize
+ nResizeRefX=aRef1.X();
+ nResizeRefY=aRef1.Y();
+ }
+ aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH,aRect.Right()-aRect.Left()));
+ aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT,aRect.Bottom()-aRect.Top()));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X,nResizeRefX));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y,nResizeRefY));
+
+ Point aRotateAxe(aRef1);
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->LogicToPagePos(aRotateAxe);
+ }
+
+ // Drehung
+ long nRotateRefX=aRect.Center().X();
+ long nRotateRefY=aRect.Center().Y();
+ if (eDragMode==SDRDRAG_ROTATE) {
+ nRotateRefX=aRotateAxe.X();
+ nRotateRefY=aRotateAxe.Y();
+ }
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,GetMarkedObjRotate()));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,nRotateRefX));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y,nRotateRefY));
+
+ // Shear
+ long nShearRefX=aRect.Left();
+ long nShearRefY=aRect.Bottom();
+ if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Shear
+ nShearRefX=aRotateAxe.X();
+ nShearRefY=aRotateAxe.Y();
+ }
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,GetMarkedObjShear()));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,nShearRefX));
+ aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,nShearRefY));
+
+ // Pruefen der einzelnen Objekte, ob Objekte geschuetzt sind
+ const SdrMarkList& rMarkList=GetMarkedObjectList();
+ ULONG nMarkCount=rMarkList.GetMarkCount();
+ SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
+ BOOL bPosProt=pObj->IsMoveProtect();
+ BOOL bSizProt=pObj->IsResizeProtect();
+ BOOL bPosProtDontCare=FALSE;
+ BOOL bSizProtDontCare=FALSE;
+ for (ULONG i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); i++) {
+ pObj=rMarkList.GetMark(i)->GetMarkedSdrObj();
+ if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=TRUE;
+ if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=TRUE;
+ }
+
+ // InvalidateItem setzt das Item auf DONT_CARE
+ if (bPosProtDontCare) {
+ aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS);
+ } else {
+ aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS,bPosProt));
+ }
+ if (bSizProtDontCare) {
+ aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE);
+ } else {
+ aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE,bSizProt));
+ }
+
+ SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH);
+ BOOL bAutoGrow=((SdrTextAutoGrowWidthItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
+ if (eState==SFX_ITEM_DONTCARE) {
+ aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH);
+ } else if (eState==SFX_ITEM_SET) {
+ aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH,bAutoGrow));
+ }
+
+ eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT);
+ bAutoGrow=((SdrTextAutoGrowHeightItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
+ if (eState==SFX_ITEM_DONTCARE) {
+ aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT);
+ } else if (eState==SFX_ITEM_SET) {
+ aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT,bAutoGrow));
+ }
+
+ eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS);
+ long nRadius=((SdrEckenradiusItem&)(aMarkAttr.Get(SDRATTR_ECKENRADIUS))).GetValue();
+ if (eState==SFX_ITEM_DONTCARE) {
+ aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS);
+ } else if (eState==SFX_ITEM_SET) {
+ aRetSet.Put(SdrEckenradiusItem(nRadius));
+ }
+
+ }
+ return aRetSet;
+}
+
+Point ImpGetPoint(Rectangle aRect, RECT_POINT eRP)
+{
+ switch(eRP) {
+ case RP_LT: return aRect.TopLeft();
+ case RP_MT: return aRect.TopCenter();
+ case RP_RT: return aRect.TopRight();
+ case RP_LM: return aRect.LeftCenter();
+ case RP_MM: return aRect.Center();
+ case RP_RM: return aRect.RightCenter();
+ case RP_LB: return aRect.BottomLeft();
+ case RP_MB: return aRect.BottomCenter();
+ case RP_RB: return aRect.BottomRight();
+ }
+ return Point(); // Sollte nicht vorkommen !
+}
+
+void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr)
+{
+ Rectangle aRect(GetMarkedObjRect());
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->LogicToPagePos(aRect);
+ }
+
+ long nOldRotateAngle=GetMarkedObjRotate();
+ long nOldShearAngle=GetMarkedObjShear();
+ const SdrMarkList& rMarkList=GetMarkedObjectList();
+ ULONG nMarkCount=rMarkList.GetMarkCount();
+ SdrObject* pObj=NULL;
+
+ RECT_POINT eSizePoint=RP_MM;
+ long nPosDX=0;
+ long nPosDY=0;
+ long nSizX=0;
+ long nSizY=0;
+ long nRotateAngle=0;
+
+ // #86909#
+ sal_Bool bModeIsRotate(eDragMode == SDRDRAG_ROTATE);
+ long nRotateX(0);
+ long nRotateY(0);
+ long nOldRotateX(0);
+ long nOldRotateY(0);
+ if(bModeIsRotate)
+ {
+ Point aRotateAxe(aRef1);
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->LogicToPagePos(aRotateAxe);
+ }
+
+ nRotateX = nOldRotateX = aRotateAxe.X();
+ nRotateY = nOldRotateY = aRotateAxe.Y();
+ }
+
+ long nNewShearAngle=0;
+ long nShearAngle=0;
+ long nShearX=0;
+ long nShearY=0;
+ BOOL bShearVert=FALSE;
+
+ BOOL bChgPos=FALSE;
+ BOOL bChgSiz=FALSE;
+ BOOL bChgHgt=FALSE;
+ BOOL bRotate=FALSE;
+ BOOL bShear =FALSE;
+
+ BOOL bSetAttr=FALSE;
+ SfxItemSet aSetAttr(pMod->GetItemPool());
+
+ const SfxPoolItem* pPoolItem=NULL;
+
+ // Position
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_X,TRUE,&pPoolItem)) {
+ nPosDX=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Left();
+ bChgPos=TRUE;
+ }
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_Y,TRUE,&pPoolItem)){
+ nPosDY=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Top();
+ bChgPos=TRUE;
+ }
+ // Groesse
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,TRUE,&pPoolItem)) {
+ nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue();
+ bChgSiz=TRUE;
+ }
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,TRUE,&pPoolItem)) {
+ nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue();
+ bChgSiz=TRUE;
+ bChgHgt=TRUE;
+ }
+ if (bChgSiz) {
+ eSizePoint=(RECT_POINT)((const SfxAllEnumItem&)rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINT)).GetValue();
+ }
+
+ // Rotation
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,TRUE,&pPoolItem)) {
+ nRotateAngle=((const SfxInt32Item*)pPoolItem)->GetValue()-nOldRotateAngle;
+ bRotate = (nRotateAngle != 0);
+ }
+
+ // #86909# pos rot point x
+ if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_X, TRUE ,&pPoolItem))
+ nRotateX = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_X)).GetValue();
+
+ // #86909# pos rot point y
+ if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_Y, TRUE ,&pPoolItem))
+ nRotateY = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_Y)).GetValue();
+
+ // Shear
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,TRUE,&pPoolItem)) {
+ nNewShearAngle=((const SfxInt32Item*)pPoolItem)->GetValue();
+ if (nNewShearAngle>SDRMAXSHEAR) nNewShearAngle=SDRMAXSHEAR;
+ if (nNewShearAngle<-SDRMAXSHEAR) nNewShearAngle=-SDRMAXSHEAR;
+ if (nNewShearAngle!=nOldShearAngle) {
+ bShearVert=((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue();
+ if (bShearVert) {
+ nShearAngle=nNewShearAngle;
+ } else {
+ if (nNewShearAngle!=0 && nOldShearAngle!=0) {
+ // Bugfix #25714#.
+ double nOld=tan((double)nOldShearAngle*nPi180);
+ double nNew=tan((double)nNewShearAngle*nPi180);
+ nNew-=nOld;
+ nNew=atan(nNew)/nPi180;
+ nShearAngle=Round(nNew);
+ } else {
+ nShearAngle=nNewShearAngle-nOldShearAngle;
+ }
+ }
+ bShear=nShearAngle!=0;
+ if (bShear) {
+ nShearX=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue();
+ nShearY=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue();
+ }
+ }
+ }
+
+ // AutoGrow
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH,TRUE,&pPoolItem)) {
+ BOOL bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
+ aSetAttr.Put(SdrTextAutoGrowWidthItem(bAutoGrow));
+ bSetAttr=TRUE;
+ }
+
+ if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT,TRUE,&pPoolItem)) {
+ BOOL bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
+ aSetAttr.Put(SdrTextAutoGrowHeightItem(bAutoGrow));
+ bSetAttr=TRUE;
+ }
+
+ // Eckenradius
+ if (bEdgeRadiusAllowed && SFX_ITEM_SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,TRUE,&pPoolItem)) {
+ long nRadius=((SdrEckenradiusItem*)pPoolItem)->GetValue();
+ aSetAttr.Put(SdrEckenradiusItem(nRadius));
+ bSetAttr=TRUE;
+ }
+
+ ForcePossibilities();
+
+ BegUndo(ImpGetResStr(STR_EditTransform),GetDescriptionOfMarkedObjects());
+
+ if (bSetAttr) {
+ SetAttrToMarked(aSetAttr,FALSE);
+ }
+
+ // Groesse und Hoehe aendern
+ if (bChgSiz && (bResizeFreeAllowed || bResizePropAllowed)) {
+ Fraction aWdt(nSizX,aRect.Right()-aRect.Left());
+ Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top());
+ Point aRef(ImpGetPoint(aRect,eSizePoint));
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->PagePosToLogic(aRef);
+ }
+
+ ResizeMarkedObj(aRef,aWdt,aHgt);
+ }
+
+ // Rotieren
+ if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) {
+ Point aRef(nRotateX,nRotateY);
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->PagePosToLogic(aRef);
+ }
+
+ RotateMarkedObj(aRef,nRotateAngle);
+ }
+
+ // #86909# set rotation point position
+ if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY))
+ {
+ Point aNewRef1(nRotateX, nRotateY);
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->PagePosToLogic(aNewRef1);
+ }
+
+ SetRef1(aNewRef1);
+ }
+
+ // Shear
+ if (bShear && bShearAllowed) {
+ Point aRef(nShearX,nShearY);
+
+ if(GetSdrPageView())
+ {
+ GetSdrPageView()->PagePosToLogic(aRef);
+ }
+
+ ShearMarkedObj(aRef,nShearAngle,bShearVert);
+
+ // #i74358#
+ // ShearMarkedObj creates a linear combination of the existing transformation and
+ // the new shear to apply. If the object is already transformed (e.g. rotated) the
+ // linear combination will not decompose to the same start values again, but to a
+ // new combination. Thus it makes no sense to check if the wanted shear is reached
+ // or not. Taking out.
+#if 0
+ long nTempAngle=GetMarkedObjShear();
+ if (nTempAngle!=0 && nTempAngle!=nNewShearAngle && !bShearVert) {
+ // noch eine 2. Iteration zur Kompensation der Rundungsfehler
+ double nOld=tan((double)nTempAngle*nPi180);
+ double nNew=tan((double)nNewShearAngle*nPi180);
+ nNew-=nOld;
+ nNew=atan(nNew)/nPi180;
+ nTempAngle=Round(nNew);
+ if (nTempAngle!=0) {
+ ShearMarkedObj(aRef,nTempAngle,bShearVert);
+ }
+ }
+#endif
+ }
+
+ // Position aendern
+ if (bChgPos && bMoveAllowed) {
+ MoveMarkedObj(Size(nPosDX,nPosDY));
+ }
+
+ // protect position
+ if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, TRUE, &pPoolItem))
+ {
+ const sal_Bool bProtPos(((const SfxBoolItem*)pPoolItem)->GetValue());
+ bool bChanged(false);
+
+ for(sal_uInt32 i(0); i < nMarkCount; i++)
+ {
+ pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ if(pObj->IsMoveProtect() != bProtPos)
+ {
+ bChanged = true;
+ pObj->SetMoveProtect(bProtPos);
+
+ if(bProtPos)
+ {
+ pObj->SetResizeProtect(true);
+ }
+ }
+ }
+
+ if(bChanged)
+ {
+ bMoveProtect = bProtPos;
+
+ if(bProtPos)
+ {
+ bResizeProtect = true;
+ }
+
+ // #i77187# there is no simple method to get the toolbars updated
+ // in the application. The App is listening to selection change and i
+ // will use it here (even if not true). It's acceptable since changing
+ // this model data is pretty rare and only possible using the F4 dialog
+ MarkListHasChanged();
+ }
+ }
+
+ if(!bMoveProtect)
+ {
+ // protect size
+ if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE, TRUE, &pPoolItem))
+ {
+ const sal_Bool bProtSize(((const SfxBoolItem*)pPoolItem)->GetValue());
+ bool bChanged(false);
+
+ for(sal_uInt32 i(0); i < nMarkCount; i++)
+ {
+ pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ if(pObj->IsResizeProtect() != bProtSize)
+ {
+ bChanged = true;
+ pObj->SetResizeProtect(bProtSize);
+ }
+ }
+
+ if(bChanged)
+ {
+ bResizeProtect = bProtSize;
+
+ // #i77187# see above
+ MarkListHasChanged();
+ }
+ }
+ }
+
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrEditView::IsAlignPossible() const
+{ // Mindestens 2 markierte Objekte, davon mind. 1 beweglich
+ ForcePossibilities();
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz==0) return FALSE; // Nix markiert!
+ if (nAnz==1) return bMoveAllowed; // einzelnes Obj an der Seite ausrichten
+ return bOneOrMoreMovable; // ansonsten ist MarkCount>=2
+}
+
+void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert, BOOL bBoundRects)
+{
+ if (eHor==SDRHALIGN_NONE && eVert==SDRVALIGN_NONE)
+ return;
+
+ SortMarkedObjects();
+ if (GetMarkedObjectCount()<1)
+ return;
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aStr(GetDescriptionOfMarkedObjects());
+ if (eHor==SDRHALIGN_NONE)
+ {
+ switch (eVert)
+ {
+ case SDRVALIGN_TOP : ImpTakeDescriptionStr(STR_EditAlignVTop ,aStr); break;
+ case SDRVALIGN_BOTTOM: ImpTakeDescriptionStr(STR_EditAlignVBottom,aStr); break;
+ case SDRVALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignVCenter,aStr); break;
+ default: break;
+ }
+ }
+ else if (eVert==SDRVALIGN_NONE)
+ {
+ switch (eHor)
+ {
+ case SDRHALIGN_LEFT : ImpTakeDescriptionStr(STR_EditAlignHLeft ,aStr); break;
+ case SDRHALIGN_RIGHT : ImpTakeDescriptionStr(STR_EditAlignHRight ,aStr); break;
+ case SDRHALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignHCenter,aStr); break;
+ default: break;
+ }
+ }
+ else if (eHor==SDRHALIGN_CENTER && eVert==SDRVALIGN_CENTER)
+ {
+ ImpTakeDescriptionStr(STR_EditAlignCenter,aStr);
+ }
+ else
+ {
+ ImpTakeDescriptionStr(STR_EditAlign,aStr);
+ }
+ BegUndo(aStr);
+ }
+
+ Rectangle aBound;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ ULONG nm;
+ BOOL bHasFixed=FALSE;
+ for (nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+ if (!aInfo.bMoveAllowed || pObj->IsMoveProtect())
+ {
+ Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
+ aBound.Union(aObjRect);
+ bHasFixed=TRUE;
+ }
+ }
+ if (!bHasFixed)
+ {
+ if (nMarkAnz==1)
+ { // einzelnes Obj an der Seite ausrichten
+ const SdrObject* pObj=GetMarkedObjectByIndex(0L);
+ const SdrPage* pPage=pObj->GetPage();
+ const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect()));
+ const SdrPageGridFrame* pFrame=NULL;
+ if (pGFL!=NULL && pGFL->GetCount()!=0)
+ { // Writer
+ pFrame=&((*pGFL)[0]);
+ }
+
+ if (pFrame!=NULL)
+ { // Writer
+ aBound=pFrame->GetUserArea();
+ }
+ else
+ {
+ aBound=Rectangle(pPage->GetLftBorder(),pPage->GetUppBorder(),
+ pPage->GetWdt()-pPage->GetRgtBorder(),
+ pPage->GetHgt()-pPage->GetLwrBorder());
+ }
+ }
+ else
+ {
+ if (bBoundRects)
+ aBound=GetMarkedObjBoundRect();
+ else
+ aBound=GetMarkedObjRect();
+ }
+ }
+ Point aCenter(aBound.Center());
+ for (nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+ if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
+ {
+ // SdrPageView* pPV=pM->GetPageView();
+ long nXMov=0;
+ long nYMov=0;
+ Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
+ switch (eVert)
+ {
+ case SDRVALIGN_TOP : nYMov=aBound.Top() -aObjRect.Top() ; break;
+ case SDRVALIGN_BOTTOM: nYMov=aBound.Bottom()-aObjRect.Bottom() ; break;
+ case SDRVALIGN_CENTER: nYMov=aCenter.Y() -aObjRect.Center().Y(); break;
+ default: break;
+ }
+ switch (eHor)
+ {
+ case SDRHALIGN_LEFT : nXMov=aBound.Left() -aObjRect.Left() ; break;
+ case SDRHALIGN_RIGHT : nXMov=aBound.Right() -aObjRect.Right() ; break;
+ case SDRHALIGN_CENTER: nXMov=aCenter.X() -aObjRect.Center().X(); break;
+ default: break;
+ }
+ if (nXMov!=0 || nYMov!=0)
+ {
+ // #104104# SdrEdgeObj needs an extra SdrUndoGeoObj since the
+ // connections may need to be saved
+ if( bUndo )
+ {
+ if( dynamic_cast<SdrEdgeObj*>(pObj) )
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+ }
+
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov)));
+ }
+
+ pObj->Move(Size(nXMov,nYMov));
+ }
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+}
+
diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx
new file mode 100644
index 000000000000..8cf83c0429cc
--- /dev/null
+++ b/svx/source/svdraw/svdedtv2.cxx
@@ -0,0 +1,2139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdedtv.hxx>
+#include <editeng/outliner.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdogrp.hxx> // fuer's Gruppieren
+#include <svx/svdovirt.hxx> // fuer VirtualObject-Bundling (Writer)
+#include <svx/svdopath.hxx> // fuer CombineObjects
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include "svditer.hxx"
+#include <svx/svdograf.hxx> // fuer Possibilities
+#include <svx/svdoole2.hxx> // und Mtf-Import
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include "svdfmtf.hxx"
+#include <svx/svdetc.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <vcl/msgbox.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/eeitem.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+#include <svx/svxdlg.hxx> //CHINA001
+#include <svx/dialogs.hrc> //CHINA001
+
+// #i37011#
+#include <svx/svdoashp.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::ImpBundleVirtObjOfMarkList()
+{
+ // ... fehlende Implementation
+}
+
+SdrObject* SdrEditView::GetMaxToTopObj(SdrObject* /*pObj*/) const
+{
+ return NULL;
+}
+
+SdrObject* SdrEditView::GetMaxToBtmObj(SdrObject* /*pObj*/) const
+{
+ return NULL;
+}
+
+void SdrEditView::ObjOrderChanged(SdrObject* /*pObj*/, ULONG /*nOldPos*/, ULONG /*nNewPos*/)
+{
+}
+
+void SdrEditView::MovMarkedToTop()
+{
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz!=0)
+ {
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditMovToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOTOP);
+
+ SortMarkedObjects();
+ ULONG nm;
+ for (nm=0; nm<nAnz; nm++)
+ { // Ordnums muessen alle stimmen!
+ GetMarkedObjectByIndex(nm)->GetOrdNum();
+ }
+ BOOL bChg=FALSE;
+ SdrObjList* pOL0=NULL;
+ ULONG nNewPos=0;
+ for (nm=nAnz; nm>0;)
+ {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0)
+ {
+ nNewPos=ULONG(pOL->GetObjCount()-1);
+ pOL0=pOL;
+ }
+ ULONG nNowPos=pObj->GetOrdNumDirect();
+ const Rectangle& rBR=pObj->GetCurrentBoundRect();
+ ULONG nCmpPos=nNowPos+1;
+ SdrObject* pMaxObj=GetMaxToTopObj(pObj);
+ if (pMaxObj!=NULL)
+ {
+ ULONG nMaxPos=pMaxObj->GetOrdNum();
+ if (nMaxPos!=0)
+ nMaxPos--;
+ if (nNewPos>nMaxPos)
+ nNewPos=nMaxPos; // diesen nicht ueberholen.
+ if (nNewPos<nNowPos)
+ nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ }
+ BOOL bEnd=FALSE;
+ while (nCmpPos<nNewPos && !bEnd)
+ {
+ SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
+ if (pCmpObj==NULL)
+ {
+ DBG_ERROR("MovMarkedToTop(): Vergleichsobjekt nicht gefunden");
+ bEnd=TRUE;
+ }
+ else if (pCmpObj==pMaxObj)
+ {
+ nNewPos=nCmpPos;
+ nNewPos--;
+ bEnd=TRUE;
+ }
+ else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
+ {
+ nNewPos=nCmpPos;
+ bEnd=TRUE;
+ }
+ else
+ {
+ nCmpPos++;
+ }
+ }
+ if (nNowPos!=nNewPos)
+ {
+ bChg=TRUE;
+ pOL->SetObjectOrdNum(nNowPos,nNewPos);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
+ ObjOrderChanged(pObj,nNowPos,nNewPos);
+ }
+ nNewPos--;
+ }
+
+ if( bUndo )
+ EndUndo();
+
+ if (bChg)
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::MovMarkedToBtm()
+{
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz!=0)
+ {
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditMovToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOBTM);
+
+ SortMarkedObjects();
+ ULONG nm;
+ for (nm=0; nm<nAnz; nm++)
+ { // Ordnums muessen alle stimmen!
+ GetMarkedObjectByIndex(nm)->GetOrdNum();
+ }
+
+ BOOL bChg=FALSE;
+ SdrObjList* pOL0=NULL;
+ ULONG nNewPos=0;
+ for (nm=0; nm<nAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0)
+ {
+ nNewPos=0;
+ pOL0=pOL;
+ }
+ ULONG nNowPos=pObj->GetOrdNumDirect();
+ const Rectangle& rBR=pObj->GetCurrentBoundRect();
+ ULONG nCmpPos=nNowPos; if (nCmpPos>0) nCmpPos--;
+ SdrObject* pMaxObj=GetMaxToBtmObj(pObj);
+ if (pMaxObj!=NULL)
+ {
+ ULONG nMinPos=pMaxObj->GetOrdNum()+1;
+ if (nNewPos<nMinPos)
+ nNewPos=nMinPos; // diesen nicht ueberholen.
+ if (nNewPos>nNowPos)
+ nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ }
+ BOOL bEnd=FALSE;
+ // nNewPos ist an dieser Stelle noch die maximale Position,
+ // an der das Obj hinruecken darf, ohne seinen Vorgaenger
+ // (Mehrfachselektion) zu ueberholen.
+ while (nCmpPos>nNewPos && !bEnd)
+ {
+ SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
+ if (pCmpObj==NULL)
+ {
+ DBG_ERROR("MovMarkedToBtm(): Vergleichsobjekt nicht gefunden");
+ bEnd=TRUE;
+ }
+ else if (pCmpObj==pMaxObj)
+ {
+ nNewPos=nCmpPos;
+ nNewPos++;
+ bEnd=TRUE;
+ }
+ else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
+ {
+ nNewPos=nCmpPos;
+ bEnd=TRUE;
+ }
+ else
+ {
+ nCmpPos--;
+ }
+ }
+ if (nNowPos!=nNewPos)
+ {
+ bChg=TRUE;
+ pOL->SetObjectOrdNum(nNowPos,nNewPos);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
+ ObjOrderChanged(pObj,nNowPos,nNewPos);
+ }
+ nNewPos++;
+ }
+
+ if(bUndo)
+ EndUndo();
+
+ if(bChg)
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::PutMarkedToTop()
+{
+ PutMarkedInFrontOfObj(NULL);
+}
+
+void SdrEditView::PutMarkedInFrontOfObj(const SdrObject* pRefObj)
+{
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz!=0)
+ {
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditPutToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOTOP);
+
+ SortMarkedObjects();
+
+ if (pRefObj!=NULL)
+ {
+ // Damit "Vor das Objekt" auch funktioniert wenn die
+ // markierten Objekte bereits vor dem Objekt stehen
+ ULONG nRefMark=TryToFindMarkedObject(pRefObj);
+ SdrMark aRefMark;
+ if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ aRefMark=*GetSdrMarkByIndex(nRefMark);
+ GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
+ }
+ PutMarkedToBtm();
+ if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
+ SortMarkedObjects();
+ }
+ }
+ ULONG nm;
+ for (nm=0; nm<nAnz; nm++)
+ { // Ordnums muessen alle stimmen!
+ GetMarkedObjectByIndex(nm)->GetOrdNum();
+ }
+ BOOL bChg=FALSE;
+ SdrObjList* pOL0=NULL;
+ ULONG nNewPos=0;
+ for (nm=nAnz; nm>0;)
+ {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (pObj!=pRefObj)
+ {
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0)
+ {
+ nNewPos=ULONG(pOL->GetObjCount()-1);
+ pOL0=pOL;
+ }
+ ULONG nNowPos=pObj->GetOrdNumDirect();
+ SdrObject* pMaxObj=GetMaxToTopObj(pObj);
+ if (pMaxObj!=NULL)
+ {
+ ULONG nMaxOrd=pMaxObj->GetOrdNum(); // geht leider nicht anders
+ if (nMaxOrd>0)
+ nMaxOrd--;
+ if (nNewPos>nMaxOrd)
+ nNewPos=nMaxOrd; // nicht ueberholen.
+ if (nNewPos<nNowPos)
+ nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ }
+ if (pRefObj!=NULL)
+ {
+ if (pRefObj->GetObjList()==pObj->GetObjList())
+ {
+ ULONG nMaxOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
+ if (nNewPos>nMaxOrd)
+ nNewPos=nMaxOrd; // nicht ueberholen.
+ if (nNewPos<nNowPos)
+ nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ }
+ else
+ {
+ nNewPos=nNowPos; // andere PageView, also nicht veraendern
+ }
+ }
+ if (nNowPos!=nNewPos)
+ {
+ bChg=TRUE;
+ pOL->SetObjectOrdNum(nNowPos,nNewPos);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
+ ObjOrderChanged(pObj,nNowPos,nNewPos);
+ }
+ nNewPos--;
+ } // if (pObj!=pRefObj)
+ } // for-Schleife ueber alle Markierten Objekte
+
+ if( bUndo )
+ EndUndo();
+
+ if(bChg)
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::PutMarkedToBtm()
+{
+ PutMarkedBehindObj(NULL);
+}
+
+void SdrEditView::PutMarkedBehindObj(const SdrObject* pRefObj)
+{
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz!=0)
+ {
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditPutToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOBTM);
+
+ SortMarkedObjects();
+ if (pRefObj!=NULL)
+ {
+ // Damit "Hinter das Objekt" auch funktioniert wenn die
+ // markierten Objekte bereits hinter dem Objekt stehen
+ ULONG nRefMark=TryToFindMarkedObject(pRefObj);
+ SdrMark aRefMark;
+ if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ aRefMark=*GetSdrMarkByIndex(nRefMark);
+ GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
+ }
+ PutMarkedToTop();
+ if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
+ SortMarkedObjects();
+ }
+ }
+ ULONG nm;
+ for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
+ GetMarkedObjectByIndex(nm)->GetOrdNum();
+ }
+ BOOL bChg=FALSE;
+ SdrObjList* pOL0=NULL;
+ ULONG nNewPos=0;
+ for (nm=0; nm<nAnz; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (pObj!=pRefObj) {
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0) {
+ nNewPos=0;
+ pOL0=pOL;
+ }
+ ULONG nNowPos=pObj->GetOrdNumDirect();
+ SdrObject* pMinObj=GetMaxToBtmObj(pObj);
+ if (pMinObj!=NULL) {
+ ULONG nMinOrd=pMinObj->GetOrdNum()+1; // geht leider nicht anders
+ if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
+ if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ }
+ if (pRefObj!=NULL) {
+ if (pRefObj->GetObjList()==pObj->GetObjList()) {
+ ULONG nMinOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
+ if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
+ if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
+ } else {
+ nNewPos=nNowPos; // andere PageView, also nicht veraendern
+ }
+ }
+ if (nNowPos!=nNewPos) {
+ bChg=TRUE;
+ pOL->SetObjectOrdNum(nNowPos,nNewPos);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
+ ObjOrderChanged(pObj,nNowPos,nNewPos);
+ }
+ nNewPos++;
+ } // if (pObj!=pRefObj)
+ } // for-Schleife ueber alle markierten Objekte
+
+ if(bUndo)
+ EndUndo();
+
+ if(bChg)
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::ReverseOrderOfMarked()
+{
+ SortMarkedObjects();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz>0)
+ {
+ //BOOL bNeedBundle=FALSE;
+ BOOL bChg=FALSE;
+
+ bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditRevOrder),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_REVORDER);
+
+ ULONG a=0;
+ do {
+ // Markierung ueber mehrere PageViews berueksichtigen
+ ULONG b=a+1;
+ while (b<nMarkAnz && GetSdrPageViewOfMarkedByIndex(b) == GetSdrPageViewOfMarkedByIndex(a)) b++;
+ b--;
+ SdrObjList* pOL=GetSdrPageViewOfMarkedByIndex(a)->GetObjList();
+ ULONG c=b;
+ if (a<c) { // Sicherstellen, dass die OrdNums nicht Dirty sind
+ GetMarkedObjectByIndex(a)->GetOrdNum();
+ }
+ while (a<c) {
+ SdrObject* pObj1=GetMarkedObjectByIndex(a);
+ SdrObject* pObj2=GetMarkedObjectByIndex(c);
+ ULONG nOrd1=pObj1->GetOrdNumDirect();
+ ULONG nOrd2=pObj2->GetOrdNumDirect();
+ if( bUndo )
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj1,nOrd1,nOrd2));
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj2,nOrd2-1,nOrd1));
+ }
+ pOL->SetObjectOrdNum(nOrd1,nOrd2);
+ // Obj 2 ist um eine Position nach vorn gerutscht, deshalb nun nOrd2-1
+ pOL->SetObjectOrdNum(nOrd2-1,nOrd1);
+ // Verwendung von Replace statt SetOrdNum wg. Performance (Neuberechnung der Ordnums)
+ a++; c--;
+ bChg=TRUE;
+ }
+ a=b+1;
+ } while (a<nMarkAnz);
+
+ if(bUndo)
+ EndUndo();
+
+ if(bChg)
+ MarkListHasChanged();
+ }
+}
+
+void SdrEditView::ImpCheckToTopBtmPossible()
+{
+ ULONG nAnz=GetMarkedObjectCount();
+ if (nAnz==0)
+ return;
+ if (nAnz==1)
+ { // Sonderbehandlung fuer Einzelmarkierung
+ SdrObject* pObj=GetMarkedObjectByIndex(0);
+ SdrObjList* pOL=pObj->GetObjList();
+ ULONG nMax=pOL->GetObjCount();
+ ULONG nMin=0;
+ ULONG nObjNum=pObj->GetOrdNum();
+ SdrObject* pRestrict=GetMaxToTopObj(pObj);
+ if (pRestrict!=NULL) {
+ ULONG nRestrict=pRestrict->GetOrdNum();
+ if (nRestrict<nMax) nMax=nRestrict;
+ }
+ pRestrict=GetMaxToBtmObj(pObj);
+ if (pRestrict!=NULL) {
+ ULONG nRestrict=pRestrict->GetOrdNum();
+ if (nRestrict>nMin) nMin=nRestrict;
+ }
+ bToTopPossible=nObjNum<ULONG(nMax-1);
+ bToBtmPossible=nObjNum>nMin;
+ } else { // Mehrfachselektion
+ ULONG nm=0;
+ SdrObjList* pOL0=NULL;
+ long nPos0=-1;
+ while (!bToBtmPossible && nm<nAnz) { // 'nach hinten' checken
+ SdrObject* pObj=GetMarkedObjectByIndex(nm);
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0) {
+ nPos0=-1;
+ pOL0=pOL;
+ }
+ ULONG nPos=pObj->GetOrdNum();
+ bToBtmPossible=nPos>ULONG(nPos0+1);
+ nPos0=long(nPos);
+ nm++;
+ }
+ nm=nAnz;
+ pOL0=NULL;
+ nPos0=0x7FFFFFFF;
+ while (!bToTopPossible && nm>0) { // 'nach vorn' checken
+ nm--;
+ SdrObject* pObj=GetMarkedObjectByIndex(nm);
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0) {
+ nPos0=pOL->GetObjCount();
+ pOL0=pOL;
+ }
+ ULONG nPos=pObj->GetOrdNum();
+ bToTopPossible=nPos+1<ULONG(nPos0);
+ nPos0=nPos;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
+// @@ @@ @@ @@ @@@ @@@ @@ @@ @@ @@@ @@ @@
+// @@ @@ @@ @@@@@@@ @@ @@ @@ @@@@@@ @@
+// @@ @@ @@ @@@@@@@ @@@@@ @@ @@@@@@ @@@@
+// @@ @@ @@ @@ @ @@ @@ @@ @@ @@ @@@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::ImpCopyAttributes(const SdrObject* pSource, SdrObject* pDest) const
+{
+ if (pSource!=NULL) {
+ SdrObjList* pOL=pSource->GetSubList();
+ if (pOL!=NULL && !pSource->Is3DObj()) { // erstes Nichtgruppenobjekt aus der Gruppe holen
+ SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
+ pSource=aIter.Next();
+ }
+ }
+
+ if(pSource && pDest)
+ {
+ SfxItemSet aSet(pMod->GetItemPool(),
+ SDRATTR_START, SDRATTR_NOTPERSIST_FIRST-1,
+ SDRATTR_NOTPERSIST_LAST+1, SDRATTR_END,
+ EE_ITEMS_START, EE_ITEMS_END,
+ 0, 0); // #52757#, #52762#
+
+ aSet.Put(pSource->GetMergedItemSet());
+
+ pDest->ClearMergedItem();
+ pDest->SetMergedItemSet(aSet);
+
+ pDest->NbcSetLayer(pSource->GetLayer());
+ pDest->NbcSetStyleSheet(pSource->GetStyleSheet(), sal_True);
+ }
+}
+
+sal_Bool SdrEditView::ImpCanConvertForCombine1(const SdrObject* pObj) const
+{
+ // #69711 : new condition IsLine() to be able to combine simple Lines
+ sal_Bool bIsLine(sal_False);
+
+ const SdrPathObj* pPath = PTR_CAST(SdrPathObj,pObj);
+
+ if(pPath)
+ {
+ bIsLine = pPath->IsLine();
+ }
+
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+
+ return (aInfo.bCanConvToPath || aInfo.bCanConvToPoly || bIsLine);
+}
+
+sal_Bool SdrEditView::ImpCanConvertForCombine(const SdrObject* pObj) const
+{
+ SdrObjList* pOL = pObj->GetSubList();
+
+ if(pOL && !pObj->Is3DObj())
+ {
+ SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pObj1 = aIter.Next();
+
+ // Es muessen alle Member einer Gruppe konvertierbar sein
+ if(!ImpCanConvertForCombine1(pObj1))
+ {
+ return sal_False;
+ }
+ }
+ }
+ else
+ {
+ if(!ImpCanConvertForCombine1(pObj))
+ {
+ return sal_False;
+ }
+ }
+
+ return sal_True;
+}
+
+basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon1(const SdrObject* pObj, sal_Bool bCombine) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
+
+ if(bCombine && pPath && !pObj->GetOutlinerParaObject())
+ {
+ aRetval = pPath->GetPathPoly();
+ }
+ else
+ {
+ SdrObject* pConvObj = pObj->ConvertToPolyObj(bCombine, sal_False);
+
+ if(pConvObj)
+ {
+ SdrObjList* pOL = pConvObj->GetSubList();
+
+ if(pOL)
+ {
+ SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pObj1 = aIter.Next();
+ pPath = PTR_CAST(SdrPathObj, pObj1);
+
+ if(pPath)
+ {
+ aRetval.append(pPath->GetPathPoly());
+ }
+ }
+ }
+ else
+ {
+ pPath = PTR_CAST(SdrPathObj, pConvObj);
+
+ if(pPath)
+ {
+ aRetval = pPath->GetPathPoly();
+ }
+ }
+
+ SdrObject::Free( pConvObj );
+ }
+ }
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon(const SdrObject* pObj, sal_Bool bCombine) const
+{
+ SdrObjList* pOL = pObj->GetSubList();
+
+ if(pOL && !pObj->Is3DObj())
+ {
+ basegfx::B2DPolyPolygon aRetval;
+ SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pObj1 = aIter.Next();
+ aRetval.append(ImpGetPolyPolygon1(pObj1, bCombine));
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return ImpGetPolyPolygon1(pObj, bCombine);
+ }
+}
+
+basegfx::B2DPolygon SdrEditView::ImpCombineToSinglePolygon(const basegfx::B2DPolyPolygon& rPolyPolygon) const
+{
+ const sal_uInt32 nPolyCount(rPolyPolygon.count());
+
+ if(0L == nPolyCount)
+ {
+ return basegfx::B2DPolygon();
+ }
+ else if(1L == nPolyCount)
+ {
+ return rPolyPolygon.getB2DPolygon(0L);
+ }
+ else
+ {
+ basegfx::B2DPolygon aRetval(rPolyPolygon.getB2DPolygon(0L));
+
+ for(sal_uInt32 a(1L); a < nPolyCount; a++)
+ {
+ basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
+
+ if(aRetval.count())
+ {
+ if(aCandidate.count())
+ {
+ const basegfx::B2DPoint aCA(aCandidate.getB2DPoint(0L));
+ const basegfx::B2DPoint aCB(aCandidate.getB2DPoint(aCandidate.count() - 1L));
+ const basegfx::B2DPoint aRA(aRetval.getB2DPoint(0L));
+ const basegfx::B2DPoint aRB(aRetval.getB2DPoint(aRetval.count() - 1L));
+
+ const double fRACA(basegfx::B2DVector(aCA - aRA).getLength());
+ const double fRACB(basegfx::B2DVector(aCB - aRA).getLength());
+ const double fRBCA(basegfx::B2DVector(aCA - aRB).getLength());
+ const double fRBCB(basegfx::B2DVector(aCB - aRB).getLength());
+
+ const double fSmallestRA(fRACA < fRACB ? fRACA : fRACB);
+ const double fSmallestRB(fRBCA < fRBCB ? fRBCA : fRBCB);
+
+ if(fSmallestRA < fSmallestRB)
+ {
+ // flip result
+ aRetval.flip();
+ }
+
+ const double fSmallestCA(fRACA < fRBCA ? fRACA : fRBCA);
+ const double fSmallestCB(fRACB < fRBCB ? fRACB : fRBCB);
+
+ if(fSmallestCB < fSmallestCA)
+ {
+ // flip candidate
+ aCandidate.flip();
+ }
+
+ // append candidate to retval
+ aRetval.append(aCandidate);
+ }
+ }
+ else
+ {
+ aRetval = aCandidate;
+ }
+ }
+
+ return aRetval;
+ }
+}
+
+// for distribution dialog function
+struct ImpDistributeEntry
+{
+ SdrObject* mpObj;
+ INT32 mnPos;
+ INT32 mnLength;
+};
+
+DECLARE_LIST(ImpDistributeEntryList, ImpDistributeEntry*)
+
+void SdrEditView::DistributeMarkedObjects()
+{
+ UINT32 nMark(GetMarkedObjectCount());
+
+ if(nMark > 2)
+ {
+ SfxItemSet aNewAttr(pMod->GetItemPool());
+ //CHINA001 SvxDistributeDialog* pDlg = new SvxDistributeDialog(NULL, aNewAttr);
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
+ {
+ AbstractSvxDistributeDialog *pDlg = pFact->CreateSvxDistributeDialog(NULL, aNewAttr);
+ DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
+
+ UINT16 nResult = pDlg->Execute();
+
+ if(nResult == RET_OK)
+ {
+ SvxDistributeHorizontal eHor = pDlg->GetDistributeHor();
+ SvxDistributeVertical eVer = pDlg->GetDistributeVer();
+ ImpDistributeEntryList aEntryList;
+ UINT32 a, nInsPos, nFullLength;
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo();
+
+ if(eHor != SvxDistributeHorizontalNone)
+ {
+ // build sorted entry list
+ nFullLength = 0L;
+
+ for(a=0;a<nMark;a++)
+ {
+ SdrMark* pMark = GetSdrMarkByIndex(a);
+ ImpDistributeEntry* pNew = new ImpDistributeEntry;
+
+ pNew->mpObj = pMark->GetMarkedSdrObj();
+ nInsPos = 0;
+
+ switch(eHor)
+ {
+ case SvxDistributeHorizontalLeft:
+ {
+ pNew->mnPos = pNew->mpObj->GetSnapRect().Left();
+ break;
+ }
+ case SvxDistributeHorizontalCenter:
+ {
+ pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
+ break;
+ }
+ case SvxDistributeHorizontalDistance:
+ {
+ pNew->mnLength = pNew->mpObj->GetSnapRect().GetWidth() + 1;
+ nFullLength += pNew->mnLength;
+ pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
+ break;
+ }
+ case SvxDistributeHorizontalRight:
+ {
+ pNew->mnPos = pNew->mpObj->GetSnapRect().Right();
+ break;
+ }
+ default: break;
+ }
+
+ while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
+ nInsPos++;
+
+ aEntryList.Insert(pNew, nInsPos);
+ }
+
+ if(eHor == SvxDistributeHorizontalDistance)
+ {
+ // calc room in-between
+ INT32 nWidth = GetAllMarkedBoundRect().GetWidth() + 1;
+ double fStepWidth = ((double)nWidth - (double)nFullLength) / (double)(aEntryList.Count() - 1);
+ double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
+ fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
+
+ // move entries 1..n-1
+ for(a=1;a<aEntryList.Count()-1;a++)
+ {
+ ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
+ ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
+ INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
+ pCurr->mpObj->Move(Size(nDelta, 0));
+ fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
+ }
+ }
+ else
+ {
+ // calc distances
+ INT32 nWidth = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
+ double fStepWidth = (double)nWidth / (double)(aEntryList.Count() - 1);
+ double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
+ fStepStart += fStepWidth;
+
+ // move entries 1..n-1
+ for(a=1;a<aEntryList.Count()-1;a++)
+ {
+ ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
+ INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
+ pCurr->mpObj->Move(Size(nDelta, 0));
+ fStepStart += fStepWidth;
+ }
+ }
+
+ // clear list
+ while(aEntryList.Count())
+ delete aEntryList.Remove((ULONG)0L);
+ }
+
+ if(eVer != SvxDistributeVerticalNone)
+ {
+ // build sorted entry list
+ nFullLength = 0L;
+
+ for(a=0;a<nMark;a++)
+ {
+ SdrMark* pMark = GetSdrMarkByIndex(a);
+ ImpDistributeEntry* pNew = new ImpDistributeEntry;
+
+ pNew->mpObj = pMark->GetMarkedSdrObj();
+ nInsPos = 0;
+
+ switch(eVer)
+ {
+ case SvxDistributeVerticalTop:
+ {
+ pNew->mnPos = pNew->mpObj->GetSnapRect().Top();
+ break;
+ }
+ case SvxDistributeVerticalCenter:
+ {
+ pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
+ break;
+ }
+ case SvxDistributeVerticalDistance:
+ {
+ pNew->mnLength = pNew->mpObj->GetSnapRect().GetHeight() + 1;
+ nFullLength += pNew->mnLength;
+ pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
+ break;
+ }
+ case SvxDistributeVerticalBottom:
+ {
+ pNew->mnPos = pNew->mpObj->GetSnapRect().Bottom();
+ break;
+ }
+ default: break;
+ }
+
+ while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
+ nInsPos++;
+
+ aEntryList.Insert(pNew, nInsPos);
+ }
+
+ if(eVer == SvxDistributeVerticalDistance)
+ {
+ // calc room in-between
+ INT32 nHeight = GetAllMarkedBoundRect().GetHeight() + 1;
+ double fStepWidth = ((double)nHeight - (double)nFullLength) / (double)(aEntryList.Count() - 1);
+ double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
+ fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
+
+ // move entries 1..n-1
+ for(a=1;a<aEntryList.Count()-1;a++)
+ {
+ ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
+ ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
+ INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
+ pCurr->mpObj->Move(Size(0, nDelta));
+ fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
+ }
+ }
+ else
+ {
+ // calc distances
+ INT32 nHeight = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
+ double fStepWidth = (double)nHeight / (double)(aEntryList.Count() - 1);
+ double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
+ fStepStart += fStepWidth;
+
+ // move entries 1..n-1
+ for(a=1;a<aEntryList.Count()-1;a++)
+ {
+ ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
+ INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
+ pCurr->mpObj->Move(Size(0, nDelta));
+ fStepStart += fStepWidth;
+ }
+ }
+
+ // clear list
+ while(aEntryList.Count())
+ delete aEntryList.Remove((ULONG)0L);
+ }
+
+ // UNDO-Comment and end of UNDO
+ SetUndoComment(ImpGetResStr(STR_DistributeMarkedObjects));
+
+ if( bUndo )
+ EndUndo();
+ }
+
+ delete(pDlg);
+ }
+ }
+}
+
+void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode)
+{
+ // #i73441# check content
+ if(AreObjectsMarked())
+ {
+ SdrMarkList aRemove;
+ SortMarkedObjects();
+
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo();
+
+ UINT32 nInsPos=0xFFFFFFFF;
+ const SdrObject* pAttrObj = NULL;
+ basegfx::B2DPolyPolygon aMergePolyPolygonA;
+ basegfx::B2DPolyPolygon aMergePolyPolygonB;
+
+ SdrObjList* pInsOL = NULL;
+ SdrPageView* pInsPV = NULL;
+ BOOL bFirstObjectComplete(FALSE);
+
+ // make sure selected objects are contour objects
+ // since now basegfx::tools::adaptiveSubdivide() is used, it is no longer
+ // necessary to use ConvertMarkedToPolyObj which will subdivide curves using the old
+ // mechanisms. In a next step the polygon clipper will even be able to clip curves...
+ // ConvertMarkedToPolyObj(TRUE);
+ ConvertMarkedToPathObj(sal_True);
+ OSL_ENSURE(AreObjectsMarked(), "no more objects selected after preparations (!)");
+
+ for(UINT32 a=0;a<GetMarkedObjectCount();a++)
+ {
+ SdrMark* pM = GetSdrMarkByIndex(a);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+
+ if(ImpCanConvertForCombine(pObj))
+ {
+ if(!pAttrObj)
+ pAttrObj = pObj;
+
+ nInsPos = pObj->GetOrdNum() + 1;
+ pInsPV = pM->GetPageView();
+ pInsOL = pObj->GetObjList();
+
+ // #i76891# use single iter from SJ here whcih works on SdrObjects and takes
+ // groups into account by itself
+ SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
+
+ while(aIter.IsMore())
+ {
+ SdrObject* pCandidate = aIter.Next();
+ SdrPathObj* pPathObj = PTR_CAST(SdrPathObj, pCandidate);
+ if(pPathObj)
+ {
+ basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly());
+
+ // #i76891# unfortunately ConvertMarkedToPathObj has converted all
+ // involved polygon data to curve segments, even if not necessary.
+ // It is better to try to reduce to more simple polygons.
+ aTmpPoly = basegfx::tools::simplifyCurveSegments(aTmpPoly);
+
+ // for each part polygon as preparation, remove self-intersections
+ // correct orientations and get rid of evtl. neutral polygons.
+ aTmpPoly = basegfx::tools::prepareForPolygonOperation(aTmpPoly);
+
+ if(!bFirstObjectComplete)
+ {
+ // #i111987# Also need to collect ORed source shape when more than
+ // a single polygon is involved
+ if(aMergePolyPolygonA.count())
+ {
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aTmpPoly);
+ }
+ else
+ {
+ aMergePolyPolygonA = aTmpPoly;
+ }
+ }
+ else
+ {
+ if(aMergePolyPolygonB.count())
+ {
+ // to topologically correctly collect the 2nd polygon
+ // group it is necessary to OR the parts (each is seen as
+ // XOR-FillRule polygon and they are drawn over each-other)
+ aMergePolyPolygonB = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonB, aTmpPoly);
+ }
+ else
+ {
+ aMergePolyPolygonB = aTmpPoly;
+ }
+ }
+ }
+ }
+
+ // was there something added to the first poly?
+ if(!bFirstObjectComplete && aMergePolyPolygonA.count())
+ {
+ bFirstObjectComplete = TRUE;
+ }
+
+ // move object to temporary delete list
+ aRemove.InsertEntry(SdrMark(pObj, pM->GetPageView()));
+ }
+ }
+
+ switch(eMode)
+ {
+ case SDR_MERGE_MERGE:
+ {
+ // merge all contained parts (OR)
+ static bool bTestXOR(false);
+ if(bTestXOR)
+ {
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
+ }
+ else
+ {
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
+ }
+ break;
+ }
+ case SDR_MERGE_SUBSTRACT:
+ {
+ // Substract B from A
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+ case SDR_MERGE_INTERSECT:
+ {
+ // AND B and A
+ aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
+ break;
+ }
+ }
+
+ // #i73441# check insert list before taking actions
+ if(pInsOL)
+ {
+ SdrPathObj* pPath = new SdrPathObj(OBJ_PATHFILL, aMergePolyPolygonA);
+ ImpCopyAttributes(pAttrObj, pPath);
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pAttrObj);
+ pInsOL->InsertObject(pPath, nInsPos, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
+ MarkObj(pPath, pInsPV, FALSE, TRUE);
+ }
+
+ aRemove.ForceSort();
+ switch(eMode)
+ {
+ case SDR_MERGE_MERGE:
+ {
+ SetUndoComment(
+ ImpGetResStr(STR_EditMergeMergePoly),
+ aRemove.GetMarkDescription());
+ break;
+ }
+ case SDR_MERGE_SUBSTRACT:
+ {
+ SetUndoComment(
+ ImpGetResStr(STR_EditMergeSubstractPoly),
+ aRemove.GetMarkDescription());
+ break;
+ }
+ case SDR_MERGE_INTERSECT:
+ {
+ SetUndoComment(
+ ImpGetResStr(STR_EditMergeIntersectPoly),
+ aRemove.GetMarkDescription());
+ break;
+ }
+ }
+ DeleteMarkedList(aRemove);
+
+ if( bUndo )
+ EndUndo();
+ }
+}
+
+void SdrEditView::CombineMarkedObjects(sal_Bool bNoPolyPoly)
+{
+ // #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would
+ // create a 2nd Undo-action and Undo-Comment.
+
+ bool bUndo = IsUndoEnabled();
+
+ // Undo-String will be set later
+ if( bUndo )
+ BegUndo(String(), String(), bNoPolyPoly ? SDRREPFUNC_OBJ_COMBINE_ONEPOLY : SDRREPFUNC_OBJ_COMBINE_POLYPOLY);
+
+ // #105899# First, guarantee that all objects are converted to polyobjects,
+ // especially for SdrGrafObj with bitmap filling this is necessary to not
+ // loose the bitmap filling.
+
+ // #i12392#
+ // ConvertMarkedToPolyObj was too strong here, it will loose quality and
+ // information when curve objects are combined. This can be replaced by
+ // using ConvertMarkedToPathObj without changing the previous fix.
+
+ // #i21250#
+ // Instead of simply passing sal_True as LineToArea, use bNoPolyPoly as info
+ // if this command is a 'Combine' or a 'Connect' command. On Connect it's sal_True.
+ // To not concert line segments with a set line width to polygons in that case,
+ // use this info. Do not convert LineToArea on Connect commands.
+ // ConvertMarkedToPathObj(!bNoPolyPoly);
+
+ // #114310#
+ // This is used for Combine and Connect. In no case it is necessary to force
+ // the content to curve, but it is also not good to force to polygons. Thus,
+ // curve is the less information loosing one. Remember: This place is not
+ // used for merge.
+ // LineToArea is never necessary, both commands are able to take over the
+ // set line style and to display it correctly. Thus, i will use a
+ // ConvertMarkedToPathObj with a sal_False in any case. Only drawback is that
+ // simple polygons will be changed to curves, but with no information loss.
+ ConvertMarkedToPathObj(sal_False /* bLineToArea */);
+
+ // continue as before
+ basegfx::B2DPolyPolygon aPolyPolygon;
+ SdrObjList* pAktOL = 0L;
+ SdrMarkList aRemoveMerker;
+
+ SortMarkedObjects();
+ sal_uInt32 nInsPos(0xFFFFFFFF);
+ SdrObjList* pInsOL = 0L;
+ SdrPageView* pInsPV = 0L;
+ const sal_uInt32 nAnz(GetMarkedObjectCount());
+ const SdrObject* pAttrObj = 0L;
+
+ for(sal_uInt32 a(nAnz); a > 0L; )
+ {
+ a--;
+ SdrMark* pM = GetSdrMarkByIndex(a);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+ SdrObjList* pThisOL = pObj->GetObjList();
+
+ if(pAktOL != pThisOL)
+ {
+ pAktOL = pThisOL;
+ }
+
+ if(ImpCanConvertForCombine(pObj))
+ {
+ // Obj merken fuer Attribute kopieren
+ pAttrObj = pObj;
+
+ // unfortunately ConvertMarkedToPathObj has converted all
+ // involved polygon data to curve segments, even if not necessary.
+ // It is better to try to reduce to more simple polygons.
+ basegfx::B2DPolyPolygon aTmpPoly(basegfx::tools::simplifyCurveSegments(ImpGetPolyPolygon(pObj, sal_True)));
+ aPolyPolygon.insert(0L, aTmpPoly);
+
+ if(!pInsOL)
+ {
+ nInsPos = pObj->GetOrdNum() + 1L;
+ pInsPV = pM->GetPageView();
+ pInsOL = pObj->GetObjList();
+ }
+
+ aRemoveMerker.InsertEntry(SdrMark(pObj, pM->GetPageView()));
+ }
+ }
+
+ if(bNoPolyPoly)
+ {
+ basegfx::B2DPolygon aCombinedPolygon(ImpCombineToSinglePolygon(aPolyPolygon));
+ aPolyPolygon.clear();
+ aPolyPolygon.append(aCombinedPolygon);
+ }
+
+ const sal_uInt32 nPolyCount(aPolyPolygon.count());
+
+ if(nPolyCount)
+ {
+ SdrObjKind eKind = OBJ_PATHFILL;
+
+ if(nPolyCount > 1L)
+ {
+ aPolyPolygon.setClosed(true);
+ }
+ else
+ {
+ // auf Polyline Checken
+ const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0L));
+ const sal_uInt32 nPointCount(aPolygon.count());
+
+ if(nPointCount <= 2L)
+ {
+ eKind = OBJ_PATHLINE;
+ }
+ else
+ {
+ if(!aPolygon.isClosed())
+ {
+ const basegfx::B2DPoint aPointA(aPolygon.getB2DPoint(0L));
+ const basegfx::B2DPoint aPointB(aPolygon.getB2DPoint(nPointCount - 1L));
+ const double fDistance(basegfx::B2DVector(aPointB - aPointA).getLength());
+ const double fJoinTolerance(10.0);
+
+ if(fDistance < fJoinTolerance)
+ {
+ aPolyPolygon.setClosed(true);
+ }
+ else
+ {
+ eKind = OBJ_PATHLINE;
+ }
+ }
+ }
+ }
+
+ SdrPathObj* pPath = new SdrPathObj(eKind,aPolyPolygon);
+
+ // Attribute des untersten Objekts
+ ImpCopyAttributes(pAttrObj, pPath);
+
+ // #100408# If LineStyle of pAttrObj is XLINE_NONE force to XLINE_SOLID to make visible.
+ const XLineStyle eLineStyle = ((const XLineStyleItem&)pAttrObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
+ const XFillStyle eFillStyle = ((const XFillStyleItem&)pAttrObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
+
+ // #110635#
+ // Take fill style/closed state of pAttrObj in account when deciding to change the line style
+ sal_Bool bIsClosedPathObj(pAttrObj->ISA(SdrPathObj) && ((SdrPathObj*)pAttrObj)->IsClosed());
+
+ if(XLINE_NONE == eLineStyle && (XFILL_NONE == eFillStyle || !bIsClosedPathObj))
+ {
+ pPath->SetMergedItem(XLineStyleItem(XLINE_SOLID));
+ }
+
+ SdrInsertReason aReason(SDRREASON_VIEWCALL,pAttrObj);
+ pInsOL->InsertObject(pPath,nInsPos,&aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
+
+ // #111111#
+ // Here was a severe error: Without UnmarkAllObj, the new object was marked
+ // additionally to the two ones which are deleted below. As long as those are
+ // in the UNDO there is no problem, but as soon as they get deleted, the
+ // MarkList will contain deleted objects -> GPF.
+ UnmarkAllObj(pInsPV);
+ MarkObj(pPath, pInsPV, FALSE, TRUE);
+ }
+
+ // UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
+ aRemoveMerker.ForceSort(); // wichtig fuer Remove (s.u.)
+ if( bUndo )
+ SetUndoComment(ImpGetResStr(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveMerker.GetMarkDescription());
+
+ // die tatsaechlich verwendeten Objekten aus der Liste entfernen
+ DeleteMarkedList(aRemoveMerker);
+ if( bUndo )
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@ @@@@ @@ @@ @@@@ @@ @@ @@@@@@ @@ @@@@@
+// @@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@@@@@@ @@ @@ @@@@@@ @@ @@ @@
+// @@ @@ @@ @@@@ @@@@@@@ @@@@@@ @@@@@@ @@ @@ @@@@
+// @@ @@ @@ @@ @@ @ @@ @@ @@ @@ @@@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@@ @@ @@@@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrEditView::ImpCanDismantle(const basegfx::B2DPolyPolygon& rPpolyPolygon, sal_Bool bMakeLines) const
+{
+ sal_Bool bCan(sal_False);
+ const sal_uInt32 nPolygonCount(rPpolyPolygon.count());
+
+ if(nPolygonCount >= 2L)
+ {
+ // #i69172# dismantle makes sense with 2 or more polygons in a polyPolygon
+ bCan = sal_True;
+ }
+ else if(bMakeLines && 1L == nPolygonCount)
+ {
+ // #i69172# ..or with at least 2 edges (curves or lines)
+ const basegfx::B2DPolygon aPolygon(rPpolyPolygon.getB2DPolygon(0L));
+ const sal_uInt32 nPointCount(aPolygon.count());
+
+ if(nPointCount > 2L)
+ {
+ bCan = sal_True;
+ }
+ }
+
+ return bCan;
+}
+
+sal_Bool SdrEditView::ImpCanDismantle(const SdrObject* pObj, sal_Bool bMakeLines) const
+{
+ sal_Bool bOtherObjs(sal_False); // TRUE=andere Objekte ausser PathObj's vorhanden
+ sal_Bool bMin1PolyPoly(sal_False); // TRUE=mind. 1 PolyPolygon mit mehr als ein Polygon vorhanden
+ SdrObjList* pOL = pObj->GetSubList();
+
+ if(pOL)
+ {
+ // Aha, Gruppenobjekt. Also alle Member ansehen.
+ // Alle muessen PathObjs sein !
+ SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
+
+ while(aIter.IsMore() && !bOtherObjs)
+ {
+ const SdrObject* pObj1 = aIter.Next();
+ const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj1);
+
+ if(pPath)
+ {
+ if(ImpCanDismantle(pPath->GetPathPoly(), bMakeLines))
+ {
+ bMin1PolyPoly = sal_True;
+ }
+
+ SdrObjTransformInfoRec aInfo;
+ pObj1->TakeObjInfo(aInfo);
+
+ if(!aInfo.bCanConvToPath)
+ {
+ // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
+ bOtherObjs = sal_True;
+ }
+ }
+ else
+ {
+ bOtherObjs = sal_True;
+ }
+ }
+ }
+ else
+ {
+ const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
+ const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
+
+ // #i37011#
+ if(pPath)
+ {
+ if(ImpCanDismantle(pPath->GetPathPoly(),bMakeLines))
+ {
+ bMin1PolyPoly = sal_True;
+ }
+
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+
+ // #69711 : new condition IsLine() to be able to break simple Lines
+ if(!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine())
+ {
+ // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
+ bOtherObjs = sal_True;
+ }
+ }
+ else if(pCustomShape)
+ {
+ if(bMakeLines)
+ {
+ // allow break command
+ bMin1PolyPoly = sal_True;
+ }
+ }
+ else
+ {
+ bOtherObjs = sal_True;
+ }
+ }
+ return bMin1PolyPoly && !bOtherObjs;
+}
+
+void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, ULONG& rPos, SdrPageView* pPV, BOOL bMakeLines)
+{
+ const SdrPathObj* pSrcPath = PTR_CAST(SdrPathObj, pObj);
+ const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
+
+ const bool bUndo = IsUndoEnabled();
+
+ if(pSrcPath)
+ {
+ // #i74631# redesigned due to XpolyPolygon removal and explicit constructors
+ SdrObject* pLast = 0; // fuer die Zuweisung des OutlinerParaObject
+ const basegfx::B2DPolyPolygon& rPolyPolygon(pSrcPath->GetPathPoly());
+ const sal_uInt32 nPolyCount(rPolyPolygon.count());
+
+ for(sal_uInt32 a(0); a < nPolyCount; a++)
+ {
+ const basegfx::B2DPolygon& rCandidate(rPolyPolygon.getB2DPolygon(a));
+ const sal_uInt32 nPointCount(rCandidate.count());
+
+ if(!bMakeLines || nPointCount < 2)
+ {
+ SdrPathObj* pPath = new SdrPathObj((SdrObjKind)pSrcPath->GetObjIdentifier(), basegfx::B2DPolyPolygon(rCandidate));
+ ImpCopyAttributes(pSrcPath, pPath);
+ pLast = pPath;
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
+ rOL.InsertObject(pPath, rPos, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, TRUE));
+ MarkObj(pPath, pPV, FALSE, TRUE);
+ rPos++;
+ }
+ else
+ {
+ const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
+
+ for(sal_uInt32 b(0); b < nLoopCount; b++)
+ {
+ SdrObjKind eKind(OBJ_PLIN);
+ basegfx::B2DPolygon aNewPolygon;
+ const sal_uInt32 nNextIndex((b + 1) % nPointCount);
+
+ aNewPolygon.append(rCandidate.getB2DPoint(b));
+
+ if(rCandidate.areControlPointsUsed())
+ {
+ aNewPolygon.appendBezierSegment(
+ rCandidate.getNextControlPoint(b),
+ rCandidate.getPrevControlPoint(nNextIndex),
+ rCandidate.getB2DPoint(nNextIndex));
+ eKind = OBJ_PATHLINE;
+ }
+ else
+ {
+ aNewPolygon.append(rCandidate.getB2DPoint(nNextIndex));
+ }
+
+ SdrPathObj* pPath = new SdrPathObj(eKind, basegfx::B2DPolyPolygon(aNewPolygon));
+ ImpCopyAttributes(pSrcPath, pPath);
+ pLast = pPath;
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
+ rOL.InsertObject(pPath, rPos, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, TRUE));
+ MarkObj(pPath, pPV, FALSE, TRUE);
+ rPos++;
+ }
+ }
+ }
+
+ if(pLast && pSrcPath->GetOutlinerParaObject())
+ {
+ pLast->SetOutlinerParaObject(new OutlinerParaObject(*pSrcPath->GetOutlinerParaObject()));
+ }
+ }
+ else if(pCustomShape)
+ {
+ if(bMakeLines)
+ {
+ // break up custom shape
+ const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
+
+ if(pReplacement)
+ {
+ SdrObject* pCandidate = pReplacement->Clone();
+ DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
+ pCandidate->SetModel(pCustomShape->GetModel());
+
+ if(((SdrShadowItem&)pCustomShape->GetMergedItem(SDRATTR_SHADOW)).GetValue())
+ {
+ if(pReplacement->ISA(SdrObjGroup))
+ {
+ pCandidate->SetMergedItem(SdrShadowItem(sal_True));
+ }
+ }
+
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pCustomShape);
+ rOL.InsertObject(pCandidate, rPos, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
+ MarkObj(pCandidate, pPV, FALSE, TRUE);
+
+ if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
+ {
+ // #i37011# also create a text object and add at rPos + 1
+ SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject(
+ pCustomShape->GetObjInventor(), OBJ_TEXT, 0L, pCustomShape->GetModel());
+
+ // Copy text content
+ OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
+ if(pParaObj)
+ {
+ pTextObj->NbcSetOutlinerParaObject(new OutlinerParaObject(*pParaObj));
+ }
+
+ // copy all attributes
+ SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
+
+ // clear fill and line style
+ aTargetItemSet.Put(XLineStyleItem(XLINE_NONE));
+ aTargetItemSet.Put(XFillStyleItem(XFILL_NONE));
+
+ // get the text bounds and set at text object
+ Rectangle aTextBounds = pCustomShape->GetSnapRect();
+ if(pCustomShape->GetTextBounds(aTextBounds))
+ {
+ pTextObj->SetSnapRect(aTextBounds);
+ }
+
+ // if rotated, copy GeoStat, too.
+ const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
+ if(rSourceGeo.nDrehWink)
+ {
+ pTextObj->NbcRotate(
+ pCustomShape->GetSnapRect().Center(), rSourceGeo.nDrehWink,
+ rSourceGeo.nSin, rSourceGeo.nCos);
+ }
+
+ // set modified ItemSet at text object
+ pTextObj->SetMergedItemSet(aTargetItemSet);
+
+ // insert object
+ rOL.InsertObject(pTextObj, rPos + 1, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
+ MarkObj(pTextObj, pPV, FALSE, TRUE);
+ }
+ }
+ }
+ }
+}
+
+void SdrEditView::DismantleMarkedObjects(BOOL bMakeLines)
+{
+ //UINT32 nCnt(0);
+ // Temporaere Marklist
+ SdrMarkList aRemoveMerker;
+
+ SortMarkedObjects();
+
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ // Der Comment wird spaeter zusammengebaut
+ BegUndo(String(), String(),
+ bMakeLines ? SDRREPFUNC_OBJ_DISMANTLE_LINES : SDRREPFUNC_OBJ_DISMANTLE_POLYS);
+ }
+
+ ULONG nm;
+ ULONG nAnz=GetMarkedObjectCount();
+ SdrObjList* pOL0=NULL;
+ for (nm=nAnz; nm>0;) {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // sicherstellen, dass OrdNums stimmen!
+ if (ImpCanDismantle(pObj,bMakeLines)) {
+ aRemoveMerker.InsertEntry(SdrMark(pObj,pM->GetPageView()));
+ ULONG nPos0=pObj->GetOrdNumDirect();
+ ULONG nPos=nPos0+1;
+ SdrObjList* pSubList=pObj->GetSubList();
+ if (pSubList!=NULL && !pObj->Is3DObj()) {
+ SdrObjListIter aIter(*pSubList,IM_DEEPNOGROUPS);
+ while (aIter.IsMore()) {
+ const SdrObject* pObj1=aIter.Next();
+ ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
+ }
+ } else {
+ ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
+ }
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,TRUE));
+ pOL->RemoveObject(nPos0);
+
+ if( !bUndo )
+ SdrObject::Free(pObj);
+ }
+ }
+
+ if( bUndo )
+ {
+ // UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
+ SetUndoComment(ImpGetResStr(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveMerker.GetMarkDescription());
+ // die tatsaechlich verwendeten Objekten aus der Liste entfernen
+ EndUndo();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// #### #### ### # # ####
+// # # # # # # # # #
+// # ## #### # # # # ####
+// # # # # # # # # #
+// #### # # ### ### #
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::GroupMarked(const SdrObject* pUserGrp)
+{
+ if (AreObjectsMarked())
+ {
+ SortMarkedObjects();
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ BegUndo(ImpGetResStr(STR_EditGroup),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_GROUP);
+
+ const ULONG nAnz = GetMarkedObjectCount();
+ for(ULONG nm = nAnz; nm>0; )
+ {
+ // UndoActions fuer alle betroffenen Objekte anlegen
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj = pM->GetMarkedSdrObj();
+ std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
+ AddUndoActions( vConnectorUndoActions );
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject( *pObj ));
+ }
+ }
+
+ SdrMarkList aNewMark;
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ SdrObjList* pAktLst=pPV->GetObjList();
+ SdrObjList* pSrcLst=pAktLst;
+ SdrObjList* pSrcLst0=pSrcLst;
+ SdrPage* pPage=pPV->GetPage();
+ // sicherstellen, dass die OrdNums stimmen
+ if (pSrcLst->IsObjOrdNumsDirty())
+ pSrcLst->RecalcObjOrdNums();
+ SdrObject* pGrp=NULL;
+ SdrObject* pRefObj=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
+ SdrObject* pRefObj1=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
+ SdrObjList* pDstLst=NULL;
+ // Falls alle markierten Objekte aus Fremden Obj-Listen
+ // kommen, kommt das Gruppenobjekt an das Ende der Liste.
+ ULONG nInsPos=pSrcLst->GetObjCount();
+ BOOL bNeedInsPos=TRUE;
+ for (ULONG nm=GetMarkedObjectCount(); nm>0;)
+ {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ if (pM->GetPageView()==pPV)
+ {
+ if (pGrp==NULL)
+ {
+ if (pUserGrp!=NULL)
+ pGrp=pUserGrp->Clone();
+ if (pGrp==NULL)
+ pGrp=new SdrObjGroup;
+ pDstLst=pGrp->GetSubList();
+ DBG_ASSERT(pDstLst!=NULL,"Angebliches Gruppenobjekt liefert keine Objektliste");
+ }
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ pSrcLst=pObj->GetObjList();
+ if (pSrcLst!=pSrcLst0)
+ {
+ if (pSrcLst->IsObjOrdNumsDirty())
+ pSrcLst->RecalcObjOrdNums();
+ }
+ BOOL bForeignList=pSrcLst!=pAktLst;
+ BOOL bGrouped=pSrcLst!=pPage;
+ if (!bForeignList && bNeedInsPos)
+ {
+ nInsPos=pObj->GetOrdNum(); // ua, damit sind alle ObjOrdNum der Page gesetzt
+ nInsPos++;
+ bNeedInsPos=FALSE;
+ }
+ pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
+ if (!bForeignList)
+ nInsPos--; // InsertPos korregieren
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pDstLst->InsertObject(pObj,0,&aReason);
+ GetMarkedObjectListWriteAccess().DeleteMark(nm);
+ if (pRefObj1==NULL)
+ pRefObj1=pObj; // Das oberste sichtbare Objekt
+ if (!bGrouped)
+ {
+ if (pRefObj==NULL)
+ pRefObj=pObj; // Das oberste sichtbare nicht gruppierte Objekt
+ }
+ pSrcLst0=pSrcLst;
+ }
+ }
+ if (pRefObj==NULL)
+ pRefObj=pRefObj1;
+ if (pGrp!=NULL)
+ {
+ aNewMark.InsertEntry(SdrMark(pGrp,pPV));
+ ULONG nAnz=pDstLst->GetObjCount();
+ SdrInsertReason aReason(SDRREASON_VIEWCALL,pRefObj);
+ pAktLst->InsertObject(pGrp,nInsPos,&aReason);
+ if( bUndo )
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pGrp,true)); // Kein Recalc!
+ for (ULONG no=0; no<nAnz; no++)
+ {
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pDstLst->GetObj(no)));
+ }
+ }
+ }
+ }
+ GetMarkedObjectListWriteAccess().Merge(aNewMark);
+ MarkListHasChanged();
+
+ if( bUndo )
+ EndUndo();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// # # # # #### #### ### # # ####
+// # # ## # # # # # # # # # #
+// # # # # # # ## #### # # # # ####
+// # # # ## # # # # # # # # #
+// ### # # #### # # ### ### #
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::UnGroupMarked()
+{
+ SdrMarkList aNewMark;
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(String(), String(), SDRREPFUNC_OBJ_UNGROUP);
+
+ ULONG nCount=0;
+ XubString aName1;
+ XubString aName;
+ BOOL bNameOk=FALSE;
+ for (ULONG nm=GetMarkedObjectCount(); nm>0;) {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pGrp=pM->GetMarkedSdrObj();
+ SdrObjList* pSrcLst=pGrp->GetSubList();
+ if (pSrcLst!=NULL) {
+ nCount++;
+ if (nCount==1) {
+ pGrp->TakeObjNameSingul(aName); // Bezeichnung der Gruppe holen
+ pGrp->TakeObjNamePlural(aName1); // Bezeichnung der Gruppe holen
+ bNameOk=TRUE;
+ } else {
+ if (nCount==2) aName=aName1; // Pluralname setzen
+ if (bNameOk) {
+ XubString aStr;
+ pGrp->TakeObjNamePlural(aStr); // Bezeichnung der Gruppe holen
+
+ if(!aStr.Equals(aName))
+ bNameOk = FALSE;
+ }
+ }
+ ULONG nDstCnt=pGrp->GetOrdNum();
+ SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
+
+ // FIRST move contained objects to parent of group, so that
+ // the contained objects are NOT migrated to the UNDO-ItemPool
+ // when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
+ ULONG nAnz=pSrcLst->GetObjCount();
+ ULONG no;
+
+ if( bUndo )
+ {
+ for (no=nAnz; no>0;)
+ {
+ no--;
+ SdrObject* pObj=pSrcLst->GetObj(no);
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
+ }
+ }
+ for (no=0; no<nAnz; no++)
+ {
+ SdrObject* pObj=pSrcLst->RemoveObject(0);
+ SdrInsertReason aReason(SDRREASON_VIEWCALL,pGrp);
+ pDstLst->InsertObject(pObj,nDstCnt,&aReason);
+ if( bUndo )
+ AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
+ nDstCnt++;
+ // Kein SortCheck beim einfuegen in die MarkList, denn das
+ // wuerde wg. pObj->GetOrdNum() jedesmal ein RecalcOrdNums()
+ // provozieren:
+ aNewMark.InsertEntry(SdrMark(pObj,pM->GetPageView()),FALSE);
+ }
+
+ if( bUndo )
+ {
+ // Now it is safe to add the delete-UNDO which trigers the
+ // MigrateItemPool now only for itself, not for the subobjects.
+ // nDstCnt is right, because previous inserts move group
+ // object deeper and increase nDstCnt.
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
+ }
+ pDstLst->RemoveObject(nDstCnt);
+
+ if( !bUndo )
+ SdrObject::Free(pGrp);
+
+ GetMarkedObjectListWriteAccess().DeleteMark(nm);
+ }
+ }
+ if (nCount!=0)
+ {
+ if (!bNameOk)
+ aName=ImpGetResStr(STR_ObjNamePluralGRUP); // Oberbegriff Gruppenobjekte verwenden, wenn verschiedene Objekte.
+ SetUndoComment(ImpGetResStr(STR_EditUngroup),aName);
+ }
+
+ if( bUndo )
+ EndUndo();
+
+ if (nCount!=0)
+ {
+ GetMarkedObjectListWriteAccess().Merge(aNewMark,TRUE); // Durch das obige Einsortieren ist aNewMark genau verkehrtherum
+ MarkListHasChanged();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// ### ### # # # # ##### #### ##### ##### ### #### ### # # #
+// # # # # ## # # # # # # # # # # # # # # # # #
+// # # # # # # # # #### #### # # # # #### # # # #
+// # # # # # ## # # # # # # # # # # # # # #
+// ### ### # # # ##### # # # # ### # ### #### #
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrEditView::ImpConvertOneObj(SdrObject* pObj, BOOL bPath, BOOL bLineToArea)
+{
+ SdrObject* pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
+ if (pNewObj!=NULL)
+ {
+ SdrObjList* pOL=pObj->GetObjList();
+ DBG_ASSERT(pOL!=NULL,"ConvertTo: Obj liefert keine ObjList");
+ if (pOL!=NULL)
+ {
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
+
+ pOL->ReplaceObject(pNewObj,pObj->GetOrdNum());
+
+ if( !bUndo )
+ SdrObject::Free(pObj);
+ }
+ }
+ return pNewObj;
+}
+
+void SdrEditView::ImpConvertTo(BOOL bPath, BOOL bLineToArea)
+{
+ BOOL bMrkChg=FALSE;
+ BOOL bModChg=FALSE;
+ if (AreObjectsMarked()) {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ USHORT nDscrID=0;
+ if(bLineToArea)
+ {
+ if(nMarkAnz == 1)
+ nDscrID = STR_EditConvToContour;
+ else
+ nDscrID = STR_EditConvToContours;
+
+ BegUndo(ImpGetResStr(nDscrID), GetDescriptionOfMarkedObjects());
+ }
+ else
+ {
+ if (bPath) {
+ if (nMarkAnz==1) nDscrID=STR_EditConvToCurve;
+ else nDscrID=STR_EditConvToCurves;
+ BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPATH);
+ } else {
+ if (nMarkAnz==1) nDscrID=STR_EditConvToPoly;
+ else nDscrID=STR_EditConvToPolys;
+ BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPOLY);
+ }
+ }
+ for (ULONG nm=nMarkAnz; nm>0;) {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
+ SdrObject* pGrp=pObj;
+ SdrObjListIter aIter(*pGrp,IM_DEEPNOGROUPS);
+ while (aIter.IsMore()) {
+ pObj=aIter.Next();
+ if (ImpConvertOneObj(pObj,bPath,bLineToArea)) bModChg=TRUE;
+ }
+ } else {
+ SdrObject* pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
+ if (pNewObj!=NULL) {
+ bModChg=TRUE;
+ bMrkChg=TRUE;
+ GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj,pPV),nm);
+ }
+ }
+ }
+ EndUndo();
+ if (bMrkChg) AdjustMarkHdl();
+ if (bMrkChg) MarkListHasChanged();
+ }
+}
+
+void SdrEditView::ConvertMarkedToPathObj(BOOL bLineToArea)
+{
+ ImpConvertTo(TRUE, bLineToArea);
+}
+
+void SdrEditView::ConvertMarkedToPolyObj(BOOL bLineToArea)
+{
+ ImpConvertTo(FALSE, bLineToArea);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// # # ##### ##### ### ##### # # ##### # # # #### ### #### #####
+// ## ## # # # # # # # # # ## ## # # # # # # #
+// # # # #### # ##### ### # # #### ### # # # # #### # # #### #
+// # # # # # # # # # # # # # # # # # # #
+// # # ##### # # # # # #### ##### # # # # ### # # #
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo(String(), String(), SDRREPFUNC_OBJ_IMPORTMTF);
+
+ SortMarkedObjects();
+ SdrMarkList aForTheDescription;
+ SdrMarkList aNewMarked;
+ ULONG nAnz=GetMarkedObjectCount();
+
+ for (ULONG nm=nAnz; nm>0;)
+ { // Undo Objekte fuer alle neuen Objekte erzeugen
+ // zwischen den Metafiles auf Abbruch testen
+ if( pProgrInfo != NULL )
+ {
+ pProgrInfo->SetNextObject();
+ if(!pProgrInfo->ReportActions(0))
+ break;
+ }
+
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ SdrObjList* pOL=pObj->GetObjList();
+ ULONG nInsPos=pObj->GetOrdNum()+1;
+ SdrGrafObj* pGraf=PTR_CAST(SdrGrafObj,pObj);
+ SdrOle2Obj* pOle2=PTR_CAST(SdrOle2Obj,pObj);
+ ULONG nInsAnz=0;
+ if (pGraf!=NULL && pGraf->HasGDIMetaFile())
+ {
+ ImpSdrGDIMetaFileImport aFilter(*pMod);
+ aFilter.SetScaleRect(pGraf->GetSnapRect());
+ aFilter.SetLayer(pObj->GetLayer());
+ nInsAnz=aFilter.DoImport(pGraf->GetTransformedGraphic().GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
+ }
+ if ( pOle2!=NULL && pOle2->GetGraphic() )
+ {
+ //const GDIMetaFile* pMtf=pOle2->GetGDIMetaFile();
+ ImpSdrGDIMetaFileImport aFilter(*pMod);
+ aFilter.SetScaleRect(pOle2->GetLogicRect());
+ aFilter.SetLayer(pObj->GetLayer());
+ nInsAnz=aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
+ }
+ if (nInsAnz!=0)
+ {
+ ULONG nObj=nInsPos;
+ for (ULONG i=0; i<nInsAnz; i++)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
+
+ // Neue MarkList pflegen
+ SdrMark aNewMark(pOL->GetObj(nObj), pPV);
+ aNewMarked.InsertEntry(aNewMark);
+
+ nObj++;
+ }
+ aForTheDescription.InsertEntry(*pM);
+
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
+
+ // Objekt aus selektion loesen und loeschen
+ GetMarkedObjectListWriteAccess().DeleteMark(TryToFindMarkedObject(pObj));
+ pOL->RemoveObject(nInsPos-1);
+
+ if( !bUndo )
+ SdrObject::Free(pObj);
+ }
+ }
+
+ // MarkObj... fehlt... jetzt nicht mehr (AW)
+ if(aNewMarked.GetMarkCount())
+ {
+ // Neue Selektion bilden
+ for(ULONG a(0); a < aNewMarked.GetMarkCount(); a++)
+ {
+ GetMarkedObjectListWriteAccess().InsertEntry(*aNewMarked.GetMark(a));
+ }
+
+ SortMarkedObjects();
+ }
+
+ if( bUndo )
+ {
+ SetUndoComment(ImpGetResStr(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
+ EndUndo();
+ }
+}
+
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
new file mode 100644
index 000000000000..7235310def0b
--- /dev/null
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -0,0 +1,2146 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <com/sun/star/i18n/WordType.hpp>
+
+#include <svtools/accessibilityoptions.hxx>
+
+#include <svx/svdedxv.hxx>
+#include <svl/solar.hrc>
+
+//#include <tools/string.h>
+#include <svl/itemiter.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/hatch.hxx>
+#include <svl/whiter.hxx>
+#include <svl/style.hxx>
+#include <editeng/editstat.hxx>
+#include <tools/config.hxx>
+#include <vcl/cursor.hxx>
+#include <editeng/unotext.hxx>
+
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/scripttypeitem.hxx>
+#include "svditext.hxx"
+#include <svx/svdoutl.hxx>
+#include <svx/sdtfchim.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdundo.hxx>
+#include "svditer.hxx"
+#include "svx/svdpagv.hxx"
+#include "svx/svdpage.hxx"
+#include "svx/svdetc.hxx" // fuer GetDraftFillColor
+#include "svx/svdotable.hxx"
+#include <svx/selectioncontroller.hxx>
+#ifdef DBG_UTIL
+#include <svdibrow.hxx>
+#endif
+
+#include <svx/svdoutl.hxx>
+#include <svx/svddrgv.hxx> // fuer SetSolidDragging()
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include "globl3d.hxx"
+#include <editeng/outliner.hxx>
+#include <editeng/adjitem.hxx>
+
+// #98988#
+#include <svtools/colorcfg.hxx>
+#include <vcl/svapp.hxx> //add CHINA001
+#include <sdrpaintwindow.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObjEditView::ImpClearVars()
+{
+ bQuickTextEditMode=TRUE;
+ bMacroMode=TRUE;
+ pTextEditOutliner=NULL;
+ pTextEditOutlinerView=NULL;
+ pTextEditPV=NULL;
+ pTextEditWin=NULL;
+ pTextEditCursorMerker=NULL;
+ pEditPara=NULL;
+ bTextEditNewObj=FALSE;
+ bMacroDown=FALSE;
+ pMacroObj=NULL;
+ pMacroPV=NULL;
+ pMacroWin=NULL;
+ nMacroTol=0;
+ bTextEditDontDelete=FALSE;
+ bTextEditOnlyOneView=FALSE;
+}
+
+SdrObjEditView::SdrObjEditView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrGlueEditView(pModel1,pOut)
+{
+ ImpClearVars();
+}
+
+SdrObjEditView::~SdrObjEditView()
+{
+ pTextEditWin = NULL; // Damit es in SdrEndTextEdit kein ShowCursor gibt
+ if (IsTextEdit()) SdrEndTextEdit();
+ if (pTextEditOutliner!=NULL) {
+ delete pTextEditOutliner;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrObjEditView::IsAction() const
+{
+ return IsMacroObj() || SdrGlueEditView::IsAction();
+}
+
+void SdrObjEditView::MovAction(const Point& rPnt)
+{
+ if (IsMacroObj()) MovMacroObj(rPnt);
+ SdrGlueEditView::MovAction(rPnt);
+}
+
+void SdrObjEditView::EndAction()
+{
+ if (IsMacroObj()) EndMacroObj();
+ SdrGlueEditView::EndAction();
+}
+
+void SdrObjEditView::BckAction()
+{
+ BrkMacroObj();
+ SdrGlueEditView::BckAction();
+}
+
+void SdrObjEditView::BrkAction()
+{
+ BrkMacroObj();
+ SdrGlueEditView::BrkAction();
+}
+
+void SdrObjEditView::TakeActionRect(Rectangle& rRect) const
+{
+ if (IsMacroObj()) {
+ rRect=pMacroObj->GetCurrentBoundRect();
+ } else {
+ SdrGlueEditView::TakeActionRect(rRect);
+ }
+}
+
+void __EXPORT SdrObjEditView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SdrGlueEditView::Notify(rBC,rHint);
+ // Printerwechsel waerend des Editierens
+ SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
+ if (pSdrHint!=NULL && pTextEditOutliner!=NULL) {
+ SdrHintKind eKind=pSdrHint->GetKind();
+ if (eKind==HINT_REFDEVICECHG) {
+ pTextEditOutliner->SetRefDevice(pMod->GetRefDevice());
+ }
+ if (eKind==HINT_DEFAULTTABCHG) {
+ pTextEditOutliner->SetDefTab(pMod->GetDefaultTabulator());
+ }
+ if (eKind==HINT_DEFFONTHGTCHG) {
+ // ...
+ }
+ if (eKind==HINT_MODELSAVED) { // #43095#
+ pTextEditOutliner->ClearModifyFlag();
+ }
+ }
+}
+
+void SdrObjEditView::ModelHasChanged()
+{
+ SdrGlueEditView::ModelHasChanged();
+ if (mxTextEditObj.is() && !mxTextEditObj->IsInserted()) SdrEndTextEdit(); // Objekt geloescht
+ // TextEditObj geaendert?
+ if (IsTextEdit()) {
+ SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( mxTextEditObj.get() );
+ if (pTextObj!=NULL) {
+ ULONG nOutlViewAnz=pTextEditOutliner->GetViewCount();
+ BOOL bAreaChg=FALSE;
+ BOOL bAnchorChg=FALSE;
+ BOOL bColorChg=FALSE;
+ bool bContourFrame=pTextObj->IsContourTextFrame();
+ EVAnchorMode eNewAnchor(ANCHOR_VCENTER_HCENTER);
+ Rectangle aOldArea(aMinTextEditArea);
+ aOldArea.Union(aTextEditArea);
+ Color aNewColor;
+ { // Area Checken
+ Size aPaperMin1;
+ Size aPaperMax1;
+ Rectangle aEditArea1;
+ Rectangle aMinArea1;
+ pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1);
+
+ // #108784#
+ Point aPvOfs(pTextObj->GetTextEditOffset());
+
+ aEditArea1.Move(aPvOfs.X(),aPvOfs.Y());
+ aMinArea1.Move(aPvOfs.X(),aPvOfs.Y());
+ Rectangle aNewArea(aMinArea1);
+ aNewArea.Union(aEditArea1);
+ if (aNewArea!=aOldArea || aEditArea1!=aTextEditArea || aMinArea1!=aMinTextEditArea ||
+ pTextEditOutliner->GetMinAutoPaperSize()!=aPaperMin1 || pTextEditOutliner->GetMaxAutoPaperSize()!=aPaperMax1) {
+ aTextEditArea=aEditArea1;
+ aMinTextEditArea=aMinArea1;
+ pTextEditOutliner->SetUpdateMode(FALSE);
+ pTextEditOutliner->SetMinAutoPaperSize(aPaperMin1);
+ pTextEditOutliner->SetMaxAutoPaperSize(aPaperMax1);
+ pTextEditOutliner->SetPaperSize(Size(0,0)); // Damit der Outliner neu formatiert
+ if (!bContourFrame) {
+ pTextEditOutliner->ClearPolygon();
+ ULONG nStat=pTextEditOutliner->GetControlWord();
+ nStat|=EE_CNTRL_AUTOPAGESIZE;
+ pTextEditOutliner->SetControlWord(nStat);
+ } else {
+ ULONG nStat=pTextEditOutliner->GetControlWord();
+ nStat&=~EE_CNTRL_AUTOPAGESIZE;
+ pTextEditOutliner->SetControlWord(nStat);
+ Rectangle aAnchorRect;
+ pTextObj->TakeTextAnchorRect(aAnchorRect);
+ pTextObj->ImpSetContourPolygon(*pTextEditOutliner,aAnchorRect, TRUE);
+ }
+ for (ULONG nOV=0; nOV<nOutlViewAnz; nOV++) {
+ OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
+ ULONG nStat0=pOLV->GetControlWord();
+ ULONG nStat=nStat0;
+ // AutoViewSize nur wenn nicht KontourFrame.
+ if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
+ else nStat&=~EV_CNTRL_AUTOSIZE;
+ if (nStat!=nStat0) pOLV->SetControlWord(nStat);
+ }
+ pTextEditOutliner->SetUpdateMode(TRUE);
+ bAreaChg=TRUE;
+ }
+ }
+ if (pTextEditOutlinerView!=NULL) { // Fuellfarbe und Anker checken
+ EVAnchorMode eOldAnchor=pTextEditOutlinerView->GetAnchorMode();
+ eNewAnchor=(EVAnchorMode)pTextObj->GetOutlinerViewAnchorMode();
+ bAnchorChg=eOldAnchor!=eNewAnchor;
+ Color aOldColor(pTextEditOutlinerView->GetBackgroundColor());
+ aNewColor = GetTextEditBackgroundColor(*this);
+ bColorChg=aOldColor!=aNewColor;
+ }
+ // #104082# refresh always when it's a contour frame. That
+ // refresh is necessary since it triggers the repaint
+ // which makes the Handles visible. Changes at TakeTextRect()
+ // seem to have resulted in a case where no refresh is executed.
+ // Before that, a refresh must have been always executed
+ // (else this error would have happend earlier), thus i
+ // even think here a refresh should be done always.
+ // Since follow-up problems cannot even be guessed I only
+ // add this one more case to the if below.
+ // BTW: It's VERY bad style that here, inside ModelHasChanged()
+ // the outliner is again massively changed for the text object
+ // in text edit mode. Normally, all necessary data should be
+ // set at SdrBeginTextEdit(). Some changes and value assigns in
+ // SdrBeginTextEdit() are completely useless since they are set here
+ // again on ModelHasChanged().
+ if (bContourFrame || bAreaChg || bAnchorChg || bColorChg)
+ {
+ for (ULONG nOV=0; nOV<nOutlViewAnz; nOV++)
+ {
+ OutlinerView* pOLV=pTextEditOutliner->GetView(nOV);
+ { // Alten OutlinerView-Bereich invalidieren
+ Window* pWin=pOLV->GetWindow();
+ Rectangle aTmpRect(aOldArea);
+ USHORT nPixSiz=pOLV->GetInvalidateMore()+1;
+ Size aMore(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
+ aTmpRect.Left()-=aMore.Width();
+ aTmpRect.Right()+=aMore.Width();
+ aTmpRect.Top()-=aMore.Height();
+ aTmpRect.Bottom()+=aMore.Height();
+ InvalidateOneWin(*pWin,aTmpRect);
+ }
+ if (bAnchorChg)
+ pOLV->SetAnchorMode(eNewAnchor);
+ if (bColorChg)
+ pOLV->SetBackgroundColor( aNewColor );
+
+ pOLV->SetOutputArea(aTextEditArea); // weil sonst scheinbar nicht richtig umgeankert wird
+ ImpInvalidateOutlinerView(*pOLV);
+ }
+ pTextEditOutlinerView->ShowCursor();
+ }
+ }
+ ImpMakeTextCursorAreaVisible();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@@ @@@@@ @@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@@@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObjEditView::ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect) const
+{
+ Window* pWin = rOutlView.GetWindow();
+
+ if(pWin)
+ {
+ const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
+ bool bTextFrame(pText && pText->IsTextFrame());
+ bool bFitToSize(0 != (pTextEditOutliner->GetControlWord() & EE_CNTRL_STRETCHING));
+ bool bModifyMerk(pTextEditOutliner->IsModified()); // #43095#
+ Rectangle aBlankRect(rOutlView.GetOutputArea());
+ aBlankRect.Union(aMinTextEditArea);
+ Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
+ aBlankRect.Intersection(rRect);
+ rOutlView.GetOutliner()->SetUpdateMode(TRUE); // Bugfix #22596#
+ rOutlView.Paint(aBlankRect);
+
+ if(!bModifyMerk)
+ {
+ // #43095#
+ pTextEditOutliner->ClearModifyFlag();
+ }
+
+ if(bTextFrame && !bFitToSize)
+ {
+ aPixRect.Left()--;
+ aPixRect.Top()--;
+ aPixRect.Right()++;
+ aPixRect.Bottom()++;
+ sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
+
+ {
+ // xPixRect Begrenzen, wegen Treiberproblem bei zu weit hinausragenden Pixelkoordinaten
+ Size aMaxXY(pWin->GetOutputSizePixel());
+ long a(2 * nPixSiz);
+ long nMaxX(aMaxXY.Width() + a);
+ long nMaxY(aMaxXY.Height() + a);
+
+ if (aPixRect.Left ()<-a) aPixRect.Left()=-a;
+ if (aPixRect.Top ()<-a) aPixRect.Top ()=-a;
+ if (aPixRect.Right ()>nMaxX) aPixRect.Right ()=nMaxX;
+ if (aPixRect.Bottom()>nMaxY) aPixRect.Bottom()=nMaxY;
+ }
+
+ Rectangle aOuterPix(aPixRect);
+ aOuterPix.Left()-=nPixSiz;
+ aOuterPix.Top()-=nPixSiz;
+ aOuterPix.Right()+=nPixSiz;
+ aOuterPix.Bottom()+=nPixSiz;
+
+ bool bMerk(pWin->IsMapModeEnabled());
+ pWin->EnableMapMode(FALSE);
+ PolyPolygon aPolyPoly( 2 );
+
+ svtools::ColorConfig aColorConfig;
+ Color aHatchCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
+ const Hatch aHatch( HATCH_SINGLE, aHatchCol, 3, 450 );
+
+ aPolyPoly.Insert( aOuterPix );
+ aPolyPoly.Insert( aPixRect );
+ pWin->DrawHatch( aPolyPoly, aHatch );
+
+ pWin->EnableMapMode(bMerk);
+ }
+
+ rOutlView.ShowCursor();
+ }
+}
+
+void SdrObjEditView::ImpInvalidateOutlinerView(OutlinerView& rOutlView) const
+{
+ Window* pWin = rOutlView.GetWindow();
+
+ if(pWin)
+ {
+ const SdrTextObj* pText = PTR_CAST(SdrTextObj,GetTextEditObject());
+ bool bTextFrame(pText && pText->IsTextFrame());
+ bool bFitToSize(0 != (pTextEditOutliner->GetControlWord() & EE_CNTRL_STRETCHING));
+
+ if(bTextFrame && !bFitToSize)
+ {
+ Rectangle aBlankRect(rOutlView.GetOutputArea());
+ aBlankRect.Union(aMinTextEditArea);
+ Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
+ sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
+
+ aPixRect.Left()--;
+ aPixRect.Top()--;
+ aPixRect.Right()++;
+ aPixRect.Bottom()++;
+
+ {
+ // xPixRect Begrenzen, wegen Treiberproblem bei zu weit hinausragenden Pixelkoordinaten
+ Size aMaxXY(pWin->GetOutputSizePixel());
+ long a(2 * nPixSiz);
+ long nMaxX(aMaxXY.Width() + a);
+ long nMaxY(aMaxXY.Height() + a);
+
+ if (aPixRect.Left ()<-a) aPixRect.Left()=-a;
+ if (aPixRect.Top ()<-a) aPixRect.Top ()=-a;
+ if (aPixRect.Right ()>nMaxX) aPixRect.Right ()=nMaxX;
+ if (aPixRect.Bottom()>nMaxY) aPixRect.Bottom()=nMaxY;
+ }
+
+ Rectangle aOuterPix(aPixRect);
+ aOuterPix.Left()-=nPixSiz;
+ aOuterPix.Top()-=nPixSiz;
+ aOuterPix.Right()+=nPixSiz;
+ aOuterPix.Bottom()+=nPixSiz;
+
+ bool bMerk(pWin->IsMapModeEnabled());
+ pWin->EnableMapMode(FALSE);
+ pWin->Invalidate(aOuterPix);
+ pWin->EnableMapMode(bMerk);
+ }
+ }
+}
+
+OutlinerView* SdrObjEditView::ImpMakeOutlinerView(Window* pWin, BOOL /*bNoPaint*/, OutlinerView* pGivenView) const
+{
+ // Hintergrund
+ Color aBackground(GetTextEditBackgroundColor(*this));
+ SdrTextObj* pText = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
+ BOOL bTextFrame=pText!=NULL && pText->IsTextFrame();
+ BOOL bContourFrame=pText!=NULL && pText->IsContourTextFrame();
+ // OutlinerView erzeugen
+ OutlinerView* pOutlView=pGivenView;
+ pTextEditOutliner->SetUpdateMode(FALSE);
+ if (pOutlView==NULL) pOutlView=new OutlinerView(pTextEditOutliner,pWin);
+ else pOutlView->SetWindow(pWin);
+ // Scrollen verbieten
+ ULONG nStat=pOutlView->GetControlWord();
+ nStat&=~EV_CNTRL_AUTOSCROLL;
+ // AutoViewSize nur wenn nicht KontourFrame.
+ if (!bContourFrame) nStat|=EV_CNTRL_AUTOSIZE;
+ if (bTextFrame) {
+ USHORT nPixSiz=aHdl.GetHdlSize()*2+1;
+ nStat|=EV_CNTRL_INVONEMORE;
+ pOutlView->SetInvalidateMore(nPixSiz);
+ }
+ pOutlView->SetControlWord(nStat);
+ pOutlView->SetBackgroundColor( aBackground );
+ if (pText!=NULL)
+ {
+ pOutlView->SetAnchorMode((EVAnchorMode)(pText->GetOutlinerViewAnchorMode()));
+ pTextEditOutliner->SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)pText->GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ }
+ pOutlView->SetOutputArea(aTextEditArea);
+ pTextEditOutliner->SetUpdateMode(TRUE);
+ ImpInvalidateOutlinerView(*pOutlView);
+ return pOutlView;
+}
+
+BOOL SdrObjEditView::IsTextEditFrame() const
+{
+ SdrTextObj* pText = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
+ return pText!=NULL && pText->IsTextFrame();
+}
+
+IMPL_LINK(SdrObjEditView,ImpOutlinerStatusEventHdl,EditStatus*,pEditStat)
+{
+ if(pTextEditOutliner )
+ {
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj * >( mxTextEditObj.get() );
+ if( pTextObj )
+ {
+ pTextObj->onEditOutlinerStatusEvent( pEditStat );
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK(SdrObjEditView,ImpOutlinerCalcFieldValueHdl,EditFieldInfo*,pFI)
+{
+ bool bOk=false;
+ String& rStr=pFI->GetRepresentation();
+ rStr.Erase();
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
+ if (pTextObj!=NULL) {
+ Color* pTxtCol=NULL;
+ Color* pFldCol=NULL;
+ bOk=pTextObj->CalcFieldValue(pFI->GetField(),pFI->GetPara(),pFI->GetPos(),TRUE,pTxtCol,pFldCol,rStr);
+ if (bOk) {
+ if (pTxtCol!=NULL) {
+ pFI->SetTxtColor(*pTxtCol);
+ delete pTxtCol;
+ }
+ if (pFldCol!=NULL) {
+ pFI->SetFldColor(*pFldCol);
+ delete pFldCol;
+ } else {
+ pFI->SetFldColor(Color(COL_LIGHTGRAY)); // kann spaeter (357) raus
+ }
+ }
+ }
+ Outliner& rDrawOutl=pMod->GetDrawOutliner(pTextObj);
+ Link aDrawOutlLink=rDrawOutl.GetCalcFieldValueHdl();
+ if (!bOk && aDrawOutlLink.IsSet()) {
+ aDrawOutlLink.Call(pFI);
+ bOk = (BOOL)rStr.Len();
+ }
+ if (!bOk && aOldCalcFieldValueLink.IsSet()) {
+ return aOldCalcFieldValueLink.Call(pFI);
+ }
+ return 0;
+}
+
+sal_Bool SdrObjEditView::SdrBeginTextEdit(
+ SdrObject* pObj, SdrPageView* pPV, Window* pWin,
+ sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner,
+ OutlinerView* pGivenOutlinerView,
+ sal_Bool bDontDeleteOutliner, sal_Bool bOnlyOneView,
+ sal_Bool bGrabFocus)
+{
+ SdrEndTextEdit();
+
+ if( dynamic_cast< SdrTextObj* >( pObj ) == 0 )
+ return FALSE; // currently only possible with text objects
+
+ if(bGrabFocus && pWin)
+ {
+ // attetion, this call may cause an EndTextEdit() call to this view
+ pWin->GrabFocus(); // to force the cursor into the edit view
+ }
+
+ bTextEditDontDelete=bDontDeleteOutliner && pGivenOutliner!=NULL;
+ bTextEditOnlyOneView=bOnlyOneView;
+ bTextEditNewObj=bIsNewObj;
+ const sal_uInt32 nWinAnz(PaintWindowCount());
+ sal_uInt32 i;
+ sal_Bool bBrk(sal_False);
+ // Abbruch, wenn kein Objekt angegeben.
+
+ if(!pObj)
+ {
+ bBrk = sal_True;
+ }
+
+ if(!bBrk && !pWin)
+ {
+ for(i = 0L; i < nWinAnz && !pWin; i++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
+
+ if(OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
+ {
+ pWin = (Window*)(&pPaintWindow->GetOutputDevice());
+ }
+ }
+
+ // Abbruch, wenn kein Window da.
+ if(!pWin)
+ {
+ bBrk = sal_True;
+ }
+ }
+
+ if(!bBrk && !pPV)
+ {
+ pPV = GetSdrPageView();
+
+ // Abbruch, wenn keine PageView zu dem Objekt vorhanden.
+ if(!pPV)
+ {
+ bBrk = sal_True;
+ }
+ }
+
+ if(pObj && pPV)
+ {
+ // Kein TextEdit an Objekten im gesperrten Layer
+ if(pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
+ {
+ bBrk = sal_True;
+ }
+ }
+
+ if(pTextEditOutliner)
+ {
+ DBG_ERROR("SdrObjEditView::SdrBeginTextEdit() da stand noch ein alter Outliner rum");
+ delete pTextEditOutliner;
+ pTextEditOutliner = 0L;
+ }
+
+ if(!bBrk)
+ {
+ pTextEditWin=pWin;
+ pTextEditPV=pPV;
+ mxTextEditObj.reset( pObj );
+ pTextEditOutliner=pGivenOutliner;
+ if (pTextEditOutliner==NULL)
+ pTextEditOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, mxTextEditObj->GetModel() );
+
+ {
+ SvtAccessibilityOptions aOptions;
+ pTextEditOutliner->ForceAutoColor( aOptions.GetIsAutomaticFontColor() );
+ }
+
+ BOOL bEmpty = mxTextEditObj->GetOutlinerParaObject()==NULL;
+
+ aOldCalcFieldValueLink=pTextEditOutliner->GetCalcFieldValueHdl();
+ // Der FieldHdl muss von SdrBeginTextEdit gesetzt sein, da dor ein UpdateFields gerufen wird.
+ pTextEditOutliner->SetCalcFieldValueHdl(LINK(this,SdrObjEditView,ImpOutlinerCalcFieldValueHdl));
+ pTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this,SdrObjEditView,BeginPasteOrDropHdl));
+ pTextEditOutliner->SetEndPasteOrDropHdl(LINK(this,SdrObjEditView, EndPasteOrDropHdl));
+
+ // It is just necessary to make the visualized page known. Set it.
+ pTextEditOutliner->setVisualizedPage(pPV ? pPV->GetPage() : 0);
+
+ pTextEditOutliner->SetTextObjNoInit( dynamic_cast< SdrTextObj* >( mxTextEditObj.get() ) );
+
+ if(mxTextEditObj->BegTextEdit(*pTextEditOutliner))
+ {
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
+ DBG_ASSERT( pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?" );
+ if( !pTextObj )
+ return FALSE;
+
+ // #111096# Switch off evtl. running TextAnimation
+ pTextObj->SetTextAnimationAllowed(sal_False);
+
+ // alten Cursor merken
+ if (pTextEditOutliner->GetViewCount()!=0)
+ {
+ OutlinerView* pTmpOLV=pTextEditOutliner->RemoveView(ULONG(0));
+ if(pTmpOLV!=NULL && pTmpOLV!=pGivenOutlinerView)
+ delete pTmpOLV;
+ }
+
+ // EditArea ueberTakeTextEditArea bestimmen
+ // Das koennte eigentlich entfallen, da TakeTextRect() die Berechnung der aTextEditArea vornimmt
+ // Die aMinTextEditArea muss jedoch wohl auch erfolgen (darum bleibt es voerst drinnen)
+ pTextObj->TakeTextEditArea(NULL,NULL,&aTextEditArea,&aMinTextEditArea);
+
+ Rectangle aTextRect;
+ Rectangle aAnchorRect;
+ pTextObj->TakeTextRect(*pTextEditOutliner, aTextRect, TRUE,
+ &aAnchorRect /* #97097# Give TRUE here, not FALSE */);
+
+ if ( !pTextObj->IsContourTextFrame() )
+ {
+ // FitToSize erstmal nicht mit ContourFrame
+ SdrFitToSizeType eFit = pTextObj->GetFitToSize();
+ if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
+ aTextRect = aAnchorRect;
+ }
+
+ aTextEditArea = aTextRect;
+
+ // #108784#
+ Point aPvOfs(pTextObj->GetTextEditOffset());
+
+ aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
+ aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
+ pTextEditCursorMerker=pWin->GetCursor();
+
+ aHdl.SetMoveOutside(TRUE);
+
+ // #i72757#
+ // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
+ // to call AdjustMarkHdl() always.
+ AdjustMarkHdl();
+
+ pTextEditOutlinerView=ImpMakeOutlinerView(pWin,!bEmpty,pGivenOutlinerView);
+
+ // check if this view is already inserted
+ ULONG i2,nCount = pTextEditOutliner->GetViewCount();
+ for( i2 = 0; i2 < nCount; i2++ )
+ {
+ if( pTextEditOutliner->GetView(i2) == pTextEditOutlinerView )
+ break;
+ }
+
+ if( i2 == nCount )
+ pTextEditOutliner->InsertView(pTextEditOutlinerView,0);
+
+ aHdl.SetMoveOutside(FALSE);
+ aHdl.SetMoveOutside(TRUE);
+ //OLMRefreshAllIAOManagers();
+
+ // alle Wins als OutlinerView beim Outliner anmelden
+ if(!bOnlyOneView)
+ {
+ for(i = 0L; i < nWinAnz; i++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+
+ if(&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
+ {
+ OutlinerView* pOutlView = ImpMakeOutlinerView((Window*)(&rOutDev), !bEmpty, 0L);
+ pTextEditOutliner->InsertView(pOutlView, (sal_uInt16)i);
+ }
+ }
+ }
+
+ pTextEditOutlinerView->ShowCursor();
+ pTextEditOutliner->SetStatusEventHdl(LINK(this,SdrObjEditView,ImpOutlinerStatusEventHdl));
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ pTextEditOutliner->ClearModifyFlag();
+
+ // #71519#, #91453#
+ if(pWin)
+ {
+ sal_Bool bExtraInvalidate(sal_False);
+
+ // #71519#
+ if(!bExtraInvalidate)
+ {
+ SdrFitToSizeType eFit = pTextObj->GetFitToSize();
+ if(eFit == SDRTEXTFIT_PROPORTIONAL || eFit == SDRTEXTFIT_ALLLINES)
+ bExtraInvalidate = sal_True;
+ }
+
+ if(bExtraInvalidate)
+ {
+ pWin->Invalidate(aTextEditArea);
+ }
+ }
+
+ // send HINT_BEGEDIT #99840#
+ if( GetModel() )
+ {
+ SdrHint aHint(*pTextObj);
+ aHint.SetKind(HINT_BEGEDIT);
+ GetModel()->Broadcast(aHint);
+ }
+
+ pTextEditOutliner->setVisualizedPage(0);
+
+ if( mxSelectionController.is() )
+ mxSelectionController->onSelectionHasChanged();
+
+ return sal_True; // Gut gelaufen, TextEdit laeuft nun
+ }
+ else
+ {
+ bBrk = sal_True;
+ pTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
+ pTextEditOutliner->SetBeginPasteOrDropHdl(Link());
+ pTextEditOutliner->SetEndPasteOrDropHdl(Link());
+
+ }
+ }
+ if (pTextEditOutliner != NULL)
+ {
+ pTextEditOutliner->setVisualizedPage(0);
+ }
+
+ // wenn hier angekommen, dann ist irgendwas schief gelaufen
+ if(!bDontDeleteOutliner)
+ {
+ if(pGivenOutliner!=NULL)
+ {
+ delete pGivenOutliner;
+ pTextEditOutliner = NULL;
+ }
+ if(pGivenOutlinerView!=NULL)
+ {
+ delete pGivenOutlinerView;
+ pGivenOutlinerView = NULL;
+ }
+ }
+ if( pTextEditOutliner!=NULL )
+ {
+ delete pTextEditOutliner;
+ }
+
+ pTextEditOutliner=NULL;
+ pTextEditOutlinerView=NULL;
+ mxTextEditObj.reset(0);
+ pTextEditPV=NULL;
+ pTextEditWin=NULL;
+ //HMHif (bMarkHdlWhenTextEdit) {
+ //HMH HideMarkHdl();
+ //HMH}
+ aHdl.SetMoveOutside(FALSE);
+ //HMHShowMarkHdl();
+
+ return sal_False;
+}
+
+SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
+{
+ SdrEndTextEditKind eRet=SDRENDTEXTEDIT_UNCHANGED;
+ SdrTextObj* pTEObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
+ Window* pTEWin =pTextEditWin;
+ SdrOutliner* pTEOutliner =pTextEditOutliner;
+ OutlinerView* pTEOutlinerView=pTextEditOutlinerView;
+ Cursor* pTECursorMerker=pTextEditCursorMerker;
+
+ // send HINT_ENDEDIT #99840#
+ if( GetModel() && mxTextEditObj.is() )
+ {
+ SdrHint aHint(*mxTextEditObj.get());
+ aHint.SetKind(HINT_ENDEDIT);
+ GetModel()->Broadcast(aHint);
+ }
+
+ mxTextEditObj.reset(0);
+ pTextEditPV=NULL;
+ pTextEditWin=NULL;
+ pTextEditOutliner=NULL;
+ pTextEditOutlinerView=NULL;
+ pTextEditCursorMerker=NULL;
+ aTextEditArea=Rectangle();
+
+ if (pTEOutliner!=NULL)
+ {
+ BOOL bModified=pTEOutliner->IsModified();
+ if (pTEOutlinerView!=NULL)
+ {
+ pTEOutlinerView->HideCursor();
+ }
+ if (pTEObj!=NULL)
+ {
+ pTEOutliner->CompleteOnlineSpelling();
+
+ SdrUndoObjSetText* pTxtUndo = 0;
+
+ if( bModified )
+ {
+ sal_Int32 nText;
+ for( nText = 0; nText < pTEObj->getTextCount(); ++nText )
+ if( pTEObj->getText( nText ) == pTEObj->getActiveText() )
+ break;
+
+ pTxtUndo = dynamic_cast< SdrUndoObjSetText* >( GetModel()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTEObj, nText ) );
+ }
+ DBG_ASSERT( !bModified || pTxtUndo, "svx::SdrObjEditView::EndTextEdit(), could not create undo action!" );
+ // Den alten CalcFieldValue-Handler wieder setzen
+ // Muss vor Obj::EndTextEdit() geschehen, da dort ein UpdateFields() gemacht wird.
+ pTEOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
+ pTEOutliner->SetBeginPasteOrDropHdl(Link());
+ pTEOutliner->SetEndPasteOrDropHdl(Link());
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aObjName;
+ pTEObj->TakeObjNameSingul(aObjName);
+ BegUndo(ImpGetResStr(STR_UndoObjSetText),aObjName);
+ }
+
+ pTEObj->EndTextEdit(*pTEOutliner);
+
+ if( (pTEObj->GetRotateAngle() != 0) || (pTEObj && pTEObj->ISA(SdrTextObj) && ((SdrTextObj*)pTEObj)->IsFontwork()) )
+ {
+ // obviously a repaint
+ pTEObj->ActionChanged();
+ }
+
+ if (pTxtUndo!=NULL)
+ {
+ pTxtUndo->AfterSetText();
+ if (!pTxtUndo->IsDifferent())
+ {
+ delete pTxtUndo;
+ pTxtUndo=NULL;
+ }
+ }
+ // Loeschung des gesamten TextObj checken
+ SdrUndoAction* pDelUndo=NULL;
+ BOOL bDelObj=FALSE;
+ SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pTEObj);
+ if (pTextObj!=NULL && bTextEditNewObj)
+ {
+ bDelObj=pTextObj->IsTextFrame() &&
+ !pTextObj->HasText() &&
+ !pTextObj->IsEmptyPresObj() &&
+ !pTextObj->HasFill() &&
+ !pTextObj->HasLine();
+
+ if(pTEObj->IsInserted() && bDelObj && pTextObj->GetObjInventor()==SdrInventor && !bDontDeleteReally)
+ {
+ SdrObjKind eIdent=(SdrObjKind)pTextObj->GetObjIdentifier();
+ if(eIdent==OBJ_TEXT || eIdent==OBJ_TEXTEXT)
+ {
+ pDelUndo= GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
+ }
+ }
+ }
+ if (pTxtUndo!=NULL)
+ {
+ if( bUndo )
+ AddUndo(pTxtUndo);
+ eRet=SDRENDTEXTEDIT_CHANGED;
+ }
+ if (pDelUndo!=NULL)
+ {
+ if( bUndo )
+ {
+ AddUndo(pDelUndo);
+ }
+ else
+ {
+ delete pDelUndo;
+ }
+ eRet=SDRENDTEXTEDIT_DELETED;
+ DBG_ASSERT(pTEObj->GetObjList()!=NULL,"SdrObjEditView::SdrEndTextEdit(): Fatal: Editiertes Objekt hat keine ObjList!");
+ if (pTEObj->GetObjList()!=NULL)
+ {
+ pTEObj->GetObjList()->RemoveObject(pTEObj->GetOrdNum());
+ CheckMarked(); // und gleich die Maekierung entfernen...
+ }
+ }
+ else if (bDelObj)
+ { // Fuer den Writer: Loeschen muss die App nachholen.
+ eRet=SDRENDTEXTEDIT_SHOULDBEDELETED;
+ }
+
+ if( bUndo )
+ EndUndo(); // EndUndo hinter Remove, falls der UndoStack gleich weggehaun' wird
+
+ // #111096#
+ // Switch on evtl. TextAnimation again after TextEdit
+ if(pTEObj->ISA(SdrTextObj))
+ {
+ ((SdrTextObj*)pTEObj)->SetTextAnimationAllowed(sal_True);
+ }
+
+ // #i72757#
+ // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
+ // to call AdjustMarkHdl() always.
+ AdjustMarkHdl();
+ }
+ // alle OutlinerViews loeschen
+ for (ULONG i=pTEOutliner->GetViewCount(); i>0;)
+ {
+ i--;
+ OutlinerView* pOLV=pTEOutliner->GetView(i);
+ USHORT nMorePix=pOLV->GetInvalidateMore() + 10; // solaris aw033 test #i#
+ Window* pWin=pOLV->GetWindow();
+ Rectangle aRect(pOLV->GetOutputArea());
+ pTEOutliner->RemoveView(i);
+ if (!bTextEditDontDelete || i!=0)
+ {
+ // die nullte gehoert mir u.U. nicht.
+ delete pOLV;
+ }
+ aRect.Union(aTextEditArea);
+ aRect.Union(aMinTextEditArea);
+ aRect=pWin->LogicToPixel(aRect);
+ aRect.Left()-=nMorePix;
+ aRect.Top()-=nMorePix;
+ aRect.Right()+=nMorePix;
+ aRect.Bottom()+=nMorePix;
+ aRect=pWin->PixelToLogic(aRect);
+ InvalidateOneWin(*pWin,aRect);
+// pWin->Invalidate(INVALIDATE_UPDATE);
+
+// pWin->Update();
+// pWin->Flush();
+ pWin->SetFillColor();
+ pWin->SetLineColor(COL_BLACK);
+ pWin->DrawPixel(aRect.TopLeft());
+ pWin->DrawPixel(aRect.TopRight());
+ pWin->DrawPixel(aRect.BottomLeft());
+ pWin->DrawPixel(aRect.BottomRight());
+ //pWin->DrawRect(aRect);
+ }
+ // und auch den Outliner selbst
+ if (!bTextEditDontDelete) delete pTEOutliner;
+ else pTEOutliner->Clear();
+ if (pTEWin!=NULL) {
+ pTEWin->SetCursor(pTECursorMerker);
+ }
+//HMH if (bMarkHdlWhenTextEdit) {
+//HMH HideMarkHdl();
+//HMH }
+ aHdl.SetMoveOutside(FALSE);
+ if (eRet!=SDRENDTEXTEDIT_UNCHANGED)
+//HMH {
+//HMH ShowMarkHdl(); // Handles kommen ansonsten via Broadcast
+//HMH }
+//HMH else
+ {
+ GetMarkedObjectListWriteAccess().SetNameDirty();
+ }
+#ifdef DBG_UTIL
+ if (pItemBrowser)
+ {
+ GetMarkedObjectListWriteAccess().SetNameDirty();
+ pItemBrowser->SetDirty();
+ }
+#endif
+ }
+
+ // #108784#
+ if( pTEObj &&
+ pTEObj->GetModel() &&
+ !pTEObj->GetModel()->isLocked() &&
+ pTEObj->GetBroadcaster())
+ {
+ SdrHint aHint(HINT_ENDEDIT);
+ aHint.SetObject(pTEObj);
+ ((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint);
+ }
+
+ return eRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// info about TextEdit. Default is sal_False.
+bool SdrObjEditView::IsTextEdit() const
+{
+ return mxTextEditObj.is();
+}
+
+// info about TextEditPageView. Default is 0L.
+SdrPageView* SdrObjEditView::GetTextEditPageView() const
+{
+ return pTextEditPV;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OutlinerView* SdrObjEditView::ImpFindOutlinerView(Window* pWin) const
+{
+ if (pWin==NULL) return NULL;
+ if (pTextEditOutliner==NULL) return NULL;
+ OutlinerView* pNewView=NULL;
+ ULONG nWinAnz=pTextEditOutliner->GetViewCount();
+ for (ULONG i=0; i<nWinAnz && pNewView==NULL; i++) {
+ OutlinerView* pView=pTextEditOutliner->GetView(i);
+ if (pView->GetWindow()==pWin) pNewView=pView;
+ }
+ return pNewView;
+}
+
+void SdrObjEditView::SetTextEditWin(Window* pWin)
+{
+ if(mxTextEditObj.is() && pWin!=NULL && pWin!=pTextEditWin)
+ {
+ OutlinerView* pNewView=ImpFindOutlinerView(pWin);
+ if (pNewView!=NULL && pNewView!=pTextEditOutlinerView)
+ {
+ if (pTextEditOutlinerView!=NULL)
+ {
+ pTextEditOutlinerView->HideCursor();
+ }
+ pTextEditOutlinerView=pNewView;
+ pTextEditWin=pWin;
+ pWin->GrabFocus(); // Damit der Cursor hier auch blinkt
+ pNewView->ShowCursor();
+ ImpMakeTextCursorAreaVisible();
+ }
+ }
+}
+
+BOOL SdrObjEditView::IsTextEditHit(const Point& rHit, short nTol) const
+{
+ BOOL bOk=FALSE;
+ if(mxTextEditObj.is())
+ {
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ // nur drittel Toleranz hier, damit die Handles
+ // noch vernuenftig getroffen werden koennen
+ nTol=nTol/3;
+ nTol=0; // Joe am 6.3.1997: Keine Hittoleranz mehr hier
+ if (!bOk)
+ {
+ Rectangle aEditArea;
+ OutlinerView* pOLV=pTextEditOutliner->GetView(0);
+ if (pOLV!=NULL)
+ {
+ aEditArea.Union(pOLV->GetOutputArea());
+ }
+ aEditArea.Left()-=nTol;
+ aEditArea.Top()-=nTol;
+ aEditArea.Right()+=nTol;
+ aEditArea.Bottom()+=nTol;
+ bOk=aEditArea.IsInside(rHit);
+ if (bOk)
+ { // Nun noch checken, ob auch wirklich Buchstaben getroffen wurden
+ Point aPnt(rHit); aPnt-=aEditArea.TopLeft();
+ long nHitTol = 2000;
+ OutputDevice* pRef = pTextEditOutliner->GetRefDevice();
+ if( pRef )
+ nHitTol = pRef->LogicToLogic( nHitTol, MAP_100TH_MM, pRef->GetMapMode().GetMapUnit() );
+
+ bOk = pTextEditOutliner->IsTextPos( aPnt, (sal_uInt16)nHitTol );
+ }
+ }
+ }
+ return bOk;
+}
+
+BOOL SdrObjEditView::IsTextEditFrameHit(const Point& rHit) const
+{
+ BOOL bOk=FALSE;
+ if(mxTextEditObj.is())
+ {
+ SdrTextObj* pText= dynamic_cast<SdrTextObj*>(mxTextEditObj.get());
+ OutlinerView* pOLV=pTextEditOutliner->GetView(0);
+ if( pOLV )
+ {
+ Window* pWin=pOLV->GetWindow();
+ if (pText!=NULL && pText->IsTextFrame() && pOLV!=NULL && pWin!=NULL) {
+ USHORT nPixSiz=pOLV->GetInvalidateMore();
+ Rectangle aEditArea(aMinTextEditArea);
+ aEditArea.Union(pOLV->GetOutputArea());
+ if (!aEditArea.IsInside(rHit)) {
+ Size aSiz(pWin->PixelToLogic(Size(nPixSiz,nPixSiz)));
+ aEditArea.Left()-=aSiz.Width();
+ aEditArea.Top()-=aSiz.Height();
+ aEditArea.Right()+=aSiz.Width();
+ aEditArea.Bottom()+=aSiz.Height();
+ bOk=aEditArea.IsInside(rHit);
+ }
+ }
+ }
+ }
+ return bOk;
+}
+
+void SdrObjEditView::AddTextEditOfs(MouseEvent& rMEvt) const
+{
+ if(mxTextEditObj.is())
+ {
+ Point aPvOfs;
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mxTextEditObj.get() );
+
+ if( pTextObj )
+ {
+ // #108784#
+ aPvOfs += pTextObj->GetTextEditOffset();
+ }
+
+ Point aObjOfs(mxTextEditObj->GetLogicRect().TopLeft());
+ (Point&)(rMEvt.GetPosPixel())+=aPvOfs+aObjOfs;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrObjEditView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
+{
+ if(pTextEditOutlinerView)
+ {
+#ifdef DBG_UTIL
+ if(rKEvt.GetKeyCode().GetCode() == KEY_RETURN && pTextEditOutliner->GetParagraphCount() == 1)
+ {
+ ByteString aLine(
+ pTextEditOutliner->GetText(pTextEditOutliner->GetParagraph( 0 ), 1),
+ gsl_getSystemTextEncoding());
+ aLine = aLine.ToUpperAscii();
+
+ if(aLine == "HELLO JOE, PLEASE SHOW THE ITEMBROWSER")
+ ShowItemBrowser();
+ }
+#endif
+ if (pTextEditOutlinerView->PostKeyEvent(rKEvt))
+ {
+ if( pMod /* && !pMod->IsChanged() */ )
+ {
+ if( pTextEditOutliner && pTextEditOutliner->IsModified() )
+ pMod->SetChanged( sal_True );
+ }
+
+ if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ }
+ }
+ return SdrGlueEditView::KeyInput(rKEvt,pWin);
+}
+
+BOOL SdrObjEditView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
+{
+ if (pTextEditOutlinerView!=NULL) {
+ BOOL bPostIt=pTextEditOutliner->IsInSelectionMode();
+ if (!bPostIt) {
+ Point aPt(rMEvt.GetPosPixel());
+ if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
+ else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
+ bPostIt=IsTextEditHit(aPt,nHitTolLog);
+ }
+ if (bPostIt) {
+ Point aPixPos(rMEvt.GetPosPixel());
+ Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
+ if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
+ if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
+ if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
+ if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
+ MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
+ rMEvt.GetButtons(),rMEvt.GetModifier());
+ if (pTextEditOutlinerView->MouseButtonDown(aMEvt)) {
+ if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ }
+ }
+ }
+ return SdrGlueEditView::MouseButtonDown(rMEvt,pWin);
+}
+
+BOOL SdrObjEditView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
+{
+ if (pTextEditOutlinerView!=NULL) {
+ BOOL bPostIt=pTextEditOutliner->IsInSelectionMode();
+ if (!bPostIt) {
+ Point aPt(rMEvt.GetPosPixel());
+ if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
+ else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
+ bPostIt=IsTextEditHit(aPt,nHitTolLog);
+ }
+ if (bPostIt) {
+ Point aPixPos(rMEvt.GetPosPixel());
+ Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
+ if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
+ if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
+ if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
+ if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
+ MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
+ rMEvt.GetButtons(),rMEvt.GetModifier());
+ if (pTextEditOutlinerView->MouseButtonUp(aMEvt)) {
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ }
+ }
+ }
+ return SdrGlueEditView::MouseButtonUp(rMEvt,pWin);
+}
+
+BOOL SdrObjEditView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
+{
+ if (pTextEditOutlinerView!=NULL) {
+ BOOL bSelMode=pTextEditOutliner->IsInSelectionMode();
+ BOOL bPostIt=bSelMode;
+ if (!bPostIt) {
+ Point aPt(rMEvt.GetPosPixel());
+ if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
+ else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
+ bPostIt=IsTextEditHit(aPt,nHitTolLog);
+ }
+ if (bPostIt) {
+ Point aPixPos(rMEvt.GetPosPixel());
+ Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
+ if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
+ if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
+ if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
+ if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
+ MouseEvent aMEvt(aPixPos,rMEvt.GetClicks(),rMEvt.GetMode(),
+ rMEvt.GetButtons(),rMEvt.GetModifier());
+ if (pTextEditOutlinerView->MouseMove(aMEvt) && bSelMode) {
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ }
+ }
+ }
+ return SdrGlueEditView::MouseMove(rMEvt,pWin);
+}
+
+BOOL SdrObjEditView::Command(const CommandEvent& rCEvt, Window* pWin)
+{
+ // solange bis die OutlinerView einen BOOL zurueckliefert
+ // bekommt sie nur COMMAND_STARTDRAG
+ if (pTextEditOutlinerView!=NULL)
+ {
+ if (rCEvt.GetCommand()==COMMAND_STARTDRAG) {
+ BOOL bPostIt=pTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
+ if (!bPostIt && rCEvt.IsMouseEvent()) {
+ Point aPt(rCEvt.GetMousePosPixel());
+ if (pWin!=NULL) aPt=pWin->PixelToLogic(aPt);
+ else if (pTextEditWin!=NULL) aPt=pTextEditWin->PixelToLogic(aPt);
+ bPostIt=IsTextEditHit(aPt,nHitTolLog);
+ }
+ if (bPostIt) {
+ Point aPixPos(rCEvt.GetMousePosPixel());
+ if (rCEvt.IsMouseEvent()) {
+ Rectangle aR(pWin->LogicToPixel(pTextEditOutlinerView->GetOutputArea()));
+ if (aPixPos.X()<aR.Left ()) aPixPos.X()=aR.Left ();
+ if (aPixPos.X()>aR.Right ()) aPixPos.X()=aR.Right ();
+ if (aPixPos.Y()<aR.Top ()) aPixPos.Y()=aR.Top ();
+ if (aPixPos.Y()>aR.Bottom()) aPixPos.Y()=aR.Bottom();
+ }
+ CommandEvent aCEvt(aPixPos,rCEvt.GetCommand(),rCEvt.IsMouseEvent());
+ // Command ist an der OutlinerView leider void
+ pTextEditOutlinerView->Command(aCEvt);
+ if (pWin!=NULL && pWin!=pTextEditWin) SetTextEditWin(pWin);
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ }
+ }
+ else // if (rCEvt.GetCommand() == COMMAND_VOICE )
+ {
+ pTextEditOutlinerView->Command(rCEvt);
+ return TRUE;
+ }
+ }
+ return SdrGlueEditView::Command(rCEvt,pWin);
+}
+
+BOOL SdrObjEditView::Cut(ULONG nFormat)
+{
+ if (pTextEditOutliner!=NULL) {
+ pTextEditOutlinerView->Cut();
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ } else {
+ return SdrGlueEditView::Cut(nFormat);
+ }
+}
+
+BOOL SdrObjEditView::Yank(ULONG nFormat)
+{
+ if (pTextEditOutliner!=NULL) {
+ pTextEditOutlinerView->Copy();
+ return TRUE;
+ } else {
+ return SdrGlueEditView::Yank(nFormat);
+ }
+}
+
+BOOL SdrObjEditView::Paste(Window* pWin, ULONG nFormat)
+{
+ if (pTextEditOutliner!=NULL) {
+ if (pWin!=NULL) {
+ OutlinerView* pNewView=ImpFindOutlinerView(pWin);
+ if (pNewView!=NULL) {
+ pNewView->Paste();
+ }
+ } else {
+ pTextEditOutlinerView->Paste();
+ }
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ ImpMakeTextCursorAreaVisible();
+ return TRUE;
+ } else {
+ return SdrGlueEditView::Paste(pWin,nFormat);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrObjEditView::ImpIsTextEditAllSelected() const
+{
+ BOOL bRet=FALSE;
+ if (pTextEditOutliner!=NULL && pTextEditOutlinerView!=NULL)
+ {
+ if(SdrTextObj::HasTextImpl( pTextEditOutliner ) )
+ {
+ const sal_uInt32 nParaAnz=pTextEditOutliner->GetParagraphCount();
+ Paragraph* pLastPara=pTextEditOutliner->GetParagraph( nParaAnz > 1 ? nParaAnz - 1 : 0 );
+
+ ESelection aESel(pTextEditOutlinerView->GetSelection());
+ if (aESel.nStartPara==0 && aESel.nStartPos==0 && aESel.nEndPara==USHORT(nParaAnz-1))
+ {
+ XubString aStr(pTextEditOutliner->GetText(pLastPara));
+
+ if(aStr.Len() == aESel.nEndPos)
+ bRet = TRUE;
+ }
+ // und nun auch noch fuer den Fall, das rueckwaerts selektiert wurde
+ if (!bRet && aESel.nEndPara==0 && aESel.nEndPos==0 && aESel.nStartPara==USHORT(nParaAnz-1))
+ {
+ XubString aStr(pTextEditOutliner->GetText(pLastPara));
+
+ if(aStr.Len() == aESel.nStartPos)
+ bRet = TRUE;
+ }
+ }
+ else
+ {
+ bRet=TRUE;
+ }
+ }
+ return bRet;
+}
+
+void SdrObjEditView::ImpMakeTextCursorAreaVisible()
+{
+ if (pTextEditOutlinerView!=NULL && pTextEditWin!=NULL) {
+ Cursor* pCsr=pTextEditWin->GetCursor();
+ if (pCsr!=NULL) {
+ Size aSiz(pCsr->GetSize());
+ if (aSiz.Width()!=0 && aSiz.Height()!=0) { // #38450#
+ MakeVisible(Rectangle(pCsr->GetPos(),aSiz),*pTextEditWin);
+ }
+ }
+ }
+}
+
+USHORT SdrObjEditView::GetScriptType() const
+{
+ USHORT nScriptType = 0;
+
+ if( IsTextEdit() )
+ {
+ if( mxTextEditObj->GetOutlinerParaObject() )
+ nScriptType = mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType();
+
+ if( pTextEditOutlinerView )
+ nScriptType = pTextEditOutlinerView->GetSelectedScriptType();
+ }
+ else
+ {
+ sal_uInt32 nMarkCount( GetMarkedObjectCount() );
+
+ for( sal_uInt32 i = 0; i < nMarkCount; i++ )
+ {
+ OutlinerParaObject* pParaObj = GetMarkedObjectByIndex( i )->GetOutlinerParaObject();
+
+ if( pParaObj )
+ {
+ nScriptType |= pParaObj->GetTextObject().GetScriptType();
+ }
+ }
+ }
+
+ if( nScriptType == 0 )
+ nScriptType = SCRIPTTYPE_LATIN;
+
+ return nScriptType;
+}
+
+/* new interface src537 */
+BOOL SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, BOOL bOnlyHardAttr) const
+{
+ if( mxSelectionController.is() )
+ if( mxSelectionController->GetAttributes( rTargetSet, bOnlyHardAttr ) )
+ return TRUE;
+
+ if(IsTextEdit())
+ {
+ DBG_ASSERT(pTextEditOutlinerView!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
+ DBG_ASSERT(pTextEditOutliner!=NULL,"SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
+
+ // #92389# take care of bOnlyHardAttr(!)
+ if(!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
+ rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
+
+ // add object attributes
+ rTargetSet.Put( mxTextEditObj->GetMergedItemSet() );
+
+ if( mxTextEditObj->GetOutlinerParaObject() )
+ rTargetSet.Put( SvxScriptTypeItem( mxTextEditObj->GetOutlinerParaObject()->GetTextObject().GetScriptType() ) );
+
+ if(pTextEditOutlinerView)
+ {
+ // FALSE= InvalidItems nicht al Default, sondern als "Loecher" betrachten
+ rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), FALSE);
+ rTargetSet.Put( SvxScriptTypeItem( pTextEditOutlinerView->GetSelectedScriptType() ), FALSE );
+ }
+
+ if(GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
+ {
+ MergeNotPersistAttrFromMarked(rTargetSet, bOnlyHardAttr);
+ }
+
+ return TRUE;
+ }
+ else
+ {
+ return SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
+ }
+}
+
+BOOL SdrObjEditView::SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll)
+{
+ BOOL bRet=FALSE;
+ BOOL bTextEdit=pTextEditOutlinerView!=NULL && mxTextEditObj.is();
+ BOOL bAllTextSelected=ImpIsTextEditAllSelected();
+ SfxItemSet* pModifiedSet=NULL;
+ const SfxItemSet* pSet=&rSet;
+ //const SvxAdjustItem* pParaJust=NULL;
+
+ if (!bTextEdit)
+ {
+ // Kein TextEdit aktiv -> alle Items ans Zeichenobjekt
+ if( mxSelectionController.is() )
+ bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
+
+ if( !bRet )
+ {
+ bRet=SdrGlueEditView::SetAttributes(*pSet,bReplaceAll);
+ }
+ }
+ else
+ {
+#ifdef DBG_UTIL
+ {
+ BOOL bHasEEFeatureItems=FALSE;
+ SfxItemIter aIter(rSet);
+ const SfxPoolItem* pItem=aIter.FirstItem();
+ while (!bHasEEFeatureItems && pItem!=NULL)
+ {
+ if (!IsInvalidItem(pItem))
+ {
+ USHORT nW=pItem->Which();
+ if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END)
+ bHasEEFeatureItems=TRUE;
+ }
+
+ pItem=aIter.NextItem();
+ }
+
+ if(bHasEEFeatureItems)
+ {
+ String aMessage;
+ aMessage.AppendAscii("SdrObjEditView::SetAttributes(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten.");
+ InfoBox(NULL, aMessage).Execute();
+ }
+ }
+#endif
+
+ BOOL bOnlyEEItems;
+ BOOL bNoEEItems=!SearchOutlinerItems(*pSet,bReplaceAll,&bOnlyEEItems);
+ // alles selektiert? -> Attrs auch an den Rahmen
+ // und falls keine EEItems, dann Attrs nur an den Rahmen
+ if (bAllTextSelected || bNoEEItems)
+ {
+ if( mxSelectionController.is() )
+ bRet=mxSelectionController->SetAttributes(*pSet,bReplaceAll );
+
+ if( !bRet )
+ {
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ {
+ String aStr;
+ ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
+ BegUndo(aStr);
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
+
+ // #i43537#
+ // If this is a text object also rescue the OutlinerParaObject since
+ // applying attributes to the object may change text layout when
+ // multiple portions exist with multiple formats. If a OutlinerParaObject
+ // really exists and needs to be rescued is evaluated in the undo
+ // implementation itself.
+ bool bRescueText = dynamic_cast< SdrTextObj* >(mxTextEditObj.get());
+
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,!bNoEEItems || bRescueText));
+ EndUndo();
+ }
+
+ mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
+
+ FlushComeBackTimer(); // Damit ModeHasChanged sofort kommt
+ bRet=TRUE;
+ }
+ }
+ else if (!bOnlyEEItems)
+ {
+ // sonst Set ggf. splitten
+ // Es wird nun ein ItemSet aSet gemacht, in den die EE_Items von
+ // *pSet nicht enhalten ist (ansonsten ist es eine Kopie).
+ USHORT* pNewWhichTable=RemoveWhichRange(pSet->GetRanges(),EE_ITEMS_START,EE_ITEMS_END);
+ SfxItemSet aSet(pMod->GetItemPool(),pNewWhichTable);
+ /*90353*/ delete[] pNewWhichTable;
+ SfxWhichIter aIter(aSet);
+ USHORT nWhich=aIter.FirstWhich();
+ while (nWhich!=0)
+ {
+ const SfxPoolItem* pItem;
+ SfxItemState eState=pSet->GetItemState(nWhich,FALSE,&pItem);
+ if (eState==SFX_ITEM_SET) aSet.Put(*pItem);
+ nWhich=aIter.NextWhich();
+ }
+
+
+ if( mxSelectionController.is() )
+ bRet=mxSelectionController->SetAttributes(aSet,bReplaceAll );
+
+ if( !bRet )
+ {
+ if( IsUndoEnabled() )
+ {
+ String aStr;
+ ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
+ BegUndo(aStr);
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get(),false,false));
+ EndUndo();
+ }
+
+ mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
+
+ if (GetMarkedObjectCount()==1 && GetMarkedObjectByIndex(0)==mxTextEditObj.get())
+ {
+ SetNotPersistAttrToMarked(aSet,bReplaceAll);
+ }
+ }
+ FlushComeBackTimer();
+ bRet=TRUE;
+ }
+ if(!bNoEEItems)
+ {
+ // und nun die Attribute auch noch an die EditEngine
+ if (bReplaceAll) {
+ // Am Outliner kann man leider nur alle Attribute platthauen
+ pTextEditOutlinerView->RemoveAttribs( TRUE );
+ }
+ pTextEditOutlinerView->SetAttribs(rSet);
+
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL)
+ pItemBrowser->SetDirty();
+#endif
+
+ ImpMakeTextCursorAreaVisible();
+ }
+ bRet=TRUE;
+ }
+ if (pModifiedSet!=NULL)
+ delete pModifiedSet;
+ return bRet;
+}
+
+SfxStyleSheet* SdrObjEditView::GetStyleSheet() const
+{
+ SfxStyleSheet* pSheet = 0;
+
+ if( mxSelectionController.is() )
+ {
+ if( mxSelectionController->GetStyleSheet( pSheet ) )
+ return pSheet;
+ }
+
+ if ( pTextEditOutlinerView )
+ {
+ pSheet = pTextEditOutlinerView->GetStyleSheet();
+ }
+ else
+ {
+ pSheet = SdrGlueEditView::GetStyleSheet();
+ }
+ return pSheet;
+}
+
+BOOL SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ if( mxSelectionController.is() )
+ {
+ if( mxSelectionController->SetStyleSheet( pStyleSheet, bDontRemoveHardAttr ) )
+ return TRUE;
+ }
+
+ // if we are currently in edit mode we must also set the stylesheet
+ // on all paragraphs in the Outliner for the edit view
+ // #92191#
+ if( NULL != pTextEditOutlinerView )
+ {
+ Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
+
+ const ULONG nParaCount = pOutliner->GetParagraphCount();
+ ULONG nPara;
+ for( nPara = 0; nPara < nParaCount; nPara++ )
+ {
+ pOutliner->SetStyleSheet( nPara, pStyleSheet );
+ }
+ }
+
+ return SdrGlueEditView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObjEditView::AddWindowToPaintView(OutputDevice* pNewWin)
+{
+ SdrGlueEditView::AddWindowToPaintView(pNewWin);
+
+ if(mxTextEditObj.is() && !bTextEditOnlyOneView && pNewWin->GetOutDevType()==OUTDEV_WINDOW)
+ {
+ OutlinerView* pOutlView=ImpMakeOutlinerView((Window*)pNewWin,FALSE,NULL);
+ pTextEditOutliner->InsertView(pOutlView);
+ }
+}
+
+void SdrObjEditView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
+{
+ SdrGlueEditView::DeleteWindowFromPaintView(pOldWin);
+
+ if(mxTextEditObj.is() && !bTextEditOnlyOneView && pOldWin->GetOutDevType()==OUTDEV_WINDOW)
+ {
+ for (ULONG i=pTextEditOutliner->GetViewCount(); i>0;) {
+ i--;
+ OutlinerView* pOLV=pTextEditOutliner->GetView(i);
+ if (pOLV && pOLV->GetWindow()==(Window*)pOldWin) {
+ delete pTextEditOutliner->RemoveView(i);
+ }
+ }
+ }
+}
+
+BOOL SdrObjEditView::IsTextEditInSelectionMode() const
+{
+ return pTextEditOutliner!=NULL && pTextEditOutliner->IsInSelectionMode();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@ @@@@ @@@@ @@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@
+// @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@ @@ @@
+// @@@@@@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@ @@ @@ @@ @@
+// @@@@@@@ @@@@@@ @@ @@@@@ @@ @@ @@@@@@@ @@ @@ @@ @@ @@@@
+// @@ @ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@@@ @@ @@ @@@@ @@ @@ @@@@ @@@@@ @@@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV, Window* pWin)
+{
+ BOOL bRet=FALSE;
+ BrkMacroObj();
+ if (pObj!=NULL && pPV!=NULL && pWin!=NULL && pObj->HasMacro()) {
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ pMacroObj=pObj;
+ pMacroPV=pPV;
+ pMacroWin=pWin;
+ bMacroDown=FALSE;
+ nMacroTol=USHORT(nTol);
+ aMacroDownPos=rPnt;
+ MovMacroObj(rPnt);
+ }
+ return bRet;
+}
+
+void SdrObjEditView::ImpMacroUp(const Point& rUpPos)
+{
+ if (pMacroObj!=NULL && bMacroDown)
+ {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=rUpPos;
+ aHitRec.aDownPos=aMacroDownPos;
+ aHitRec.nTol=nMacroTol;
+ aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
+ aHitRec.pPageView=pMacroPV;
+ aHitRec.pOut=pMacroWin;
+ pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
+ bMacroDown=FALSE;
+ }
+}
+
+void SdrObjEditView::ImpMacroDown(const Point& rDownPos)
+{
+ if (pMacroObj!=NULL && !bMacroDown)
+ {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=rDownPos;
+ aHitRec.aDownPos=aMacroDownPos;
+ aHitRec.nTol=nMacroTol;
+ aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
+ aHitRec.pPageView=pMacroPV;
+ aHitRec.bDown=TRUE;
+ aHitRec.pOut=pMacroWin;
+ pMacroObj->PaintMacro(*pMacroWin,Rectangle(),aHitRec);
+ bMacroDown=TRUE;
+ }
+}
+
+void SdrObjEditView::MovMacroObj(const Point& rPnt)
+{
+ if (pMacroObj!=NULL) {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=rPnt;
+ aHitRec.aDownPos=aMacroDownPos;
+ aHitRec.nTol=nMacroTol;
+ aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
+ aHitRec.pPageView=pMacroPV;
+ aHitRec.bDown=bMacroDown;
+ aHitRec.pOut=pMacroWin;
+ BOOL bDown=pMacroObj->IsMacroHit(aHitRec);
+ if (bDown) ImpMacroDown(rPnt);
+ else ImpMacroUp(rPnt);
+ }
+}
+
+void SdrObjEditView::BrkMacroObj()
+{
+ if (pMacroObj!=NULL) {
+ ImpMacroUp(aMacroDownPos);
+ pMacroObj=NULL;
+ pMacroPV=NULL;
+ pMacroWin=NULL;
+ }
+}
+
+BOOL SdrObjEditView::EndMacroObj()
+{
+ if (pMacroObj!=NULL && bMacroDown) {
+ ImpMacroUp(aMacroDownPos);
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=aMacroDownPos;
+ aHitRec.aDownPos=aMacroDownPos;
+ aHitRec.nTol=nMacroTol;
+ aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
+ aHitRec.pPageView=pMacroPV;
+ aHitRec.bDown=TRUE;
+ aHitRec.pOut=pMacroWin;
+ bool bRet=pMacroObj->DoMacro(aHitRec);
+ pMacroObj=NULL;
+ pMacroPV=NULL;
+ pMacroWin=NULL;
+ return bRet;
+ } else {
+ BrkMacroObj();
+ return FALSE;
+ }
+}
+
+/** fills the given any with a XTextCursor for the current text selection.
+ Leaves the any untouched if there currently is no text selected */
+void SdrObjEditView::getTextSelection( ::com::sun::star::uno::Any& rSelection )
+{
+ if( IsTextEdit() )
+ {
+ OutlinerView* pOutlinerView = GetTextEditOutlinerView();
+ if( pOutlinerView && pOutlinerView->HasSelection() )
+ {
+ SdrObject* pObj = GetTextEditObject();
+
+ if( pObj )
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > xText( pObj->getUnoShape(), ::com::sun::star::uno::UNO_QUERY );
+ if( xText.is() )
+ {
+ SvxUnoTextBase* pRange = SvxUnoTextBase::getImplementation( xText );
+ if( pRange )
+ {
+ rSelection <<= pRange->createTextCursorBySelection( pOutlinerView->GetSelection() );
+ }
+ }
+ }
+ }
+ }
+}
+
+namespace sdr { namespace table {
+extern rtl::Reference< sdr::SelectionController > CreateTableController( SdrObjEditView* pView, const SdrObject* pObj, const rtl::Reference< sdr::SelectionController >& xRefController );
+} }
+
+/* check if we have a single selection and that single object likes
+ to handle the mouse and keyboard events itself
+
+ @todo: the selection controller should be queried from the
+ object specific view contact. Currently this method only
+ works for tables.
+*/
+void SdrObjEditView::MarkListHasChanged()
+{
+ SdrGlueEditView::MarkListHasChanged();
+
+ if( mxSelectionController.is() )
+ {
+ mxLastSelectionController = mxSelectionController;
+ mxSelectionController->onSelectionHasChanged();
+ }
+
+ mxSelectionController.clear();
+
+ const SdrMarkList& rMarkList=GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() == 1 )
+ {
+ const SdrObject* pObj= rMarkList.GetMark(0)->GetMarkedSdrObj();
+ // check for table
+ if( pObj && (pObj->GetObjInventor() == SdrInventor ) && (pObj->GetObjIdentifier() == OBJ_TABLE) )
+ {
+ mxSelectionController = sdr::table::CreateTableController( this, pObj, mxLastSelectionController );
+ if( mxSelectionController.is() )
+ {
+ mxLastSelectionController.clear();
+ mxSelectionController->onSelectionHasChanged();
+ }
+ }
+ }
+}
+
+IMPL_LINK( SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
+{
+ OnEndPasteOrDrop( pInfos );
+ return 0;
+}
+
+IMPL_LINK( SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
+{
+ OnBeginPasteOrDrop( pInfos );
+ return 0;
+}
+
+void SdrObjEditView::OnBeginPasteOrDrop( PasteOrDropInfos* )
+{
+ // applications can derive from these virtual methods to do something before a drop or paste operation
+}
+
+void SdrObjEditView::OnEndPasteOrDrop( PasteOrDropInfos* )
+{
+ // applications can derive from these virtual methods to do something before a drop or paste operation
+}
+
+bool SdrObjEditView::SupportsFormatPaintbrush( UINT32 nObjectInventor, UINT16 nObjectIdentifier ) const
+{
+ if( nObjectInventor != SdrInventor && nObjectInventor != E3dInventor )
+ return false;
+ switch(nObjectIdentifier)
+ {
+ case OBJ_NONE:
+ case OBJ_GRUP:
+ return false;
+ case OBJ_LINE:
+ case OBJ_RECT:
+ case OBJ_CIRC:
+ case OBJ_SECT:
+ case OBJ_CARC:
+ case OBJ_CCUT:
+ case OBJ_POLY:
+ case OBJ_PLIN:
+ case OBJ_PATHLINE:
+ case OBJ_PATHFILL:
+ case OBJ_FREELINE:
+ case OBJ_FREEFILL:
+ case OBJ_SPLNLINE:
+ case OBJ_SPLNFILL:
+ case OBJ_TEXT:
+ case OBJ_TEXTEXT:
+ case OBJ_TITLETEXT:
+ case OBJ_OUTLINETEXT:
+ case OBJ_GRAF:
+ case OBJ_OLE2:
+ case OBJ_TABLE:
+ return true;
+ case OBJ_EDGE:
+ case OBJ_CAPTION:
+ return false;
+ case OBJ_PATHPOLY:
+ case OBJ_PATHPLIN:
+ return true;
+ case OBJ_PAGE:
+ case OBJ_MEASURE:
+ case OBJ_DUMMY:
+ case OBJ_FRAME:
+ case OBJ_UNO:
+ return false;
+ case OBJ_CUSTOMSHAPE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const USHORT* GetFormatRangeImpl( bool bTextOnly )
+{
+ static const USHORT gRanges[] = {
+ SDRATTR_SHADOW_FIRST, SDRATTR_SHADOW_LAST,
+ SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST,
+ SDRATTR_TABLE_FIRST, SDRATTR_TABLE_LAST,
+ XATTR_LINE_FIRST, XATTR_LINE_LAST,
+ XATTR_FILL_FIRST, XATTRSET_FILL,
+ EE_PARA_START, EE_PARA_END,
+ EE_CHAR_START, EE_CHAR_END,
+ 0,0
+ };
+ return &gRanges[ bTextOnly ? 10 : 0];
+}
+
+bool SdrObjEditView::TakeFormatPaintBrush( boost::shared_ptr< SfxItemSet >& rFormatSet )
+{
+ if( mxSelectionController.is() && mxSelectionController->TakeFormatPaintBrush(rFormatSet) )
+ return true;
+
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() >= 1 )
+ {
+ OutlinerView* pOLV = GetTextEditOutlinerView();
+
+ rFormatSet.reset( new SfxItemSet( GetModel()->GetItemPool(), GetFormatRangeImpl( pOLV != NULL ) ) );
+ if( pOLV )
+ {
+ rFormatSet->Put( pOLV->GetAttribs() );
+ }
+ else
+ {
+ const BOOL bOnlyHardAttr = FALSE;
+ rFormatSet->Put( GetAttrFromMarked(bOnlyHardAttr) );
+ }
+ return true;
+ }
+
+ return false;
+}
+
+static SfxItemSet CreatePaintSet( const USHORT *pRanges, SfxItemPool& rPool, const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
+{
+ SfxItemSet aPaintSet( rPool, pRanges );
+
+ while( *pRanges )
+ {
+ USHORT nWhich = *pRanges++;
+ const USHORT nLastWhich = *pRanges++;
+
+ if( bNoCharacterFormats && (nWhich == EE_CHAR_START) )
+ continue;
+
+ if( bNoParagraphFormats && (nWhich == EE_PARA_START ) )
+ continue;
+
+ for( ; nWhich < nLastWhich; nWhich++ )
+ {
+ const SfxPoolItem* pSourceItem = rSourceSet.GetItem( nWhich );
+ const SfxPoolItem* pTargetItem = rTargetSet.GetItem( nWhich );
+
+ if( (pSourceItem && !pTargetItem) || (pSourceItem && pTargetItem && !((*pSourceItem) == (*pTargetItem)) ) )
+ {
+ aPaintSet.Put( *pSourceItem );
+ }
+ }
+ }
+ return aPaintSet;
+}
+
+void SdrObjEditView::ApplyFormatPaintBrushToText( SfxItemSet& rFormatSet, SdrTextObj& rTextObj, SdrText* pText, bool bNoCharacterFormats, bool bNoParagraphFormats )
+{
+ OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0;
+ if(pParaObj)
+ {
+ SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
+ rOutliner.SetText(*pParaObj);
+
+ sal_uInt32 nParaCount(rOutliner.GetParagraphCount());
+
+ if(nParaCount)
+ {
+ for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++)
+ {
+ if( !bNoCharacterFormats )
+ rOutliner.QuickRemoveCharAttribs( nPara, /* remove all */0 );
+
+ SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
+ aSet.Put(CreatePaintSet( GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
+ rOutliner.SetParaAttribs(nPara, aSet);
+ }
+
+ OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount);
+ rOutliner.Clear();
+
+ rTextObj.NbcSetOutlinerParaObjectForText(pTemp,pText);
+ }
+ }
+}
+
+void SdrObjEditView::ApplyFormatPaintBrush( SfxItemSet& rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats )
+{
+ if( !mxSelectionController.is() || !mxSelectionController->ApplyFormatPaintBrush( rFormatSet, bNoCharacterFormats, bNoParagraphFormats ) )
+ {
+ const SdrMarkList& rMarkList = GetMarkedObjectList();
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ OutlinerView* pOLV = GetTextEditOutlinerView();
+
+ const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
+
+ if( !pOLV )
+ {
+ // if not in text edit mode (aka the user selected text or clicked on a word)
+ // apply formating attributes to selected shape
+ // All formating items (see ranges above) that are unequal in selected shape and
+ // the format paintbrush are hard set on the selected shape.
+
+ const USHORT* pRanges = rFormatSet.GetRanges();
+ bool bTextOnly = true;
+
+ while( *pRanges )
+ {
+ if( (*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START) )
+ {
+ bTextOnly = false;
+ break;
+ }
+ pRanges += 2;
+ }
+
+ if( !bTextOnly )
+ {
+ SfxItemSet aPaintSet( CreatePaintSet( GetFormatRangeImpl(false), *rShapeSet.GetPool(), rFormatSet, rShapeSet, bNoCharacterFormats, bNoParagraphFormats ) );
+ const BOOL bReplaceAll = FALSE;
+ SetAttrToMarked(aPaintSet, bReplaceAll);
+ }
+
+ // now apply character and paragraph formating to text, if the shape has any
+ SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
+ if( pTextObj )
+ {
+ sal_Int32 nText = pTextObj->getTextCount();
+
+ while( --nText >= 0 )
+ {
+ SdrText* pText = pTextObj->getText( nText );
+ ApplyFormatPaintBrushToText( rFormatSet, *pTextObj, pText, bNoCharacterFormats, bNoParagraphFormats );
+ }
+ }
+ }
+ else
+ {
+ ::Outliner* pOutliner = pOLV->GetOutliner();
+ if( pOutliner )
+ {
+ const EditEngine& rEditEngine = pOutliner->GetEditEngine();
+
+ ESelection aSel( pOLV->GetSelection() );
+ if( !aSel.HasRange() )
+ pOLV->SetSelection( rEditEngine.GetWord( aSel, com::sun::star::i18n::WordType::DICTIONARY_WORD ) );
+
+ const BOOL bRemoveParaAttribs = !bNoParagraphFormats;
+ pOLV->RemoveAttribsKeepLanguages( bRemoveParaAttribs );
+ SfxItemSet aSet( pOLV->GetAttribs() );
+ SfxItemSet aPaintSet( CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet, bNoCharacterFormats, bNoParagraphFormats ) );
+ pOLV->SetAttribs( aPaintSet );
+ }
+ }
+ }
+}
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
new file mode 100644
index 000000000000..8a4245919821
--- /dev/null
+++ b/svx/source/svdraw/svdetc.cxx
@@ -0,0 +1,1118 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include "editeng/forbiddencharacterstable.hxx"
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <svx/svdetc.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/svdtrans.hxx>
+#include "svdglob.hxx"
+#include "svdstr.hrc"
+#include "svdviter.hxx"
+#include <svx/svdview.hxx>
+#include <svx/svdoutl.hxx>
+#include <vcl/bmpacc.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/itemset.hxx>
+#include <tools/config.hxx>
+#include <unotools/cacheoptions.hxx>
+#include <svl/whiter.hxx>
+#include <tools/bigint.hxx>
+#include "editeng/fontitem.hxx"
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/svdoole2.hxx>
+#include <svl/itempool.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <comphelper/processfactory.hxx>
+#include <i18npool/lang.h>
+#include <unotools/charclass.hxx>
+#include <unotools/syslocale.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/extrusionbar.hxx>
+#include <svx/fontworkbar.hxx>
+#include <vcl/svapp.hxx> //add CHINA001
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+using namespace ::com::sun::star;
+
+/******************************************************************************
+* Globale Daten der DrawingEngine
+******************************************************************************/
+
+SdrGlobalData::SdrGlobalData() :
+ pSysLocale(NULL),
+ pCharClass(NULL),
+ pLocaleData(NULL),
+ pOutliner(NULL),
+ pDefaults(NULL),
+ pResMgr(NULL),
+ nExchangeFormat(0)
+{
+ //pSysLocale = new SvtSysLocale;
+ //pCharClass = pSysLocale->GetCharClassPtr();
+ //pLocaleData = pSysLocale->GetLocaleDataPtr();
+
+ svx::ExtrusionBar::RegisterInterface();
+ svx::FontworkBar::RegisterInterface();
+}
+
+SdrGlobalData::~SdrGlobalData()
+{
+ delete pOutliner;
+ delete pDefaults;
+ delete pResMgr;
+ //! do NOT delete pCharClass and pLocaleData
+ delete pSysLocale;
+}
+const SvtSysLocale* SdrGlobalData::GetSysLocale()
+{
+ if ( !pSysLocale )
+ pSysLocale = new SvtSysLocale;
+ return pSysLocale;
+}
+const CharClass* SdrGlobalData::GetCharClass()
+{
+ if ( !pCharClass )
+ pCharClass = GetSysLocale()->GetCharClassPtr();
+ return pCharClass;
+}
+const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
+{
+ if ( !pLocaleData )
+ pLocaleData = GetSysLocale()->GetLocaleDataPtr();
+ return pLocaleData;
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OLEObjCache::OLEObjCache()
+: Container( 0 )
+{
+ SvtCacheOptions aCacheOptions;
+
+ nSize = aCacheOptions.GetDrawingEngineOLE_Objects();
+ pTimer = new AutoTimer();
+ Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
+
+ pTimer->SetTimeoutHdl(aLink);
+ pTimer->SetTimeout(20000);
+ pTimer->Start();
+
+ aLink.Call(pTimer);
+}
+
+OLEObjCache::~OLEObjCache()
+{
+ pTimer->Stop();
+ delete pTimer;
+}
+
+void OLEObjCache::UnloadOnDemand()
+{
+ if ( nSize < Count() )
+ {
+ // more objects than configured cache size try to remove objects
+ // of course not the freshly inserted one at nIndex=0
+ ULONG nCount2 = Count();
+ ULONG nIndex = nCount2-1;
+ while( nIndex && nCount2 > nSize )
+ {
+ SdrOle2Obj* pUnloadObj = (SdrOle2Obj*) GetObject(nIndex--);
+ if ( pUnloadObj )
+ {
+ try
+ {
+ // it is important to get object without reinitialization to avoid reentrance
+ uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
+
+ sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
+
+ // check whether the object can be unloaded before looking for the parent objects
+ if ( xUnloadObj.is() && bUnload )
+ {
+ uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
+ if ( xUnloadModel.is() )
+ {
+ for ( ULONG nCheckInd = 0; nCheckInd < Count(); nCheckInd++ )
+ {
+ SdrOle2Obj* pCacheObj = (SdrOle2Obj*) GetObject(nCheckInd);
+ if ( pCacheObj && pCacheObj != pUnloadObj )
+ {
+ uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
+ if ( xUnloadModel == xParentModel )
+ bUnload = sal_False; // the object has running embedded objects
+ }
+ }
+ }
+ }
+
+ if ( bUnload && UnloadObj(pUnloadObj) )
+ // object was successfully unloaded
+ nCount2--;
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+ }
+}
+
+void OLEObjCache::SetSize(ULONG nNewSize)
+{
+ nSize = nNewSize;
+}
+
+void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
+{
+ if ( Count() )
+ {
+ SdrOle2Obj* pExistingObj = (SdrOle2Obj*)GetObject( 0 );
+ if ( pObj == pExistingObj )
+ // the object is already on the top, nothing has to be changed
+ return;
+ }
+
+ // get the old position of the object to know whether it is already in container
+ ULONG nOldPos = GetPos( pObj );
+
+ // insert object into first position
+ Remove( nOldPos );
+ Insert(pObj, (ULONG) 0L);
+
+ if ( nOldPos == CONTAINER_ENTRY_NOTFOUND )
+ {
+ // a new object was inserted, recalculate the cache
+ UnloadOnDemand();
+ }
+}
+
+void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
+{
+ Remove(pObj);
+}
+
+BOOL OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
+{
+ BOOL bUnloaded = FALSE;
+ if (pObj)
+ {
+ //#i80528# The old mechanism is completely useless, only taking into account if
+ // in all views the GrafDraft feature is used. This will nearly never have been the
+ // case since no one ever used this option.
+ //
+ // A much better (and working) criteria would be the VOC contact count.
+ // The quesion is what will happen whe i make it work now suddenly? I
+ // will try it for 2.4.
+ const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
+ const bool bVisible(rViewContact.HasViewObjectContacts(true));
+
+ if(!bVisible)
+ {
+ bUnloaded = pObj->Unload();
+ }
+ }
+
+ return bUnloaded;
+}
+
+IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
+{
+ UnloadOnDemand();
+ return 0;
+}
+
+void ContainerSorter::DoSort(ULONG a, ULONG b) const
+{
+ ULONG nAnz=rCont.Count();
+ if (b>nAnz) b=nAnz;
+ if (b>0) b--;
+ if (a<b) ImpSubSort(a,b);
+}
+
+void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const
+{
+}
+
+void ContainerSorter::ImpSubSort(long nL, long nR) const
+{
+ long i,j;
+ const void* pX;
+ void* pI;
+ void* pJ;
+ i=nL;
+ j=nR;
+ pX=rCont.GetObject((nL+nR)/2);
+ do {
+ pI=rCont.Seek(i);
+ while (pI!=pX && Compare(pI,pX)<0) { i++; pI=rCont.Next(); }
+ pJ=rCont.Seek(j);
+ while (pJ!=pX && Compare(pX,pJ)<0) { j--; pJ=rCont.Prev(); }
+ if (i<=j) {
+ rCont.Replace(pJ,i);
+ rCont.Replace(pI,j);
+ i++;
+ j--;
+ }
+ } while (i<=j);
+ if (nL<j) ImpSubSort(nL,j);
+ if (i<nR) ImpSubSort(i,nR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpUShortContainerSorter: public ContainerSorter {
+public:
+ ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
+ virtual int Compare(const void* pElem1, const void* pElem2) const;
+};
+
+int ImpUShortContainerSorter::Compare(const void* pElem1, const void* pElem2) const
+{
+ USHORT n1=USHORT(ULONG(pElem1));
+ USHORT n2=USHORT(ULONG(pElem2));
+ return n1<n2 ? -1 : n1>n2 ? 1 : 0;
+}
+
+void UShortCont::Sort()
+{
+ ImpUShortContainerSorter aSorter(aArr);
+ aSorter.DoSort();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpClipMerk {
+ Region aClip;
+ FASTBOOL bClip;
+public:
+ ImpClipMerk(const OutputDevice& rOut): aClip(rOut.GetClipRegion()),bClip(rOut.IsClipRegion()) {}
+ void Restore(OutputDevice& rOut)
+ {
+ // Kein Clipping in die Metafileaufzeichnung
+ GDIMetaFile* pMtf=rOut.GetConnectMetaFile();
+ if (pMtf!=NULL && (!pMtf->IsRecord() || pMtf->IsPause())) pMtf=NULL;
+ if (pMtf!=NULL) pMtf->Pause(TRUE);
+ if (bClip) rOut.SetClipRegion(aClip);
+ else rOut.SetClipRegion();
+ if (pMtf!=NULL) pMtf->Pause(FALSE);
+ }
+};
+
+class ImpColorMerk {
+ Color aLineColor;
+ Color aFillColor;
+ Color aBckgrdColor;
+ Font aFont;
+public:
+ ImpColorMerk(const OutputDevice& rOut):
+ aLineColor( rOut.GetLineColor() ),
+ aFillColor( rOut.GetFillColor() ),
+ aBckgrdColor( rOut.GetBackground().GetColor() ),
+ aFont (rOut.GetFont()) {}
+
+ ImpColorMerk(const OutputDevice& rOut, USHORT nMode)
+ {
+ if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN )
+ aLineColor = rOut.GetLineColor();
+
+ if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
+ {
+ aFillColor = rOut.GetFillColor();
+ aBckgrdColor = rOut.GetBackground().GetColor();
+ }
+
+ if ( (nMode & SDRHDC_SAVEFONT) == SDRHDC_SAVEFONT)
+ aFont=rOut.GetFont();
+ }
+
+ void Restore(OutputDevice& rOut, USHORT nMode=SDRHDC_SAVEPENANDBRUSHANDFONT)
+ {
+ if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN)
+ rOut.SetLineColor( aLineColor );
+
+ if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
+ {
+ rOut.SetFillColor( aFillColor );
+ rOut.SetBackground( Wallpaper( aBckgrdColor ) );
+ }
+ if ((nMode & SDRHDC_SAVEFONT) ==SDRHDC_SAVEFONT)
+ {
+ if (!rOut.GetFont().IsSameInstance(aFont))
+ {
+ rOut.SetFont(aFont);
+ }
+ }
+ }
+
+ const Color& GetLineColor() const { return aLineColor; }
+};
+
+ImpSdrHdcMerk::ImpSdrHdcMerk(const OutputDevice& rOut, USHORT nNewMode, FASTBOOL bAutoMerk):
+ pFarbMerk(NULL),
+ pClipMerk(NULL),
+ pLineColorMerk(NULL),
+ nMode(nNewMode)
+{
+ if (bAutoMerk) Save(rOut);
+}
+
+ImpSdrHdcMerk::~ImpSdrHdcMerk()
+{
+ if (pFarbMerk!=NULL) delete pFarbMerk;
+ if (pClipMerk!=NULL) delete pClipMerk;
+ if (pLineColorMerk !=NULL) delete pLineColorMerk;
+}
+
+void ImpSdrHdcMerk::Save(const OutputDevice& rOut)
+{
+ if (pFarbMerk!=NULL)
+ {
+ delete pFarbMerk;
+ pFarbMerk=NULL;
+ }
+ if (pClipMerk!=NULL)
+ {
+ delete pClipMerk;
+ pClipMerk=NULL;
+ }
+ if (pLineColorMerk !=NULL)
+ {
+ delete pLineColorMerk ;
+ pLineColorMerk =NULL;
+ }
+ if ((nMode & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING)
+ pClipMerk=new ImpClipMerk(rOut);
+
+ USHORT nCol=nMode & SDRHDC_SAVEPENANDBRUSHANDFONT;
+
+ if (nCol==SDRHDC_SAVEPEN)
+ pLineColorMerk=new Color( rOut.GetLineColor() );
+ else if (nCol==SDRHDC_SAVEPENANDBRUSHANDFONT)
+ pFarbMerk=new ImpColorMerk(rOut);
+ else if (nCol!=0)
+ pFarbMerk=new ImpColorMerk(rOut,nCol);
+}
+
+void ImpSdrHdcMerk::Restore(OutputDevice& rOut, USHORT nMask) const
+{
+ nMask&=nMode; // nur restaurieren, was auch gesichert wurde
+
+ if ((nMask & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING && pClipMerk!=NULL)
+ pClipMerk->Restore(rOut);
+
+ USHORT nCol=nMask & SDRHDC_SAVEPENANDBRUSHANDFONT;
+
+ if (nCol==SDRHDC_SAVEPEN)
+ {
+ if (pLineColorMerk!=NULL)
+ rOut.SetLineColor(*pLineColorMerk);
+ else if (pFarbMerk!=NULL)
+ rOut.SetLineColor( pFarbMerk->GetLineColor() );
+ } else if (nCol!=0 && pFarbMerk!=NULL)
+ pFarbMerk->Restore(rOut,nCol);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrLinkList::Clear()
+{
+ unsigned nAnz=GetLinkCount();
+ for (unsigned i=0; i<nAnz; i++) {
+ delete (Link*)aList.GetObject(i);
+ }
+ aList.Clear();
+}
+
+unsigned SdrLinkList::FindEntry(const Link& rLink) const
+{
+ unsigned nAnz=GetLinkCount();
+ for (unsigned i=0; i<nAnz; i++) {
+ if (GetLink(i)==rLink) return i;
+ }
+ return 0xFFFF;
+}
+
+void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
+{
+ unsigned nFnd=FindEntry(rLink);
+ if (nFnd==0xFFFF) {
+ if (rLink.IsSet()) {
+ aList.Insert(new Link(rLink),nPos);
+ } else {
+ DBG_ERROR("SdrLinkList::InsertLink(): Versuch, einen nicht gesetzten Link einzufuegen");
+ }
+ } else {
+ DBG_ERROR("SdrLinkList::InsertLink(): Link schon vorhanden");
+ }
+}
+
+void SdrLinkList::RemoveLink(const Link& rLink)
+{
+ unsigned nFnd=FindEntry(rLink);
+ if (nFnd!=0xFFFF) {
+ Link* pLink=(Link*)aList.Remove(nFnd);
+ delete pLink;
+ } else {
+ DBG_ERROR("SdrLinkList::RemoveLink(): Link nicht gefunden");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #98988# Re-implement GetDraftFillColor(...)
+
+FASTBOOL GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
+{
+ XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
+ FASTBOOL bRetval(FALSE);
+
+ switch(eFill)
+ {
+ case XFILL_SOLID:
+ {
+ rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_HATCH:
+ {
+ Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
+ Color aCol2(COL_WHITE);
+
+ // #97870# when hatch background is activated, use object fill color as hatch color
+ sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
+ if(bFillHatchBackground)
+ {
+ aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
+ }
+
+ const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
+ rCol = Color(aAverageColor);
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_GRADIENT: {
+ const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
+ Color aCol1(rGrad.GetStartColor());
+ Color aCol2(rGrad.GetEndColor());
+ const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
+ rCol = Color(aAverageColor);
+ bRetval = TRUE;
+
+ break;
+ }
+ case XFILL_BITMAP:
+ {
+ const Bitmap& rBitmap = ((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap();
+ const Size aSize(rBitmap.GetSizePixel());
+ const sal_uInt32 nWidth = aSize.Width();
+ const sal_uInt32 nHeight = aSize.Height();
+ Bitmap aBitmap(rBitmap);
+ BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
+
+ if(pAccess && nWidth > 0 && nHeight > 0)
+ {
+ sal_uInt32 nRt(0L);
+ sal_uInt32 nGn(0L);
+ sal_uInt32 nBl(0L);
+ const sal_uInt32 nMaxSteps(8L);
+ const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
+ const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
+ sal_uInt32 nAnz(0L);
+
+ for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
+ {
+ for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
+ {
+ const BitmapColor& rCol2 = (pAccess->HasPalette())
+ ? pAccess->GetPaletteColor((BYTE)pAccess->GetPixel(nY, nX))
+ : pAccess->GetPixel(nY, nX);
+
+ nRt += rCol2.GetRed();
+ nGn += rCol2.GetGreen();
+ nBl += rCol2.GetBlue();
+ nAnz++;
+ }
+ }
+
+ nRt /= nAnz;
+ nGn /= nAnz;
+ nBl /= nAnz;
+
+ rCol = Color(UINT8(nRt), UINT8(nGn), UINT8(nBl));
+
+ bRetval = TRUE;
+ }
+
+ if(pAccess)
+ {
+ aBitmap.ReleaseAccess(pAccess);
+ }
+
+ break;
+ }
+ default: break;
+ }
+
+ return bRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrEngineDefaults::SdrEngineDefaults():
+ aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
+ eFontFamily(FAMILY_ROMAN),
+ aFontColor(COL_AUTO),
+ nFontHeight(847), // 847/100mm = ca. 24 Point
+ eMapUnit(MAP_100TH_MM),
+ aMapFraction(1,1)
+{
+}
+
+SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ if (rGlobalData.pDefaults==NULL) {
+ rGlobalData.pDefaults=new SdrEngineDefaults;
+ }
+ return *rGlobalData.pDefaults;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrEngineDefaults::LanguageHasChanged()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ if (rGlobalData.pResMgr!=NULL) {
+ delete rGlobalData.pResMgr;
+ rGlobalData.pResMgr=NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrOutliner* SdrMakeOutliner( USHORT nOutlinerMode, SdrModel* pModel )
+{
+ //SdrEngineDefaults& rDefaults = SdrEngineDefaults::GetDefaults();
+
+ SfxItemPool* pPool = &pModel->GetItemPool();
+ SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
+ pOutl->SetEditTextObjectPool( pPool );
+ pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
+ pOutl->SetDefTab( pModel->GetDefaultTabulator() );
+ pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
+ pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
+ pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
+ pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
+
+ return pOutl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+SdrLinkList& ImpGetUserMakeObjHdl()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ return rGlobalData.aUserMakeObjHdl;
+}
+
+SdrLinkList& ImpGetUserMakeObjUserDataHdl()
+{
+ SdrGlobalData& rGlobalData=GetSdrGlobalData();
+ return rGlobalData.aUserMakeObjUserDataHdl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ResMgr* ImpGetResMgr()
+{
+ SdrGlobalData& rGlobalData = GetSdrGlobalData();
+
+ if(!rGlobalData.pResMgr)
+ {
+ ByteString aName("svx");
+ rGlobalData.pResMgr =
+ ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILocale() );
+ }
+
+ return rGlobalData.pResMgr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+String ImpGetResStr(sal_uInt16 nResID)
+{
+ return String(ResId(nResID, *ImpGetResMgr()));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+String GetResourceString(sal_uInt16 nResID)
+{
+ return ImpGetResStr( nResID );
+}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SearchOutlinerItems(const SfxItemSet& rSet, BOOL bInklDefaults, BOOL* pbOnlyEE)
+{
+ BOOL bHas=FALSE;
+ BOOL bOnly=TRUE;
+ BOOL bLookOnly=pbOnlyEE!=NULL;
+ SfxWhichIter aIter(rSet);
+ USHORT nWhich=aIter.FirstWhich();
+ while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
+ // bei bInklDefaults ist der gesamte Which-Range
+ // ausschlaggebend, ansonsten nur die gesetzten Items
+ // Disabled und DontCare wird als Loch im Which-Range betrachtet
+ SfxItemState eState=rSet.GetItemState(nWhich);
+ if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
+ if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=FALSE;
+ else bHas=TRUE;
+ }
+ nWhich=aIter.NextWhich();
+ }
+ if (!bHas) bOnly=FALSE;
+ if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
+ return bHas;
+}
+
+USHORT* RemoveWhichRange(const USHORT* pOldWhichTable, USHORT nRangeBeg, USHORT nRangeEnd)
+{
+ // insgesamt sind 6 Faelle moeglich (je Range):
+ // [Beg..End] zu entfernender Range
+ // [b..e] [b..e] [b..e] Fall 1,3,2: egal, ganz weg, egal + Ranges
+ // [b........e] [b........e] Fall 4,5 : Bereich verkleinern | in
+ // [b......................e] Fall 6 : Splitting + pOldWhichTable
+ USHORT nAnz=0;
+ while (pOldWhichTable[nAnz]!=0) nAnz++;
+ nAnz++; // nAnz muesste nun in jedem Fall eine ungerade Zahl sein (0 am Ende des Arrays)
+ DBG_ASSERT((nAnz&1)==1,"Joe: RemoveWhichRange: WhichTable hat keine ungerade Anzahl von Eintraegen");
+ USHORT nAlloc=nAnz;
+ // benoetigte Groesse des neuen Arrays ermitteln
+ USHORT nNum=nAnz-1;
+ while (nNum!=0) {
+ nNum-=2;
+ USHORT nBeg=pOldWhichTable[nNum];
+ USHORT nEnd=pOldWhichTable[nNum+1];
+ if (nEnd<nRangeBeg) /*nCase=1*/ ;
+ else if (nBeg>nRangeEnd) /* nCase=2 */ ;
+ else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
+ else if (nEnd<=nRangeEnd) /* nCase=4 */;
+ else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
+ else /* nCase=6 */ nAlloc+=2;
+ }
+
+ USHORT* pNewWhichTable=new USHORT[nAlloc];
+ memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(USHORT));
+ pNewWhichTable[nAlloc-1]=0; // im Falle 3 fehlt die 0 am Ende
+ // nun die unerwuenschten Ranges entfernen
+ nNum=nAlloc-1;
+ while (nNum!=0) {
+ nNum-=2;
+ USHORT nBeg=pNewWhichTable[nNum];
+ USHORT nEnd=pNewWhichTable[nNum+1];
+ unsigned nCase=0;
+ if (nEnd<nRangeBeg) nCase=1;
+ else if (nBeg>nRangeEnd) nCase=2;
+ else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
+ else if (nEnd<=nRangeEnd) nCase=4;
+ else if (nBeg>=nRangeBeg) nCase=5;
+ else nCase=6;
+ switch (nCase) {
+ case 3: {
+ unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
+ memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
+ nAnz-=2; // Merken: Array hat sich verkleinert
+ } break;
+ case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
+ case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
+ case 6: {
+ unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
+ memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
+ nAnz+=2; // Merken: Array hat sich vergroessert
+ pNewWhichTable[nNum+2]=nRangeEnd+1;
+ pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
+ pNewWhichTable[nNum+1]=nRangeBeg-1;
+ } break;
+ } // switch
+ }
+ return pNewWhichTable;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvdProgressInfo::SvdProgressInfo( Link *_pLink )
+{
+ DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): Kein Link angegeben!!");
+
+ pLink = _pLink;
+ nSumActionCount = 0;
+ nSumCurAction = 0;
+
+ nObjCount = 0;
+ nCurObj = 0;
+
+ nActionCount = 0;
+ nCurAction = 0;
+
+ nInsertCount = 0;
+ nCurInsert = 0;
+}
+
+void SvdProgressInfo::Init( ULONG _nSumActionCount, ULONG _nObjCount )
+{
+ nSumActionCount = _nSumActionCount;
+ nObjCount = _nObjCount;
+}
+
+BOOL SvdProgressInfo::ReportActions( ULONG nAnzActions )
+{
+ nSumCurAction += nAnzActions;
+ nCurAction += nAnzActions;
+ if(nCurAction > nActionCount)
+ nCurAction = nActionCount;
+
+ return pLink->Call(NULL) == 1L;
+}
+
+BOOL SvdProgressInfo::ReportInserts( ULONG nAnzInserts )
+{
+ nSumCurAction += nAnzInserts;
+ nCurInsert += nAnzInserts;
+
+ return pLink->Call(NULL) == 1L;
+}
+
+BOOL SvdProgressInfo::ReportRescales( ULONG nAnzRescales )
+{
+ nSumCurAction += nAnzRescales;
+ return pLink->Call(NULL) == 1L;
+}
+
+void SvdProgressInfo::SetActionCount( ULONG _nActionCount )
+{
+ nActionCount = _nActionCount;
+}
+
+void SvdProgressInfo::SetInsertCount( ULONG _nInsertCount )
+{
+ nInsertCount = _nInsertCount;
+}
+
+BOOL SvdProgressInfo::SetNextObject()
+{
+ nActionCount = 0;
+ nCurAction = 0;
+
+ nInsertCount = 0;
+ nCurInsert = 0;
+
+ nCurObj++;
+ return ReportActions(0);
+}
+
+void SvdProgressInfo::ReportError()
+{
+ pLink->Call((void *)1L);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i101872# isolate GetTextEditBackgroundColor to tooling; it woll anyways only be used as long
+// as text edit is not running on overlay
+
+namespace
+{
+ bool impGetSdrObjListFillColor(
+ const SdrObjList& rList,
+ const Point& rPnt,
+ const SdrPageView& rTextEditPV,
+ const SetOfByte& rVisLayers,
+ Color& rCol)
+ {
+ if(!rList.GetModel())
+ return false;
+
+ bool bRet(false);
+ bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
+
+ for(ULONG no(rList.GetObjCount()); !bRet && no > 0; )
+ {
+ no--;
+ SdrObject* pObj = rList.GetObj(no);
+ SdrObjList* pOL = pObj->GetSubList();
+
+ if(pOL)
+ {
+ // group object
+ bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
+ }
+ else
+ {
+ SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
+
+ // #108867# Exclude zero master page object (i.e. background shape) from color query
+ if(pText
+ && pObj->IsClosedObj()
+ && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
+ && pObj->GetCurrentBoundRect().IsInside(rPnt)
+ && !pText->IsHideContour()
+ && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
+ {
+ bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
+ }
+ }
+ }
+
+ return bRet;
+ }
+
+ bool impGetSdrPageFillColor(
+ const SdrPage& rPage,
+ const Point& rPnt,
+ const SdrPageView& rTextEditPV,
+ const SetOfByte& rVisLayers,
+ Color& rCol,
+ bool bSkipBackgroundShape)
+ {
+ if(!rPage.GetModel())
+ return false;
+
+ bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
+
+ if(!bRet && !rPage.IsMasterPage())
+ {
+ if(rPage.TRG_HasMasterPage())
+ {
+ SetOfByte aSet(rVisLayers);
+ aSet &= rPage.TRG_GetMasterPageVisibleLayers();
+ SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
+
+ // #108867# Don't fall back to background shape on
+ // master pages. This is later handled by
+ // GetBackgroundColor, and is necessary to cater for
+ // the silly ordering: 1. shapes, 2. master page
+ // shapes, 3. page background, 4. master page
+ // background.
+ bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
+ }
+ }
+
+ // #108867# Only now determine background color from background shapes
+ if(!bRet && !bSkipBackgroundShape)
+ {
+ rCol = rPage.GetPageBackgroundColor();
+ return true;
+ }
+
+ return bRet;
+ }
+
+ Color impCalcBackgroundColor(
+ const Rectangle& rArea,
+ const SdrPageView& rTextEditPV,
+ const SdrPage& rPage)
+ {
+ svtools::ColorConfig aColorConfig;
+ Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ if(!rStyleSettings.GetHighContrastMode())
+ {
+ // search in page
+ const USHORT SPOTCOUNT(5);
+ Point aSpotPos[SPOTCOUNT];
+ Color aSpotColor[SPOTCOUNT];
+ ULONG nHeight( rArea.GetSize().Height() );
+ ULONG nWidth( rArea.GetSize().Width() );
+ ULONG nWidth14 = nWidth / 4;
+ ULONG nHeight14 = nHeight / 4;
+ ULONG nWidth34 = ( 3 * nWidth ) / 4;
+ ULONG nHeight34 = ( 3 * nHeight ) / 4;
+
+ USHORT i;
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ // five spots are used
+ switch ( i )
+ {
+ case 0 :
+ {
+ // Center-Spot
+ aSpotPos[i] = rArea.Center();
+ }
+ break;
+
+ case 1 :
+ {
+ // TopLeft-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth14;
+ aSpotPos[i].Y() += nHeight14;
+ }
+ break;
+
+ case 2 :
+ {
+ // TopRight-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth34;
+ aSpotPos[i].Y() += nHeight14;
+ }
+ break;
+
+ case 3 :
+ {
+ // BottomLeft-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth14;
+ aSpotPos[i].Y() += nHeight34;
+ }
+ break;
+
+ case 4 :
+ {
+ // BottomRight-Spot
+ aSpotPos[i] = rArea.TopLeft();
+ aSpotPos[i].X() += nWidth34;
+ aSpotPos[i].Y() += nHeight34;
+ }
+ break;
+
+ }
+
+ aSpotColor[i] = Color( COL_WHITE );
+ impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
+ }
+
+ USHORT aMatch[SPOTCOUNT];
+
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ // were same spot colors found?
+ aMatch[i] = 0;
+
+ for ( USHORT j = 0; j < SPOTCOUNT; j++ )
+ {
+ if( j != i )
+ {
+ if( aSpotColor[i] == aSpotColor[j] )
+ {
+ aMatch[i]++;
+ }
+ }
+ }
+ }
+
+ // highest weight to center spot
+ aBackground = aSpotColor[0];
+
+ for ( USHORT nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
+ {
+ // which spot color was found most?
+ for ( i = 0; i < SPOTCOUNT; i++ )
+ {
+ if( aMatch[i] == nMatchCount )
+ {
+ aBackground = aSpotColor[i];
+ nMatchCount = 1; // break outer for-loop
+ break;
+ }
+ }
+ }
+ }
+
+ return aBackground;
+ }
+} // end of anonymous namespace
+
+Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
+{
+ svtools::ColorConfig aColorConfig;
+ Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ if(!rStyleSettings.GetHighContrastMode())
+ {
+ bool bFound(false);
+ SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
+
+ if(pText && pText->IsClosedObj())
+ {
+ ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
+
+ if( pTable )
+ bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
+
+ if( !bFound )
+ bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
+ }
+
+ if(!bFound && pText)
+ {
+ SdrPageView* pTextEditPV = rView.GetTextEditPageView();
+
+ if(pTextEditPV)
+ {
+ Point aPvOfs(pText->GetTextEditOffset());
+ const SdrPage* pPg = pTextEditPV->GetPage();
+
+ if(pPg)
+ {
+ Rectangle aSnapRect( pText->GetSnapRect() );
+ aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
+
+ return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
+ }
+ }
+ }
+ }
+
+ return aBackground;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
new file mode 100644
index 000000000000..34a77fcd9e62
--- /dev/null
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -0,0 +1,1028 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svdfmtf.hxx"
+#include <editeng/editdata.hxx>
+#include <math.h>
+#include <svx/xpoly.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/shdditem.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xflgrit.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/colritem.hxx>
+#include <vcl/metric.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdobj.hxx>
+#include "svditext.hxx"
+#include <svx/svdotext.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdetc.hxx>
+#include <svl/itemset.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlndsit.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ImpSdrGDIMetaFileImport::ImpSdrGDIMetaFileImport(SdrModel& rModel):
+ nMapScalingOfs(0),
+ pLineAttr(NULL),pFillAttr(NULL),pTextAttr(NULL),
+ pPage(NULL),pModel(NULL),nLayer(0),
+ nLineWidth(0),
+ maLineJoin(basegfx::B2DLINEJOIN_NONE),
+ maDash(XDASH_RECT, 0, 0, 0, 0, 0),
+ bFntDirty(TRUE),
+ bLastObjWasPolyWithoutLine(FALSE),bNoLine(FALSE),bNoFill(FALSE),bLastObjWasLine(FALSE)
+{
+ aVD.EnableOutput(FALSE);
+
+ // #i111954# init to no fill and no line initially
+ aVD.SetLineColor();
+ aVD.SetFillColor();
+
+ aOldLineColor.SetRed( aVD.GetLineColor().GetRed() + 1 ); // invalidate old line color
+ pLineAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_LINE_FIRST,XATTR_LINE_LAST);
+ pFillAttr=new SfxItemSet(rModel.GetItemPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
+ pTextAttr=new SfxItemSet(rModel.GetItemPool(),EE_ITEMS_START,EE_ITEMS_END);
+ pModel=&rModel;
+}
+
+ImpSdrGDIMetaFileImport::~ImpSdrGDIMetaFileImport()
+{
+ delete pLineAttr;
+ delete pFillAttr;
+ delete pTextAttr;
+}
+
+ULONG ImpSdrGDIMetaFileImport::DoImport(const GDIMetaFile& rMtf,
+ SdrObjList& rOL,
+ ULONG nInsPos,
+ SvdProgressInfo *pProgrInfo)
+{
+ pPage = rOL.GetPage();
+ GDIMetaFile* pTmpMtf=NULL;
+ GDIMetaFile* pMtf = (GDIMetaFile*) &rMtf;
+ ULONG nActionAnz=pMtf->GetActionCount();
+ sal_Bool bError = sal_False;
+
+
+ // setup some global scale parameter
+ // fScaleX, fScaleY, aScaleX, aScaleY, bMov, bSize
+ fScaleX = fScaleY = 1.0;
+ Size aMtfSize( pMtf->GetPrefSize() );
+ if ( aMtfSize.Width() & aMtfSize.Height() && ( aScaleRect.IsEmpty() == sal_False ) )
+ {
+ aOfs = aScaleRect.TopLeft();
+ if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
+ fScaleX = (double)( aScaleRect.GetWidth() - 1 ) / (double)aMtfSize.Width();
+ if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
+ fScaleY = (double)( aScaleRect.GetHeight() - 1 ) / (double)aMtfSize.Height();
+ }
+
+ bMov = aOfs.X()!=0 || aOfs.Y()!=0;
+ bSize = sal_False;
+
+ aScaleX = Fraction( 1, 1 );
+ aScaleY = Fraction( 1, 1 );
+ if ( aMtfSize.Width() != ( aScaleRect.GetWidth() - 1 ) )
+ {
+ aScaleX = Fraction( aScaleRect.GetWidth() - 1, aMtfSize.Width() );
+ bSize = sal_True;
+ }
+ if ( aMtfSize.Height() != ( aScaleRect.GetHeight() - 1 ) )
+ {
+ aScaleY = Fraction( aScaleRect.GetHeight() - 1, aMtfSize.Height() );
+ bSize = sal_True;
+ }
+
+ if(65000 < nActionAnz)
+ {
+ nActionAnz = 65000;
+ bError = TRUE;
+ }
+
+ if(pProgrInfo)
+ pProgrInfo->SetActionCount(nActionAnz);
+
+ ULONG nActionsToReport = 0;
+
+ for( MetaAction* pAct = pMtf->FirstAction(); pAct; pAct = pMtf->NextAction() )
+ {
+ switch (pAct->GetType())
+ {
+ case META_PIXEL_ACTION : DoAction((MetaPixelAction &)*pAct); break;
+ case META_POINT_ACTION : DoAction((MetaPointAction &)*pAct); break;
+ case META_LINE_ACTION : DoAction((MetaLineAction &)*pAct); break;
+ case META_RECT_ACTION : DoAction((MetaRectAction &)*pAct); break;
+ case META_ROUNDRECT_ACTION : DoAction((MetaRoundRectAction &)*pAct); break;
+ case META_ELLIPSE_ACTION : DoAction((MetaEllipseAction &)*pAct); break;
+ case META_ARC_ACTION : DoAction((MetaArcAction &)*pAct); break;
+ case META_PIE_ACTION : DoAction((MetaPieAction &)*pAct); break;
+ case META_CHORD_ACTION : DoAction((MetaChordAction &)*pAct); break;
+ case META_POLYLINE_ACTION : DoAction((MetaPolyLineAction &)*pAct); break;
+ case META_POLYGON_ACTION : DoAction((MetaPolygonAction &)*pAct); break;
+ case META_POLYPOLYGON_ACTION : DoAction((MetaPolyPolygonAction &)*pAct); break;
+ case META_TEXT_ACTION : DoAction((MetaTextAction &)*pAct); break;
+ case META_TEXTARRAY_ACTION : DoAction((MetaTextArrayAction &)*pAct); break;
+ case META_STRETCHTEXT_ACTION : DoAction((MetaStretchTextAction &)*pAct); break;
+ case META_BMP_ACTION : DoAction((MetaBmpAction &)*pAct); break;
+ case META_BMPSCALE_ACTION : DoAction((MetaBmpScaleAction &)*pAct); break;
+ case META_BMPEX_ACTION : DoAction((MetaBmpExAction &)*pAct); break;
+ case META_BMPEXSCALE_ACTION : DoAction((MetaBmpExScaleAction &)*pAct); break;
+ case META_LINECOLOR_ACTION : DoAction((MetaLineColorAction &)*pAct); break;
+ case META_FILLCOLOR_ACTION : DoAction((MetaFillColorAction &)*pAct); break;
+ case META_TEXTCOLOR_ACTION : DoAction((MetaTextColorAction &)*pAct); break;
+ case META_TEXTFILLCOLOR_ACTION : DoAction((MetaTextFillColorAction &)*pAct); break;
+ case META_FONT_ACTION : DoAction((MetaFontAction &)*pAct); break;
+ case META_TEXTALIGN_ACTION : DoAction((MetaTextAlignAction &)*pAct); break;
+ case META_MAPMODE_ACTION : DoAction((MetaMapModeAction &)*pAct); break;
+ case META_CLIPREGION_ACTION : DoAction((MetaClipRegionAction &)*pAct); break;
+ case META_MOVECLIPREGION_ACTION : DoAction((MetaMoveClipRegionAction &)*pAct); break;
+ case META_ISECTRECTCLIPREGION_ACTION: DoAction((MetaISectRectClipRegionAction&)*pAct); break;
+ case META_ISECTREGIONCLIPREGION_ACTION: DoAction((MetaISectRegionClipRegionAction&)*pAct); break;
+ case META_RASTEROP_ACTION : DoAction((MetaRasterOpAction &)*pAct); break;
+ case META_PUSH_ACTION : DoAction((MetaPushAction &)*pAct); break;
+ case META_POP_ACTION : DoAction((MetaPopAction &)*pAct); break;
+ case META_HATCH_ACTION : DoAction((MetaHatchAction &)*pAct); break;
+ case META_COMMENT_ACTION : DoAction((MetaCommentAction &)*pAct, pMtf); break;
+
+ }
+
+ if(pProgrInfo != NULL)
+ {
+ nActionsToReport++;
+ if(nActionsToReport >= 16) // Alle 16 Action updaten
+ {
+ if(!pProgrInfo->ReportActions(nActionsToReport))
+ break;
+ nActionsToReport = 0;
+ }
+ }
+ }
+
+ if(pProgrInfo != NULL)
+ {
+ pProgrInfo->ReportActions(nActionsToReport);
+ nActionsToReport = 0;
+ }
+
+ // MapMode-Scaling vornehmen
+ MapScaling();
+ // Objekte in vorgegebenes Rechteck hineinskalieren
+ ULONG nAnz=aTmpList.GetObjCount();
+
+ // Beim berechnen der Fortschrittsanzeige wird GetActionCount()*3 benutzt.
+ // Da in aTmpList allerdings weniger eintraege als GetActionCount()
+ // existieren koennen, muessen hier die zuviel vermuteten Actionen wieder
+ // hinzugefuegt werden.
+ nActionsToReport = (pMtf->GetActionCount() - nAnz)*2;
+
+
+ // Alle noch nicht gemeldeten Rescales melden
+ if(pProgrInfo)
+ {
+ pProgrInfo->ReportRescales(nActionsToReport);
+ pProgrInfo->SetInsertCount(nAnz);
+ }
+ nActionsToReport = 0;
+
+ // alle in aTmpList zwischengespeicherten Objekte nun in rOL ab der Position nInsPos einfuegen
+ if (nInsPos>rOL.GetObjCount()) nInsPos=rOL.GetObjCount();
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ for (ULONG i=0; i<nAnz; i++)
+ {
+ SdrObject* pObj=aTmpList.GetObj(i);
+ rOL.NbcInsertObject(pObj,nInsPos,&aReason);
+ nInsPos++;
+
+ if(pProgrInfo != NULL)
+ {
+ nActionsToReport++;
+ if(nActionsToReport >= 32) // Alle 32 Action updaten
+ {
+ pProgrInfo->ReportInserts(nActionsToReport);
+ nActionsToReport = 0;
+ }
+ }
+ }
+ if (pTmpMtf!=NULL) delete pTmpMtf;
+
+ // ein letztesmal alle verbliebennen Inserts reporten
+ if(pProgrInfo != NULL)
+ {
+ pProgrInfo->ReportInserts(nActionsToReport);
+ if(bError)
+ pProgrInfo->ReportError();
+ }
+
+ return aTmpList.GetObjCount();
+}
+
+void ImpSdrGDIMetaFileImport::SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr)
+{
+ bNoLine = FALSE; bNoFill = FALSE;
+ FASTBOOL bLine=TRUE && !bForceTextAttr;
+ FASTBOOL bFill=pObj==NULL || pObj->IsClosedObj() && !bForceTextAttr;
+ FASTBOOL bText=bForceTextAttr || (pObj!=NULL && pObj->GetOutlinerParaObject()!=NULL);
+
+ if ( bLine )
+ {
+ if ( nLineWidth )
+ pLineAttr->Put( XLineWidthItem( nLineWidth ) );
+ else
+ pLineAttr->Put( XLineWidthItem( 0 ) );
+
+ aOldLineColor = aVD.GetLineColor();
+ if( aVD.IsLineColor() )
+ {
+ pLineAttr->Put(XLineStyleItem(XLINE_SOLID));
+ pLineAttr->Put(XLineColorItem(String(), aVD.GetLineColor()));
+ }
+ else
+ pLineAttr->Put(XLineStyleItem(XLINE_NONE));
+
+ switch(maLineJoin)
+ {
+ default : // basegfx::B2DLINEJOIN_NONE
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_NONE));
+ break;
+ case basegfx::B2DLINEJOIN_MIDDLE:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_MIDDLE));
+ break;
+ case basegfx::B2DLINEJOIN_BEVEL:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_BEVEL));
+ break;
+ case basegfx::B2DLINEJOIN_MITER:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_MITER));
+ break;
+ case basegfx::B2DLINEJOIN_ROUND:
+ pLineAttr->Put(XLineJointItem(XLINEJOINT_ROUND));
+ break;
+ }
+
+ if(((maDash.GetDots() && maDash.GetDotLen()) || (maDash.GetDashes() && maDash.GetDashLen())) && maDash.GetDistance())
+ {
+ pLineAttr->Put(XLineDashItem(String(), maDash));
+ }
+ else
+ {
+ pLineAttr->Put(XLineDashItem(String(), XDash(XDASH_RECT)));
+ }
+ }
+ else
+ bNoLine = TRUE;
+
+ if ( bFill )
+ {
+ if( aVD.IsFillColor() )
+ {
+ pFillAttr->Put(XFillStyleItem(XFILL_SOLID));
+ pFillAttr->Put(XFillColorItem(String(), aVD.GetFillColor()));
+ }
+ else
+ pFillAttr->Put(XFillStyleItem(XFILL_NONE));
+ }
+ else
+ bNoFill = TRUE;
+
+ if ( bText && bFntDirty )
+ {
+ Font aFnt(aVD.GetFont());
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO ) );
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CJK ) );
+ pTextAttr->Put( SvxFontItem( aFnt.GetFamily(), aFnt.GetName(), aFnt.GetStyleName(),
+ aFnt.GetPitch(), aFnt.GetCharSet(), EE_CHAR_FONTINFO_CTL ) );
+ pTextAttr->Put(SvxPostureItem(aFnt.GetItalic(), EE_CHAR_ITALIC));
+ pTextAttr->Put(SvxWeightItem(aFnt.GetWeight(), EE_CHAR_WEIGHT));
+ sal_uInt32 nHeight = FRound(aFnt.GetSize().Height() * fScaleY);
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) );
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pTextAttr->Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+ pTextAttr->Put(SvxCharScaleWidthItem(100, EE_CHAR_FONTWIDTH));
+ pTextAttr->Put(SvxUnderlineItem(aFnt.GetUnderline(), EE_CHAR_UNDERLINE));
+ pTextAttr->Put(SvxOverlineItem(aFnt.GetOverline(), EE_CHAR_OVERLINE));
+ pTextAttr->Put(SvxCrossedOutItem(aFnt.GetStrikeout(), EE_CHAR_STRIKEOUT));
+ pTextAttr->Put(SvxShadowedItem(aFnt.IsShadow(), EE_CHAR_SHADOW));
+ pTextAttr->Put(SvxAutoKernItem(aFnt.IsKerning(), EE_CHAR_KERNING));
+ pTextAttr->Put(SvxWordLineModeItem(aFnt.IsWordLineMode(), EE_CHAR_WLM));
+ pTextAttr->Put(SvxContourItem(aFnt.IsOutline(), EE_CHAR_OUTLINE));
+ pTextAttr->Put(SvxColorItem(aFnt.GetColor(), EE_CHAR_COLOR));
+ //... svxfont textitem svditext
+ bFntDirty=FALSE;
+ }
+ if (pObj!=NULL)
+ {
+ pObj->SetLayer(nLayer);
+ if (bLine) pObj->SetMergedItemSet(*pLineAttr);
+ if (bFill) pObj->SetMergedItemSet(*pFillAttr);
+ if (bText)
+ {
+ pObj->SetMergedItemSet(*pTextAttr);
+ pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_LEFT ) );
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::InsertObj( SdrObject* pObj, sal_Bool bScale )
+{
+ if ( bScale && !aScaleRect.IsEmpty() )
+ {
+ if ( bSize )
+ pObj->NbcResize( Point(), aScaleX, aScaleY );
+ if ( bMov )
+ pObj->NbcMove( Size( aOfs.X(), aOfs.Y() ) );
+ }
+
+ // #i111954# check object for visibility
+ // used are SdrPathObj, SdrRectObj, SdrCircObj, SdrGrafObj
+ bool bVisible(false);
+
+ if(pObj->HasLineStyle())
+ {
+ bVisible = true;
+ }
+
+ if(!bVisible && pObj->HasFillStyle())
+ {
+ bVisible = true;
+ }
+
+ if(!bVisible)
+ {
+ SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(pObj);
+
+ if(pTextObj && pTextObj->HasText())
+ {
+ bVisible = true;
+ }
+ }
+
+ if(!bVisible)
+ {
+ SdrGrafObj* pGrafObj = dynamic_cast< SdrGrafObj* >(pObj);
+
+ if(pGrafObj)
+ {
+ // this may be refined to check if the graphic really is visible. It
+ // is here to ensure that graphic objects without fill, line and text
+ // get created
+ bVisible = true;
+ }
+ }
+
+ if(!bVisible)
+ {
+ SdrObject::Free(pObj);
+ }
+ else
+ {
+ aTmpList.InsertObject( pObj );
+ if ( HAS_BASE( SdrPathObj, pObj ) )
+ {
+ FASTBOOL bClosed=pObj->IsClosedObj();
+ bLastObjWasPolyWithoutLine=bNoLine && bClosed;
+ bLastObjWasLine=!bClosed;
+ }
+ else
+ {
+ bLastObjWasPolyWithoutLine = FALSE;
+ bLastObjWasLine = FALSE;
+ }
+ }
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPixelAction& /*rAct*/)
+{
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPointAction& /*rAct*/)
+{
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaLineAction& rAct)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ const basegfx::B2DPoint aStart(rAct.GetStartPoint().X(), rAct.GetStartPoint().Y());
+ const basegfx::B2DPoint aEnd(rAct.GetEndPoint().X(), rAct.GetEndPoint().Y());
+
+ if(!aStart.equal(aEnd))
+ {
+ basegfx::B2DPolygon aLine;
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+
+ aLine.append(aStart);
+ aLine.append(aEnd);
+ aLine.transform(aTransform);
+
+ const LineInfo& rLineInfo = rAct.GetLineInfo();
+ const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
+ bool bCreateLineObject(true);
+
+ if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aLine))
+ {
+ bCreateLineObject = false;
+ }
+
+ if(bCreateLineObject)
+ {
+ SdrPathObj* pPath = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aLine));
+ nLineWidth = nNewLineWidth;
+ maLineJoin = rLineInfo.GetLineJoin();
+ maDash = XDash(XDASH_RECT,
+ rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
+ rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
+ rLineInfo.GetDistance());
+ SetAttributes(pPath);
+ nLineWidth = 0;
+ maLineJoin = basegfx::B2DLINEJOIN_NONE;
+ maDash = XDash();
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaRectAction& rAct)
+{
+ SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
+ SetAttributes(pRect);
+ InsertObj(pRect);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaRoundRectAction& rAct)
+{
+ SdrRectObj* pRect=new SdrRectObj(rAct.GetRect());
+ SetAttributes(pRect);
+ long nRad=(rAct.GetHorzRound()+rAct.GetVertRound())/2;
+ if (nRad!=0) {
+ SfxItemSet aSet(*pLineAttr->GetPool(),SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS);
+ aSet.Put(SdrEckenradiusItem(nRad));
+ pRect->SetMergedItemSet(aSet);
+ }
+ InsertObj(pRect);
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaEllipseAction& rAct)
+{
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CIRC,rAct.GetRect());
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaArcAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CARC,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPieAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_SECT,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaChordAction& rAct)
+{
+ Point aCenter(rAct.GetRect().Center());
+ long nStart=GetAngle(rAct.GetStartPoint()-aCenter);
+ long nEnd=GetAngle(rAct.GetEndPoint()-aCenter);
+ SdrCircObj* pCirc=new SdrCircObj(OBJ_CCUT,rAct.GetRect(),nStart,nEnd);
+ SetAttributes(pCirc);
+ InsertObj(pCirc);
+}
+
+/**************************************************************************************************/
+
+bool ImpSdrGDIMetaFileImport::CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly)
+{
+ // #i102706# Do not merge closed polygons
+ if(rSrcPoly.isClosed())
+ {
+ return false;
+ }
+
+ // #i73407# reformulation to use new B2DPolygon classes
+ if(bLastObjWasLine && (aOldLineColor == aVD.GetLineColor()) && rSrcPoly.count())
+ {
+ SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
+ SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
+
+ if(pLastPoly)
+ {
+ if(1L == pLastPoly->GetPathPoly().count())
+ {
+ bool bOk(false);
+ basegfx::B2DPolygon aDstPoly(pLastPoly->GetPathPoly().getB2DPolygon(0L));
+
+ // #i102706# Do not merge closed polygons
+ if(aDstPoly.isClosed())
+ {
+ return false;
+ }
+
+ if(aDstPoly.count())
+ {
+ const sal_uInt32 nMaxDstPnt(aDstPoly.count() - 1L);
+ const sal_uInt32 nMaxSrcPnt(rSrcPoly.count() - 1L);
+
+ if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(0L))
+ {
+ aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
+ {
+ basegfx::B2DPolygon aNew(rSrcPoly);
+ aNew.append(aDstPoly, 1L, aDstPoly.count() - 1L);
+ aDstPoly = aNew;
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(0L) == rSrcPoly.getB2DPoint(0L))
+ {
+ aDstPoly.flip();
+ aDstPoly.append(rSrcPoly, 1L, rSrcPoly.count() - 1L);
+ bOk = true;
+ }
+ else if(aDstPoly.getB2DPoint(nMaxDstPnt) == rSrcPoly.getB2DPoint(nMaxSrcPnt))
+ {
+ basegfx::B2DPolygon aNew(rSrcPoly);
+ aNew.flip();
+ aDstPoly.append(aNew, 1L, aNew.count() - 1L);
+ bOk = true;
+ }
+ }
+
+ if(bOk)
+ {
+ pLastPoly->NbcSetPathPoly(basegfx::B2DPolyPolygon(aDstPoly));
+ }
+
+ return bOk;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool ImpSdrGDIMetaFileImport::CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon & rPolyPolygon)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ if(bLastObjWasPolyWithoutLine)
+ {
+ SdrObject* pTmpObj = aTmpList.GetObj(aTmpList.GetObjCount() - 1);
+ SdrPathObj* pLastPoly = PTR_CAST(SdrPathObj, pTmpObj);
+
+ if(pLastPoly)
+ {
+ if(pLastPoly->GetPathPoly() == rPolyPolygon)
+ {
+ SetAttributes(NULL);
+
+ if(!bNoLine && bNoFill)
+ {
+ pLastPoly->SetMergedItemSet(*pLineAttr);
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaPolyLineAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+ }
+
+ const LineInfo& rLineInfo = rAct.GetLineInfo();
+ const sal_Int32 nNewLineWidth(rLineInfo.GetWidth());
+ bool bCreateLineObject(true);
+
+ if(bLastObjWasLine && (nNewLineWidth == nLineWidth) && CheckLastLineMerge(aSource))
+ {
+ bCreateLineObject = false;
+ }
+ else if(bLastObjWasPolyWithoutLine && CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
+ {
+ bCreateLineObject = false;
+ }
+
+ if(bCreateLineObject)
+ {
+ SdrPathObj* pPath = new SdrPathObj(
+ aSource.isClosed() ? OBJ_POLY : OBJ_PLIN,
+ basegfx::B2DPolyPolygon(aSource));
+ nLineWidth = nNewLineWidth;
+ maLineJoin = rLineInfo.GetLineJoin();
+ maDash = XDash(XDASH_RECT,
+ rLineInfo.GetDotCount(), rLineInfo.GetDotLen(),
+ rLineInfo.GetDashCount(), rLineInfo.GetDashLen(),
+ rLineInfo.GetDistance());
+ SetAttributes(pPath);
+ nLineWidth = 0;
+ maLineJoin = basegfx::B2DLINEJOIN_NONE;
+ maDash = XDash();
+ InsertObj(pPath, false);
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaPolygonAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolygon aSource(rAct.GetPolygon().getB2DPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(basegfx::B2DPolyPolygon(aSource)))
+ {
+ // #i73407# make sure polygon is closed, it's a filled primitive
+ aSource.setClosed(true);
+
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, basegfx::B2DPolyPolygon(aSource));
+ SetAttributes(pPath);
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaPolyPolygonAction& rAct)
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ // #i73407# make sure polygon is closed, it's a filled primitive
+ aSource.setClosed(true);
+
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SetAttributes(pPath);
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+/**************************************************************************************************/
+
+void ImpSdrGDIMetaFileImport::ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct )
+{
+ // calc text box size, add 5% to make it fit safely
+
+ FontMetric aFontMetric( aVD.GetFontMetric() );
+ Font aFnt( aVD.GetFont() );
+ FontAlign eAlg( aFnt.GetAlign() );
+
+ sal_Int32 nTextWidth = (sal_Int32)( aVD.GetTextWidth( rStr ) * fScaleX );
+ sal_Int32 nTextHeight = (sal_Int32)( aVD.GetTextHeight() * fScaleY );
+ //sal_Int32 nDxWidth = 0;
+ //sal_Int32 nLen = rStr.Len();
+
+ Point aPos( FRound(rPos.X() * fScaleX + aOfs.X()), FRound(rPos.Y() * fScaleY + aOfs.Y()) );
+ Size aSize( nTextWidth, nTextHeight );
+
+ if ( eAlg == ALIGN_BASELINE )
+ aPos.Y() -= FRound(aFontMetric.GetAscent() * fScaleY);
+ else if ( eAlg == ALIGN_BOTTOM )
+ aPos.Y() -= nTextHeight;
+
+ Rectangle aTextRect( aPos, aSize );
+ SdrRectObj* pText =new SdrRectObj( OBJ_TEXT, aTextRect );
+
+ if ( aFnt.GetWidth() || ( rAct.GetType() == META_STRETCHTEXT_ACTION ) )
+ {
+ pText->ClearMergedItem( SDRATTR_TEXT_AUTOGROWWIDTH );
+ pText->SetMergedItem( SdrTextAutoGrowHeightItem( FALSE ) );
+ // don't let the margins eat the space needed for the text
+ pText->SetMergedItem ( SdrTextUpperDistItem (0));
+ pText->SetMergedItem ( SdrTextLowerDistItem (0));
+ pText->SetMergedItem ( SdrTextRightDistItem (0));
+ pText->SetMergedItem ( SdrTextLeftDistItem (0));
+ pText->SetMergedItem( SdrTextFitToSizeTypeItem( SDRTEXTFIT_ALLLINES ) );
+ }
+ else
+ pText->SetMergedItem( SdrTextAutoGrowWidthItem( sal_True ) );
+
+ pText->SetModel( pModel );
+ pText->SetLayer( nLayer );
+ pText->NbcSetText( rStr );
+ SetAttributes( pText, TRUE );
+ pText->SetSnapRect( aTextRect );
+
+ if (!aFnt.IsTransparent())
+ {
+ SfxItemSet aAttr(*pFillAttr->GetPool(),XATTR_FILL_FIRST,XATTR_FILL_LAST);
+ aAttr.Put(XFillStyleItem(XFILL_SOLID));
+ aAttr.Put(XFillColorItem(String(), aFnt.GetFillColor()));
+ pText->SetMergedItemSet(aAttr);
+ }
+ sal_uInt32 nWink = aFnt.GetOrientation();
+ if ( nWink )
+ {
+ nWink*=10;
+ double a=nWink*nPi180;
+ double nSin=sin(a);
+ double nCos=cos(a);
+ pText->NbcRotate(aPos,nWink,nSin,nCos);
+ }
+ InsertObj( pText, sal_False );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaTextAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaTextArrayAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaStretchTextAction& rAct)
+{
+ XubString aStr(rAct.GetText());
+ aStr.Erase(0,rAct.GetIndex());
+ aStr.Erase(rAct.GetLen());
+ ImportText( rAct.GetPoint(), aStr, rAct );
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetBitmap().GetSizePixel());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpScaleAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj(Graphic(rAct.GetBitmap()),aRect);
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetBitmapEx().GetSizePixel());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
+ InsertObj(pGraf);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaBmpExScaleAction& rAct)
+{
+ Rectangle aRect(rAct.GetPoint(),rAct.GetSize());
+ aRect.Right()++; aRect.Bottom()++;
+ SdrGrafObj* pGraf=new SdrGrafObj( rAct.GetBitmapEx(), aRect );
+ InsertObj(pGraf);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaHatchAction& rAct )
+{
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(rAct.GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ const basegfx::B2DHomMatrix aTransform(basegfx::tools::createScaleTranslateB2DHomMatrix(fScaleX, fScaleY, aOfs.X(), aOfs.Y()));
+ aSource.transform(aTransform);
+
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ const Hatch& rHatch = rAct.GetHatch();
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SfxItemSet aHatchAttr(pModel->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLSTYLE,
+ XATTR_FILLHATCH, XATTR_FILLHATCH, 0, 0 );
+ XHatchStyle eStyle;
+
+ switch(rHatch.GetStyle())
+ {
+ case(HATCH_TRIPLE) :
+ {
+ eStyle = XHATCH_TRIPLE;
+ break;
+ }
+
+ case(HATCH_DOUBLE) :
+ {
+ eStyle = XHATCH_DOUBLE;
+ break;
+ }
+
+ default:
+ {
+ eStyle = XHATCH_SINGLE;
+ break;
+ }
+ }
+
+ SetAttributes(pPath);
+ aHatchAttr.Put(XFillStyleItem(XFILL_HATCH));
+ aHatchAttr.Put(XFillHatchItem(&pModel->GetItemPool(), XHatch(rHatch.GetColor(), eStyle, rHatch.GetDistance(), rHatch.GetAngle())));
+ pPath->SetMergedItemSet(aHatchAttr);
+
+ InsertObj(pPath, false);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaLineColorAction& rAct)
+{
+ rAct.Execute(&aVD);
+}
+
+void ImpSdrGDIMetaFileImport::DoAction(MetaMapModeAction& rAct)
+{
+ MapScaling();
+ rAct.Execute(&aVD);
+ bLastObjWasPolyWithoutLine=FALSE;
+ bLastObjWasLine=FALSE;
+}
+
+void ImpSdrGDIMetaFileImport::MapScaling()
+{
+ sal_uInt32 i, nAnz = aTmpList.GetObjCount();
+ const MapMode& rMap = aVD.GetMapMode();
+ Point aMapOrg( rMap.GetOrigin() );
+ sal_Bool bMov2 = aMapOrg.X() != 0 || aMapOrg.Y() != 0;
+ if ( bMov2 )
+ {
+ for ( i = nMapScalingOfs; i < nAnz; i++ )
+ {
+ SdrObject* pObj = aTmpList.GetObj(i);
+ if ( bMov2 )
+ pObj->NbcMove( Size( aMapOrg.X(), aMapOrg.Y() ) );
+ }
+ }
+ nMapScalingOfs = nAnz;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction& rAct, GDIMetaFile* pMtf )
+{
+ ByteString aSkipComment;
+
+ if( rAct.GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL )
+ {
+ MetaGradientExAction* pAct = (MetaGradientExAction*) pMtf->NextAction();
+
+ if( pAct && pAct->GetType() == META_GRADIENTEX_ACTION )
+ {
+ // #i73407# reformulation to use new B2DPolygon classes
+ basegfx::B2DPolyPolygon aSource(pAct->GetPolyPolygon().getB2DPolyPolygon());
+
+ if(aSource.count())
+ {
+ if(!bLastObjWasPolyWithoutLine || !CheckLastPolyLineAndFillMerge(aSource))
+ {
+ const Gradient& rGrad = pAct->GetGradient();
+ SdrPathObj* pPath = new SdrPathObj(OBJ_POLY, aSource);
+ SfxItemSet aGradAttr(pModel->GetItemPool(),
+ XATTR_FILLSTYLE, XATTR_FILLSTYLE,
+ XATTR_FILLGRADIENT, XATTR_FILLGRADIENT, 0, 0 );
+ XGradient aXGradient;
+
+ aXGradient.SetGradientStyle((XGradientStyle)rGrad.GetStyle());
+ aXGradient.SetStartColor(rGrad.GetStartColor());
+ aXGradient.SetEndColor(rGrad.GetEndColor());
+ aXGradient.SetAngle((USHORT)rGrad.GetAngle());
+ aXGradient.SetBorder(rGrad.GetBorder());
+ aXGradient.SetXOffset(rGrad.GetOfsX());
+ aXGradient.SetYOffset(rGrad.GetOfsY());
+ aXGradient.SetStartIntens(rGrad.GetStartIntensity());
+ aXGradient.SetEndIntens(rGrad.GetEndIntensity());
+ aXGradient.SetSteps(rGrad.GetSteps());
+
+ if(aVD.IsLineColor())
+ {
+ // switch line off; when there was one there will be a
+ // META_POLYLINE_ACTION following creating another object
+ const Color aLineColor(aVD.GetLineColor());
+ aVD.SetLineColor();
+ SetAttributes(pPath);
+ aVD.SetLineColor(aLineColor);
+ }
+ else
+ {
+ SetAttributes(pPath);
+ }
+
+ aGradAttr.Put(XFillStyleItem(XFILL_GRADIENT));
+ aGradAttr.Put(XFillGradientItem(&pModel->GetItemPool(), aXGradient));
+ pPath->SetMergedItemSet(aGradAttr);
+
+ InsertObj(pPath);
+ }
+ }
+
+ aSkipComment = "XGRAD_SEQ_END";
+ }
+ }
+
+ if(aSkipComment.Len())
+ {
+ MetaAction* pSkipAct = pMtf->NextAction();
+
+ while( pSkipAct
+ && ((pSkipAct->GetType() != META_COMMENT_ACTION )
+ || (((MetaCommentAction*)pSkipAct)->GetComment().CompareIgnoreCaseToAscii(aSkipComment.GetBuffer()) != COMPARE_EQUAL)))
+ {
+ pSkipAct = pMtf->NextAction();
+ }
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/svdfmtf.hxx b/svx/source/svdraw/svdfmtf.hxx
new file mode 100644
index 000000000000..2562b81efa8d
--- /dev/null
+++ b/svx/source/svdraw/svdfmtf.hxx
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVDFMTF_HXX
+#define _SVDFMTF_HXX
+
+#include <vcl/metaact.hxx>
+#include <vcl/virdev.hxx>
+#include <svx/svdobj.hxx>
+
+//************************************************************
+// Vorausdeklarationen
+//************************************************************
+
+class SfxItemSet;
+class SdrObjList;
+class SdrModel;
+class SdrPage;
+class SdrObject;
+class SvdProgressInfo;
+
+//************************************************************
+// Hilfsklasse SdrObjRefList
+//************************************************************
+
+class SdrObjRefList
+{
+ Container aList;
+public:
+
+ SdrObjRefList()
+ : aList(1024,64,64)
+ {}
+
+ void Clear() { aList.Clear(); }
+ ULONG GetObjCount() const { return aList.Count(); }
+ SdrObject* GetObj(ULONG nNum) const { return (SdrObject*)aList.GetObject(nNum); }
+ SdrObject* operator[](ULONG nNum) const { return (SdrObject*)aList.GetObject(nNum); }
+ void InsertObject(SdrObject* pObj, ULONG nPos=CONTAINER_APPEND) { aList.Insert(pObj,nPos); }
+ void RemoveObject(ULONG nPos) { aList.Remove(nPos); }
+};
+
+//************************************************************
+// Hilfsklasse ImpSdrGDIMetaFileImport
+//************************************************************
+
+class ImpSdrGDIMetaFileImport
+{
+protected:
+ SdrObjRefList aTmpList;
+ VirtualDevice aVD;
+ Rectangle aScaleRect;
+ ULONG nMapScalingOfs; // ab hier nocht nicht mit MapScaling bearbeitet
+ SfxItemSet* pLineAttr;
+ SfxItemSet* pFillAttr;
+ SfxItemSet* pTextAttr;
+ SdrPage* pPage;
+ SdrModel* pModel;
+ SdrLayerID nLayer;
+ Color aOldLineColor;
+ sal_Int32 nLineWidth;
+ basegfx::B2DLineJoin maLineJoin;
+ XDash maDash;
+
+ sal_Bool bMov;
+ sal_Bool bSize;
+ Point aOfs;
+ double fScaleX;
+ double fScaleY;
+ Fraction aScaleX;
+ Fraction aScaleY;
+
+ sal_Bool bFntDirty;
+
+ // fuer Optimierung von (PenNULL,Brush,DrawPoly),(Pen,BrushNULL,DrawPoly) -> aus 2 mach ein
+ sal_Bool bLastObjWasPolyWithoutLine;
+ sal_Bool bNoLine;
+ sal_Bool bNoFill;
+
+ // fuer Optimierung mehrerer Linien zu einer Polyline
+ sal_Bool bLastObjWasLine;
+
+protected:
+ void DoAction(MetaPixelAction & rAct);
+ void DoAction(MetaPointAction & rAct);
+ void DoAction(MetaLineAction & rAct);
+ void DoAction(MetaRectAction & rAct);
+ void DoAction(MetaRoundRectAction & rAct);
+ void DoAction(MetaEllipseAction & rAct);
+ void DoAction(MetaArcAction & rAct);
+ void DoAction(MetaPieAction & rAct);
+ void DoAction(MetaChordAction & rAct);
+ void DoAction(MetaPolyLineAction & rAct);
+ void DoAction(MetaPolygonAction & rAct);
+ void DoAction(MetaPolyPolygonAction & rAct);
+ void DoAction(MetaTextAction & rAct);
+ void DoAction(MetaTextArrayAction & rAct);
+ void DoAction(MetaStretchTextAction & rAct);
+ void DoAction(MetaBmpAction & rAct);
+ void DoAction(MetaBmpScaleAction & rAct);
+ void DoAction(MetaBmpExAction & rAct);
+ void DoAction(MetaBmpExScaleAction & rAct);
+ void DoAction(MetaHatchAction & rAct);
+ void DoAction(MetaLineColorAction & rAct);
+ void DoAction(MetaMapModeAction & rAct);
+ void DoAction(MetaFillColorAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaTextColorAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaTextFillColorAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaFontAction & rAct) { rAct.Execute(&aVD); bFntDirty=TRUE; }
+ void DoAction(MetaTextAlignAction & rAct) { rAct.Execute(&aVD); bFntDirty=TRUE; }
+ void DoAction(MetaClipRegionAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaRasterOpAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaPushAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaPopAction & rAct) { rAct.Execute(&aVD); bFntDirty=TRUE; }
+ void DoAction(MetaMoveClipRegionAction & rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaISectRectClipRegionAction& rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaISectRegionClipRegionAction& rAct) { rAct.Execute(&aVD); }
+ void DoAction(MetaCommentAction& rAct, GDIMetaFile* pMtf);
+
+ void ImportText( const Point& rPos, const XubString& rStr, const MetaAction& rAct );
+ void SetAttributes(SdrObject* pObj, FASTBOOL bForceTextAttr=FALSE);
+ void InsertObj( SdrObject* pObj, sal_Bool bScale = sal_True );
+ void MapScaling();
+
+ // #i73407# reformulation to use new B2DPolygon classes
+ bool CheckLastLineMerge(const basegfx::B2DPolygon& rSrcPoly);
+ bool CheckLastPolyLineAndFillMerge(const basegfx::B2DPolyPolygon& rPolyPolygon);
+
+public:
+ ImpSdrGDIMetaFileImport(SdrModel& rModel);
+ ~ImpSdrGDIMetaFileImport();
+ ULONG DoImport(const GDIMetaFile& rMtf, SdrObjList& rDestList, ULONG nInsPos=CONTAINER_APPEND, SvdProgressInfo *pProgrInfo = NULL);
+ void SetLayer(SdrLayerID nLay) { nLayer=nLay; }
+ SdrLayerID GetLayer() const { return nLayer; }
+ void SetScaleRect(const Rectangle& rRect) { aScaleRect=rRect; }
+ const Rectangle& GetScaleRect() const { return aScaleRect; }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif //_SVDFMTF_HXX
+// eof
diff --git a/svx/source/svdraw/svdglev.cxx b/svx/source/svdraw/svdglev.cxx
new file mode 100644
index 000000000000..6eab2ea7ecfa
--- /dev/null
+++ b/svx/source/svdraw/svdglev.cxx
@@ -0,0 +1,422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdglev.hxx>
+#include <math.h>
+
+#include <svx/svdundo.hxx>
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/svdpagv.hxx>
+#include <svx/svdglue.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdobj.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGlueEditView::ImpClearVars()
+{
+}
+
+SdrGlueEditView::SdrGlueEditView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrPolyEditView(pModel1,pOut)
+{
+ ImpClearVars();
+}
+
+SdrGlueEditView::~SdrGlueEditView()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGlueEditView::ImpDoMarkedGluePoints(PGlueDoFunc pDoFunc, BOOL bConst, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
+{
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+ if (nPtAnz!=0) {
+ SdrGluePointList* pGPL=NULL;
+ if (bConst) {
+ const SdrGluePointList* pConstGPL=pObj->GetGluePointList();
+ pGPL=(SdrGluePointList*)pConstGPL;
+ } else {
+ pGPL=pObj->ForceGluePointList();
+ }
+ if (pGPL!=NULL)
+ {
+ if(!bConst && IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
+ {
+ USHORT nPtId=pPts->GetObject(nPtNum);
+ USHORT nGlueIdx=pGPL->FindGluePoint(nPtId);
+ if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
+ {
+ SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
+ (*pDoFunc)(rGP,pObj,p1,p2,p3,p4,p5);
+ }
+ }
+ if (!bConst)
+ {
+ pObj->SetChanged();
+ pObj->BroadcastObjectChange();
+ }
+ }
+ }
+ }
+ if (!bConst && nMarkAnz!=0) pMod->SetChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpGetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnThisEsc, const void* pnRet, const void*, const void*)
+{
+ USHORT& nRet=*(USHORT*)pnRet;
+ BOOL& bFirst=*(BOOL*)pbFirst;
+ if (nRet!=FUZZY) {
+ USHORT nEsc=rGP.GetEscDir();
+ BOOL bOn=(nEsc & *(USHORT*)pnThisEsc)!=0;
+ if (bFirst) { nRet=bOn; bFirst=FALSE; }
+ else if (nRet!=bOn) nRet=FUZZY;
+ }
+}
+
+TRISTATE SdrGlueEditView::IsMarkedGluePointsEscDir(USHORT nThisEsc) const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bFirst=TRUE;
+ USHORT nRet=FALSE;
+ ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetEscDir,TRUE,&bFirst,&nThisEsc,&nRet);
+ return (TRISTATE)nRet;
+}
+
+static void ImpSetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pnThisEsc, const void* pbOn, const void*, const void*, const void*)
+{
+ USHORT nEsc=rGP.GetEscDir();
+ if (*(BOOL*)pbOn) nEsc|=*(USHORT*)pnThisEsc;
+ else nEsc&=~*(USHORT*)pnThisEsc;
+ rGP.SetEscDir(nEsc);
+}
+
+void SdrGlueEditView::SetMarkedGluePointsEscDir(USHORT nThisEsc, BOOL bOn)
+{
+ ForceUndirtyMrkPnt();
+ BegUndo(ImpGetResStr(STR_EditSetGlueEscDir),GetDescriptionOfMarkedGluePoints());
+ ImpDoMarkedGluePoints(ImpSetEscDir,FALSE,&nThisEsc,&bOn);
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpGetPercent(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnRet, const void*, const void*, const void*)
+{
+ USHORT& nRet=*(USHORT*)pnRet;
+ BOOL& bFirst=*(BOOL*)pbFirst;
+ if (nRet!=FUZZY) {
+ bool bOn=rGP.IsPercent();
+ if (bFirst) { nRet=bOn; bFirst=FALSE; }
+ else if ((nRet!=0)!=bOn) nRet=FUZZY;
+ }
+}
+
+TRISTATE SdrGlueEditView::IsMarkedGluePointsPercent() const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bFirst=TRUE;
+ USHORT nRet=TRUE;
+ ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetPercent,TRUE,&bFirst,&nRet);
+ return (TRISTATE)nRet;
+}
+
+static void ImpSetPercent(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbOn, const void*, const void*, const void*, const void*)
+{
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ rGP.SetPercent(*(BOOL*)pbOn);
+ rGP.SetAbsolutePos(aPos,*pObj);
+}
+
+void SdrGlueEditView::SetMarkedGluePointsPercent(BOOL bOn)
+{
+ ForceUndirtyMrkPnt();
+ BegUndo(ImpGetResStr(STR_EditSetGluePercent),GetDescriptionOfMarkedGluePoints());
+ ImpDoMarkedGluePoints(ImpSetPercent,FALSE,&bOn);
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpGetAlign(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pbDontCare, const void* pbVert, const void* pnRet, const void*)
+{
+ USHORT& nRet=*(USHORT*)pnRet;
+ BOOL& bFirst=*(BOOL*)pbFirst;
+ BOOL& bDontCare=*(BOOL*)pbDontCare;
+ BOOL bVert=*(BOOL*)pbVert;
+ if (!bDontCare) {
+ USHORT nAlg=0;
+ if (bVert) {
+ nAlg=rGP.GetVertAlign();
+ } else {
+ nAlg=rGP.GetHorzAlign();
+ }
+ if (bFirst) { nRet=nAlg; bFirst=FALSE; }
+ else if (nRet!=nAlg) {
+ if (bVert) {
+ nRet=SDRVERTALIGN_DONTCARE;
+ } else {
+ nRet=SDRHORZALIGN_DONTCARE;
+ }
+ bDontCare=TRUE;
+ }
+ }
+}
+
+USHORT SdrGlueEditView::GetMarkedGluePointsAlign(BOOL bVert) const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bFirst=TRUE;
+ BOOL bDontCare=FALSE;
+ USHORT nRet=0;
+ ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetAlign,TRUE,&bFirst,&bDontCare,&bVert,&nRet);
+ return nRet;
+}
+
+static void ImpSetAlign(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbVert, const void* pnAlign, const void*, const void*, const void*)
+{
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ if (*(BOOL*)pbVert) { // bVert?
+ rGP.SetVertAlign(*(USHORT*)pnAlign);
+ } else {
+ rGP.SetHorzAlign(*(USHORT*)pnAlign);
+ }
+ rGP.SetAbsolutePos(aPos,*pObj);
+}
+
+void SdrGlueEditView::SetMarkedGluePointsAlign(BOOL bVert, USHORT nAlign)
+{
+ ForceUndirtyMrkPnt();
+ BegUndo(ImpGetResStr(STR_EditSetGlueAlign),GetDescriptionOfMarkedGluePoints());
+ ImpDoMarkedGluePoints(ImpSetAlign,FALSE,&bVert,&nAlign);
+ EndUndo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrGlueEditView::IsDeleteMarkedGluePointsPossible() const
+{
+ return HasMarkedGluePoints();
+}
+
+void SdrGlueEditView::DeleteMarkedGluePoints()
+{
+ BrkAction();
+ ForceUndirtyMrkPnt();
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_DELETE);
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+ if (nPtAnz!=0)
+ {
+ SdrGluePointList* pGPL=pObj->ForceGluePointList();
+ if (pGPL!=NULL)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
+ {
+ USHORT nPtId=pPts->GetObject(nPtNum);
+ USHORT nGlueIdx=pGPL->FindGluePoint(nPtId);
+ if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
+ {
+ pGPL->Delete(nGlueIdx);
+ }
+ }
+ pObj->SetChanged();
+ pObj->BroadcastObjectChange();
+ }
+ }
+ }
+ if( bUndo )
+ EndUndo();
+ UnmarkAllGluePoints();
+ if (nMarkAnz!=0)
+ pMod->SetChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGlueEditView::ImpCopyMarkedGluePoints()
+{
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ SdrGluePointList* pGPL=pObj->ForceGluePointList();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+ if (nPtAnz!=0 && pGPL!=NULL)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++)
+ {
+ USHORT nPtId=pPts->GetObject(nPtNum);
+ USHORT nGlueIdx=pGPL->FindGluePoint(nPtId);
+ if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
+ {
+ SdrGluePoint aNewGP((*pGPL)[nGlueIdx]); // GluePoint klonen
+ USHORT nNewIdx=pGPL->Insert(aNewGP); // und einfuegen
+ USHORT nNewId=(*pGPL)[nNewIdx].GetId(); // Id des neuen GluePoints ermitteln
+ pPts->Replace(nNewId,nPtNum); // und diesen markieren (anstelle des alten)
+ }
+ }
+ }
+ }
+ if( bUndo )
+ EndUndo();
+
+ if (nMarkAnz!=0)
+ pMod->SetChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
+{
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+ if (nPtAnz!=0) {
+ SdrGluePointList* pGPL=pObj->ForceGluePointList();
+ if (pGPL!=NULL)
+ {
+ if( IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ for (ULONG nPtNum=0; nPtNum<nPtAnz; nPtNum++) {
+ USHORT nPtId=pPts->GetObject(nPtNum);
+ USHORT nGlueIdx=pGPL->FindGluePoint(nPtId);
+ if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) {
+ SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ (*pTrFunc)(aPos,p1,p2,p3,p4,p5);
+ rGP.SetAbsolutePos(aPos,*pObj);
+ }
+ }
+ pObj->SetChanged();
+ pObj->BroadcastObjectChange();
+ }
+ }
+ }
+ if (nMarkAnz!=0) pMod->SetChanged();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpMove(Point& rPt, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/, const void* /*p5*/)
+{
+ rPt.X()+=((const Size*)p1)->Width();
+ rPt.Y()+=((const Size*)p1)->Height();
+}
+
+void SdrGlueEditView::MoveMarkedGluePoints(const Size& rSiz, bool bCopy)
+{
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditMove));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_MOVE);
+ if (bCopy) ImpCopyMarkedGluePoints();
+ ImpTransformMarkedGluePoints(ImpMove,&rSiz);
+ EndUndo();
+ AdjustMarkHdl();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpResize(Point& rPt, const void* p1, const void* p2, const void* p3, const void* /*p4*/, const void* /*p5*/)
+{
+ ResizePoint(rPt,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
+}
+
+void SdrGlueEditView::ResizeMarkedGluePoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
+{
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditResize));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_RESIZE);
+ if (bCopy) ImpCopyMarkedGluePoints();
+ ImpTransformMarkedGluePoints(ImpResize,&rRef,&xFact,&yFact);
+ EndUndo();
+ AdjustMarkHdl();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void ImpRotate(Point& rPt, const void* p1, const void* /*p2*/, const void* p3, const void* p4, const void* /*p5*/)
+{
+ RotatePoint(rPt,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
+}
+
+void SdrGlueEditView::RotateMarkedGluePoints(const Point& rRef, long nWink, bool bCopy)
+{
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditRotate));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_ROTATE);
+ if (bCopy) ImpCopyMarkedGluePoints();
+ double nSin=sin(nWink*nPi180);
+ double nCos=cos(nWink*nPi180);
+ ImpTransformMarkedGluePoints(ImpRotate,&rRef,&nWink,&nSin,&nCos);
+ EndUndo();
+ AdjustMarkHdl();
+}
+
diff --git a/svx/source/svdraw/svdglue.cxx b/svx/source/svdraw/svdglue.cxx
new file mode 100644
index 000000000000..634d7060e735
--- /dev/null
+++ b/svx/source/svdraw/svdglue.cxx
@@ -0,0 +1,450 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <tools/debug.hxx>
+
+#include <svx/svdglue.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdtrans.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGluePoint::SetReallyAbsolute(FASTBOOL bOn, const SdrObject& rObj)
+{
+ if ( bReallyAbsolute != bOn )
+ {
+ if ( bOn )
+ {
+ aPos=GetAbsolutePos(rObj);
+ bReallyAbsolute=bOn;
+ }
+ else
+ {
+ bReallyAbsolute=bOn;
+ Point aPt(aPos);
+ SetAbsolutePos(aPt,rObj);
+ }
+ }
+}
+
+Point SdrGluePoint::GetAbsolutePos(const SdrObject& rObj) const
+{
+ if (bReallyAbsolute) return aPos;
+ Rectangle aSnap(rObj.GetSnapRect());
+ Rectangle aBound(rObj.GetSnapRect());
+ Point aPt(aPos);
+
+ Point aOfs(aSnap.Center());
+ switch (GetHorzAlign()) {
+ case SDRHORZALIGN_LEFT : aOfs.X()=aSnap.Left(); break;
+ case SDRHORZALIGN_RIGHT : aOfs.X()=aSnap.Right(); break;
+ }
+ switch (GetVertAlign()) {
+ case SDRVERTALIGN_TOP : aOfs.Y()=aSnap.Top(); break;
+ case SDRVERTALIGN_BOTTOM: aOfs.Y()=aSnap.Bottom(); break;
+ }
+ if (!bNoPercent) {
+ long nXMul=aSnap.Right()-aSnap.Left();
+ long nYMul=aSnap.Bottom()-aSnap.Top();
+ long nXDiv=10000;
+ long nYDiv=10000;
+ if (nXMul!=nXDiv) {
+ aPt.X()*=nXMul;
+ aPt.X()/=nXDiv;
+ }
+ if (nYMul!=nYDiv) {
+ aPt.Y()*=nYMul;
+ aPt.Y()/=nYDiv;
+ }
+ }
+ aPt+=aOfs;
+ // Und nun auf's BoundRect des Objekts begrenzen
+ if (aPt.X()<aBound.Left ()) aPt.X()=aBound.Left ();
+ if (aPt.X()>aBound.Right ()) aPt.X()=aBound.Right ();
+ if (aPt.Y()<aBound.Top ()) aPt.Y()=aBound.Top ();
+ if (aPt.Y()>aBound.Bottom()) aPt.Y()=aBound.Bottom();
+ return aPt;
+}
+
+void SdrGluePoint::SetAbsolutePos(const Point& rNewPos, const SdrObject& rObj)
+{
+ if (bReallyAbsolute) {
+ aPos=rNewPos;
+ return;
+ }
+ Rectangle aSnap(rObj.GetSnapRect());
+ Point aPt(rNewPos);
+
+ Point aOfs(aSnap.Center());
+ switch (GetHorzAlign()) {
+ case SDRHORZALIGN_LEFT : aOfs.X()=aSnap.Left(); break;
+ case SDRHORZALIGN_RIGHT : aOfs.X()=aSnap.Right(); break;
+ }
+ switch (GetVertAlign()) {
+ case SDRVERTALIGN_TOP : aOfs.Y()=aSnap.Top(); break;
+ case SDRVERTALIGN_BOTTOM: aOfs.Y()=aSnap.Bottom(); break;
+ }
+ aPt-=aOfs;
+ if (!bNoPercent) {
+ long nXMul=aSnap.Right()-aSnap.Left();
+ long nYMul=aSnap.Bottom()-aSnap.Top();
+ if (nXMul==0) nXMul=1;
+ if (nYMul==0) nYMul=1;
+ long nXDiv=10000;
+ long nYDiv=10000;
+ if (nXMul!=nXDiv) {
+ aPt.X()*=nXDiv;
+ aPt.X()/=nXMul;
+ }
+ if (nYMul!=nYDiv) {
+ aPt.Y()*=nYDiv;
+ aPt.Y()/=nYMul;
+ }
+ }
+ aPos=aPt;
+}
+
+long SdrGluePoint::GetAlignAngle() const
+{
+ switch (nAlign) {
+ case SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER: return 0; // Invalid!
+ case SDRHORZALIGN_RIGHT |SDRVERTALIGN_CENTER: return 0;
+ case SDRHORZALIGN_RIGHT |SDRVERTALIGN_TOP : return 4500;
+ case SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP : return 9000;
+ case SDRHORZALIGN_LEFT |SDRVERTALIGN_TOP : return 13500;
+ case SDRHORZALIGN_LEFT |SDRVERTALIGN_CENTER: return 18000;
+ case SDRHORZALIGN_LEFT |SDRVERTALIGN_BOTTOM: return 22500;
+ case SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM: return 27000;
+ case SDRHORZALIGN_RIGHT |SDRVERTALIGN_BOTTOM: return 31500;
+ } // switch
+ return 0;
+}
+
+void SdrGluePoint::SetAlignAngle(long nWink)
+{
+ nWink=NormAngle360(nWink);
+ if (nWink>=33750 || nWink<2250) nAlign=SDRHORZALIGN_RIGHT |SDRVERTALIGN_CENTER;
+ else if (nWink< 6750) nAlign=SDRHORZALIGN_RIGHT |SDRVERTALIGN_TOP ;
+ else if (nWink<11250) nAlign=SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP ;
+ else if (nWink<15750) nAlign=SDRHORZALIGN_LEFT |SDRVERTALIGN_TOP ;
+ else if (nWink<20250) nAlign=SDRHORZALIGN_LEFT |SDRVERTALIGN_CENTER;
+ else if (nWink<24750) nAlign=SDRHORZALIGN_LEFT |SDRVERTALIGN_BOTTOM;
+ else if (nWink<29250) nAlign=SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM;
+ else if (nWink<33750) nAlign=SDRHORZALIGN_RIGHT |SDRVERTALIGN_BOTTOM;
+}
+
+long SdrGluePoint::EscDirToAngle(USHORT nEsc) const
+{
+ switch (nEsc) {
+ case SDRESC_RIGHT : return 0;
+ case SDRESC_TOP : return 9000;
+ case SDRESC_LEFT : return 18000;
+ case SDRESC_BOTTOM: return 27000;
+ } // switch
+ return 0;
+}
+
+USHORT SdrGluePoint::EscAngleToDir(long nWink) const
+{
+ nWink=NormAngle360(nWink);
+ if (nWink>=31500 || nWink<4500) return SDRESC_RIGHT;
+ if (nWink<13500) return SDRESC_TOP;
+ if (nWink<22500) return SDRESC_LEFT;
+ if (nWink<31500) return SDRESC_BOTTOM;
+ return 0;
+}
+
+void SdrGluePoint::Rotate(const Point& rRef, long nWink, double sn, double cs, const SdrObject* pObj)
+{
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ RotatePoint(aPt,rRef,sn,cs);
+ // Bezugskante drehen
+ if(nAlign != (SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER))
+ {
+ SetAlignAngle(GetAlignAngle()+nWink);
+ }
+ // Austrittsrichtungen drehen
+ USHORT nEscDir0=nEscDir;
+ USHORT nEscDir1=0;
+ if ((nEscDir0&SDRESC_LEFT )!=0) nEscDir1|=EscAngleToDir(EscDirToAngle(SDRESC_LEFT )+nWink);
+ if ((nEscDir0&SDRESC_TOP )!=0) nEscDir1|=EscAngleToDir(EscDirToAngle(SDRESC_TOP )+nWink);
+ if ((nEscDir0&SDRESC_RIGHT )!=0) nEscDir1|=EscAngleToDir(EscDirToAngle(SDRESC_RIGHT )+nWink);
+ if ((nEscDir0&SDRESC_BOTTOM)!=0) nEscDir1|=EscAngleToDir(EscDirToAngle(SDRESC_BOTTOM)+nWink);
+ nEscDir=nEscDir1;
+ if (pObj!=NULL) SetAbsolutePos(aPt,*pObj); else SetPos(aPt);
+}
+
+void SdrGluePoint::Mirror(const Point& rRef1, const Point& rRef2, const SdrObject* pObj)
+{
+ Point aPt(rRef2); aPt-=rRef1;
+ long nWink=GetAngle(aPt);
+ Mirror(rRef1,rRef2,nWink,pObj);
+}
+
+void SdrGluePoint::Mirror(const Point& rRef1, const Point& rRef2, long nWink, const SdrObject* pObj)
+{
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ MirrorPoint(aPt,rRef1,rRef2);
+ // Bezugskante spiegeln
+ if(nAlign != (SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER))
+ {
+ long nAW=GetAlignAngle();
+ nAW+=2*(nWink-nAW);
+ SetAlignAngle(nAW);
+ }
+ // Austrittsrichtungen spiegeln
+ USHORT nEscDir0=nEscDir;
+ USHORT nEscDir1=0;
+ if ((nEscDir0&SDRESC_LEFT)!=0) {
+ long nEW=EscDirToAngle(SDRESC_LEFT);
+ nEW+=2*(nWink-nEW);
+ nEscDir1|=EscAngleToDir(nEW);
+ }
+ if ((nEscDir0&SDRESC_TOP)!=0) {
+ long nEW=EscDirToAngle(SDRESC_TOP);
+ nEW+=2*(nWink-nEW);
+ nEscDir1|=EscAngleToDir(nEW);
+ }
+ if ((nEscDir0&SDRESC_RIGHT)!=0) {
+ long nEW=EscDirToAngle(SDRESC_RIGHT);
+ nEW+=2*(nWink-nEW);
+ nEscDir1|=EscAngleToDir(nEW);
+ }
+ if ((nEscDir0&SDRESC_BOTTOM)!=0) {
+ long nEW=EscDirToAngle(SDRESC_BOTTOM);
+ nEW+=2*(nWink-nEW);
+ nEscDir1|=EscAngleToDir(nEW);
+ }
+ nEscDir=nEscDir1;
+ if (pObj!=NULL) SetAbsolutePos(aPt,*pObj); else SetPos(aPt);
+}
+
+void SdrGluePoint::Shear(const Point& rRef, long /*nWink*/, double tn, FASTBOOL bVShear, const SdrObject* pObj)
+{
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ ShearPoint(aPt,rRef,tn,bVShear);
+ if (pObj!=NULL) SetAbsolutePos(aPt,*pObj); else SetPos(aPt);
+}
+
+void SdrGluePoint::Draw(OutputDevice& rOut, const SdrObject* pObj) const
+{
+ Color aBackPenColor(COL_WHITE);
+ Color aForePenColor(COL_LIGHTBLUE);
+
+ bool bMapMerk=rOut.IsMapModeEnabled();
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ aPt=rOut.LogicToPixel(aPt);
+ rOut.EnableMapMode(FALSE);
+ long x=aPt.X(),y=aPt.Y(); // Groesse erstmal fest auf 7 Pixel
+
+ rOut.SetLineColor( aBackPenColor );
+ rOut.DrawLine(Point(x-2,y-3),Point(x+3,y+2));
+ rOut.DrawLine(Point(x-3,y-2),Point(x+2,y+3));
+ rOut.DrawLine(Point(x-3,y+2),Point(x+2,y-3));
+ rOut.DrawLine(Point(x-2,y+3),Point(x+3,y-2));
+
+ if (bNoPercent)
+ {
+ switch (GetHorzAlign())
+ {
+ case SDRHORZALIGN_LEFT : rOut.DrawLine(Point(x-3,y-1),Point(x-3,y+1)); break;
+ case SDRHORZALIGN_RIGHT : rOut.DrawLine(Point(x+3,y-1),Point(x+3,y+1)); break;
+ }
+
+ switch (GetVertAlign())
+ {
+ case SDRVERTALIGN_TOP : rOut.DrawLine(Point(x-1,y-3),Point(x+1,y-3)); break;
+ case SDRVERTALIGN_BOTTOM: rOut.DrawLine(Point(x-1,y+3),Point(x+1,y+3)); break;
+ }
+ }
+
+ rOut.SetLineColor( aForePenColor );
+ rOut.DrawLine(Point(x-2,y-2),Point(x+2,y+2));
+ rOut.DrawLine(Point(x-2,y+2),Point(x+2,y-2));
+ rOut.EnableMapMode(bMapMerk);
+}
+
+void SdrGluePoint::Invalidate(Window& rWin, const SdrObject* pObj) const
+{
+ bool bMapMerk=rWin.IsMapModeEnabled();
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ aPt=rWin.LogicToPixel(aPt);
+ rWin.EnableMapMode(FALSE);
+ long x=aPt.X(),y=aPt.Y(); // Groesse erstmal fest auf 7 Pixel
+
+ // #111096#
+ // do not erase background, that causes flicker (!)
+ rWin.Invalidate(Rectangle(Point(x-3,y-3),Point(x+3,y+3)), INVALIDATE_NOERASE);
+
+ rWin.EnableMapMode(bMapMerk);
+}
+
+FASTBOOL SdrGluePoint::IsHit(const Point& rPnt, const OutputDevice& rOut, const SdrObject* pObj) const
+{
+ Point aPt(pObj!=NULL ? GetAbsolutePos(*pObj) : GetPos());
+ Size aSiz=rOut.PixelToLogic(Size(3,3));
+ Rectangle aRect(aPt.X()-aSiz.Width(),aPt.Y()-aSiz.Height(),aPt.X()+aSiz.Width(),aPt.Y()+aSiz.Height());
+ return aRect.IsInside(rPnt);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrGluePointList::Clear()
+{
+ USHORT nAnz=GetCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ delete GetObject(i);
+ }
+ aList.Clear();
+}
+
+void SdrGluePointList::operator=(const SdrGluePointList& rSrcList)
+{
+ if (GetCount()!=0) Clear();
+ USHORT nAnz=rSrcList.GetCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ Insert(rSrcList[i]);
+ }
+}
+
+// Die Id's der Klebepunkte in der Liste sind stets streng monoton steigend!
+// Ggf. wird dem neuen Klebepunkt eine neue Id zugewiesen (wenn diese bereits
+// vergeben ist). Die Id 0 ist reserviert.
+USHORT SdrGluePointList::Insert(const SdrGluePoint& rGP)
+{
+ SdrGluePoint* pGP=new SdrGluePoint(rGP);
+ USHORT nId=pGP->GetId();
+ USHORT nAnz=GetCount();
+ USHORT nInsPos=nAnz;
+ USHORT nLastId=nAnz!=0 ? GetObject(nAnz-1)->GetId() : 0;
+ DBG_ASSERT(nLastId>=nAnz,"SdrGluePointList::Insert(): nLastId<nAnz");
+ FASTBOOL bHole=nLastId>nAnz;
+ if (nId<=nLastId) {
+ if (!bHole || nId==0) {
+ nId=nLastId+1;
+ } else {
+ FASTBOOL bBrk=FALSE;
+ for (USHORT nNum=0; nNum<nAnz && !bBrk; nNum++) {
+ const SdrGluePoint* pGP2=GetObject(nNum);
+ USHORT nTmpId=pGP2->GetId();
+ if (nTmpId==nId) {
+ nId=nLastId+1; // bereits vorhanden
+ bBrk=TRUE;
+ }
+ if (nTmpId>nId) {
+ nInsPos=nNum; // Hier einfuegen (einsortieren)
+ bBrk=TRUE;
+ }
+ }
+ }
+ pGP->SetId(nId);
+ }
+ aList.Insert(pGP,nInsPos);
+ return nInsPos;
+}
+
+void SdrGluePointList::Invalidate(Window& rWin, const SdrObject* pObj) const
+{
+ USHORT nAnz=GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ GetObject(nNum)->Invalidate(rWin,pObj);
+ }
+}
+
+USHORT SdrGluePointList::FindGluePoint(USHORT nId) const
+{
+ // Hier noch einen optimaleren Suchalgorithmus implementieren.
+ // Die Liste sollte stets sortiert sein!!!!
+ USHORT nAnz=GetCount();
+ USHORT nRet=SDRGLUEPOINT_NOTFOUND;
+ for (USHORT nNum=0; nNum<nAnz && nRet==SDRGLUEPOINT_NOTFOUND; nNum++) {
+ const SdrGluePoint* pGP=GetObject(nNum);
+ if (pGP->GetId()==nId) nRet=nNum;
+ }
+ return nRet;
+}
+
+USHORT SdrGluePointList::HitTest(const Point& rPnt, const OutputDevice& rOut, const SdrObject* pObj, FASTBOOL bBack, FASTBOOL bNext, USHORT nId0) const
+{
+ USHORT nAnz=GetCount();
+ USHORT nRet=SDRGLUEPOINT_NOTFOUND;
+ USHORT nNum=bBack ? 0 : nAnz;
+ while ((bBack ? nNum<nAnz : nNum>0) && nRet==SDRGLUEPOINT_NOTFOUND) {
+ if (!bBack) nNum--;
+ const SdrGluePoint* pGP=GetObject(nNum);
+ if (bNext) {
+ if (pGP->GetId()==nId0) bNext=FALSE;
+ } else {
+ if (pGP->IsHit(rPnt,rOut,pObj)) nRet=nNum;
+ }
+ if (bBack) nNum++;
+ }
+ return nRet;
+}
+
+void SdrGluePointList::SetReallyAbsolute(FASTBOOL bOn, const SdrObject& rObj)
+{
+ USHORT nAnz=GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ GetObject(nNum)->SetReallyAbsolute(bOn,rObj);
+ }
+}
+
+void SdrGluePointList::Rotate(const Point& rRef, long nWink, double sn, double cs, const SdrObject* pObj)
+{
+ USHORT nAnz=GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ GetObject(nNum)->Rotate(rRef,nWink,sn,cs,pObj);
+ }
+}
+
+void SdrGluePointList::Mirror(const Point& rRef1, const Point& rRef2, const SdrObject* pObj)
+{
+ Point aPt(rRef2); aPt-=rRef1;
+ long nWink=GetAngle(aPt);
+ Mirror(rRef1,rRef2,nWink,pObj);
+}
+
+void SdrGluePointList::Mirror(const Point& rRef1, const Point& rRef2, long nWink, const SdrObject* pObj)
+{
+ USHORT nAnz=GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ GetObject(nNum)->Mirror(rRef1,rRef2,nWink,pObj);
+ }
+}
+
+void SdrGluePointList::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear, const SdrObject* pObj)
+{
+ USHORT nAnz=GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ GetObject(nNum)->Shear(rRef,nWink,tn,bVShear,pObj);
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
new file mode 100644
index 000000000000..47a04241e5bb
--- /dev/null
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -0,0 +1,2417 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <algorithm>
+
+#include <svx/svdhdl.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdmrkv.hxx>
+#include <vcl/window.hxx>
+
+#include <vcl/virdev.hxx>
+#include <tools/poly.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <svx/sxekitm.hxx>
+#include "svdstr.hrc"
+#include "svdglob.hxx"
+
+#include <svx/svdmodel.hxx>
+#include "gradtrns.hxx"
+#include <svx/xflgrit.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/xflftrit.hxx>
+
+// #105678#
+#include <svx/svdopath.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
+#include <svx/sdr/overlay/overlaybitmapex.hxx>
+#include <svx/sdr/overlay/overlayline.hxx>
+#include <svx/sdr/overlay/overlaytriangle.hxx>
+#include <svx/sdr/overlay/overlayhatchrect.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <sdrpaintwindow.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/sdr/overlay/overlaypolypolygon.hxx>
+#include <vcl/lazydelete.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i15222#
+// Due to the ressource problems in Win95/98 with bitmap ressources i
+// will change this handle bitmap provinging class. Old version was splitting
+// and preparing all small handle bitmaps in device bitmap format, now this will
+// be done on the fly. Thus, tehre is only the one big bitmap remembered. With
+// three source bitmaps, this will be 3 system bitmap ressources instead of hundreds.
+// The price for that needs to be evaluated. Maybe we will need another change here
+// if this is too expensive.
+class SdrHdlBitmapSet
+{
+ // the bitmap holding all infos
+ BitmapEx maMarkersBitmap;
+
+ // the cropped Bitmaps for reusage
+ ::std::vector< BitmapEx > maRealMarkers;
+
+ // elpers
+ BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle);
+
+public:
+ SdrHdlBitmapSet(UINT16 nResId);
+ ~SdrHdlBitmapSet();
+
+ const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, UINT16 nInd=0);
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#define KIND_COUNT (14)
+#define INDEX_COUNT (6)
+#define INDIVIDUAL_COUNT (4)
+
+SdrHdlBitmapSet::SdrHdlBitmapSet(UINT16 nResId)
+: maMarkersBitmap(),
+ // 14 kinds (BitmapMarkerKind) use index [0..5], 4 extra
+ maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
+{
+ // #101928# change color used for transparent parts to 0x00ff00ff (ImageList standard)
+ const Color aColTransparent(0x00ff00ff);
+ const Bitmap aBitmap(ResId(nResId, *ImpGetResMgr()));
+ const Bitmap aMask(aBitmap.CreateMask(aColTransparent));
+
+ // create a real BitmapEx with an AlphaMask
+ maMarkersBitmap = BitmapEx(aBitmap, aMask);
+ // maMarkersBitmap = BitmapEx(aBitmap, aColTransparent);
+}
+
+SdrHdlBitmapSet::~SdrHdlBitmapSet()
+{
+}
+
+BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle)
+{
+ BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
+
+ if(rTargetBitmap.IsEmpty())
+ {
+ rTargetBitmap = maMarkersBitmap;
+ rTargetBitmap.Crop(rRectangle);
+ }
+
+ return rTargetBitmap;
+}
+
+// change getting of bitmap to use the big ressource bitmap
+const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, UINT16 nInd)
+{
+ // fill in size and source position in maMarkersBitmap
+ const sal_uInt16 nYPos(nInd * 11);
+
+ switch(eKindOfMarker)
+ {
+ default:
+ {
+ DBG_ERROR( "unknown kind of marker" );
+ // no break here, return Rect_7x7 as default
+ }
+ case Rect_7x7:
+ {
+ return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, Rectangle(Point(0, nYPos), Size(7, 7)));
+ }
+
+ case Rect_9x9:
+ {
+ return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, Rectangle(Point(7, nYPos), Size(9, 9)));
+ }
+
+ case Rect_11x11:
+ {
+ return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, Rectangle(Point(16, nYPos), Size(11, 11)));
+ }
+
+ case Rect_13x13:
+ {
+ const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
+
+ switch(nInd)
+ {
+ case 0:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 66), Size(13, 13)));
+ }
+ case 1:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 66), Size(13, 13)));
+ }
+ case 2:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 78), Size(13, 13)));
+ }
+ case 3:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 78), Size(13, 13)));
+ }
+ case 4:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 78), Size(13, 13)));
+ }
+ default: // case 5:
+ {
+ return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 66), Size(13, 13)));
+ }
+ }
+ }
+
+ case Circ_7x7:
+ {
+ return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, Rectangle(Point(27, nYPos), Size(7, 7)));
+ }
+
+ case Circ_9x9:
+ case Customshape1:
+ {
+ return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, Rectangle(Point(34, nYPos), Size(9, 9)));
+ }
+
+ case Circ_11x11:
+ {
+ return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, Rectangle(Point(43, nYPos), Size(11, 11)));
+ }
+
+ case Elli_7x9:
+ {
+ return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, Rectangle(Point(54, nYPos), Size(7, 9)));
+ }
+
+ case Elli_9x11:
+ {
+ return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, Rectangle(Point(61, nYPos), Size(9, 11)));
+ }
+
+ case Elli_9x7:
+ {
+ return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, Rectangle(Point(70, nYPos), Size(9, 7)));
+ }
+
+ case Elli_11x9:
+ {
+ return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, Rectangle(Point(79, nYPos), Size(11, 9)));
+ }
+
+ case RectPlus_7x7:
+ {
+ return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, Rectangle(Point(90, nYPos), Size(7, 7)));
+ }
+
+ case RectPlus_9x9:
+ {
+ return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, Rectangle(Point(97, nYPos), Size(9, 9)));
+ }
+
+ case RectPlus_11x11:
+ {
+ return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, Rectangle(Point(106, nYPos), Size(11, 11)));
+ }
+
+ case Crosshair:
+ {
+ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, Rectangle(Point(0, 68), Size(15, 15)));
+ }
+
+ case Glue:
+ {
+ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, Rectangle(Point(15, 74), Size(9, 9)));
+ }
+
+ case Anchor: // #101688# AnchorTR for SW
+ case AnchorTR:
+ {
+ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, Rectangle(Point(24, 68), Size(24, 23)));
+ }
+
+ // #98388# add AnchorPressed to be able to aninate anchor control
+ case AnchorPressed:
+ case AnchorPressedTR:
+ {
+ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, Rectangle(Point(48, 68), Size(24, 23)));
+ }
+ }
+
+ // cannot happen since all pathes return something; return Rect_7x7 as default (see switch)
+ return maRealMarkers[0];
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrHdlBitmapSet& getSimpleSet()
+{
+ static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aSimpleSet(new SdrHdlBitmapSet(SIP_SA_MARKERS));
+ return *aSimpleSet.get();
+}
+
+SdrHdlBitmapSet& getModernSet()
+{
+ static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aModernSet(new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS));
+ return *aModernSet.get();
+}
+
+SdrHdlBitmapSet& getHighContrastSet()
+{
+ static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aHighContrastSet(new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS));
+ return *aHighContrastSet.get();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrHdl::SdrHdl():
+ pObj(NULL),
+ pPV(NULL),
+ pHdlList(NULL),
+ eKind(HDL_MOVE),
+ nDrehWink(0),
+ nObjHdlNum(0),
+ nPolyNum(0),
+ nPPntNum(0),
+ nSourceHdlNum(0),
+ bSelect(FALSE),
+ b1PixMore(FALSE),
+ bPlusHdl(FALSE),
+ mbMoveOutside(false),
+ mbMouseOver(false)
+{
+}
+
+SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
+ pObj(NULL),
+ pPV(NULL),
+ pHdlList(NULL),
+ aPos(rPnt),
+ eKind(eNewKind),
+ nDrehWink(0),
+ nObjHdlNum(0),
+ nPolyNum(0),
+ nPPntNum(0),
+ nSourceHdlNum(0),
+ bSelect(FALSE),
+ b1PixMore(FALSE),
+ bPlusHdl(FALSE),
+ mbMoveOutside(false),
+ mbMouseOver(false)
+{
+}
+
+SdrHdl::~SdrHdl()
+{
+ GetRidOfIAObject();
+}
+
+void SdrHdl::Set1PixMore(BOOL bJa)
+{
+ if(b1PixMore != bJa)
+ {
+ b1PixMore = bJa;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdl::SetMoveOutside( bool bMoveOutside )
+{
+ if(mbMoveOutside != bMoveOutside)
+ {
+ mbMoveOutside = bMoveOutside;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdl::SetDrehWink(long n)
+{
+ if(nDrehWink != n)
+ {
+ nDrehWink = n;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdl::SetPos(const Point& rPnt)
+{
+ if(aPos != rPnt)
+ {
+ // remember new position
+ aPos = rPnt;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdl::SetSelected(BOOL bJa)
+{
+ if(bSelect != bJa)
+ {
+ // remember new value
+ bSelect = bJa;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdl::SetHdlList(SdrHdlList* pList)
+{
+ if(pHdlList != pList)
+ {
+ // rememver list
+ pHdlList = pList;
+
+ // now its possible to create graphic representation
+ Touch();
+ }
+}
+
+void SdrHdl::SetObj(SdrObject* pNewObj)
+{
+ if(pObj != pNewObj)
+ {
+ // remember new object
+ pObj = pNewObj;
+
+ // graphic representation may have changed
+ Touch();
+ }
+}
+
+void SdrHdl::Touch()
+{
+ // force update of graphic representation
+ CreateB2dIAObject();
+}
+
+void SdrHdl::GetRidOfIAObject()
+{
+ //OLMaIAOGroup.Delete();
+
+ // OVERLAYMANAGER
+ maOverlayGroup.clear();
+}
+
+void SdrHdl::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
+ {
+ BitmapColorIndex eColIndex = LightGreen;
+ BitmapMarkerKind eKindOfMarker = Rect_7x7;
+
+ BOOL bRot = pHdlList->IsRotateShear();
+ if(pObj)
+ eColIndex = (bSelect) ? Cyan : LightCyan;
+ if(bRot)
+ {
+ // Drehhandles in Rot
+ if(pObj && bSelect)
+ eColIndex = Red;
+ else
+ eColIndex = LightRed;
+ }
+
+ switch(eKind)
+ {
+ case HDL_MOVE:
+ {
+ eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
+ break;
+ }
+ case HDL_UPLFT:
+ case HDL_UPRGT:
+ case HDL_LWLFT:
+ case HDL_LWRGT:
+ {
+ // corner handles
+ if(bRot)
+ {
+ eKindOfMarker = Circ_7x7;
+ }
+ else
+ {
+ eKindOfMarker = Rect_7x7;
+ }
+ break;
+ }
+ case HDL_UPPER:
+ case HDL_LOWER:
+ {
+ // Upper/Lower handles
+ if(bRot)
+ {
+ eKindOfMarker = Elli_9x7;
+ }
+ else
+ {
+ eKindOfMarker = Rect_7x7;
+ }
+ break;
+ }
+ case HDL_LEFT:
+ case HDL_RIGHT:
+ {
+ // Left/Right handles
+ if(bRot)
+ {
+ eKindOfMarker = Elli_7x9;
+ }
+ else
+ {
+ eKindOfMarker = Rect_7x7;
+ }
+ break;
+ }
+ case HDL_POLY:
+ {
+ if(bRot)
+ {
+ eKindOfMarker = (b1PixMore) ? Circ_9x9 : Circ_7x7;
+ }
+ else
+ {
+ eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
+ }
+ break;
+ }
+ case HDL_BWGT: // weight at poly
+ {
+ eKindOfMarker = Circ_7x7;
+ break;
+ }
+ case HDL_CIRC:
+ {
+ eKindOfMarker = Rect_11x11;
+ break;
+ }
+ case HDL_REF1:
+ case HDL_REF2:
+ {
+ eKindOfMarker = Crosshair;
+ break;
+ }
+ case HDL_GLUE:
+ {
+ eKindOfMarker = Glue;
+ break;
+ }
+ case HDL_ANCHOR:
+ {
+ eKindOfMarker = Anchor;
+ break;
+ }
+ case HDL_USER:
+ {
+ break;
+ }
+ // #101688# top right anchor for SW
+ case HDL_ANCHOR_TR:
+ {
+ eKindOfMarker = AnchorTR;
+ break;
+ }
+
+ // for SJ and the CustomShapeHandles:
+ case HDL_CUSTOMSHAPE1:
+ {
+ eKindOfMarker = Customshape1;
+ eColIndex = Yellow;
+ break;
+ }
+ default:
+ break;
+ }
+
+ SdrMarkView* pView = pHdlList->GetView();
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ Point aMoveOutsideOffset(0, 0);
+
+ // add offset if necessary
+ if(pHdlList->IsMoveOutside() || mbMoveOutside)
+ {
+ OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
+ Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
+
+ if(eKind == HDL_UPLFT || eKind == HDL_UPPER || eKind == HDL_UPRGT)
+ aMoveOutsideOffset.Y() -= aOffset.Width();
+ if(eKind == HDL_LWLFT || eKind == HDL_LOWER || eKind == HDL_LWRGT)
+ aMoveOutsideOffset.Y() += aOffset.Height();
+ if(eKind == HDL_UPLFT || eKind == HDL_LEFT || eKind == HDL_LWLFT)
+ aMoveOutsideOffset.X() -= aOffset.Width();
+ if(eKind == HDL_UPRGT || eKind == HDL_RIGHT || eKind == HDL_LWRGT)
+ aMoveOutsideOffset.X() += aOffset.Height();
+ }
+
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
+ aPosition,
+ eColIndex,
+ eKindOfMarker,
+ aMoveOutsideOffset);
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+BitmapMarkerKind SdrHdl::GetNextBigger(BitmapMarkerKind eKnd) const
+{
+ BitmapMarkerKind eRetval(eKnd);
+
+ switch(eKnd)
+ {
+ case Rect_7x7: eRetval = Rect_9x9; break;
+ case Rect_9x9: eRetval = Rect_11x11; break;
+ case Rect_11x11: eRetval = Rect_13x13; break;
+ //case Rect_13x13: eRetval = ; break;
+
+ case Circ_7x7: eRetval = Circ_9x9; break;
+ case Circ_9x9: eRetval = Circ_11x11; break;
+ //case Circ_11x11: eRetval = ; break;
+
+ case Elli_7x9: eRetval = Elli_9x11; break;
+ //case Elli_9x11: eRetval = ; break;
+
+ case Elli_9x7: eRetval = Elli_11x9; break;
+ //case Elli_11x9: eRetval = ; break;
+
+ case RectPlus_7x7: eRetval = RectPlus_9x9; break;
+ case RectPlus_9x9: eRetval = RectPlus_11x11; break;
+ //case RectPlus_11x11: eRetval = ; break;
+
+ //case Crosshair: eRetval = ; break;
+ //case Glue: eRetval = ; break;
+
+ // #98388# let anchor blink with it's pressed state
+ case Anchor: eRetval = AnchorPressed; break;
+
+ // #101688# same for AnchorTR
+ case AnchorTR: eRetval = AnchorPressedTR; break;
+ default:
+ break;
+ }
+
+ return eRetval;
+}
+
+// #101928#
+BitmapEx SdrHdl::ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd, sal_Bool bFine, sal_Bool bIsHighContrast)
+{
+ if(bIsHighContrast)
+ {
+ return getHighContrastSet().GetBitmapEx(eKindOfMarker, nInd);
+ }
+ else
+ {
+ if(bFine)
+ {
+ return getModernSet().GetBitmapEx(eKindOfMarker, nInd);
+ }
+ else
+ {
+ return getSimpleSet().GetBitmapEx(eKindOfMarker, nInd);
+ }
+ }
+}
+
+::sdr::overlay::OverlayObject* SdrHdl::CreateOverlayObject(
+ const basegfx::B2DPoint& rPos,
+ BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset)
+{
+ ::sdr::overlay::OverlayObject* pRetval = 0L;
+ sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
+
+ // support bigger sizes
+ sal_Bool bForceBiggerSize(sal_False);
+
+ if(pHdlList->GetHdlSize() > 3)
+ {
+ bForceBiggerSize = sal_True;
+ }
+
+ // #101928# ...for high contrast, too.
+ if(!bForceBiggerSize && bIsHighContrast)
+ {
+ // #107925#
+ // ...but not for anchors, else they will not blink when activated
+ if(Anchor != eKindOfMarker && AnchorTR != eKindOfMarker)
+ {
+ bForceBiggerSize = sal_True;
+ }
+ }
+
+ if(bForceBiggerSize)
+ {
+ eKindOfMarker = GetNextBigger(eKindOfMarker);
+ }
+
+ // #97016# II This handle has the focus, visualize it
+ if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this)
+ {
+ // create animated handle
+ BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
+
+ if(eNextBigger == eKindOfMarker)
+ {
+ // this may happen for the not supported getting-bigger types.
+ // Choose an alternative here
+ switch(eKindOfMarker)
+ {
+ case Rect_13x13: eNextBigger = Rect_11x11; break;
+ case Circ_11x11: eNextBigger = Elli_11x9; break;
+ case Elli_9x11: eNextBigger = Elli_11x9; break;
+ case Elli_11x9: eNextBigger = Elli_9x11; break;
+ case RectPlus_11x11: eNextBigger = Rect_13x13; break;
+
+ case Crosshair:
+ eNextBigger = Glue;
+ break;
+
+ case Glue:
+ eNextBigger = Crosshair;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // create animated hdl
+ // #101928# use ImpGetBitmapEx(...) now
+ BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
+ BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
+
+ // #i53216# Use system cursor blink time. Use the unsigned value.
+ const sal_uInt32 nBlinkTime((sal_uInt32)Application::GetSettings().GetStyleSettings().GetCursorBlinkTime());
+
+ if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
+ {
+ // #98388# when anchor is used take upper left as reference point inside the handle
+ pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime);
+ }
+ else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
+ {
+ // #101688# AnchorTR for SW, take top right as (0,0)
+ pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
+ (UINT16)(aBmpEx1.GetSizePixel().Width() - 1), 0,
+ (UINT16)(aBmpEx2.GetSizePixel().Width() - 1), 0);
+ }
+ else
+ {
+ // create centered handle as default
+ pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
+ (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
+ (UINT16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
+ }
+ }
+ else
+ {
+ // create normal handle
+ // #101928# use ImpGetBitmapEx(...) now
+ BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
+
+ if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
+ {
+ // #98388# upper left as reference point inside the handle for AnchorPressed, too
+ pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx);
+ }
+ else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
+ {
+ // #101688# AnchorTR for SW, take top right as (0,0)
+ pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx,
+ (UINT16)(aBmpEx.GetSizePixel().Width() - 1), 0);
+ }
+ else
+ {
+ sal_uInt16 nCenX((sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1L) >> 1);
+ sal_uInt16 nCenY((sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1L) >> 1);
+
+ if(aMoveOutsideOffset.X() > 0)
+ {
+ nCenX = 0;
+ }
+ else if(aMoveOutsideOffset.X() < 0)
+ {
+ nCenX = (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1);
+ }
+
+ if(aMoveOutsideOffset.Y() > 0)
+ {
+ nCenY = 0;
+ }
+ else if(aMoveOutsideOffset.Y() < 0)
+ {
+ nCenY = (sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1);
+ }
+
+ // create centered handle as default
+ pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY);
+ }
+ }
+
+ return pRetval;
+}
+
+bool SdrHdl::IsHdlHit(const Point& rPnt) const
+{
+ // OVERLAYMANAGER
+ basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y());
+ return maOverlayGroup.isHitLogic(aPosition);
+}
+
+Pointer SdrHdl::GetPointer() const
+{
+ PointerStyle ePtr=POINTER_MOVE;
+ const BOOL bSize=eKind>=HDL_UPLFT && eKind<=HDL_LWRGT;
+ const BOOL bRot=pHdlList!=NULL && pHdlList->IsRotateShear();
+ const BOOL bDis=pHdlList!=NULL && pHdlList->IsDistortShear();
+ if (bSize && pHdlList!=NULL && (bRot || bDis)) {
+ switch (eKind) {
+ case HDL_UPLFT: case HDL_UPRGT:
+ case HDL_LWLFT: case HDL_LWRGT: ePtr=bRot ? POINTER_ROTATE : POINTER_REFHAND; break;
+ case HDL_LEFT : case HDL_RIGHT: ePtr=POINTER_VSHEAR; break;
+ case HDL_UPPER: case HDL_LOWER: ePtr=POINTER_HSHEAR; break;
+ default:
+ break;
+ }
+ } else {
+ // Fuer Resize von gedrehten Rechtecken die Mauszeiger etwas mitdrehen
+ if (bSize && nDrehWink!=0) {
+ long nHdlWink=0;
+ switch (eKind) {
+ case HDL_LWRGT: nHdlWink=31500; break;
+ case HDL_LOWER: nHdlWink=27000; break;
+ case HDL_LWLFT: nHdlWink=22500; break;
+ case HDL_LEFT : nHdlWink=18000; break;
+ case HDL_UPLFT: nHdlWink=13500; break;
+ case HDL_UPPER: nHdlWink=9000; break;
+ case HDL_UPRGT: nHdlWink=4500; break;
+ case HDL_RIGHT: nHdlWink=0; break;
+ default:
+ break;
+ }
+ nHdlWink+=nDrehWink+2249; // und etwas drauf (zum runden)
+ while (nHdlWink<0) nHdlWink+=36000;
+ while (nHdlWink>=36000) nHdlWink-=36000;
+ nHdlWink/=4500;
+ switch ((BYTE)nHdlWink) {
+ case 0: ePtr=POINTER_ESIZE; break;
+ case 1: ePtr=POINTER_NESIZE; break;
+ case 2: ePtr=POINTER_NSIZE; break;
+ case 3: ePtr=POINTER_NWSIZE; break;
+ case 4: ePtr=POINTER_WSIZE; break;
+ case 5: ePtr=POINTER_SWSIZE; break;
+ case 6: ePtr=POINTER_SSIZE; break;
+ case 7: ePtr=POINTER_SESIZE; break;
+ } // switch
+ } else {
+ switch (eKind) {
+ case HDL_UPLFT: ePtr=POINTER_NWSIZE; break;
+ case HDL_UPPER: ePtr=POINTER_NSIZE; break;
+ case HDL_UPRGT: ePtr=POINTER_NESIZE; break;
+ case HDL_LEFT : ePtr=POINTER_WSIZE; break;
+ case HDL_RIGHT: ePtr=POINTER_ESIZE; break;
+ case HDL_LWLFT: ePtr=POINTER_SWSIZE; break;
+ case HDL_LOWER: ePtr=POINTER_SSIZE; break;
+ case HDL_LWRGT: ePtr=POINTER_SESIZE; break;
+ case HDL_POLY : ePtr=POINTER_MOVEPOINT; break;
+ case HDL_CIRC : ePtr=POINTER_HAND; break;
+ case HDL_REF1 : ePtr=POINTER_REFHAND; break;
+ case HDL_REF2 : ePtr=POINTER_REFHAND; break;
+ case HDL_BWGT : ePtr=POINTER_MOVEBEZIERWEIGHT; break;
+ case HDL_GLUE : ePtr=POINTER_MOVEPOINT; break;
+ case HDL_CUSTOMSHAPE1 : ePtr=POINTER_HAND; break;
+ default:
+ break;
+ }
+ }
+ }
+ return Pointer(ePtr);
+}
+
+// #97016# II
+BOOL SdrHdl::IsFocusHdl() const
+{
+ switch(eKind)
+ {
+ case HDL_UPLFT: // Oben links
+ case HDL_UPPER: // Oben
+ case HDL_UPRGT: // Oben rechts
+ case HDL_LEFT: // Links
+ case HDL_RIGHT: // Rechts
+ case HDL_LWLFT: // Unten links
+ case HDL_LOWER: // Unten
+ case HDL_LWRGT: // Unten rechts
+ {
+ // if it's a activated TextEdit, it's moved to extended points
+ if(pHdlList && pHdlList->IsMoveOutside())
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ case HDL_MOVE: // Handle zum Verschieben des Objekts
+ case HDL_POLY: // Punktselektion an Polygon oder Bezierkurve
+ case HDL_BWGT: // Gewicht an einer Bezierkurve
+ case HDL_CIRC: // Winkel an Kreissegmenten, Eckenradius am Rect
+ case HDL_REF1: // Referenzpunkt 1, z.B. Rotationsmitte
+ case HDL_REF2: // Referenzpunkt 2, z.B. Endpunkt der Spiegelachse
+ //case HDL_MIRX: // Die Spiegelachse selbst
+ case HDL_GLUE: // GluePoint
+
+ // #98388# do NOT activate here, let SW implement their own SdrHdl and
+ // overload IsFocusHdl() there to make the anchor accessible
+ //case HDL_ANCHOR: // anchor symbol (SD, SW)
+ // #101688# same for AnchorTR
+ //case HDL_ANCHOR_TR: // anchor symbol (SD, SW)
+
+ //case HDL_TRNS: // interactive transparence
+ //case HDL_GRAD: // interactive gradient
+ //case HDL_COLR: // interactive color
+
+ // for SJ and the CustomShapeHandles:
+ case HDL_CUSTOMSHAPE1:
+
+ case HDL_USER:
+ {
+ return TRUE;
+ }
+
+ default:
+ {
+ return FALSE;
+ }
+ }
+}
+
+void SdrHdl::onMouseEnter(const MouseEvent& /*rMEvt*/)
+{
+}
+
+void SdrHdl::onMouseLeave()
+{
+}
+
+bool SdrHdl::isMouseOver() const
+{
+ return mbMouseOver;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// class SdrHdlColor
+
+SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, BOOL bLum)
+: SdrHdl(rRef, HDL_COLR),
+ aMarkerSize(rSize),
+ bUseLuminance(bLum)
+{
+ if(IsUseLuminance())
+ aCol = GetLuminance(aCol);
+
+ // remember color
+ aMarkerColor = aCol;
+}
+
+SdrHdlColor::~SdrHdlColor()
+{
+}
+
+void SdrHdlColor::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ Bitmap aBmpCol(CreateColorDropper(aMarkerColor));
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = new
+ ::sdr::overlay::OverlayBitmapEx(
+ aPosition,
+ BitmapEx(aBmpCol),
+ (UINT16)(aBmpCol.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpCol.GetSizePixel().Height() - 1) >> 1
+ );
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+Bitmap SdrHdlColor::CreateColorDropper(Color aCol)
+{
+ // get the Bitmap
+ Bitmap aRetval(aMarkerSize, 24);
+ aRetval.Erase(aCol);
+
+ // get write access
+ BitmapWriteAccess* pWrite = aRetval.AcquireWriteAccess();
+ DBG_ASSERT(pWrite, "Got NO write access to a new Bitmap !!!");
+
+ if(pWrite)
+ {
+ // draw outer border
+ INT32 nWidth = aMarkerSize.Width();
+ INT32 nHeight = aMarkerSize.Height();
+
+ pWrite->SetLineColor(Color(COL_LIGHTGRAY));
+ pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1));
+ pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0));
+ pWrite->SetLineColor(Color(COL_GRAY));
+ pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1));
+ pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2));
+
+ // draw lighter UpperLeft
+ const Color aLightColor(
+ (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetRed() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
+ (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetGreen() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
+ (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetBlue() + (sal_Int16)0x0040), (sal_Int16)0x00ff)));
+ pWrite->SetLineColor(aLightColor);
+ pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2));
+ pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1));
+
+ // draw darker LowerRight
+ const Color aDarkColor(
+ (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetRed() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
+ (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetGreen() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
+ (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetBlue() - (sal_Int16)0x0040), (sal_Int16)0x0000)));
+ pWrite->SetLineColor(aDarkColor);
+ pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2));
+ pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3));
+
+ // get rid of write access
+ delete pWrite;
+ }
+
+ return aRetval;
+}
+
+Color SdrHdlColor::GetLuminance(const Color& rCol)
+{
+ UINT8 aLum = rCol.GetLuminance();
+ Color aRetval(aLum, aLum, aLum);
+ return aRetval;
+}
+
+void SdrHdlColor::CallColorChangeLink()
+{
+ aColorChangeHdl.Call(this);
+}
+
+void SdrHdlColor::SetColor(Color aNew, BOOL bCallLink)
+{
+ if(IsUseLuminance())
+ aNew = GetLuminance(aNew);
+
+ if(aMarkerColor != aNew)
+ {
+ // remember new color
+ aMarkerColor = aNew;
+
+ // create new display
+ Touch();
+
+ // tell about change
+ if(bCallLink)
+ CallColorChangeLink();
+ }
+}
+
+void SdrHdlColor::SetSize(const Size& rNew)
+{
+ if(rNew != aMarkerSize)
+ {
+ // remember new size
+ aMarkerSize = rNew;
+
+ // create new display
+ Touch();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// class SdrHdlGradient
+
+SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, BOOL bGrad)
+: SdrHdl(rRef1, bGrad ? HDL_GRAD : HDL_TRNS),
+ pColHdl1(NULL),
+ pColHdl2(NULL),
+ a2ndPos(rRef2),
+ bGradient(bGrad)
+{
+}
+
+SdrHdlGradient::~SdrHdlGradient()
+{
+}
+
+void SdrHdlGradient::Set2ndPos(const Point& rPnt)
+{
+ if(a2ndPos != rPnt)
+ {
+ // remember new position
+ a2ndPos = rPnt;
+
+ // create new display
+ Touch();
+ }
+}
+
+void SdrHdlGradient::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ // striped line in between
+ basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
+ double fVecLen = aVec.getLength();
+ double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
+ double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
+ aVec.normalize();
+ basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
+ INT32 nMidX = (INT32)(aPos.X() + aVec.getX() * fLongPercentArrow);
+ INT32 nMidY = (INT32)(aPos.Y() + aVec.getY() * fLongPercentArrow);
+ Point aMidPoint(nMidX, nMidY);
+
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+ basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
+
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = new
+ ::sdr::overlay::OverlayLineStriped(
+ aPosition, aMidPos
+ );
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ pNewOverlayObject->setBaseColor(IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE));
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+
+ // arrowhead
+ Point aLeft(aMidPoint.X() + (INT32)(aPerpend.getX() * fHalfArrowWidth),
+ aMidPoint.Y() + (INT32)(aPerpend.getY() * fHalfArrowWidth));
+ Point aRight(aMidPoint.X() - (INT32)(aPerpend.getX() * fHalfArrowWidth),
+ aMidPoint.Y() - (INT32)(aPerpend.getY() * fHalfArrowWidth));
+
+ basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
+ basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
+ basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
+
+ pNewOverlayObject = new
+ ::sdr::overlay::OverlayTriangle(
+ aPositionLeft,
+ aPosition2,
+ aPositionRight,
+ IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE)
+ );
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+IMPL_LINK(SdrHdlGradient, ColorChangeHdl, SdrHdl*, /*pHdl*/)
+{
+ if(GetObj())
+ FromIAOToItem(GetObj(), TRUE, TRUE);
+ return 0;
+}
+
+void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, BOOL bSetItemOnObject, BOOL bUndo)
+{
+ // from IAO positions and colors to gradient
+ const SfxItemSet& rSet = _pObj->GetMergedItemSet();
+
+ GradTransformer aGradTransformer;
+ GradTransGradient aOldGradTransGradient;
+ GradTransGradient aGradTransGradient;
+ GradTransVector aGradTransVector;
+
+ String aString;
+
+ aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
+ aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
+ if(pColHdl1)
+ aGradTransVector.aCol1 = pColHdl1->GetColor();
+ if(pColHdl2)
+ aGradTransVector.aCol2 = pColHdl2->GetColor();
+
+ if(IsGradient())
+ aOldGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
+ else
+ aOldGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
+
+ // transform vector data to gradient
+ aGradTransformer.VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
+
+ if(bSetItemOnObject)
+ {
+ SdrModel* pModel = _pObj->GetModel();
+ SfxItemSet aNewSet(pModel->GetItemPool());
+
+ if(IsGradient())
+ {
+ aString = String();
+ XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
+ aNewSet.Put(aNewGradItem);
+ }
+ else
+ {
+ aString = String();
+ XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
+ aNewSet.Put(aNewTransItem);
+ }
+
+ if(bUndo && pModel->IsUndoEnabled())
+ {
+ pModel->BegUndo(SVX_RESSTR(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
+ pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
+ pModel->EndUndo();
+ }
+
+ pObj->SetMergedItemSetAndBroadcast(aNewSet);
+ }
+
+ // back transformation, set values on pIAOHandle
+ aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, _pObj);
+
+ SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
+ Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
+ if(pColHdl1)
+ {
+ pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
+ pColHdl1->SetColor(aGradTransVector.aCol1);
+ }
+ if(pColHdl2)
+ {
+ pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
+ pColHdl2->SetColor(aGradTransVector.aCol2);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrHdlLine::~SdrHdlLine() {}
+
+void SdrHdlLine::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2)
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
+ basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y());
+
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = new
+ ::sdr::overlay::OverlayLineStriped(
+ aPosition1,
+ aPosition2
+ );
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ // color(?)
+ pNewOverlayObject->setBaseColor(Color(COL_LIGHTRED));
+
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+Pointer SdrHdlLine::GetPointer() const
+{
+ return Pointer(POINTER_REFHAND);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrHdlBezWgt::~SdrHdlBezWgt() {}
+
+void SdrHdlBezWgt::CreateB2dIAObject()
+{
+ // call parent
+ SdrHdl::CreateB2dIAObject();
+
+ // create lines
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
+ basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y());
+
+ if(!aPosition1.equal(aPosition2))
+ {
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = new
+ ::sdr::overlay::OverlayLineStriped(
+ aPosition1,
+ aPosition2
+ );
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ // line part is not hittable
+ pNewOverlayObject->setHittable(sal_False);
+
+ // color(?)
+ pNewOverlayObject->setBaseColor(Color(COL_LIGHTBLUE));
+
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+E3dVolumeMarker::E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly)
+{
+ aWireframePoly = rWireframePoly;
+}
+
+void E3dVolumeMarker::CreateB2dIAObject()
+{
+ // create lines
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager() && aWireframePoly.count())
+ {
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = new
+ ::sdr::overlay::OverlayPolyPolygonStriped(aWireframePoly);
+ DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ pNewOverlayObject->setBaseColor(Color(COL_BLACK));
+
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ImpEdgeHdl::~ImpEdgeHdl()
+{
+}
+
+void ImpEdgeHdl::CreateB2dIAObject()
+{
+ if(nObjHdlNum <= 1 && pObj)
+ {
+ // first throw away old one
+ GetRidOfIAObject();
+
+ BitmapColorIndex eColIndex = LightCyan;
+ BitmapMarkerKind eKindOfMarker = Rect_7x7;
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ const SdrEdgeObj* pEdge = (SdrEdgeObj*)pObj;
+
+ if(pEdge->GetConnectedNode(nObjHdlNum == 0) != NULL)
+ eColIndex = LightRed;
+
+ if(nPPntNum < 2)
+ {
+ // Handle with plus sign inside
+ eKindOfMarker = Circ_7x7;
+ }
+
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
+ aPosition,
+ eColIndex,
+ eKindOfMarker);
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // call parent
+ SdrHdl::CreateB2dIAObject();
+ }
+}
+
+void ImpEdgeHdl::SetLineCode(SdrEdgeLineCode eCode)
+{
+ if(eLineCode != eCode)
+ {
+ // remember new value
+ eLineCode = eCode;
+
+ // create new display
+ Touch();
+ }
+}
+
+Pointer ImpEdgeHdl::GetPointer() const
+{
+ SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
+ if (pEdge==NULL)
+ return SdrHdl::GetPointer();
+ if (nObjHdlNum<=1)
+ return Pointer(POINTER_MOVEPOINT); //Pointer(POINTER_DRAW_CONNECT);
+ if (IsHorzDrag())
+ return Pointer(POINTER_ESIZE);
+ else
+ return Pointer(POINTER_SSIZE);
+}
+
+BOOL ImpEdgeHdl::IsHorzDrag() const
+{
+ SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
+ if (pEdge==NULL)
+ return FALSE;
+ if (nObjHdlNum<=1)
+ return FALSE;
+
+ SdrEdgeKind eEdgeKind = ((SdrEdgeKindItem&)(pEdge->GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
+
+ const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
+ if (eEdgeKind==SDREDGE_ORTHOLINES || eEdgeKind==SDREDGE_BEZIER)
+ {
+ return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
+ }
+ else if (eEdgeKind==SDREDGE_THREELINES)
+ {
+ long nWink=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
+ if (nWink==0 || nWink==18000)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ImpMeasureHdl::~ImpMeasureHdl()
+{
+}
+
+void ImpMeasureHdl::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ BitmapColorIndex eColIndex = LightCyan;
+ BitmapMarkerKind eKindOfMarker = Rect_9x9;
+
+ if(nObjHdlNum > 1)
+ {
+ eKindOfMarker = Rect_7x7;
+ }
+
+ if(bSelect)
+ {
+ eColIndex = Cyan;
+ }
+
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+
+ ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
+ aPosition,
+ eColIndex,
+ eKindOfMarker);
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+Pointer ImpMeasureHdl::GetPointer() const
+{
+ switch (nObjHdlNum)
+ {
+ case 0: case 1: return Pointer(POINTER_HAND);
+ case 2: case 3: return Pointer(POINTER_MOVEPOINT);
+ case 4: case 5: return SdrHdl::GetPointer(); // wird dann entsprechend gedreht
+ } // switch
+ return Pointer(POINTER_NOTALLOWED);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ImpTextframeHdl::ImpTextframeHdl(const Rectangle& rRect) :
+ SdrHdl(rRect.TopLeft(),HDL_MOVE),
+ maRect(rRect)
+{
+}
+
+void ImpTextframeHdl::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ if(pHdlList)
+ {
+ SdrMarkView* pView = pHdlList->GetView();
+
+ if(pView && !pView->areMarkHandlesHidden())
+ {
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top());
+ const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom());
+ const svtools::ColorConfig aColorConfig;
+ const Color aHatchCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
+
+ ::sdr::overlay::OverlayHatchRect* pNewOverlayObject = new ::sdr::overlay::OverlayHatchRect(
+ aTopLeft,
+ aBottomRight,
+ aHatchCol,
+ 3.0,
+ 3.0,
+ 45 * F_PI180,
+ nDrehWink * -F_PI18000);
+ pNewOverlayObject->setHittable(false);
+
+ // OVERLAYMANAGER
+ if(pNewOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
+ maOverlayGroup.append(*pNewOverlayObject);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpSdrHdlListSorter: public ContainerSorter {
+public:
+ ImpSdrHdlListSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
+ virtual int Compare(const void* pElem1, const void* pElem2) const;
+};
+
+int ImpSdrHdlListSorter::Compare(const void* pElem1, const void* pElem2) const
+{
+ SdrHdlKind eKind1=((SdrHdl*)pElem1)->GetKind();
+ SdrHdlKind eKind2=((SdrHdl*)pElem2)->GetKind();
+ // Level 1: Erst normale Handles, dann Glue, dann User, dann Plushandles, dann Retpunkt-Handles
+ unsigned n1=1;
+ unsigned n2=1;
+ if (eKind1!=eKind2)
+ {
+ if (eKind1==HDL_REF1 || eKind1==HDL_REF2 || eKind1==HDL_MIRX) n1=5;
+ else if (eKind1==HDL_GLUE) n1=2;
+ else if (eKind1==HDL_USER) n1=3;
+ else if (eKind1==HDL_SMARTTAG) n1=0;
+ if (eKind2==HDL_REF1 || eKind2==HDL_REF2 || eKind2==HDL_MIRX) n2=5;
+ else if (eKind2==HDL_GLUE) n2=2;
+ else if (eKind2==HDL_USER) n2=3;
+ else if (eKind2==HDL_SMARTTAG) n2=0;
+ }
+ if (((SdrHdl*)pElem1)->IsPlusHdl()) n1=4;
+ if (((SdrHdl*)pElem2)->IsPlusHdl()) n2=4;
+ if (n1==n2)
+ {
+ // Level 2: PageView (Pointer)
+ SdrPageView* pPV1=((SdrHdl*)pElem1)->GetPageView();
+ SdrPageView* pPV2=((SdrHdl*)pElem2)->GetPageView();
+ if (pPV1==pPV2)
+ {
+ // Level 3: Position (x+y)
+ SdrObject* pObj1=((SdrHdl*)pElem1)->GetObj();
+ SdrObject* pObj2=((SdrHdl*)pElem2)->GetObj();
+ if (pObj1==pObj2)
+ {
+ sal_uInt32 nNum1=((SdrHdl*)pElem1)->GetObjHdlNum();
+ sal_uInt32 nNum2=((SdrHdl*)pElem2)->GetObjHdlNum();
+ if (nNum1==nNum2)
+ { // #48763#
+ if (eKind1==eKind2)
+ return (long)pElem1<(long)pElem2 ? -1 : 1; // Notloesung, um immer die gleiche Sortierung zu haben
+ return (USHORT)eKind1<(USHORT)eKind2 ? -1 : 1;
+ }
+ else
+ return nNum1<nNum2 ? -1 : 1;
+ }
+ else
+ {
+ return (long)pObj1<(long)pObj2 ? -1 : 1;
+ }
+ }
+ else
+ {
+ return (long)pPV1<(long)pPV2 ? -1 : 1;
+ }
+ }
+ else
+ {
+ return n1<n2 ? -1 : 1;
+ }
+}
+
+SdrMarkView* SdrHdlList::GetView() const
+{
+ return pView;
+}
+
+// #105678# Help struct for re-sorting handles
+struct ImplHdlAndIndex
+{
+ SdrHdl* mpHdl;
+ sal_uInt32 mnIndex;
+};
+
+// #105678# Help method for sorting handles taking care of OrdNums, keeping order in
+// single objects and re-sorting polygon handles intuitively
+extern "C" int __LOADONCALLAPI ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
+{
+ const ImplHdlAndIndex* p1 = (ImplHdlAndIndex*)pVoid1;
+ const ImplHdlAndIndex* p2 = (ImplHdlAndIndex*)pVoid2;
+
+ if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
+ {
+ if(p1->mpHdl->GetObj() && p1->mpHdl->GetObj()->ISA(SdrPathObj))
+ {
+ // same object and a path object
+ if((p1->mpHdl->GetKind() == HDL_POLY || p1->mpHdl->GetKind() == HDL_BWGT)
+ && (p2->mpHdl->GetKind() == HDL_POLY || p2->mpHdl->GetKind() == HDL_BWGT))
+ {
+ // both handles are point or control handles
+ if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
+ {
+ if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(!p1->mpHdl->GetObj())
+ {
+ return -1;
+ }
+ else if(!p2->mpHdl->GetObj())
+ {
+ return 1;
+ }
+ else
+ {
+ // different objects, use OrdNum for sort
+ const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
+ const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
+
+ if(nOrdNum1 < nOrdNum2)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ }
+
+ // fallback to indices
+ if(p1->mnIndex < p2->mnIndex)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #97016# II
+
+void SdrHdlList::TravelFocusHdl(sal_Bool bForward)
+{
+ // security correction
+ if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex >= GetHdlCount())
+ mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
+
+ if(aList.Count())
+ {
+ // take care of old handle
+ const ULONG nOldHdlNum(mnFocusIndex);
+ SdrHdl* pOld = GetHdl(nOldHdlNum);
+ //SDOsal_Bool bRefresh(sal_False);
+
+ if(pOld)
+ {
+ // switch off old handle
+ mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
+ pOld->Touch();
+ //SDObRefresh = sal_True;
+ }
+
+ // #105678# Alloc pointer array for sorted handle list
+ ImplHdlAndIndex* pHdlAndIndex = new ImplHdlAndIndex[aList.Count()];
+
+ // #105678# build sorted handle list
+ sal_uInt32 a;
+ for( a = 0; a < aList.Count(); a++)
+ {
+ pHdlAndIndex[a].mpHdl = (SdrHdl*)aList.GetObject(a);
+ pHdlAndIndex[a].mnIndex = a;
+ }
+
+ // #105678# qsort all entries
+ qsort(pHdlAndIndex, aList.Count(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
+
+ // #105678# look for old num in sorted array
+ ULONG nOldHdl(nOldHdlNum);
+
+ if(nOldHdlNum != CONTAINER_ENTRY_NOTFOUND)
+ {
+ for(a = 0; a < aList.Count(); a++)
+ {
+ if(pHdlAndIndex[a].mpHdl == pOld)
+ {
+ nOldHdl = a;
+ break;
+ }
+ }
+ }
+
+ // #105678# build new HdlNum
+ ULONG nNewHdl(nOldHdl);
+
+ // #105678# do the focus travel
+ if(bForward)
+ {
+ if(nOldHdl != CONTAINER_ENTRY_NOTFOUND)
+ {
+ if(nOldHdl == aList.Count() - 1)
+ {
+ // end forward run
+ nNewHdl = CONTAINER_ENTRY_NOTFOUND;
+ }
+ else
+ {
+ // simply the next handle
+ nNewHdl++;
+ }
+ }
+ else
+ {
+ // start forward run at first entry
+ nNewHdl = 0;
+ }
+ }
+ else
+ {
+ if(nOldHdl == CONTAINER_ENTRY_NOTFOUND)
+ {
+ // start backward run at last entry
+ nNewHdl = aList.Count() - 1;
+
+ }
+ else
+ {
+ if(nOldHdl == 0)
+ {
+ // end backward run
+ nNewHdl = CONTAINER_ENTRY_NOTFOUND;
+ }
+ else
+ {
+ // simply the previous handle
+ nNewHdl--;
+ }
+ }
+ }
+
+ // #105678# build new HdlNum
+ sal_uInt32 nNewHdlNum(nNewHdl);
+
+ // look for old num in sorted array
+ if(nNewHdl != CONTAINER_ENTRY_NOTFOUND)
+ {
+ SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
+
+ for(a = 0; a < aList.Count(); a++)
+ {
+ if((SdrHdl*)aList.GetObject(a) == pNew)
+ {
+ nNewHdlNum = a;
+ break;
+ }
+ }
+ }
+
+ // take care of next handle
+ if(nOldHdlNum != nNewHdlNum)
+ {
+ mnFocusIndex = nNewHdlNum;
+ SdrHdl* pNew = GetHdl(mnFocusIndex);
+
+ if(pNew)
+ {
+ pNew->Touch();
+ //SDObRefresh = sal_True;
+ }
+ }
+
+ // #105678# free mem again
+ delete [] pHdlAndIndex;
+ }
+}
+
+SdrHdl* SdrHdlList::GetFocusHdl() const
+{
+ if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex < GetHdlCount())
+ return GetHdl(mnFocusIndex);
+ else
+ return 0L;
+}
+
+void SdrHdlList::SetFocusHdl(SdrHdl* pNew)
+{
+ if(pNew)
+ {
+ SdrHdl* pActual = GetFocusHdl();
+
+ if(!pActual || pActual != pNew)
+ {
+ ULONG nNewHdlNum = GetHdlNum(pNew);
+
+ if(nNewHdlNum != CONTAINER_ENTRY_NOTFOUND)
+ {
+ //SDOsal_Bool bRefresh(sal_False);
+ mnFocusIndex = nNewHdlNum;
+
+ if(pActual)
+ {
+ pActual->Touch();
+ //SDObRefresh = sal_True;
+ }
+
+ if(pNew)
+ {
+ pNew->Touch();
+ //SDObRefresh = sal_True;
+ }
+
+ //OLMif(bRefresh)
+ //OLM{
+ //OLM if(pView)
+ //OLM pView->RefreshAllIAOManagers();
+ //OLM}
+ }
+ }
+ }
+}
+
+void SdrHdlList::ResetFocusHdl()
+{
+ SdrHdl* pHdl = GetFocusHdl();
+
+ mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
+
+ if(pHdl)
+ {
+ pHdl->Touch();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrHdlList::SdrHdlList(SdrMarkView* pV)
+: mnFocusIndex(CONTAINER_ENTRY_NOTFOUND),
+ pView(pV),
+ aList(1024,32,32)
+{
+ nHdlSize = 3;
+ bRotateShear = FALSE;
+ bMoveOutside = FALSE;
+ bDistortShear = FALSE;
+ bFineHandles = FALSE;
+}
+
+SdrHdlList::~SdrHdlList()
+{
+ Clear();
+}
+
+void SdrHdlList::SetHdlSize(USHORT nSiz)
+{
+ if(nHdlSize != nSiz)
+ {
+ // remember new value
+ nHdlSize = nSiz;
+
+ // propagate change to IAOs
+ for(UINT32 i=0; i<GetHdlCount(); i++)
+ {
+ SdrHdl* pHdl = GetHdl(i);
+ pHdl->Touch();
+ }
+ }
+}
+
+void SdrHdlList::SetMoveOutside(BOOL bOn)
+{
+ if(bMoveOutside != bOn)
+ {
+ // remember new value
+ bMoveOutside = bOn;
+
+ // propagate change to IAOs
+ for(UINT32 i=0; i<GetHdlCount(); i++)
+ {
+ SdrHdl* pHdl = GetHdl(i);
+ pHdl->Touch();
+ }
+ }
+}
+
+void SdrHdlList::SetRotateShear(BOOL bOn)
+{
+ bRotateShear = bOn;
+}
+
+void SdrHdlList::SetDistortShear(BOOL bOn)
+{
+ bDistortShear = bOn;
+}
+
+void SdrHdlList::SetFineHdl(BOOL bOn)
+{
+ if(bFineHandles != bOn)
+ {
+ // remember new state
+ bFineHandles = bOn;
+
+ // propagate change to IAOs
+ for(UINT32 i=0; i<GetHdlCount(); i++)
+ {
+ SdrHdl* pHdl = GetHdl(i);
+ pHdl->Touch();
+ }
+ }
+}
+
+SdrHdl* SdrHdlList::RemoveHdl(ULONG nNum)
+{
+ SdrHdl* pRetval = (SdrHdl*)aList.Remove(nNum);
+
+ return pRetval;
+}
+
+void SdrHdlList::Clear()
+{
+ for (ULONG i=0; i<GetHdlCount(); i++)
+ {
+ SdrHdl* pHdl=GetHdl(i);
+ delete pHdl;
+ }
+ aList.Clear();
+
+ bRotateShear=FALSE;
+ bDistortShear=FALSE;
+}
+
+void SdrHdlList::Sort()
+{
+ // #97016# II: remember current focused handle
+ SdrHdl* pPrev = GetFocusHdl();
+
+ ImpSdrHdlListSorter aSort(aList);
+ aSort.DoSort();
+
+ // #97016# II: get now and compare
+ SdrHdl* pNow = GetFocusHdl();
+
+ if(pPrev != pNow)
+ {
+ //SDOsal_Bool bRefresh(sal_False);
+
+ if(pPrev)
+ {
+ pPrev->Touch();
+ //SDObRefresh = sal_True;
+ }
+
+ if(pNow)
+ {
+ pNow->Touch();
+ //SDObRefresh = sal_True;
+ }
+ }
+}
+
+ULONG SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
+{
+ if (pHdl==NULL)
+ return CONTAINER_ENTRY_NOTFOUND;
+ ULONG nPos=aList.GetPos(pHdl);
+ return nPos;
+}
+
+void SdrHdlList::AddHdl(SdrHdl* pHdl, BOOL bAtBegin)
+{
+ if (pHdl!=NULL)
+ {
+ if (bAtBegin)
+ {
+ aList.Insert(pHdl,ULONG(0));
+ }
+ else
+ {
+ aList.Insert(pHdl,CONTAINER_APPEND);
+ }
+ pHdl->SetHdlList(this);
+ }
+}
+
+SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt, BOOL bBack, BOOL bNext, SdrHdl* pHdl0) const
+{
+ SdrHdl* pRet=NULL;
+ ULONG nAnz=GetHdlCount();
+ ULONG nNum=bBack ? 0 : nAnz;
+ while ((bBack ? nNum<nAnz : nNum>0) && pRet==NULL)
+ {
+ if (!bBack)
+ nNum--;
+ SdrHdl* pHdl=GetHdl(nNum);
+ if (bNext)
+ {
+ if (pHdl==pHdl0)
+ bNext=FALSE;
+ }
+ else
+ {
+ if (pHdl->IsHdlHit(rPnt))
+ pRet=pHdl;
+ }
+ if (bBack)
+ nNum++;
+ }
+ return pRet;
+}
+
+SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const
+{
+ SdrHdl* pRet=NULL;
+ for (ULONG i=0; i<GetHdlCount() && pRet==NULL; i++)
+ {
+ SdrHdl* pHdl=GetHdl(i);
+ if (pHdl->GetKind()==eKind1)
+ pRet=pHdl;
+ }
+ return pRet;
+}
+
+// --------------------------------------------------------------------
+// SdrCropHdl
+// --------------------------------------------------------------------
+
+SdrCropHdl::SdrCropHdl(const Point& rPnt, SdrHdlKind eNewKind)
+: SdrHdl( rPnt, eNewKind )
+{
+}
+
+// --------------------------------------------------------------------
+
+BitmapEx SdrCropHdl::GetHandlesBitmap( bool bIsFineHdl, bool bIsHighContrast )
+{
+ if( bIsHighContrast )
+ {
+ static BitmapEx* pHighContrastBitmap = 0;
+ if( pHighContrastBitmap == 0 )
+ pHighContrastBitmap = new BitmapEx(ResId(SIP_SA_ACCESSIBILITY_CROP_MARKERS, *ImpGetResMgr()));
+ return *pHighContrastBitmap;
+ }
+ else if( bIsFineHdl )
+ {
+ static BitmapEx* pModernBitmap = 0;
+ if( pModernBitmap == 0 )
+ pModernBitmap = new BitmapEx(ResId(SIP_SA_CROP_FINE_MARKERS, *ImpGetResMgr()));
+ return *pModernBitmap;
+ }
+ else
+ {
+ static BitmapEx* pSimpleBitmap = 0;
+ if( pSimpleBitmap == 0 )
+ pSimpleBitmap = new BitmapEx(ResId(SIP_SA_CROP_MARKERS, *ImpGetResMgr()));
+ return *pSimpleBitmap;
+ }
+}
+
+// --------------------------------------------------------------------
+
+BitmapEx SdrCropHdl::GetBitmapForHandle( const BitmapEx& rBitmap, int nSize )
+{
+ int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
+
+ if( nSize <= 3 )
+ {
+ nPixelSize = 13;
+ nOffset = 0;
+ }
+ else if( nSize <=4 )
+ {
+ nPixelSize = 17;
+ nOffset = 36;
+ }
+ else
+ {
+ nPixelSize = 21;
+ nOffset = 84;
+ }
+
+ switch( eKind )
+ {
+ case HDL_UPLFT: nX = 0; nY = 0; break;
+ case HDL_UPPER: nX = 1; nY = 0; break;
+ case HDL_UPRGT: nX = 2; nY = 0; break;
+ case HDL_LEFT: nX = 0; nY = 1; break;
+ case HDL_RIGHT: nX = 2; nY = 1; break;
+ case HDL_LWLFT: nX = 0; nY = 2; break;
+ case HDL_LOWER: nX = 1; nY = 2; break;
+ case HDL_LWRGT: nX = 2; nY = 2; break;
+ default: break;
+ }
+
+ Rectangle aSourceRect( Point( nX * (nPixelSize-1) + nOffset, nY * (nPixelSize-1)), Size(nPixelSize, nPixelSize) );
+
+ BitmapEx aRetval(rBitmap);
+ aRetval.Crop(aSourceRect);
+ return aRetval;
+}
+
+// --------------------------------------------------------------------
+
+void SdrCropHdl::CreateB2dIAObject()
+{
+ // first throw away old one
+ GetRidOfIAObject();
+
+ SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
+ SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
+
+ if( pPageView && !pView->areMarkHandlesHidden() )
+ {
+ sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
+ int nHdlSize = pHdlList->GetHdlSize();
+ if( bIsHighContrast )
+ nHdlSize = 4;
+
+ const BitmapEx aHandlesBitmap( GetHandlesBitmap( bIsFineHdl, bIsHighContrast ) );
+ BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
+
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
+ const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+ if(rPageWindow.GetPaintWindow().OutputToWindow())
+ {
+ if(rPageWindow.GetOverlayManager())
+ {
+ basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
+
+ ::sdr::overlay::OverlayObject* pOverlayObject = 0L;
+
+ // animate focused handles
+ if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
+ {
+ if( nHdlSize >= 2 )
+ nHdlSize = 1;
+
+ BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
+
+ const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
+
+ pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBmpEx1, aBmpEx2, nBlinkTime,
+ (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
+ (UINT16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
+ }
+ else
+ {
+ // create centered handle as default
+ pOverlayObject = new ::sdr::overlay::OverlayBitmapEx(aPosition, aBmpEx1,
+ (UINT16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
+ (UINT16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1);
+ }
+
+ // OVERLAYMANAGER
+ if(pOverlayObject)
+ {
+ rPageWindow.GetOverlayManager()->add(*pOverlayObject);
+ maOverlayGroup.append(*pOverlayObject);
+ }
+ }
+ }
+ }
+ }
+}
+
+// --------------------------------------------------------------------
diff --git a/svx/source/svdraw/svdhlpln.cxx b/svx/source/svdraw/svdhlpln.cxx
new file mode 100644
index 000000000000..2813b6f032f1
--- /dev/null
+++ b/svx/source/svdraw/svdhlpln.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdhlpln.hxx>
+#include <tools/color.hxx>
+
+#include <vcl/outdev.hxx>
+#include <vcl/window.hxx>
+#include <tools/poly.hxx>
+#include <vcl/lineinfo.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Pointer SdrHelpLine::GetPointer() const
+{
+ switch (eKind) {
+ case SDRHELPLINE_VERTICAL : return Pointer(POINTER_ESIZE);
+ case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE);
+ default : return Pointer(POINTER_MOVE);
+ } // switch
+}
+
+FASTBOOL SdrHelpLine::IsHit(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
+{
+ Size a1Pix(rOut.PixelToLogic(Size(1,1)));
+ FASTBOOL bXHit=rPnt.X()>=aPos.X()-nTolLog && rPnt.X()<=aPos.X()+nTolLog+a1Pix.Width();
+ FASTBOOL bYHit=rPnt.Y()>=aPos.Y()-nTolLog && rPnt.Y()<=aPos.Y()+nTolLog+a1Pix.Height();
+ switch (eKind) {
+ case SDRHELPLINE_VERTICAL : return bXHit;
+ case SDRHELPLINE_HORIZONTAL: return bYHit;
+ case SDRHELPLINE_POINT: {
+ if (bXHit || bYHit) {
+ Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
+ return rPnt.X()>=aPos.X()-aRad.Width() && rPnt.X()<=aPos.X()+aRad.Width()+a1Pix.Width() &&
+ rPnt.Y()>=aPos.Y()-aRad.Height() && rPnt.Y()<=aPos.Y()+aRad.Height()+a1Pix.Height();
+ }
+ } break;
+ } // switch
+ return FALSE;
+}
+
+Rectangle SdrHelpLine::GetBoundRect(const OutputDevice& rOut) const
+{
+ Rectangle aRet(aPos,aPos);
+ Point aOfs(rOut.GetMapMode().GetOrigin());
+ Size aSiz(rOut.GetOutputSize());
+ switch (eKind) {
+ case SDRHELPLINE_VERTICAL : aRet.Top()=-aOfs.Y(); aRet.Bottom()=-aOfs.Y()+aSiz.Height(); break;
+ case SDRHELPLINE_HORIZONTAL: aRet.Left()=-aOfs.X(); aRet.Right()=-aOfs.X()+aSiz.Width(); break;
+ case SDRHELPLINE_POINT : {
+ Size aRad(rOut.PixelToLogic(Size(SDRHELPLINE_POINT_PIXELSIZE,SDRHELPLINE_POINT_PIXELSIZE)));
+ aRet.Left() -=aRad.Width();
+ aRet.Right() +=aRad.Width();
+ aRet.Top() -=aRad.Height();
+ aRet.Bottom()+=aRad.Height();
+ } break;
+ } // switch
+ return aRet;
+}
+
+bool SdrHelpLine::IsVisibleEqual( const SdrHelpLine& rHelpLine, const OutputDevice& rOut ) const
+{
+ if( eKind == rHelpLine.eKind)
+ {
+ Point aPt1(rOut.LogicToPixel(aPos)), aPt2(rOut.LogicToPixel(rHelpLine.aPos));
+ switch( eKind )
+ {
+ case SDRHELPLINE_POINT:
+ return aPt1 == aPt2;
+ case SDRHELPLINE_VERTICAL:
+ return aPt1.X() == aPt2.X();
+ case SDRHELPLINE_HORIZONTAL:
+ return aPt1.Y() == aPt2.Y();
+ }
+ }
+ return false;
+}
+
+void SdrHelpLineList::Clear()
+{
+ USHORT nAnz=GetCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ delete GetObject(i);
+ }
+ aList.Clear();
+}
+
+void SdrHelpLineList::operator=(const SdrHelpLineList& rSrcList)
+{
+ Clear();
+ USHORT nAnz=rSrcList.GetCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ Insert(rSrcList[i]);
+ }
+}
+
+bool SdrHelpLineList::operator==(const SdrHelpLineList& rSrcList) const
+{
+ FASTBOOL bEqual=FALSE;
+ USHORT nAnz=GetCount();
+ if (nAnz==rSrcList.GetCount()) {
+ bEqual=TRUE;
+ for (USHORT i=0; i<nAnz && bEqual; i++) {
+ if (*GetObject(i)!=*rSrcList.GetObject(i)) {
+ bEqual=FALSE;
+ }
+ }
+ }
+ return bEqual;
+}
+
+USHORT SdrHelpLineList::HitTest(const Point& rPnt, USHORT nTolLog, const OutputDevice& rOut) const
+{
+ USHORT nAnz=GetCount();
+ for (USHORT i=nAnz; i>0;) {
+ i--;
+ if (GetObject(i)->IsHit(rPnt,nTolLog,rOut)) return i;
+ }
+ return SDRHELPLINE_NOTFOUND;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdibrow.cxx b/svx/source/svdraw/svdibrow.cxx
new file mode 100644
index 000000000000..fa3dbe852b3a
--- /dev/null
+++ b/svx/source/svdraw/svdibrow.cxx
@@ -0,0 +1,1299 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <editeng/eeitem.hxx>
+
+#include "svdibrow.hxx"
+
+#ifndef _STDLIB_H
+#include <stdlib.h>
+#define _STDLIB_H
+#endif
+
+#include "svditext.hxx"
+#include <editeng/flditem.hxx>
+#include <editeng/editdata.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdview.hxx>
+#include <svx/xenum.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xtextit0.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <svx/xftshit.hxx>
+#include <editeng/colritem.hxx>
+
+
+#include "editeng/fontitem.hxx"
+#include <editeng/fhgtitem.hxx>
+
+#include <editeng/charscaleitem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/flagitem.hxx>
+#include <svl/ptitem.hxx>
+#include <svl/rectitem.hxx>
+
+#include <svl/rngitem.hxx>
+#include <sdrpaintwindow.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define ITEMBROWSER_WHICHCOL_ID 1
+#define ITEMBROWSER_STATECOL_ID 2
+#define ITEMBROWSER_TYPECOL_ID 3
+#define ITEMBROWSER_NAMECOL_ID 4
+#define ITEMBROWSER_VALUECOL_ID 5
+
+enum ItemType {
+ ITEM_DONTKNOW, ITEM_BYTE, ITEM_INT16, ITEM_UINT16, ITEM_INT32, ITEM_UINT32,
+ ITEM_ENUM, ITEM_BOOL, ITEM_FLAG, ITEM_STRING, ITEM_POINT, ITEM_RECT, ITEM_RANGE, ITEM_LRANGE,
+ ITEM_FRACTION,
+ ITEM_XCOLOR,
+ ITEM_COLOR,
+ ITEM_FONT, ITEM_FONTHEIGHT, ITEM_FONTWIDTH, ITEM_FIELD
+};
+
+class ImpItemListRow
+{
+public:
+ XubString aName;
+ XubString aValue;
+ SfxItemState eState;
+ UINT16 nWhichId;
+
+ TypeId pType;
+ ItemType eItemType;
+
+ INT32 nVal;
+ INT32 nMin;
+ INT32 nMax;
+
+ BOOL bComment;
+ BOOL bIsNum;
+ BOOL bCanNum;
+
+public:
+ ImpItemListRow()
+ : eState(SFX_ITEM_UNKNOWN),
+ nWhichId(0),
+ pType(NULL),
+ eItemType(ITEM_DONTKNOW),
+ nVal(0),
+ nMin(0),
+ nMax(0),
+ bComment(FALSE),
+ bIsNum(FALSE),
+ bCanNum(FALSE)
+ {}
+
+ XubString GetItemTypeStr() const;
+ BOOL operator==(const ImpItemListRow& rEntry) const;
+ BOOL operator!=(const ImpItemListRow& rEntry) const { return !operator==(rEntry); }
+};
+
+XubString ImpItemListRow::GetItemTypeStr() const
+{
+ XubString aStr;
+
+ switch(eItemType)
+ {
+ case ITEM_BYTE : aStr.AppendAscii("Byte"); break;
+ case ITEM_INT16 : aStr.AppendAscii("Int16"); break;
+ case ITEM_UINT16 : aStr.AppendAscii("UInt16"); break;
+ case ITEM_INT32 : aStr.AppendAscii("Int32"); break;
+ case ITEM_UINT32 : aStr.AppendAscii("UInt32"); break;
+ case ITEM_ENUM : aStr.AppendAscii("Enum"); break;
+ case ITEM_BOOL : aStr.AppendAscii("Bool"); break;
+ case ITEM_FLAG : aStr.AppendAscii("Flag"); break;
+ case ITEM_STRING : aStr.AppendAscii("String"); break;
+ case ITEM_POINT : aStr.AppendAscii("Point"); break;
+ case ITEM_RECT : aStr.AppendAscii("Rectangle");break;
+ case ITEM_RANGE : aStr.AppendAscii("Range"); break;
+ case ITEM_LRANGE : aStr.AppendAscii("LRange"); break;
+ case ITEM_FRACTION : aStr.AppendAscii("Fraction"); break;
+ case ITEM_XCOLOR : aStr.AppendAscii("XColor"); break;
+ case ITEM_COLOR : aStr.AppendAscii("Color"); break;
+ case ITEM_FONT : aStr.AppendAscii("Font"); break;
+ case ITEM_FONTHEIGHT:aStr.AppendAscii("FontHeight");break;
+ case ITEM_FONTWIDTH :aStr.AppendAscii("FontWidth"); break;
+ case ITEM_FIELD :aStr.AppendAscii("Field"); break;
+ default: break;
+ }
+
+ return aStr;
+}
+
+BOOL ImpItemListRow::operator==(const ImpItemListRow& rEntry) const
+{
+ return (aName.Equals(rEntry.aName)
+ && aValue.Equals(rEntry.aValue)
+ && eState==rEntry.eState
+ && nWhichId==rEntry.nWhichId
+ && bComment==rEntry.bComment
+ && bIsNum==rEntry.bIsNum
+ && bCanNum==rEntry.bCanNum
+ && pType==rEntry.pType
+ && eItemType==rEntry.eItemType
+ && nVal==rEntry.nVal
+ && nMin==rEntry.nMin
+ && nMax==rEntry.nMax);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpItemEdit: public Edit
+{
+ _SdrItemBrowserControl* pBrowse;
+
+public:
+ ImpItemEdit(Window* pParent, _SdrItemBrowserControl* pBrowse_, WinBits nBits=0)
+ : Edit(pParent, nBits),
+ pBrowse(pBrowse_)
+ {}
+
+ virtual ~ImpItemEdit();
+ virtual void KeyInput(const KeyEvent& rEvt);
+};
+
+__EXPORT ImpItemEdit::~ImpItemEdit()
+{
+}
+
+void __EXPORT ImpItemEdit::KeyInput(const KeyEvent& rKEvt)
+{
+ _SdrItemBrowserControl* pBrowseMerk = pBrowse;
+
+ UINT16 nKeyCode(rKEvt.GetKeyCode().GetCode() + rKEvt.GetKeyCode().GetModifier());
+
+ if(nKeyCode == KEY_RETURN)
+ {
+ pBrowseMerk->EndChangeEntry();
+ pBrowseMerk->GrabFocus();
+ }
+ else if(nKeyCode == KEY_ESCAPE)
+ {
+ pBrowseMerk->BrkChangeEntry();
+ pBrowseMerk->GrabFocus();
+ }
+ else if(nKeyCode == KEY_UP || nKeyCode == KEY_DOWN)
+ {
+ pBrowseMerk->EndChangeEntry();
+ pBrowseMerk->GrabFocus();
+ pBrowseMerk->KeyInput(rKEvt);
+ }
+ else
+ Edit::KeyInput(rKEvt);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define MYBROWSEMODE (BROWSER_THUMBDRAGGING|BROWSER_KEEPHIGHLIGHT|BROWSER_NO_HSCROLL|BROWSER_HIDECURSOR)
+
+_SdrItemBrowserControl::_SdrItemBrowserControl(Window* pParent, WinBits nBits):
+ BrowseBox(pParent,nBits,MYBROWSEMODE),
+ aList(1024,16,16)
+{
+ ImpCtor();
+}
+
+__EXPORT _SdrItemBrowserControl::~_SdrItemBrowserControl()
+{
+ if(pEditControl)
+ delete pEditControl;
+
+ if(pAktChangeEntry)
+ delete pAktChangeEntry;
+
+ Clear();
+}
+
+void _SdrItemBrowserControl::ImpCtor()
+{
+ pEditControl = NULL;
+ pAktChangeEntry = NULL;
+ nLastWhichOfs = 0;
+ nLastWhich = 0;
+ nLastWhichOben = 0; // not implemented yet
+ nLastWhichUnten = 0; // not implemented yet
+ bWhichesButNames = FALSE;
+ bDontHideIneffectiveItems = FALSE;
+ bDontSortItems = FALSE;
+ bShowWhichIds = FALSE;
+ bShowRealValues = FALSE;
+ bShowWhichIds = TRUE; // not implemented yet
+ bShowRealValues = TRUE; // not implemented yet
+
+ rtl_TextEncoding aTextEncoding = gsl_getSystemTextEncoding();
+
+ InsertDataColumn(
+ ITEMBROWSER_WHICHCOL_ID,
+ String("Which", aTextEncoding),
+ GetTextWidth(String(" Which ", aTextEncoding)) + 2);
+ InsertDataColumn(
+ ITEMBROWSER_STATECOL_ID,
+ String("State", aTextEncoding),
+ Max(GetTextWidth(String(" State ", aTextEncoding)) + 2 ,
+ GetTextWidth(String("DontCare", aTextEncoding)) + 2));
+ InsertDataColumn(
+ ITEMBROWSER_TYPECOL_ID ,
+ String("Type", aTextEncoding),
+ GetTextWidth(String(" Type_ ", aTextEncoding)) + 2);
+ InsertDataColumn(
+ ITEMBROWSER_NAMECOL_ID ,
+ String("Name", aTextEncoding),
+ 150);
+ InsertDataColumn(
+ ITEMBROWSER_VALUECOL_ID,
+ String("Value", aTextEncoding),
+ GetTextWidth(String("12345678901234567890", aTextEncoding)));
+ SetDataRowHeight(
+ GetTextHeight());
+
+ long nWdt=GetColumnWidth(ITEMBROWSER_WHICHCOL_ID)+
+ GetColumnWidth(ITEMBROWSER_STATECOL_ID)+
+ GetColumnWidth(ITEMBROWSER_TYPECOL_ID )+
+ GetColumnWidth(ITEMBROWSER_NAMECOL_ID )+
+ GetColumnWidth(ITEMBROWSER_VALUECOL_ID);
+
+ long nHgt=GetTitleHeight()+16*GetDataRowHeight();
+
+ SetOutputSizePixel(Size(nWdt,nHgt));
+}
+
+void _SdrItemBrowserControl::Clear()
+{
+ ULONG nAnz=aList.Count();
+ for (ULONG nNum=0; nNum<nAnz; nNum++) {
+ delete ImpGetEntry(nNum);
+ }
+ aList.Clear();
+ BrowseBox::Clear();
+}
+
+long __EXPORT _SdrItemBrowserControl::GetRowCount() const
+{
+ return aList.Count();
+}
+
+BOOL __EXPORT _SdrItemBrowserControl::SeekRow(long nRow)
+{
+ nAktPaintRow=nRow;
+ return TRUE;
+}
+
+String _SdrItemBrowserControl::GetCellText(long _nRow, USHORT _nColId) const
+{
+ String sRet;
+ if ( _nRow >= 0 && _nRow < (sal_Int32)aList.Count() )
+ {
+ ImpItemListRow* pEntry = ImpGetEntry(_nRow);
+ if ( pEntry )
+ {
+ if ( pEntry->bComment )
+ {
+ if (_nColId == ITEMBROWSER_NAMECOL_ID)
+ sRet = pEntry->aName;
+ }
+ else
+ {
+ rtl_TextEncoding aTextEncoding = gsl_getSystemTextEncoding();
+
+ sRet = XubString("???", aTextEncoding);
+ switch (_nColId)
+ {
+ case ITEMBROWSER_WHICHCOL_ID:
+ sRet = UniString::CreateFromInt32(pEntry->nWhichId); break;
+ case ITEMBROWSER_STATECOL_ID:
+ {
+ switch (pEntry->eState)
+ {
+ case SFX_ITEM_UNKNOWN : sRet=String("Uknown", aTextEncoding); break;
+ case SFX_ITEM_DISABLED: sRet=String("Disabled", aTextEncoding); break;
+ case SFX_ITEM_DONTCARE: sRet=String("DontCare", aTextEncoding); break;
+ case SFX_ITEM_SET : sRet=String("Set", aTextEncoding); break;
+ case SFX_ITEM_DEFAULT : sRet=String("Default", aTextEncoding); break;
+ } // switch
+ } break;
+ case ITEMBROWSER_TYPECOL_ID: sRet = pEntry->GetItemTypeStr(); break;
+ case ITEMBROWSER_NAMECOL_ID: sRet = pEntry->aName; break;
+ case ITEMBROWSER_VALUECOL_ID: sRet = pEntry->aValue; break;
+ } // switch
+ }
+ }
+ }
+ return sRet;
+}
+
+void __EXPORT _SdrItemBrowserControl::PaintField(OutputDevice& rDev, const Rectangle& rRect, USHORT nColumnId) const
+{
+ if (nAktPaintRow<0 || (ULONG)nAktPaintRow>=aList.Count()) {
+ return;
+ }
+ Rectangle aR(rRect);
+ aR.Bottom()++;
+ ImpItemListRow* pEntry=ImpGetEntry(nAktPaintRow);
+ if (pEntry->bComment)
+ {
+ if (nColumnId==ITEMBROWSER_NAMECOL_ID)
+ {
+ rDev.SetLineColor();
+ rDev.SetFillColor( Color( COL_LIGHTGRAY ) );
+ aR.Left()=0;
+ aR.Right()=rDev.GetOutputSize().Width();
+ rDev.DrawRect(aR);
+ rDev.DrawText(rRect.TopLeft(),pEntry->aName);
+ }
+ } else {
+ rDev.SetClipRegion(aR);
+ rDev.DrawText(aR.TopLeft(),GetCellText(nAktPaintRow,nColumnId));
+ rDev.SetClipRegion();
+ }
+}
+
+ULONG _SdrItemBrowserControl::GetCurrentPos() const
+{
+ ULONG nRet=CONTAINER_ENTRY_NOTFOUND;
+ if (GetSelectRowCount()==1) {
+ long nPos=((BrowseBox*)this)->FirstSelectedRow();
+ if (nPos>=0 && (ULONG)nPos<aList.Count()) {
+ nRet=(ULONG)nPos;
+ }
+ }
+ return nRet;
+}
+
+USHORT _SdrItemBrowserControl::GetCurrentWhich() const
+{
+ USHORT nRet=0;
+ ULONG nPos=GetCurrentPos();
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ nRet=ImpGetEntry(nPos)->nWhichId;
+ }
+ return nRet;
+}
+
+void __EXPORT _SdrItemBrowserControl::DoubleClick(const BrowserMouseEvent&)
+{
+ ULONG nPos=GetCurrentPos();
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ BegChangeEntry(nPos);
+ }
+}
+
+void __EXPORT _SdrItemBrowserControl::KeyInput(const KeyEvent& rKEvt)
+{
+ USHORT nKeyCode=rKEvt.GetKeyCode().GetCode()+rKEvt.GetKeyCode().GetModifier();
+ FASTBOOL bAusgewertet=FALSE;
+ ULONG nPos=GetCurrentPos();
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ if (nKeyCode==KEY_RETURN) {
+ if (BegChangeEntry(nPos)) bAusgewertet=TRUE;
+ } else if (nKeyCode==KEY_ESCAPE) {
+ // ...
+ } else if (rKEvt.GetKeyCode().GetModifier()==KEY_SHIFT+KEY_MOD1+KEY_MOD2) { // Strg
+ if (nKeyCode==KEY_SHIFT+KEY_MOD1+KEY_MOD2+KEY_W) {
+ bWhichesButNames=!bWhichesButNames;
+ SetDirty();
+ }
+ if (nKeyCode==KEY_SHIFT+KEY_MOD1+KEY_MOD2+KEY_I) {
+ bDontHideIneffectiveItems=!bDontHideIneffectiveItems;
+ SetDirty();
+ }
+ if (nKeyCode==KEY_SHIFT+KEY_MOD1+KEY_MOD2+KEY_S) {
+ bDontSortItems=!bDontSortItems;
+ SetDirty();
+ }
+ }
+ }
+ if (!bAusgewertet) BrowseBox::KeyInput(rKEvt);
+}
+
+void _SdrItemBrowserControl::SetDirty()
+{
+ aSetDirtyHdl.Call(this);
+}
+
+Rectangle _SdrItemBrowserControl::GetFieldCharacterBounds(sal_Int32 /*_nRow*/,sal_Int32 /*_nColumnPos*/,sal_Int32 /*nIndex*/)
+{
+ // no accessibility implementation required
+ return Rectangle();
+}
+
+sal_Int32 _SdrItemBrowserControl::GetFieldIndexAtPoint(sal_Int32 /*_nRow*/,sal_Int32 /*_nColumnPos*/,const Point& /*_rPoint*/)
+{
+ // no accessibility implementation required
+ return -1;
+}
+
+void __EXPORT _SdrItemBrowserControl::Select()
+{
+ EndChangeEntry();
+ BrowseBox::Select();
+ ImpSaveWhich();
+}
+
+void _SdrItemBrowserControl::ImpSaveWhich()
+{
+ USHORT nWh=GetCurrentWhich();
+ if (nWh!=0) {
+ long nPos=GetCurrentPos();
+ long nTop=GetTopRow();
+ long nBtm=GetTopRow()+GetVisibleRows()+1;
+ nLastWhich=nWh;
+ nLastWhichOfs=nPos-nTop;
+ if (nTop<0) nTop=0;
+ if (nBtm>=(long)aList.Count()) nBtm=aList.Count()-1;
+ nLastWhichOben=ImpGetEntry(nTop)->nWhichId;
+ nLastWhichUnten=ImpGetEntry(nBtm)->nWhichId;
+ }
+}
+
+void _SdrItemBrowserControl::ImpRestoreWhich()
+{
+ if (nLastWhich!=0) {
+ FASTBOOL bFnd=FALSE;
+ USHORT nBestMinWh=0,nBestMaxWh=0xFFFF; // not implemented yet
+ ULONG nBestMinPos=0,nBestMaxPos=0xFFFFFFFF; // not implemented yet
+ ULONG nAnz=aList.Count();
+ ULONG nNum;
+ for (nNum=0; nNum<nAnz && !bFnd; nNum++) {
+ ImpItemListRow* pEntry=ImpGetEntry(nNum);
+ if (!pEntry->bComment) {
+ USHORT nWh=pEntry->nWhichId;
+ if (nWh==nLastWhich) bFnd=TRUE;
+ else if (nWh<nLastWhich && nWh>nBestMinWh) nBestMinPos=nNum;
+ else if (nWh>nLastWhich && nWh<nBestMaxWh) nBestMaxPos=nNum;
+ }
+ }
+ if (bFnd) {
+ long nPos=nNum-1;
+ long nWhichOfs=nPos-GetTopRow();
+ if (nWhichOfs!=nLastWhichOfs) {
+ ScrollRows(nWhichOfs-nLastWhichOfs);
+ }
+ GoToRow(nPos);
+ }
+ }
+}
+
+FASTBOOL _SdrItemBrowserControl::BegChangeEntry(ULONG nPos)
+{
+ BrkChangeEntry();
+ FASTBOOL bRet=FALSE;
+ ImpItemListRow* pEntry=ImpGetEntry(nPos);
+ if (pEntry!=NULL && !pEntry->bComment) {
+ SetMode(MYBROWSEMODE & ~BROWSER_KEEPHIGHLIGHT);
+ pEditControl=new ImpItemEdit(&GetDataWindow(),this,0/*|WB_BORDER|WB_3DLOOK*/);
+ Rectangle aRect(GetFieldRectPixel(nPos,ITEMBROWSER_VALUECOL_ID,FALSE));
+ aRect.Left()+=2; // Kleiner Offset fuer's Edit, damit's pixelgenau stimmt
+ aRect.Right()--;
+ pEditControl->SetPosSizePixel(aRect.TopLeft(),aRect.GetSize());
+ pEditControl->SetText(pEntry->aValue);
+ pEditControl->SetBackground( Wallpaper(Color(COL_LIGHTGRAY)));
+ Font aFont(pEditControl->GetFont());
+ aFont.SetFillColor(Color(COL_LIGHTGRAY));
+ pEditControl->SetFont(aFont);
+ pEditControl->Show();
+ pEditControl->GrabFocus();
+ pEditControl->SetSelection(Selection(SELECTION_MIN,SELECTION_MAX));
+ Window* pParent=GetParent();
+ aWNamMerk=pParent->GetText();
+ XubString aNeuNam(aWNamMerk);
+ aNeuNam += sal_Unicode(' ');
+ aNeuNam += pEntry->GetItemTypeStr();
+ if (pEntry->bCanNum) {
+ aNeuNam.AppendAscii(": ");
+ aNeuNam += UniString::CreateFromInt32(pEntry->nMin);
+ aNeuNam.AppendAscii("..");
+ aNeuNam += UniString::CreateFromInt32(pEntry->nMax);
+ }
+ aNeuNam.AppendAscii(" - Type 'del' to reset to default.");
+ pParent->SetText(aNeuNam);
+ pAktChangeEntry=new ImpItemListRow(*pEntry);
+ bRet=TRUE;
+ }
+ return bRet;
+}
+
+FASTBOOL _SdrItemBrowserControl::EndChangeEntry()
+{
+ FASTBOOL bRet=FALSE;
+ if (pEditControl!=NULL) {
+ aEntryChangedHdl.Call(this);
+ delete pEditControl;
+ pEditControl=NULL;
+ delete pAktChangeEntry;
+ pAktChangeEntry=NULL;
+ Window* pParent=GetParent();
+ pParent->SetText(aWNamMerk);
+ SetMode(MYBROWSEMODE);
+ bRet=TRUE;
+ }
+ return bRet;
+}
+
+void _SdrItemBrowserControl::BrkChangeEntry()
+{
+ if (pEditControl!=NULL) {
+ delete pEditControl;
+ pEditControl=NULL;
+ delete pAktChangeEntry;
+ pAktChangeEntry=NULL;
+ Window* pParent=GetParent();
+ pParent->SetText(aWNamMerk);
+ SetMode(MYBROWSEMODE);
+ }
+}
+
+void _SdrItemBrowserControl::ImpSetEntry(const ImpItemListRow& rEntry, ULONG nEntryNum)
+{
+ ImpItemListRow* pAktEntry=ImpGetEntry(nEntryNum);
+ if (pAktEntry==NULL) {
+ aList.Insert(new ImpItemListRow(rEntry),CONTAINER_APPEND);
+ RowInserted(nEntryNum);
+ } else if (*pAktEntry!=rEntry) {
+ FASTBOOL bStateDiff=rEntry.eState!=pAktEntry->eState;
+ FASTBOOL bValueDiff=!rEntry.aValue.Equals(pAktEntry->aValue);
+ FASTBOOL bAllDiff=TRUE;
+ if (bStateDiff || bValueDiff) {
+ // Checken, ob nur State und/oder Value geaendert
+ ImpItemListRow aTest(rEntry);
+ aTest.eState=pAktEntry->eState;
+ aTest.aValue=pAktEntry->aValue;
+ if (aTest==*pAktEntry) bAllDiff=FALSE;
+ }
+ *pAktEntry=rEntry;
+ if (bAllDiff) {
+ RowModified(nEntryNum);
+ } else {
+ if (bStateDiff) RowModified(nEntryNum,ITEMBROWSER_STATECOL_ID);
+ if (bValueDiff) RowModified(nEntryNum,ITEMBROWSER_VALUECOL_ID);
+ }
+ }
+}
+
+FASTBOOL ImpGetItem(const SfxItemSet& rSet, USHORT nWhich, const SfxPoolItem*& rpItem)
+{
+ SfxItemState eState=rSet.GetItemState(nWhich,TRUE,&rpItem);
+ if (eState==SFX_ITEM_DEFAULT) {
+ rpItem=&rSet.Get(nWhich);
+ }
+ return (eState==SFX_ITEM_DEFAULT || eState==SFX_ITEM_SET) && rpItem!=NULL;
+}
+
+FASTBOOL IsItemIneffective(USHORT nWhich, const SfxItemSet* pSet, USHORT& rIndent)
+{
+ rIndent=0;
+ if (pSet==NULL) return FALSE;
+ const SfxPoolItem* pItem=NULL;
+ FASTBOOL bRet=FALSE;
+ switch (nWhich) {
+ case XATTR_LINEDASH :
+ case XATTR_LINEWIDTH :
+ case XATTR_LINECOLOR :
+ case XATTR_LINESTART :
+ case XATTR_LINEEND :
+ case XATTR_LINESTARTWIDTH :
+ case XATTR_LINEENDWIDTH :
+ case XATTR_LINESTARTCENTER :
+ case XATTR_LINEENDCENTER :
+ case XATTR_LINETRANSPARENCE : {
+ rIndent=1;
+ if (ImpGetItem(*pSet,XATTR_LINESTYLE,pItem)) {
+ XLineStyle eLineStyle=((const XLineStyleItem*)pItem)->GetValue();
+ if (eLineStyle==XLINE_NONE) return TRUE;
+ if (eLineStyle!=XLINE_DASH && nWhich==XATTR_LINEDASH) return TRUE;
+ }
+ if (nWhich==XATTR_LINESTART || nWhich==XATTR_LINESTARTCENTER) {
+ rIndent=2;
+ if (ImpGetItem(*pSet,XATTR_LINESTARTWIDTH,pItem)) {
+ INT32 nWdt=((const XLineStartWidthItem*)pItem)->GetValue();
+ if (nWdt==0) return TRUE;
+ }
+ }
+ if (nWhich==XATTR_LINEEND || nWhich==XATTR_LINEENDCENTER) {
+ rIndent=2;
+ if (ImpGetItem(*pSet,XATTR_LINEENDWIDTH,pItem)) {
+ INT32 nWdt=((const XLineEndWidthItem*)pItem)->GetValue();
+ if (nWdt==0) return TRUE;
+ }
+ }
+ } break;
+ case XATTR_FILLCOLOR : /*nur bei Style=Color*/
+ case XATTR_FILLGRADIENT : /*nur bei Style=Gradient*/
+ case XATTR_FILLHATCH : /*nur bei Style=Hatch*/
+ case XATTR_FILLTRANSPARENCE : /*nur bei Style=Color*/
+ case XATTR_GRADIENTSTEPCOUNT : /*nur bei Style=Gradient*/
+ case XATTR_FILLBACKGROUND : /*nur bei Style=Hatch*/
+ {
+ rIndent=1;
+ if (ImpGetItem(*pSet,XATTR_FILLSTYLE,pItem)) {
+ XFillStyle eFillStyle=((const XFillStyleItem*)pItem)->GetValue();
+ if (eFillStyle==XFILL_NONE) return TRUE;
+ // Transparenz z.Zt. nur fuer SolidFill
+ if (eFillStyle!=XFILL_SOLID && (nWhich==XATTR_FILLCOLOR || nWhich==XATTR_FILLTRANSPARENCE)) return TRUE;
+ if (eFillStyle!=XFILL_GRADIENT && (nWhich==XATTR_FILLGRADIENT || nWhich==XATTR_GRADIENTSTEPCOUNT)) return TRUE;
+ if (eFillStyle!=XFILL_HATCH && (nWhich==XATTR_FILLHATCH || nWhich==XATTR_FILLBACKGROUND)) return TRUE;
+ }
+ } break;
+ case XATTR_FILLBITMAP :
+ case XATTR_FILLBMP_TILE :
+ case XATTR_FILLBMP_POS : /* z.Zt. nur wenn TILE=TRUE */
+ case XATTR_FILLBMP_SIZEX : /* nur wenn nicht Stretch */
+ case XATTR_FILLBMP_SIZEY : /* nur wenn nicht Stretch */
+ case XATTR_FILLBMP_SIZELOG : /* nur wenn SIZELOG=FALSE zum ruecksetzen auf TRUE (alt) -> doch noch in Gebrauch */
+ case XATTR_FILLBMP_TILEOFFSETX : /* nur wenn TILE=TRUE */
+ case XATTR_FILLBMP_TILEOFFSETY : /* nur wenn TILE=TRUE */
+ case XATTR_FILLBMP_STRETCH : /* nur wenn TILE=FALSE */
+ case XATTR_FILLBMP_POSOFFSETX : /* nur wenn TILE=TRUE*/
+ case XATTR_FILLBMP_POSOFFSETY : { /* nur wenn TILE=TRUE*/
+ rIndent=1;
+ if (ImpGetItem(*pSet,XATTR_FILLSTYLE,pItem)) {
+ XFillStyle eFillStyle=((const XFillStyleItem*)pItem)->GetValue();
+ if (eFillStyle!=XFILL_BITMAP) return TRUE;
+ }
+ if (nWhich==XATTR_FILLBITMAP || nWhich==XATTR_FILLBMP_TILE) {
+ return FALSE; // immer anwaehlbar
+ }
+ FASTBOOL bTileTRUE=FALSE;
+ FASTBOOL bTileFALSE=FALSE;
+ FASTBOOL bStretchTRUE=FALSE;
+ FASTBOOL bStretchFALSE=FALSE;
+ if (ImpGetItem(*pSet,XATTR_FILLBMP_TILE,pItem)) {
+ bTileTRUE=((const XFillBmpTileItem*)pItem)->GetValue();
+ bTileFALSE=!bTileTRUE;
+ }
+ if (ImpGetItem(*pSet,XATTR_FILLBMP_STRETCH,pItem)) {
+ bStretchTRUE=((const XFillBmpStretchItem*)pItem)->GetValue();
+ bStretchFALSE=!bStretchTRUE;
+ }
+ // Stretch nicht anwaehlbar, wenn Tile=TRUE
+ if (nWhich==XATTR_FILLBMP_STRETCH) return bTileTRUE;
+ // und uebrig bleiben 7+1 Item (Unterattribute)
+ rIndent=2;
+ // Pos (enum) nicht anwaehlbar, wenn Tile=FALSE
+ if (nWhich==XATTR_FILLBMP_POS) return bTileFALSE;
+ // SizeXY nicht anwaehlbar bei Stretch=TRUE
+ if (nWhich==XATTR_FILLBMP_SIZEX || nWhich==XATTR_FILLBMP_SIZEY) {
+ return bTileFALSE && bStretchTRUE;
+ }
+ // 2 Items speziell fuer Tile
+ if (nWhich==XATTR_FILLBMP_POSOFFSETX || nWhich==XATTR_FILLBMP_POSOFFSETY) {
+ return bTileFALSE;
+ }
+ // Noch 2 Items speziell fuer Tile die sich jedoch gegenseitig ausschliessen
+ if (nWhich==XATTR_FILLBMP_TILEOFFSETX || nWhich==XATTR_FILLBMP_TILEOFFSETY) {
+ if (bTileFALSE) return TRUE;
+ USHORT nX=0,nY=0;
+ FASTBOOL bX=FALSE,bY=FALSE;
+ if (ImpGetItem(*pSet,XATTR_FILLBMP_TILEOFFSETX,pItem)) {
+ nX=((const XFillBmpTileOffsetXItem*)pItem)->GetValue();
+ bX=TRUE;
+ }
+ if (ImpGetItem(*pSet,XATTR_FILLBMP_TILEOFFSETY,pItem)) {
+ nY=((const XFillBmpTileOffsetYItem*)pItem)->GetValue();
+ bY=TRUE;
+ }
+ if (nWhich==XATTR_FILLBMP_TILEOFFSETX) {
+ if (nX!=0 || !bX) return FALSE;
+ if (nY!=0) return TRUE;
+ } else {
+ if (nY!=0 || !bY) return FALSE;
+ if (nX!=0) return TRUE;
+ }
+ }
+ // SizeLog nicht anwaehlbar bei Stretch=TRUE
+ // und sonst auch nur wenn es auf SizeLog=FALSE gesetzt ist.
+ // -> wohl doch noch in Gebrauch
+ // (TRUE ist der statische PoolDefault)
+ if (nWhich==XATTR_FILLBMP_SIZELOG) {
+ if (bTileFALSE && bStretchTRUE) return TRUE;
+ }
+ } break;
+
+ case XATTR_FORMTXTADJUST :
+ case XATTR_FORMTXTDISTANCE :
+ case XATTR_FORMTXTSTART :
+ case XATTR_FORMTXTMIRROR :
+ case XATTR_FORMTXTOUTLINE :
+ case XATTR_FORMTXTSHADOW :
+ case XATTR_FORMTXTSHDWCOLOR :
+ case XATTR_FORMTXTSHDWXVAL :
+ case XATTR_FORMTXTSHDWYVAL :
+ case XATTR_FORMTXTSTDFORM :
+ case XATTR_FORMTXTHIDEFORM :
+ case XATTR_FORMTXTSHDWTRANSP: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,XATTR_FORMTXTSTYLE,pItem)) {
+ XFormTextStyle eStyle=((const XFormTextStyleItem*)pItem)->GetValue();
+ if (eStyle==XFT_NONE) return TRUE;
+ }
+ if ((nWhich>=XATTR_FORMTXTSHDWCOLOR && nWhich<=XATTR_FORMTXTSHDWYVAL) || nWhich>=XATTR_FORMTXTSHDWTRANSP) {
+ rIndent=2;
+ if (ImpGetItem(*pSet,XATTR_FORMTXTSHADOW,pItem)) {
+ XFormTextShadow eShadow=((const XFormTextShadowItem*)pItem)->GetValue();
+ if (eShadow==XFTSHADOW_NONE) return TRUE;
+ }
+ }
+ } break;
+
+ case SDRATTR_SHADOWCOLOR :
+ case SDRATTR_SHADOWXDIST :
+ case SDRATTR_SHADOWYDIST :
+ case SDRATTR_SHADOWTRANSPARENCE:
+ case SDRATTR_SHADOW3D :
+ case SDRATTR_SHADOWPERSP : {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_SHADOW,pItem)) {
+ FASTBOOL bShadow=((const SdrShadowItem*)pItem)->GetValue();
+ if (!bShadow) return TRUE;
+ }
+ } break;
+
+ case SDRATTR_CAPTIONANGLE: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_CAPTIONFIXEDANGLE,pItem)) {
+ FASTBOOL bFixed=((const SdrCaptionFixedAngleItem*)pItem)->GetValue();
+ if (!bFixed) return TRUE;
+ }
+ } break;
+ case SDRATTR_CAPTIONESCREL:
+ case SDRATTR_CAPTIONESCABS: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_CAPTIONESCISREL,pItem)) {
+ FASTBOOL bRel=((const SdrCaptionEscIsRelItem*)pItem)->GetValue();
+ if (bRel && nWhich==SDRATTR_CAPTIONESCABS) return TRUE;
+ if (!bRel && nWhich==SDRATTR_CAPTIONESCREL) return TRUE;
+ }
+ } break;
+ case SDRATTR_CAPTIONLINELEN: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_CAPTIONFITLINELEN,pItem)) {
+ FASTBOOL bFit=((const SdrCaptionFitLineLenItem*)pItem)->GetValue();
+ if (bFit) return TRUE;
+ }
+ } break;
+
+ case SDRATTR_TEXT_MINFRAMEHEIGHT:
+ case SDRATTR_TEXT_MAXFRAMEHEIGHT: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_TEXT_AUTOGROWHEIGHT,pItem)) {
+ FASTBOOL bAutoGrow=((const SdrTextAutoGrowHeightItem*)pItem)->GetValue();
+ if (!bAutoGrow) return TRUE;
+ }
+ } break;
+ case SDRATTR_TEXT_MINFRAMEWIDTH:
+ case SDRATTR_TEXT_MAXFRAMEWIDTH: {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_TEXT_AUTOGROWWIDTH,pItem)) {
+ FASTBOOL bAutoGrow=((const SdrTextAutoGrowWidthItem*)pItem)->GetValue();
+ if (!bAutoGrow) return TRUE;
+ }
+ } break;
+ case SDRATTR_TEXT_VERTADJUST:
+ case SDRATTR_TEXT_HORZADJUST: {
+ if (ImpGetItem(*pSet,SDRATTR_TEXT_FITTOSIZE,pItem)) {
+ SdrFitToSizeType eFit=((const SdrTextFitToSizeTypeItem*)pItem)->GetValue();
+ if (eFit!=SDRTEXTFIT_NONE) return TRUE;
+ }
+ } break;
+
+ case SDRATTR_TEXT_ANIDIRECTION :
+ case SDRATTR_TEXT_ANISTARTINSIDE:
+ case SDRATTR_TEXT_ANISTOPINSIDE :
+ case SDRATTR_TEXT_ANICOUNT :
+ case SDRATTR_TEXT_ANIDELAY :
+ case SDRATTR_TEXT_ANIAMOUNT : {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_TEXT_ANIKIND,pItem)) {
+ SdrTextAniKind eAniKind=((const SdrTextAniKindItem*)pItem)->GetValue();
+ if (eAniKind==SDRTEXTANI_NONE) return TRUE;
+ if (eAniKind==SDRTEXTANI_BLINK && (nWhich==SDRATTR_TEXT_ANIDIRECTION || nWhich==SDRATTR_TEXT_ANIAMOUNT)) return TRUE;
+ if (eAniKind==SDRTEXTANI_SLIDE && (nWhich==SDRATTR_TEXT_ANISTARTINSIDE || nWhich==SDRATTR_TEXT_ANISTOPINSIDE)) return TRUE;
+ }
+ } break;
+
+ case SDRATTR_EDGELINEDELTAANZ: return TRUE;
+ case SDRATTR_EDGELINE1DELTA:
+ case SDRATTR_EDGELINE2DELTA:
+ case SDRATTR_EDGELINE3DELTA: {
+ if (ImpGetItem(*pSet,SDRATTR_EDGEKIND,pItem)) {
+ SdrEdgeKind eKind=((const SdrEdgeKindItem*)pItem)->GetValue();
+ if (eKind==SDREDGE_THREELINES) {
+ if (nWhich>SDRATTR_EDGELINE2DELTA) return TRUE;
+ else return FALSE;
+ }
+ if (eKind!=SDREDGE_ORTHOLINES && eKind!=SDREDGE_BEZIER) return TRUE;
+ }
+ if (ImpGetItem(*pSet,SDRATTR_EDGELINEDELTAANZ,pItem)) {
+ UINT16 nAnz=((const SdrEdgeLineDeltaAnzItem*)pItem)->GetValue();
+ if (nAnz==0) return TRUE;
+ if (nAnz==1 && nWhich>SDRATTR_EDGELINE1DELTA) return TRUE;
+ if (nAnz==2 && nWhich>SDRATTR_EDGELINE2DELTA) return TRUE;
+ if (nAnz==3 && nWhich>SDRATTR_EDGELINE3DELTA) return TRUE;
+ }
+ } break;
+
+ case SDRATTR_CIRCSTARTANGLE:
+ case SDRATTR_CIRCENDANGLE : {
+ rIndent=1;
+ if (ImpGetItem(*pSet,SDRATTR_CIRCKIND,pItem)) {
+ SdrCircKind eKind=((const SdrCircKindItem*)pItem)->GetValue();
+ if (eKind==SDRCIRC_FULL) return TRUE;
+ }
+ } break;
+ } // switch
+ return bRet;
+}
+
+USHORT ImpSortWhich(USHORT nWhich)
+{
+ switch (nWhich) {
+ // Line
+ case XATTR_LINESTART : nWhich=XATTR_LINETRANSPARENCE ; break;
+ case XATTR_LINEEND : nWhich=XATTR_LINESTARTWIDTH ; break;
+ case XATTR_LINESTARTWIDTH : nWhich=XATTR_LINESTART ; break;
+ case XATTR_LINEENDWIDTH : nWhich=XATTR_LINESTARTCENTER ; break;
+ case XATTR_LINESTARTCENTER : nWhich=XATTR_LINEENDWIDTH ; break;
+ case XATTR_LINEENDCENTER : nWhich=XATTR_LINEEND ; break;
+ case XATTR_LINETRANSPARENCE : nWhich=XATTR_LINEENDCENTER ; break;
+
+ // Fill
+ case XATTR_FILLBMP_POS : nWhich=XATTR_FILLBMP_STRETCH ; break;
+ case XATTR_FILLBMP_SIZEX : nWhich=XATTR_FILLBMP_POS ; break;
+ case XATTR_FILLBMP_SIZEY : nWhich=XATTR_FILLBMP_SIZEX ; break;
+ case XATTR_FILLBMP_SIZELOG : nWhich=XATTR_FILLBMP_SIZEY ; break;
+ case XATTR_FILLBMP_TILEOFFSETX : nWhich=XATTR_FILLBMP_SIZELOG ; break;
+ case XATTR_FILLBMP_TILEOFFSETY : nWhich=XATTR_FILLBMP_TILEOFFSETX ; break;
+ case XATTR_FILLBMP_STRETCH : nWhich=XATTR_FILLBMP_TILEOFFSETY ; break;
+
+ // Fontwork
+ case XATTR_FORMTXTSHADOW : nWhich=XATTR_FORMTXTSTDFORM ; break;
+ case XATTR_FORMTXTSHDWCOLOR : nWhich=XATTR_FORMTXTHIDEFORM ; break;
+ case XATTR_FORMTXTSHDWXVAL : nWhich=XATTR_FORMTXTSHADOW ; break;
+ case XATTR_FORMTXTSHDWYVAL : nWhich=XATTR_FORMTXTSHDWCOLOR ; break;
+ case XATTR_FORMTXTSTDFORM : nWhich=XATTR_FORMTXTSHDWXVAL ; break;
+ case XATTR_FORMTXTHIDEFORM : nWhich=XATTR_FORMTXTSHDWYVAL ; break;
+
+ // Misc
+ case SDRATTR_TEXT_MINFRAMEHEIGHT: nWhich=SDRATTR_TEXT_FITTOSIZE ; break;
+ case SDRATTR_TEXT_AUTOGROWHEIGHT: nWhich=SDRATTR_TEXT_LEFTDIST ; break;
+ case SDRATTR_TEXT_FITTOSIZE : nWhich=SDRATTR_TEXT_RIGHTDIST ; break;
+ case SDRATTR_TEXT_LEFTDIST : nWhich=SDRATTR_TEXT_UPPERDIST ; break;
+ case SDRATTR_TEXT_RIGHTDIST : nWhich=SDRATTR_TEXT_LOWERDIST ; break;
+ case SDRATTR_TEXT_UPPERDIST : nWhich=SDRATTR_TEXT_AUTOGROWWIDTH ; break;
+ case SDRATTR_TEXT_LOWERDIST : nWhich=SDRATTR_TEXT_MINFRAMEWIDTH ; break;
+ case SDRATTR_TEXT_VERTADJUST : nWhich=SDRATTR_TEXT_MAXFRAMEWIDTH ; break;
+ case SDRATTR_TEXT_MAXFRAMEHEIGHT: nWhich=SDRATTR_TEXT_AUTOGROWHEIGHT; break;
+ case SDRATTR_TEXT_MINFRAMEWIDTH : nWhich=SDRATTR_TEXT_MINFRAMEHEIGHT; break;
+ case SDRATTR_TEXT_MAXFRAMEWIDTH : nWhich=SDRATTR_TEXT_MAXFRAMEHEIGHT; break;
+ case SDRATTR_TEXT_AUTOGROWWIDTH : nWhich=SDRATTR_TEXT_HORZADJUST ; break;
+ case SDRATTR_TEXT_HORZADJUST : nWhich=SDRATTR_TEXT_VERTADJUST ; break;
+ } // switch
+ return nWhich;
+}
+
+#define INSERTCOMMENT(nStartId,nEndId,aStr) \
+ { if (nWhich0<nStartId && nWhich>=nStartId && nWhich<=nEndId) aCommentStr=aStr; }
+
+void _SdrItemBrowserControl::SetAttributes(const SfxItemSet* pSet, const SfxItemSet* p2ndSet)
+{
+ SetMode(MYBROWSEMODE & ~BROWSER_KEEPHIGHLIGHT);
+ if (pSet!=NULL) {
+ rtl_TextEncoding aTextEncoding = gsl_getSystemTextEncoding();
+ USHORT nEntryNum=0;
+ SfxWhichIter aIter(*pSet);
+ const SfxItemPool* pPool=pSet->GetPool();
+ USHORT nWhich0=0;
+ USHORT nWhich=aIter.FirstWhich();
+ while (nWhich!=0) {
+ // Nun erstmal etwas umsortieren
+ // Geht nur, solange keine InvalidItems, d.h. keine Luecken
+ // an dieser Stelle im Set sind
+ if (!bDontSortItems) nWhich=ImpSortWhich(nWhich);
+ SfxItemState eState=pSet->GetItemState(nWhich);
+ if (p2ndSet!=NULL) {
+ SfxItemState e2ndState=p2ndSet->GetItemState(nWhich);
+ if (eState==SFX_ITEM_DEFAULT) eState=SFX_ITEM_DISABLED;
+ else if (e2ndState==SFX_ITEM_DEFAULT) eState=SFX_ITEM_DEFAULT;
+ }
+ if (eState!=SFX_ITEM_DISABLED) {
+ const SfxPoolItem& rItem=pSet->Get(nWhich);
+ USHORT nIndent=0;
+ if (!HAS_BASE(SfxVoidItem,&rItem) && !HAS_BASE(SfxSetItem,&rItem) && (!IsItemIneffective(nWhich,pSet,nIndent) || bDontHideIneffectiveItems)) {
+ XubString aCommentStr;
+
+ INSERTCOMMENT(XATTR_LINE_FIRST,XATTR_LINE_LAST,String("L I N I E", aTextEncoding));
+ INSERTCOMMENT(XATTR_FILL_FIRST,XATTR_FILL_LAST,String("F L Ä C H E", aTextEncoding));
+ INSERTCOMMENT(XATTR_TEXT_FIRST,XATTR_TEXT_LAST,String("F O N T W O R K", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_SHADOW_FIRST,SDRATTR_SHADOW_LAST,String("S C H A T T E N", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_CAPTION_FIRST,SDRATTR_CAPTION_LAST,String("L E G E N D E", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_MISC_FIRST,SDRATTR_MISC_LAST,String("V E R S C H I E D E N E S", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_EDGE_FIRST,SDRATTR_EDGE_LAST,String("V E R B I N D E R", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_MEASURE_FIRST,SDRATTR_MEASURE_LAST,String("B E M A S S U N G", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_CIRC_FIRST,SDRATTR_CIRC_LAST,String("K R E I S", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_NOTPERSIST_FIRST,SDRATTR_NOTPERSIST_LAST,String("N O T P E R S I S T", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_MOVEX,SDRATTR_VERTSHEARONE,String("Transformationen auf alle Objekte einzeln", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_RESIZEXALL,SDRATTR_VERTSHEARALL,String("Transformationen auf alle Objekte gemeinsam", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_TRANSFORMREF1X,SDRATTR_TRANSFORMREF2Y,String("View-Referenzpunkte", aTextEncoding));
+ INSERTCOMMENT(SDRATTR_GRAF_FIRST,SDRATTR_GRAF_LAST,String("G R A F I K", aTextEncoding));
+ INSERTCOMMENT(EE_ITEMS_START,EE_ITEMS_END,String("E D I T E N G I N E", aTextEncoding));
+ INSERTCOMMENT(EE_ITEMS_END+1,EE_ITEMS_END+1,String("... by Joe Merten, JME Engineering Berlin ...", aTextEncoding));
+
+ if(aCommentStr.Len())
+ {
+ ImpItemListRow aEntry;
+ aEntry.bComment=TRUE;
+ aEntry.aName=aCommentStr;
+ ImpSetEntry(aEntry,nEntryNum);
+ nEntryNum++;
+ }
+ nWhich0=nWhich;
+ ImpItemListRow aEntry;
+ SdrItemPool::TakeItemName(nWhich, aEntry.aName);
+ nIndent*=2;
+
+ while(nIndent > 0)
+ {
+ aEntry.aName.Insert(sal_Unicode(' '), 0);
+ nIndent--;
+ }
+
+ aEntry.eState=eState;
+ aEntry.nWhichId=nWhich;
+ if (!IsInvalidItem(&rItem)) {
+ aEntry.pType=rItem.Type();
+ aEntry.nMax=0x7FFFFFFF;
+ aEntry.nMin=-aEntry.nMax;
+ aEntry.nVal=-4711;
+ if (HAS_BASE(SfxByteItem ,&rItem)) aEntry.eItemType=ITEM_BYTE;
+ else if (HAS_BASE(SfxInt16Item ,&rItem)) aEntry.eItemType=ITEM_INT16;
+ else if (HAS_BASE(SfxUInt16Item ,&rItem)) aEntry.eItemType=ITEM_UINT16;
+ else if (HAS_BASE(SfxInt32Item ,&rItem)) aEntry.eItemType=ITEM_INT32;
+ else if (HAS_BASE(SfxUInt32Item ,&rItem)) aEntry.eItemType=ITEM_UINT32;
+ else if (HAS_BASE(SfxEnumItemInterface,&rItem)) aEntry.eItemType=ITEM_ENUM;
+ else if (HAS_BASE(SfxBoolItem ,&rItem)) aEntry.eItemType=ITEM_BOOL;
+ else if (HAS_BASE(SfxFlagItem ,&rItem)) aEntry.eItemType=ITEM_FLAG;
+ else if (HAS_BASE(XColorItem ,&rItem)) aEntry.eItemType=ITEM_XCOLOR;
+ else if (HAS_BASE(SfxStringItem ,&rItem)) aEntry.eItemType=ITEM_STRING;
+ else if (HAS_BASE(SfxPointItem ,&rItem)) aEntry.eItemType=ITEM_POINT;
+ else if (HAS_BASE(SfxRectangleItem,&rItem)) aEntry.eItemType=ITEM_RECT;
+ else if (HAS_BASE(SfxRangeItem ,&rItem)) aEntry.eItemType=ITEM_RANGE;
+ else if (HAS_BASE(SdrFractionItem ,&rItem)) aEntry.eItemType=ITEM_FRACTION;
+ else if (HAS_BASE(SvxColorItem ,&rItem)) aEntry.eItemType=ITEM_COLOR;
+ else if (HAS_BASE(SvxFontItem ,&rItem)) aEntry.eItemType=ITEM_FONT;
+ else if (HAS_BASE(SvxFontHeightItem,&rItem))aEntry.eItemType=ITEM_FONTHEIGHT;
+ else if (HAS_BASE(SvxCharScaleWidthItem,&rItem)) aEntry.eItemType=ITEM_FONTWIDTH;
+ else if (HAS_BASE(SvxFieldItem ,&rItem)) aEntry.eItemType=ITEM_FIELD;
+ switch (aEntry.eItemType) {
+ case ITEM_BYTE : aEntry.bIsNum=TRUE; aEntry.nVal=((SfxByteItem &)rItem).GetValue(); aEntry.nMin=0; aEntry.nMax=255; break;
+ case ITEM_INT16 : aEntry.bIsNum=TRUE; aEntry.nVal=((SfxInt16Item &)rItem).GetValue(); aEntry.nMin=-32767; aEntry.nMax=32767; break;
+ case ITEM_UINT16 : aEntry.bIsNum=TRUE; aEntry.nVal=((SfxUInt16Item&)rItem).GetValue(); aEntry.nMin=0; aEntry.nMax=65535; break;
+ case ITEM_INT32 : aEntry.bIsNum=TRUE; aEntry.nVal=((SfxInt32Item &)rItem).GetValue(); break;
+ case ITEM_UINT32 : aEntry.bIsNum=TRUE; aEntry.nVal=((SfxUInt32Item&)rItem).GetValue(); aEntry.nMin=0; /*aEntry.nMax=0xFF...*/;break;
+ case ITEM_ENUM : aEntry.bCanNum=TRUE; aEntry.nVal=((SfxEnumItemInterface&)rItem).GetEnumValue(); aEntry.nMin=0; aEntry.nMax=((SfxEnumItemInterface&)rItem).GetValueCount()-1; break;
+ case ITEM_BOOL : aEntry.bCanNum=TRUE; aEntry.nVal=((SfxBoolItem &)rItem).GetValue(); aEntry.nMin=0; aEntry.nMax=1; break;
+ case ITEM_FLAG : aEntry.bCanNum=TRUE; aEntry.nVal=((SfxFlagItem &)rItem).GetValue(); aEntry.nMin=0; aEntry.nMax=0xFFFF; break;
+ case ITEM_FONTHEIGHT: aEntry.bCanNum=TRUE; aEntry.nVal=((SvxFontHeightItem&)rItem).GetHeight(); aEntry.nMin=0; break;
+ case ITEM_FONTWIDTH : aEntry.bCanNum=TRUE; aEntry.nVal=((SvxCharScaleWidthItem&)rItem).GetValue(); aEntry.nMin=0; aEntry.nMax=0xFFFF;break;
+ default: break;
+ } // switch
+ if (aEntry.bIsNum) aEntry.bCanNum=TRUE;
+ FASTBOOL bGetPres=TRUE;
+ if (bGetPres) {
+ rItem.GetPresentation(SFX_ITEM_PRESENTATION_NAMELESS,
+ pPool->GetMetric(nWhich),
+ SFX_MAPUNIT_MM,aEntry.aValue);
+ if (aEntry.bCanNum) {
+ aEntry.aValue.InsertAscii(": ",0);
+ aEntry.aValue.Insert(UniString::CreateFromInt32(aEntry.nVal),0);
+ }
+ } else {
+ if (aEntry.eItemType==ITEM_BOOL) aEntry.aValue.AppendAscii(aEntry.nVal!=0 ? "True" : "False");
+ else if (aEntry.bCanNum) aEntry.aValue = UniString::CreateFromInt32(aEntry.nVal);
+ else if (aEntry.eItemType==ITEM_STRING) aEntry.aValue=((SfxStringItem&)rItem).GetValue();
+ else if (aEntry.eItemType==ITEM_ENUM && nWhich!=EE_CHAR_WEIGHT) aEntry.aValue=((SfxEnumItemInterface&)rItem).GetValueTextByPos((BOOL)aEntry.nVal);
+ else aEntry.aValue = String("GPF", aTextEncoding);
+ }
+ } else {
+ aEntry.aValue = String("InvalidItem", aTextEncoding);
+ }
+ ImpSetEntry(aEntry,nEntryNum);
+ nEntryNum++;
+ }
+ }
+ nWhich=aIter.NextWhich();
+ } // while
+
+ if (aList.Count()>nEntryNum) { // evtl. noch zuviele Eintraege
+ ULONG nTooMuch=aList.Count()-nEntryNum;
+ for (ULONG nNum=0; nNum<nTooMuch; nNum++) {
+ delete ImpGetEntry(nEntryNum);
+ aList.Remove(nEntryNum);
+ }
+ RowRemoved(nEntryNum,nTooMuch);
+ }
+ } else {
+ Clear(); // wenn pSet==NULL
+ }
+ ImpRestoreWhich();
+ SetMode(MYBROWSEMODE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+_SdrItemBrowserWindow::_SdrItemBrowserWindow(Window* pParent, WinBits nBits):
+ FloatingWindow(pParent,nBits),
+ aBrowse(this)
+{
+ SetOutputSizePixel(aBrowse.GetSizePixel());
+ SetText(String("Joe's ItemBrowser", gsl_getSystemTextEncoding()));
+ aBrowse.Show();
+}
+
+__EXPORT _SdrItemBrowserWindow::~_SdrItemBrowserWindow()
+{
+}
+
+void __EXPORT _SdrItemBrowserWindow::Resize()
+{
+ aBrowse.SetSizePixel(GetOutputSizePixel());
+}
+
+void __EXPORT _SdrItemBrowserWindow::GetFocus()
+{
+ aBrowse.GrabFocus();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrItemBrowser::SdrItemBrowser(SdrView& rView):
+ _SdrItemBrowserWindow(ImpGetViewWin(rView)),
+ pView(&rView),
+ bDirty(FALSE)
+{
+ aIdleTimer.SetTimeoutHdl(LINK(this,SdrItemBrowser,IdleHdl));
+ GetBrowserControl().SetEntryChangedHdl(LINK(this,SdrItemBrowser,ChangedHdl));
+ GetBrowserControl().SetSetDirtyHdl(LINK(this,SdrItemBrowser,SetDirtyHdl));
+ SetDirty();
+}
+
+Window* SdrItemBrowser::ImpGetViewWin(SdrView& rView)
+{
+ const sal_uInt32 nWinCount(rView.PaintWindowCount());
+
+ for(sal_uInt32 a(0L); a < nWinCount; a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+
+ if(OUTDEV_WINDOW == pCandidate->GetOutputDevice().GetOutDevType())
+ {
+ return (Window*)(&pCandidate->GetOutputDevice());
+ }
+ }
+
+ return 0L;
+}
+
+void SdrItemBrowser::ForceParent()
+{
+ Window* pWin=ImpGetViewWin(*pView);
+ if (pWin!=NULL) SetParent(pWin);
+}
+
+void SdrItemBrowser::SetDirty()
+{
+ if (!bDirty) {
+ bDirty=TRUE;
+ aIdleTimer.SetTimeout(1);
+ aIdleTimer.Start();
+ }
+}
+
+void SdrItemBrowser::Undirty()
+{
+ aIdleTimer.Stop();
+ bDirty = FALSE;
+
+// SfxItemSet aSet(pView->GetAttributes());
+ SfxItemSet aSet(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(aSet);
+
+ if(pView->AreObjectsMarked())
+ {
+ // SfxItemSet a2ndSet(pView->GetAttributes(TRUE));
+ SfxItemSet a2ndSet(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(a2ndSet, TRUE);
+
+ SetAttributes(&aSet,&a2ndSet);
+ }
+ else
+ {
+ SetAttributes(&aSet);
+ }
+}
+
+IMPL_LINK(SdrItemBrowser,IdleHdl,Timer*,EMPTYARG)
+{
+ Undirty();
+ return 0;
+}
+
+IMPL_LINK(SdrItemBrowser,ChangedHdl,_SdrItemBrowserControl*,pBrowse)
+{
+ const ImpItemListRow* pEntry=pBrowse->GetAktChangeEntry();
+ if (pEntry!=NULL)
+ {
+// SfxItemSet aSet(pView->GetAttributes());
+ SfxItemSet aSet(pView->GetModel()->GetItemPool());
+ pView->GetAttributes(aSet);
+
+ SfxItemSet aNewSet(*aSet.GetPool(),pEntry->nWhichId,pEntry->nWhichId);
+ XubString aNewText(pBrowse->GetNewEntryValue());
+ BOOL bDel( aNewText.EqualsAscii("del")
+ || aNewText.EqualsAscii("Del")
+ || aNewText.EqualsAscii("DEL")
+ || aNewText.EqualsAscii("default")
+ || aNewText.EqualsAscii("Default")
+ || aNewText.EqualsAscii("DEFAULT"));
+
+ if (!bDel) {
+ SfxPoolItem* pNewItem=aSet.Get(pEntry->nWhichId).Clone();
+ long nLongVal=0;
+ nLongVal = aNewText.ToInt32();
+ if (pEntry->bCanNum) {
+ if (nLongVal>pEntry->nMax) nLongVal=pEntry->nMax;
+ if (nLongVal<pEntry->nMin) nLongVal=pEntry->nMin;
+ }
+ FASTBOOL bPair=FALSE;
+ FASTBOOL bPairX=TRUE;
+ FASTBOOL bPairY=FALSE;
+ USHORT nSepLen=1;
+ long nLongX = aNewText.ToInt32();
+ long nLongY=0;
+ xub_StrLen nPos = aNewText.Search(sal_Unicode('/'));
+ if (nPos==STRING_NOTFOUND) nPos=aNewText.Search(sal_Unicode(':'));
+ if (nPos==STRING_NOTFOUND) nPos=aNewText.Search(sal_Unicode(' '));
+ if (nPos==STRING_NOTFOUND) { nPos=aNewText.SearchAscii(".."); if (nPos!=STRING_NOTFOUND) nSepLen=2; }
+ if (nPos!=STRING_NOTFOUND) {
+ bPair=TRUE;
+ bPairX=nPos>0;
+ XubString s(aNewText);
+ s.Erase(0,nPos+nSepLen);
+ bPairY = (BOOL)aNewText.Len();
+ nLongY = s.ToInt32();
+ }
+ switch (pEntry->eItemType) {
+ case ITEM_BYTE : ((SfxByteItem *)pNewItem)->SetValue((BYTE )nLongVal); break;
+ case ITEM_INT16 : ((SfxInt16Item *)pNewItem)->SetValue((INT16 )nLongVal); break;
+ case ITEM_UINT16: ((SfxUInt16Item*)pNewItem)->SetValue((UINT16)nLongVal); break;
+ case ITEM_INT32: {
+ if(HAS_BASE(SdrAngleItem, pNewItem))
+ {
+ aNewText.SearchAndReplace(sal_Unicode(','), sal_Unicode('.'));
+ double nVal = aNewText.ToFloat();
+ nLongVal = (long)(nVal * 100 + 0.5);
+ }
+ ((SfxInt32Item *)pNewItem)->SetValue((INT32)nLongVal);
+ } break;
+ case ITEM_UINT32: ((SfxUInt32Item*)pNewItem)->SetValue(aNewText.ToInt32()); break;
+ case ITEM_ENUM : ((SfxEnumItemInterface*)pNewItem)->SetEnumValue((USHORT)nLongVal); break;
+ case ITEM_BOOL: {
+ aNewText.ToUpperAscii();
+ if (aNewText.EqualsAscii("TRUE")) nLongVal=1;
+ if (aNewText.EqualsAscii("JA")) nLongVal=1;
+ if (aNewText.EqualsAscii("AN")) nLongVal=1;
+ if (aNewText.EqualsAscii("EIN")) nLongVal=1;
+ if (aNewText.EqualsAscii("ON")) nLongVal=1;
+ if (aNewText.EqualsAscii("YES")) nLongVal=1;
+ ((SfxBoolItem*)pNewItem)->SetValue((BOOL)nLongVal);
+ } break;
+ case ITEM_FLAG : ((SfxFlagItem *)pNewItem)->SetValue((USHORT)nLongVal); break;
+ case ITEM_STRING: ((SfxStringItem*)pNewItem)->SetValue(aNewText); break;
+ case ITEM_POINT : ((SfxPointItem*)pNewItem)->SetValue(Point(nLongX,nLongY)); break;
+ case ITEM_RECT : break;
+ case ITEM_RANGE : {
+ ((SfxRangeItem*)pNewItem)->From()=(USHORT)nLongX;
+ ((SfxRangeItem*)pNewItem)->From()=(USHORT)nLongY;
+ } break;
+ case ITEM_LRANGE : {
+ } break;
+ case ITEM_FRACTION: {
+ if (!bPairX) nLongX=1;
+ if (!bPairY) nLongY=1;
+ ((SdrFractionItem*)pNewItem)->SetValue(Fraction(nLongX,nLongY));
+ } break;
+ case ITEM_XCOLOR: break;
+ case ITEM_COLOR: break;
+ case ITEM_FONT: {
+ ((SvxFontItem*)pNewItem)->GetFamily()=FAMILY_DONTKNOW;
+ ((SvxFontItem*)pNewItem)->GetFamilyName()=aNewText;
+ ((SvxFontItem*)pNewItem)->GetStyleName().Erase();
+ } break;
+ case ITEM_FONTHEIGHT: {
+ ULONG nHgt=0;
+ USHORT nProp=100;
+ if (aNewText.Search(sal_Unicode('%'))!=STRING_NOTFOUND) {
+ nProp=(USHORT)nLongVal;
+ } else {
+ nHgt=nLongVal;
+ }
+ ((SvxFontHeightItem*)pNewItem)->SetHeight(nHgt,nProp);
+ } break;
+ case ITEM_FONTWIDTH: {
+ USHORT nProp=100;
+ if (aNewText.Search(sal_Unicode('%'))!=STRING_NOTFOUND) {
+ nProp=(USHORT)nLongVal;
+ }
+ ((SvxCharScaleWidthItem*)pNewItem)->SetValue(nProp);
+ } break;
+ case ITEM_FIELD: break;
+ default: break;
+ } // switch
+ aNewSet.Put(*pNewItem);
+ delete pNewItem;
+ }
+ pView->SetAttributes(aNewSet,bDel);
+ }
+ return 0;
+}
+
+IMPL_LINK(SdrItemBrowser,SetDirtyHdl,_SdrItemBrowserControl*,EMPTYARG)
+{
+ SetDirty();
+ return 0;
+}
+
+
diff --git a/svx/source/svdraw/svditer.cxx b/svx/source/svdraw/svditer.cxx
new file mode 100644
index 000000000000..30c423c7178c
--- /dev/null
+++ b/svx/source/svdraw/svditer.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include "svditer.hxx"
+#include <svx/svdpage.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdmark.hxx>
+
+// #99190#
+#include <svx/scene3d.hxx>
+
+SdrObjListIter::SdrObjListIter(const SdrObjList& rObjList, SdrIterMode eMode, BOOL bReverse)
+: maObjList(1024, 64, 64),
+ mnIndex(0L),
+ mbReverse(bReverse)
+{
+ ImpProcessObjectList(rObjList, eMode, TRUE);
+ Reset();
+}
+
+SdrObjListIter::SdrObjListIter(const SdrObjList& rObjList, BOOL bUseZOrder, SdrIterMode eMode, BOOL bReverse)
+: maObjList(1024, 64, 64),
+ mnIndex(0L),
+ mbReverse(bReverse)
+{
+ ImpProcessObjectList(rObjList, eMode, bUseZOrder);
+ Reset();
+}
+
+SdrObjListIter::SdrObjListIter( const SdrObject& rObj, SdrIterMode eMode, BOOL bReverse )
+: maObjList(1024, 64, 64),
+ mnIndex(0L),
+ mbReverse(bReverse)
+{
+ if ( rObj.ISA( SdrObjGroup ) )
+ ImpProcessObjectList(*rObj.GetSubList(), eMode, TRUE);
+ else
+ maObjList.Insert( (void*)&rObj, LIST_APPEND );
+ Reset();
+}
+
+SdrObjListIter::SdrObjListIter( const SdrMarkList& rMarkList, SdrIterMode eMode, BOOL bReverse )
+: maObjList(1024, 64, 64),
+ mnIndex(0L),
+ mbReverse(bReverse)
+{
+ ImpProcessMarkList(rMarkList, eMode);
+ Reset();
+}
+
+void SdrObjListIter::ImpProcessObjectList(const SdrObjList& rObjList, SdrIterMode eMode, BOOL bUseZOrder)
+{
+ for( ULONG nIdx = 0, nCount = rObjList.GetObjCount(); nIdx < nCount; ++nIdx )
+ {
+ SdrObject* pObj = bUseZOrder ?
+ rObjList.GetObj( nIdx ) : rObjList.GetObjectForNavigationPosition( nIdx );
+ OSL_ASSERT( pObj != 0 );
+ if( pObj )
+ ImpProcessObj( pObj, eMode, bUseZOrder );
+ }
+}
+
+void SdrObjListIter::ImpProcessMarkList( const SdrMarkList& rMarkList, SdrIterMode eMode )
+{
+ for( ULONG nIdx = 0, nCount = rMarkList.GetMarkCount(); nIdx < nCount; ++nIdx )
+ if( SdrObject* pObj = rMarkList.GetMark( nIdx )->GetMarkedSdrObj() )
+ ImpProcessObj( pObj, eMode, FALSE );
+}
+
+void SdrObjListIter::ImpProcessObj(SdrObject* pObj, SdrIterMode eMode, BOOL bUseZOrder)
+{
+ bool bIsGroup = pObj->IsGroupObject();
+ // #99190# 3D objects are no group objects, IsGroupObject()
+ // only tests if pSub is not null ptr :-(
+ if( bIsGroup && pObj->ISA( E3dObject ) && !pObj->ISA( E3dScene ) )
+ bIsGroup = false;
+
+ if( !bIsGroup || (eMode != IM_DEEPNOGROUPS) )
+ maObjList.Insert( pObj, LIST_APPEND );
+
+ if( bIsGroup && (eMode != IM_FLAT) )
+ ImpProcessObjectList( *pObj->GetSubList(), eMode, bUseZOrder );
+}
diff --git a/svx/source/svdraw/svditext.hxx b/svx/source/svdraw/svditext.hxx
new file mode 100644
index 000000000000..b181b4046f9e
--- /dev/null
+++ b/svx/source/svdraw/svditext.hxx
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SVDITEXT_HXX
+#define _SVDITEXT_HXX
+
+// SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
+
+#include <editeng/editdata.hxx>
+
+
+#endif // _SVDITEXT_HXX
+
diff --git a/svx/source/svdraw/svdlayer.cxx b/svx/source/svdraw/svdlayer.cxx
new file mode 100644
index 000000000000..098c036dcad7
--- /dev/null
+++ b/svx/source/svdraw/svdlayer.cxx
@@ -0,0 +1,458 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <svx/svdlayer.hxx>
+#include <svx/svdmodel.hxx> // fuer Broadcasting
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Namen aus der Resource
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SetOfByte
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SetOfByte::IsEmpty() const
+{
+ for(sal_uInt16 i(0); i < 32; i++)
+ {
+ if(aData[i] != 0)
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+sal_Bool SetOfByte::IsFull() const
+{
+ for(sal_uInt16 i(0); i < 32; i++)
+ {
+ if(aData[i] != 0xFF)
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+sal_uInt16 SetOfByte::GetSetCount() const
+{
+ sal_uInt16 nRet(0);
+
+ for(sal_uInt16 i(0); i < 32; i++)
+ {
+ sal_uInt8 a(aData[i]);
+
+ if(a != 0)
+ {
+ if(a & 0x80) nRet++;
+ if(a & 0x40) nRet++;
+ if(a & 0x20) nRet++;
+ if(a & 0x10) nRet++;
+ if(a & 0x08) nRet++;
+ if(a & 0x04) nRet++;
+ if(a & 0x02) nRet++;
+ if(a & 0x01) nRet++;
+ }
+ }
+
+ return nRet;
+}
+
+sal_uInt8 SetOfByte::GetSetBit(sal_uInt16 nNum) const
+{
+ nNum++;
+ sal_uInt16 i(0), j(0);
+ sal_uInt16 nRet(0);
+
+ while(j < nNum && i < 256)
+ {
+ if(IsSet(sal_uInt8(i)))
+ j++;
+ i++;
+ }
+
+ if(j == nNum)
+ nRet = i - 1;
+
+ return sal_uInt8(nRet);
+}
+
+sal_uInt16 SetOfByte::GetClearCount() const
+{
+ return sal_uInt16(256 - GetSetCount());
+}
+
+sal_uInt8 SetOfByte::GetClearBit(sal_uInt16 nNum) const
+{
+ nNum++;
+ sal_uInt16 i(0), j(0);
+ sal_uInt16 nRet(0);
+
+ while(j < nNum && i < 256)
+ {
+ if(!IsSet(sal_uInt8(i)))
+ j++;
+ i++;
+ }
+
+ if(j == nNum)
+ nRet = i - 1;
+
+ return sal_uInt8(nRet);
+}
+
+void SetOfByte::operator&=(const SetOfByte& r2ndSet)
+{
+ for(sal_uInt16 i(0); i < 32; i++)
+ {
+ aData[i] &= r2ndSet.aData[i];
+ }
+}
+
+void SetOfByte::operator|=(const SetOfByte& r2ndSet)
+{
+ for(sal_uInt16 i(0); i < 32; i++)
+ {
+ aData[i] |= r2ndSet.aData[i];
+ }
+}
+
+/** initialize this set with a uno sequence of sal_Int8
+*/
+void SetOfByte::PutValue( const com::sun::star::uno::Any & rAny )
+{
+ com::sun::star::uno::Sequence< sal_Int8 > aSeq;
+ if( rAny >>= aSeq )
+ {
+ sal_Int16 nCount = (sal_Int16)aSeq.getLength();
+ if( nCount > 32 )
+ nCount = 32;
+
+ sal_Int16 nIndex;
+ for( nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ aData[nIndex] = static_cast<BYTE>(aSeq[nIndex]);
+ }
+
+ for( ; nIndex < 32; nIndex++ )
+ {
+ aData[nIndex] = 0;
+ }
+ }
+}
+
+/** returns a uno sequence of sal_Int8
+*/
+void SetOfByte::QueryValue( com::sun::star::uno::Any & rAny ) const
+{
+ sal_Int16 nNumBytesSet = 0;
+ sal_Int16 nIndex;
+ for( nIndex = 31; nIndex >= 00; nIndex-- )
+ {
+ if( 0 != aData[nIndex] )
+ {
+ nNumBytesSet = nIndex + 1;
+ break;
+ }
+ }
+
+ com::sun::star::uno::Sequence< sal_Int8 > aSeq( nNumBytesSet );
+
+ for( nIndex = 0; nIndex < nNumBytesSet; nIndex++ )
+ {
+ aSeq[nIndex] = static_cast<sal_Int8>(aData[nIndex]);
+ }
+
+ rAny <<= aSeq;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrLayer
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrLayer::SetStandardLayer(FASTBOOL bStd)
+{
+ nType=(UINT16)bStd;
+ if (bStd) {
+ aName=ImpGetResStr(STR_StandardLayerName);
+ }
+ if (pModel!=NULL) {
+ SdrHint aHint(HINT_LAYERCHG);
+ pModel->Broadcast(aHint);
+ pModel->SetChanged();
+ }
+}
+
+void SdrLayer::SetName(const XubString& rNewName)
+{
+ if(!rNewName.Equals(aName))
+ {
+ aName = rNewName;
+ nType = 0; // Userdefined
+
+ if(pModel)
+ {
+ SdrHint aHint(HINT_LAYERCHG);
+
+ pModel->Broadcast(aHint);
+ pModel->SetChanged();
+ }
+ }
+}
+
+bool SdrLayer::operator==(const SdrLayer& rCmpLayer) const
+{
+ return (nID == rCmpLayer.nID
+ && nType == rCmpLayer.nType
+ && aName.Equals(rCmpLayer.aName));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SdrLayerAdmin
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrLayerAdmin::SdrLayerAdmin(SdrLayerAdmin* pNewParent):
+ aLayer(1024,16,16),
+ aLSets(1024,16,16),
+ pModel(NULL)
+{
+ sal_Char aTextControls[] = "Controls";
+ aControlLayerName = String(aTextControls, sizeof(aTextControls-1));
+ pParent=pNewParent;
+}
+
+SdrLayerAdmin::SdrLayerAdmin(const SdrLayerAdmin& rSrcLayerAdmin):
+ aLayer(1024,16,16),
+ aLSets(1024,16,16),
+ pParent(NULL),
+ pModel(NULL)
+{
+ sal_Char aTextControls[] = "Controls";
+ aControlLayerName = String(aTextControls, sizeof(aTextControls-1));
+ *this = rSrcLayerAdmin;
+}
+
+SdrLayerAdmin::~SdrLayerAdmin()
+{
+ ClearLayer();
+}
+
+void SdrLayerAdmin::ClearLayer()
+{
+ SdrLayer* pL;
+ pL=(SdrLayer*)aLayer.First();
+ while (pL!=NULL) {
+ delete pL;
+ pL=(SdrLayer*)aLayer.Next();
+ }
+ aLayer.Clear();
+}
+
+const SdrLayerAdmin& SdrLayerAdmin::operator=(const SdrLayerAdmin& rSrcLayerAdmin)
+{
+ ClearLayer();
+ pParent=rSrcLayerAdmin.pParent;
+ USHORT i;
+ USHORT nAnz=rSrcLayerAdmin.GetLayerCount();
+ for (i=0; i<nAnz; i++) {
+ aLayer.Insert(new SdrLayer(*rSrcLayerAdmin.GetLayer(i)),CONTAINER_APPEND);
+ }
+ return *this;
+}
+
+bool SdrLayerAdmin::operator==(const SdrLayerAdmin& rCmpLayerAdmin) const
+{
+ if (pParent!=rCmpLayerAdmin.pParent ||
+ aLayer.Count()!=rCmpLayerAdmin.aLayer.Count() ||
+ aLSets.Count()!=rCmpLayerAdmin.aLSets.Count()) return FALSE;
+ FASTBOOL bOk=TRUE;
+ USHORT nAnz=GetLayerCount();
+ USHORT i=0;
+ while (bOk && i<nAnz) {
+ bOk=*GetLayer(i)==*rCmpLayerAdmin.GetLayer(i);
+ i++;
+ }
+ return bOk;
+}
+
+void SdrLayerAdmin::SetModel(SdrModel* pNewModel)
+{
+ if (pNewModel!=pModel) {
+ pModel=pNewModel;
+ USHORT nAnz=GetLayerCount();
+ USHORT i;
+ for (i=0; i<nAnz; i++) {
+ GetLayer(i)->SetModel(pNewModel);
+ }
+ }
+}
+
+void SdrLayerAdmin::Broadcast() const
+{
+ if (pModel!=NULL) {
+ SdrHint aHint(HINT_LAYERORDERCHG);
+ pModel->Broadcast(aHint);
+ pModel->SetChanged();
+ }
+}
+
+SdrLayer* SdrLayerAdmin::RemoveLayer(USHORT nPos)
+{
+ SdrLayer* pRetLayer=(SdrLayer*)(aLayer.Remove(nPos));
+ Broadcast();
+ return pRetLayer;
+}
+
+SdrLayer* SdrLayerAdmin::NewLayer(const XubString& rName, USHORT nPos)
+{
+ SdrLayerID nID=GetUniqueLayerID();
+ SdrLayer* pLay=new SdrLayer(nID,rName);
+ pLay->SetModel(pModel);
+ aLayer.Insert(pLay,nPos);
+ Broadcast();
+ return pLay;
+}
+
+SdrLayer* SdrLayerAdmin::NewStandardLayer(USHORT nPos)
+{
+ SdrLayerID nID=GetUniqueLayerID();
+ SdrLayer* pLay=new SdrLayer(nID,String());
+ pLay->SetStandardLayer();
+ pLay->SetModel(pModel);
+ aLayer.Insert(pLay,nPos);
+ Broadcast();
+ return pLay;
+}
+
+SdrLayer* SdrLayerAdmin::MoveLayer(USHORT nPos, USHORT nNewPos)
+{
+ SdrLayer* pLayer=(SdrLayer*)(aLayer.Remove(nPos));
+ if (pLayer!=NULL) {
+ aLayer.Insert(pLayer,nNewPos);
+ }
+
+ Broadcast();
+ return pLayer;
+}
+
+void SdrLayerAdmin::MoveLayer(SdrLayer* pLayer, USHORT nNewPos)
+{
+ ULONG nPos=aLayer.GetPos(pLayer);
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ aLayer.Remove(nPos);
+ aLayer.Insert(pLayer,nNewPos);
+ Broadcast();
+ }
+}
+
+USHORT SdrLayerAdmin::GetLayerPos(SdrLayer* pLayer) const
+{
+ ULONG nRet=SDRLAYER_NOTFOUND;
+ if (pLayer!=NULL) {
+ nRet=aLayer.GetPos(pLayer);
+ if (nRet==CONTAINER_ENTRY_NOTFOUND) {
+ nRet=SDRLAYER_NOTFOUND;
+ }
+ }
+ return USHORT(nRet);
+}
+
+const SdrLayer* SdrLayerAdmin::GetLayer(const XubString& rName, FASTBOOL /*bInherited*/) const
+{
+ UINT16 i(0);
+ const SdrLayer* pLay = NULL;
+
+ while(i < GetLayerCount() && !pLay)
+ {
+ if(rName.Equals(GetLayer(i)->GetName()))
+ pLay = GetLayer(i);
+ else
+ i++;
+ }
+
+ if(!pLay && pParent)
+ {
+ pLay = pParent->GetLayer(rName, TRUE);
+ }
+
+ return pLay;
+}
+
+SdrLayerID SdrLayerAdmin::GetLayerID(const XubString& rName, FASTBOOL bInherited) const
+{
+ SdrLayerID nRet=SDRLAYER_NOTFOUND;
+ const SdrLayer* pLay=GetLayer(rName,bInherited);
+ if (pLay!=NULL) nRet=pLay->GetID();
+ return nRet;
+}
+
+const SdrLayer* SdrLayerAdmin::GetLayerPerID(USHORT nID) const
+{
+ USHORT i=0;
+ const SdrLayer* pLay=NULL;
+ while (i<GetLayerCount() && pLay==NULL) {
+ if (nID==GetLayer(i)->GetID()) pLay=GetLayer(i);
+ else i++;
+ }
+ return pLay;
+}
+
+// Globale LayerID's beginnen mit 0 aufsteigend.
+// Lokale LayerID's beginnen mit 254 absteigend.
+// 255 ist reserviert fuer SDRLAYER_NOTFOUND
+
+SdrLayerID SdrLayerAdmin::GetUniqueLayerID() const
+{
+ SetOfByte aSet;
+ sal_Bool bDown = (pParent == NULL);
+ USHORT j;
+ for (j=0; j<GetLayerCount(); j++)
+ {
+ aSet.Set(GetLayer((sal_uInt16)j)->GetID());
+ }
+ SdrLayerID i;
+ if (!bDown)
+ {
+ i=254;
+ while (i && aSet.IsSet(BYTE(i)))
+ --i;
+ if (i == 0)
+ i=254;
+ }
+ else
+ {
+ i=0;
+ while (i<=254 && aSet.IsSet(BYTE(i)))
+ i++;
+ if (i>254)
+ i=0;
+ }
+ return i;
+}
+
diff --git a/svx/source/svdraw/svdmark.cxx b/svx/source/svdraw/svdmark.cxx
new file mode 100644
index 000000000000..c871865ac87b
--- /dev/null
+++ b/svx/source/svdraw/svdmark.cxx
@@ -0,0 +1,1040 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <svx/svdmark.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include "svditer.hxx"
+#include <svx/svdpagv.hxx>
+#include <svx/svdopath.hxx> // zur Abschaltung
+#include <svx/svdogrp.hxx> // des Cache bei
+#include <svx/svdorect.hxx> // GetMarkDescription
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#include <svx/obj3d.hxx>
+#include <svx/scene3d.hxx>
+#include <svl/brdcst.hxx>
+#include <svx/svdoedge.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpSdrUShortContSorter: public ContainerSorter
+{
+public:
+ ImpSdrUShortContSorter(Container& rNewCont)
+ : ContainerSorter(rNewCont)
+ {}
+
+ virtual int Compare(const void* pElem1, const void* pElem2) const;
+};
+
+int ImpSdrUShortContSorter::Compare(const void* pElem1, const void* pElem2) const
+{
+ sal_uInt16 n1((sal_uInt16)((sal_uIntPtr)pElem1));
+ sal_uInt16 n2((sal_uInt16)((sal_uIntPtr)pElem2));
+
+ return ((n1 < n2) ? (-1) : (n1 > n2) ? (1) : (0));
+}
+
+void SdrUShortCont::Sort() const
+{
+ ImpSdrUShortContSorter aSort(*((Container*)(&maArray)));
+ aSort.DoSort();
+ ((SdrUShortCont*)this)->mbSorted = sal_True;
+
+ ULONG nNum(GetCount());
+
+ if(nNum > 1)
+ {
+ nNum--;
+ sal_uInt16 nVal0 = GetObject(nNum);
+
+ while(nNum > 0)
+ {
+ nNum--;
+ sal_uInt16 nVal1 = GetObject(nNum);
+
+ if(nVal1 == nVal0)
+ {
+ ((SdrUShortCont*)this)->Remove(nNum);
+ }
+
+ nVal0 = nVal1;
+ }
+ }
+}
+
+void SdrUShortCont::CheckSort(ULONG nPos)
+{
+ ULONG nAnz(maArray.Count());
+
+ if(nPos > nAnz)
+ nPos = nAnz;
+
+ sal_uInt16 nAktVal = GetObject(nPos);
+
+ if(nPos > 0)
+ {
+ sal_uInt16 nPrevVal = GetObject(nPos - 1);
+
+ if(nPrevVal >= nAktVal)
+ mbSorted = sal_False;
+ }
+
+ if(nPos < nAnz - 1)
+ {
+ sal_uInt16 nNextVal = GetObject(nPos + 1);
+
+ if(nNextVal <= nAktVal)
+ mbSorted = sal_False;
+ }
+}
+
+std::set< sal_uInt16 > SdrUShortCont::getContainer()
+{
+ std::set< sal_uInt16 > aSet;
+
+ sal_uInt32 nAnz = maArray.Count();
+ while(nAnz)
+ aSet.insert( GetObject(--nAnz) );
+
+ return aSet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
+: mpSelectedSdrObject(pNewObj),
+ mpPageView(pNewPageView),
+ mpPoints(0L),
+ mpLines(0L),
+ mpGluePoints(0L),
+ mbCon1(sal_False),
+ mbCon2(sal_False),
+ mnUser(0)
+{
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->AddObjectUser( *this );
+ }
+}
+
+SdrMark::SdrMark(const SdrMark& rMark)
+: ObjectUser(),
+ mpSelectedSdrObject(0L),
+ mpPageView(0L),
+ mpPoints(0L),
+ mpLines(0L),
+ mpGluePoints(0L),
+ mbCon1(sal_False),
+ mbCon2(sal_False),
+ mnUser(0)
+{
+ *this = rMark;
+}
+
+SdrMark::~SdrMark()
+{
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->RemoveObjectUser( *this );
+ }
+
+ if(mpPoints)
+ {
+ delete mpPoints;
+ }
+
+ if(mpLines)
+ {
+ delete mpLines;
+ }
+
+ if(mpGluePoints)
+ {
+ delete mpGluePoints;
+ }
+}
+
+void SdrMark::ObjectInDestruction(const SdrObject& rObject)
+{
+ (void) rObject; // avoid warnings
+ OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called form object different from hosted one (!)");
+ OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still seleceted SdrObject is deleted, deselect first (!)");
+ mpSelectedSdrObject = 0L;
+}
+
+void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
+{
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->RemoveObjectUser( *this );
+ }
+
+ mpSelectedSdrObject = pNewObj;
+
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->AddObjectUser( *this );
+ }
+}
+
+SdrObject* SdrMark::GetMarkedSdrObj() const
+{
+ return mpSelectedSdrObject;
+}
+
+SdrMark& SdrMark::operator=(const SdrMark& rMark)
+{
+ SetMarkedSdrObj(rMark.mpSelectedSdrObject);
+ mpPageView = rMark.mpPageView;
+ mbCon1 = rMark.mbCon1;
+ mbCon2 = rMark.mbCon2;
+ mnUser = rMark.mnUser;
+
+ if(!rMark.mpPoints)
+ {
+ if(mpPoints)
+ {
+ delete mpPoints;
+ mpPoints = 0L;
+ }
+ }
+ else
+ {
+ if(!mpPoints)
+ {
+ mpPoints = new SdrUShortCont(*rMark.mpPoints);
+ }
+ else
+ {
+ *mpPoints = *rMark.mpPoints;
+ }
+ }
+
+ if(!rMark.mpLines)
+ {
+ if(mpLines)
+ {
+ delete mpLines;
+ mpLines = 0L;
+ }
+ }
+ else
+ {
+ if(!mpLines)
+ {
+ mpLines = new SdrUShortCont(*rMark.mpLines);
+ }
+ else
+ {
+ *mpLines = *rMark.mpLines;
+ }
+ }
+
+ if(!rMark.mpGluePoints)
+ {
+ if(mpGluePoints)
+ {
+ delete mpGluePoints;
+ mpGluePoints = 0L;
+ }
+ }
+ else
+ {
+ if(!mpGluePoints)
+ {
+ mpGluePoints = new SdrUShortCont(*rMark.mpGluePoints);
+ }
+ else
+ {
+ *mpGluePoints = *rMark.mpGluePoints;
+ }
+ }
+
+ return *this;
+}
+
+sal_Bool SdrMark::operator==(const SdrMark& rMark) const
+{
+ sal_Bool bRet(mpSelectedSdrObject == rMark.mpSelectedSdrObject && mpPageView == rMark.mpPageView && mbCon1 == rMark.mbCon1 && mbCon2 == rMark.mbCon2 && mnUser == rMark.mnUser);
+
+ if((mpPoints != 0L) != (rMark.mpPoints != 0L))
+ bRet = sal_False;
+
+ if((mpLines != 0L) != (rMark.mpLines != 0L))
+ bRet = sal_False;
+
+ if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L))
+ bRet = sal_False;
+
+ if(bRet && mpPoints && *mpPoints != *rMark.mpPoints)
+ bRet = sal_False;
+
+ if(bRet && mpLines && *mpLines != *rMark.mpLines)
+ bRet = sal_False;
+
+ if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints)
+ bRet = sal_False;
+
+ return bRet;
+}
+
+SdrPage* SdrMark::GetPage() const
+{
+ return (mpSelectedSdrObject ? mpSelectedSdrObject->GetPage() : 0);
+}
+
+SdrObjList* SdrMark::GetObjList() const
+{
+ return (mpSelectedSdrObject ? mpSelectedSdrObject->GetObjList() : 0);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpSdrMarkListSorter: public ContainerSorter
+{
+public:
+ ImpSdrMarkListSorter(Container& rNewCont)
+ : ContainerSorter(rNewCont)
+ {}
+
+ virtual int Compare(const void* pElem1, const void* pElem2) const;
+};
+
+int ImpSdrMarkListSorter::Compare(const void* pElem1, const void* pElem2) const
+{
+ SdrObject* pObj1 = ((SdrMark*)pElem1)->GetMarkedSdrObj();
+ SdrObject* pObj2 = ((SdrMark*)pElem2)->GetMarkedSdrObj();
+ SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L;
+ SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L;
+
+ if (pOL1 == pOL2)
+ {
+ // AF: Note that I reverted a change from sal_uInt32 to ULONG (made
+ // for 64bit compliance, #i78198#) because internally in SdrObject
+ // both nOrdNum and mnNavigationPosition are stored as sal_uInt32.
+ sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0);
+ sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0);
+
+ return (nObjOrd1 < nObjOrd2 ? -1 : 1);
+ }
+ else
+ {
+ return ((long)pOL1 < (long)pOL2) ? -1 : 1;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkList::ForceSort() const
+{
+ if(!mbSorted)
+ {
+ ((SdrMarkList*)this)->ImpForceSort();
+ }
+}
+
+void SdrMarkList::ImpForceSort()
+{
+ if(!mbSorted)
+ {
+ mbSorted = sal_True;
+ ULONG nAnz = maList.Count();
+
+ // remove invalid
+ if(nAnz > 0 )
+ {
+ SdrMark* pAkt = (SdrMark*)maList.First();
+ while( pAkt )
+ {
+ if(pAkt->GetMarkedSdrObj() == 0)
+ {
+ maList.Remove();
+ delete pAkt;
+ }
+ pAkt= (SdrMark*)maList.Next();
+ }
+ nAnz = maList.Count();
+ }
+
+ if(nAnz > 1)
+ {
+ ImpSdrMarkListSorter aSort(maList);
+ aSort.DoSort();
+
+ // remove duplicates
+ if(maList.Count() > 1)
+ {
+ SdrMark* pAkt = (SdrMark*)maList.Last();
+ SdrMark* pCmp = (SdrMark*)maList.Prev();
+
+ while(pCmp)
+ {
+ if(pAkt->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj() && pAkt->GetMarkedSdrObj())
+ {
+ // Con1/Con2 Merging
+ if(pCmp->IsCon1())
+ pAkt->SetCon1(sal_True);
+
+ if(pCmp->IsCon2())
+ pAkt->SetCon2(sal_True);
+
+ // pCmp loeschen.
+ maList.Remove();
+
+ delete pCmp;
+ }
+ else
+ {
+ pAkt = pCmp;
+ }
+
+ pCmp = (SdrMark*)maList.Prev();
+ }
+ }
+ }
+ }
+}
+
+void SdrMarkList::Clear()
+{
+ for(ULONG i(0L); i < GetMarkCount(); i++)
+ {
+ SdrMark* pMark = GetMark(i);
+ delete pMark;
+ }
+
+ maList.Clear();
+ SetNameDirty();
+}
+
+void SdrMarkList::operator=(const SdrMarkList& rLst)
+{
+ Clear();
+
+ for(ULONG i(0L); i < rLst.GetMarkCount(); i++)
+ {
+ SdrMark* pMark = rLst.GetMark(i);
+ SdrMark* pNeuMark = new SdrMark(*pMark);
+ maList.Insert(pNeuMark, CONTAINER_APPEND);
+ }
+
+ maMarkName = rLst.maMarkName;
+ mbNameOk = rLst.mbNameOk;
+ maPointName = rLst.maPointName;
+ mbPointNameOk = rLst.mbPointNameOk;
+ maGluePointName = rLst.maGluePointName;
+ mbGluePointNameOk = rLst.mbGluePointNameOk;
+ mbSorted = rLst.mbSorted;
+}
+
+ULONG SdrMarkList::FindObject(const SdrObject* pObj) const
+{
+ // #109658#
+ //
+ // Since relying on OrdNums is not allowed for the selection because objects in the
+ // selection may not be inserted in a list if they are e.g. modified ATM, i changed
+ // this loop to just look if the object pointer is in the selection.
+ //
+ // Problem is that GetOrdNum() which is const, internally casts to non-const and
+ // hardly sets the OrdNum member of the object (nOrdNum) to 0 (ZERO) if the object
+ // is not inserted in a object list.
+ // Since this may be by purpose and necessary somewhere else i decided that it is
+ // less dangerous to change this method then changing SdrObject::GetOrdNum().
+ if(pObj && maList.Count())
+ {
+ for(ULONG a(0L); a < maList.Count(); a++)
+ {
+ if(((SdrMark*)(maList.GetObject(a)))->GetMarkedSdrObj() == pObj)
+ {
+ return a;
+ }
+ }
+ }
+
+ return CONTAINER_ENTRY_NOTFOUND;
+}
+
+void SdrMarkList::InsertEntry(const SdrMark& rMark, sal_Bool bChkSort)
+{
+ SetNameDirty();
+ ULONG nAnz(maList.Count());
+
+ if(!bChkSort || !mbSorted || nAnz == 0)
+ {
+ if(!bChkSort)
+ mbSorted = sal_False;
+
+ maList.Insert(new SdrMark(rMark), CONTAINER_APPEND);
+ }
+ else
+ {
+ SdrMark* pLast = GetMark(ULONG(nAnz - 1));
+ const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
+ const SdrObject* pNeuObj = rMark.GetMarkedSdrObj();
+
+ if(pLastObj == pNeuObj)
+ {
+ // Aha, den gibt's schon
+ // Con1/Con2 Merging
+ if(rMark.IsCon1())
+ pLast->SetCon1(sal_True);
+
+ if(rMark.IsCon2())
+ pLast->SetCon2(sal_True);
+ }
+ else
+ {
+ SdrMark* pKopie = new SdrMark(rMark);
+ maList.Insert(pKopie, CONTAINER_APPEND);
+
+ // und nun checken, ob die Sortierung noch ok ist
+ const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L;
+ const SdrObjList* pNeuOL = pNeuObj !=0L ? pNeuObj ->GetObjList() : 0L;
+
+ if(pLastOL == pNeuOL)
+ {
+ const ULONG nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0);
+ const ULONG nNeuNum(pNeuObj !=0L ? pNeuObj ->GetOrdNum() : 0);
+
+ if(nNeuNum < nLastNum)
+ {
+ // irgendwann muss mal sortiert werden
+ mbSorted = sal_False;
+ }
+ }
+ else
+ {
+ // irgendwann muss mal sortiert werden
+ mbSorted = sal_False;
+ }
+ }
+ }
+
+ return;
+}
+
+void SdrMarkList::DeleteMark(ULONG nNum)
+{
+ SdrMark* pMark = GetMark(nNum);
+ DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry nicht gefunden");
+
+ if(pMark)
+ {
+ maList.Remove(nNum);
+ delete pMark;
+ SetNameDirty();
+ }
+}
+
+void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, ULONG nNum)
+{
+ SdrMark* pMark = GetMark(nNum);
+ DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry nicht gefunden");
+
+ if(pMark)
+ {
+ delete pMark;
+ SetNameDirty();
+ SdrMark* pKopie = new SdrMark(rNewMark);
+ maList.Replace(pKopie, nNum);
+ mbSorted = sal_False;
+ }
+}
+
+void SdrMarkList::Merge(const SdrMarkList& rSrcList, sal_Bool bReverse)
+{
+ ULONG nAnz(rSrcList.maList.Count());
+
+ if(rSrcList.mbSorted)
+ {
+ // Merging ohne ein Sort bei rSrcList zu erzwingen
+ bReverse = sal_False;
+ }
+
+ if(!bReverse)
+ {
+ for(ULONG i(0L); i < nAnz; i++)
+ {
+ SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
+ InsertEntry(*pM);
+ }
+ }
+ else
+ {
+ for(ULONG i(nAnz); i > 0;)
+ {
+ i--;
+ SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i));
+ InsertEntry(*pM);
+ }
+ }
+}
+
+sal_Bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
+{
+ sal_Bool bChgd(sal_False);
+
+ for(ULONG i(GetMarkCount()); i > 0; )
+ {
+ i--;
+ SdrMark* pMark = GetMark(i);
+
+ if(pMark->GetPageView()==&rPV)
+ {
+ maList.Remove(i);
+ delete pMark;
+ SetNameDirty();
+ bChgd = sal_True;
+ }
+ }
+
+ return bChgd;
+}
+
+sal_Bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
+{
+ sal_Bool bChgd(sal_False);
+ DeletePageView(rPV); // erstmal alle raus, dann die ganze Seite hinten dran
+ SdrObject* pObj;
+ const SdrObjList* pOL = rPV.GetObjList();
+ ULONG nObjAnz(pOL->GetObjCount());
+
+ for(ULONG nO(0L); nO < nObjAnz; nO++)
+ {
+ pObj = pOL->GetObj(nO);
+ sal_Bool bDoIt(rPV.IsObjMarkable(pObj));
+
+ if(bDoIt)
+ {
+ SdrMark* pM = new SdrMark(pObj, (SdrPageView*)&rPV);
+ maList.Insert(pM, CONTAINER_APPEND);
+ SetNameDirty();
+ bChgd = sal_True;
+ }
+ }
+
+ return bChgd;
+}
+
+const XubString& SdrMarkList::GetMarkDescription() const
+{
+ ULONG nAnz(GetMarkCount());
+
+ if(mbNameOk && 1L == nAnz)
+ {
+ // Bei Einfachselektion nur Textrahmen cachen
+ const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
+ const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj, pObj);
+
+ if(!pTextObj || !pTextObj->IsTextFrame())
+ {
+ ((SdrMarkList*)(this))->mbNameOk = sal_False;
+ }
+ }
+
+ if(!mbNameOk)
+ {
+ SdrMark* pMark = GetMark(0);
+ XubString aNam;
+
+ if(!nAnz)
+ {
+ ((SdrMarkList*)(this))->maMarkName = ImpGetResStr(STR_ObjNameNoObj);
+ }
+ else if(1L == nAnz)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
+ }
+ }
+ else
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
+ XubString aStr1;
+ sal_Bool bEq(sal_True);
+
+ for(ULONG i = 1; i < GetMarkCount() && bEq; i++)
+ {
+ SdrMark* pMark2 = GetMark(i);
+ pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
+ bEq = aNam.Equals(aStr1);
+ }
+
+ if(!bEq)
+ {
+ aNam = ImpGetResStr(STR_ObjNamePlural);
+ }
+ }
+
+ aNam.Insert(sal_Unicode(' '), 0);
+ aNam.Insert(UniString::CreateFromInt32(nAnz), 0);
+ }
+
+ ((SdrMarkList*)(this))->maMarkName = aNam;
+ ((SdrMarkList*)(this))->mbNameOk = sal_True;
+ }
+
+ return maMarkName;
+}
+
+const XubString& SdrMarkList::GetPointMarkDescription(sal_Bool bGlue) const
+{
+ sal_Bool& rNameOk = (sal_Bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk);
+ XubString& rName = (XubString&)(bGlue ? maGluePointName : maPointName);
+ ULONG nMarkAnz(GetMarkCount());
+ ULONG nMarkPtAnz(0L);
+ ULONG nMarkPtObjAnz(0L);
+ ULONG n1stMarkNum(ULONG_MAX);
+
+ for(ULONG nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++)
+ {
+ const SdrMark* pMark = GetMark(nMarkNum);
+ const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
+ ULONG nAnz(pPts ? pPts->GetCount() : 0);
+
+ if(nAnz)
+ {
+ if(n1stMarkNum == ULONG_MAX)
+ {
+ n1stMarkNum = nMarkNum;
+ }
+
+ nMarkPtAnz += nAnz;
+ nMarkPtObjAnz++;
+ }
+
+ if(nMarkPtObjAnz > 1 && rNameOk)
+ {
+ // vorzeitige Entscheidung
+ return rName;
+ }
+ }
+
+ if(rNameOk && 1L == nMarkPtObjAnz)
+ {
+ // Bei Einfachselektion nur Textrahmen cachen
+ const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
+ const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj);
+
+ if(!pTextObj || !pTextObj->IsTextFrame())
+ {
+ rNameOk = sal_False;
+ }
+ }
+
+ if(!nMarkPtObjAnz)
+ {
+ rName.Erase();
+ rNameOk = sal_True;
+ }
+ else if(!rNameOk)
+ {
+ const SdrMark* pMark = GetMark(n1stMarkNum);
+ XubString aNam;
+
+ if(1L == nMarkPtObjAnz)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam);
+ }
+ }
+ else
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam);
+ }
+
+ XubString aStr1;
+ sal_Bool bEq(sal_True);
+
+ for(ULONG i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++)
+ {
+ const SdrMark* pMark2 = GetMark(i);
+ const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
+
+ if(pPts && pPts->GetCount() && pMark2->GetMarkedSdrObj())
+ {
+ pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1);
+ bEq = aNam.Equals(aStr1);
+ }
+ }
+
+ if(!bEq)
+ {
+ aNam = ImpGetResStr(STR_ObjNamePlural);
+ }
+
+ aNam.Insert(sal_Unicode(' '), 0);
+ aNam.Insert(UniString::CreateFromInt32(nMarkPtObjAnz), 0);
+ }
+
+ XubString aStr1;
+
+ if(1L == nMarkPtAnz)
+ {
+ aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint));
+ }
+ else
+ {
+ aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints));
+ aStr1.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nMarkPtAnz));
+ }
+
+ aStr1.SearchAndReplaceAscii("%1", aNam);
+ rName = aStr1;
+ rNameOk = sal_True;
+ }
+
+ return rName;
+}
+
+sal_Bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const
+{
+ sal_Bool bFnd(sal_False);
+ Rectangle aR;
+
+ for(ULONG i(0L); i < GetMarkCount(); i++)
+ {
+ SdrMark* pMark = GetMark(i);
+
+ if(!pPV || pMark->GetPageView() == pPV)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect();
+
+ if(bFnd)
+ {
+ rRect.Union(aR);
+ }
+ else
+ {
+ rRect = aR;
+ bFnd = sal_True;
+ }
+ }
+ }
+ }
+
+ return bFnd;
+}
+
+sal_Bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const
+{
+ sal_Bool bFnd(sal_False);
+
+ for(ULONG i(0L); i < GetMarkCount(); i++)
+ {
+ SdrMark* pMark = GetMark(i);
+
+ if(!pPV || pMark->GetPageView() == pPV)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
+
+ if(bFnd)
+ {
+ rRect.Union(aR);
+ }
+ else
+ {
+ rRect = aR;
+ bFnd = sal_True;
+ }
+ }
+ }
+ }
+
+ return bFnd;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace sdr
+{
+ ViewSelection::ViewSelection()
+ : mbEdgesOfMarkedNodesDirty(sal_False)
+ {
+ }
+
+ void ViewSelection::SetEdgesOfMarkedNodesDirty()
+ {
+ if(!mbEdgesOfMarkedNodesDirty)
+ {
+ mbEdgesOfMarkedNodesDirty = sal_True;
+ maEdgesOfMarkedNodes.Clear();
+ maMarkedEdgesOfMarkedNodes.Clear();
+ maAllMarkedObjects.Clear();
+ }
+ }
+
+ const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
+ }
+
+ return maEdgesOfMarkedNodes;
+ }
+
+ const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
+ }
+
+ return maMarkedEdgesOfMarkedNodes;
+ }
+
+ const List& ViewSelection::GetAllMarkedObjects() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes();
+ }
+
+ return maAllMarkedObjects;
+ }
+
+ void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
+ {
+ if(pObj)
+ {
+ sal_Bool bIsGroup(pObj->IsGroupObject());
+
+ if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene))
+ {
+ bIsGroup = sal_False;
+ }
+
+ if(bIsGroup)
+ {
+ SdrObjList* pList = pObj->GetSubList();
+
+ for(ULONG a(0L); a < pList->GetObjCount(); a++)
+ {
+ SdrObject* pObj2 = pList->GetObj(a);
+ ImplCollectCompleteSelection(pObj2);
+ }
+ }
+
+ maAllMarkedObjects.Insert(pObj, LIST_APPEND);
+ }
+ }
+
+ void ViewSelection::ImpForceEdgesOfMarkedNodes()
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ mbEdgesOfMarkedNodesDirty = sal_False;
+ maMarkedObjectList.ForceSort();
+ maEdgesOfMarkedNodes.Clear();
+ maMarkedEdgesOfMarkedNodes.Clear();
+ maAllMarkedObjects.Clear();
+
+ // #126320# GetMarkCount after ForceSort
+ const ULONG nMarkAnz(maMarkedObjectList.GetMarkCount());
+
+ for(ULONG a(0L); a < nMarkAnz; a++)
+ {
+ SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
+
+ if(pCandidate)
+ {
+ // build transitive hull
+ ImplCollectCompleteSelection(pCandidate);
+
+ if(pCandidate->IsNode())
+ {
+ // travel over broadcaster/listener to access edges connected to the selected object
+ const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
+
+ if(pBC)
+ {
+ sal_uInt16 nLstAnz(pBC->GetListenerCount());
+
+ for(sal_uInt16 nl(0); nl < nLstAnz; nl++)
+ {
+ SfxListener* pLst = pBC->GetListener(nl);
+ SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst);
+
+ if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage())
+ {
+ SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
+
+ if(pEdge->GetConnectedNode(sal_True) == pCandidate)
+ {
+ aM.SetCon1(sal_True);
+ }
+
+ if(pEdge->GetConnectedNode(sal_False) == pCandidate)
+ {
+ aM.SetCon2(sal_True);
+ }
+
+ if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge))
+ {
+ // nachsehen, ob er selbst markiert ist
+ maEdgesOfMarkedNodes.InsertEntry(aM);
+ }
+ else
+ {
+ maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ maEdgesOfMarkedNodes.ForceSort();
+ maMarkedEdgesOfMarkedNodes.ForceSort();
+ }
+ }
+} // end of namespace sdr
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
new file mode 100644
index 000000000000..2fcdfdffbb8a
--- /dev/null
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -0,0 +1,2250 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdmodel.hxx>
+
+#include <rtl/uuid.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <osl/endian.h>
+#include <rtl/logfile.hxx>
+#include <math.h>
+#include <tools/urlobj.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <tools/string.hxx>
+#include <svl/whiter.hxx>
+#include <svx/xit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xlnstit.hxx>
+
+#include "svditext.hxx"
+#include <editeng/editeng.hxx> // Fuer EditEngine::CreatePool()
+
+#include <svx/xtable.hxx>
+
+#include "svditer.hxx"
+#include <svx/svdtrans.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdlayer.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdotext.hxx> // fuer ReformatAllTextObjects und CalcFieldValue
+#include <svx/svdetc.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdoole2.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include "svdoutlinercache.hxx"
+
+
+#include <svl/asiancfg.hxx>
+#include "editeng/fontitem.hxx"
+#include <editeng/colritem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svl/style.hxx>
+#include <tools/bigint.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/bulitem.hxx>
+#include <editeng/outlobj.hxx>
+#include "editeng/forbiddencharacterstable.hxx"
+#include <svl/zforlist.hxx>
+#include <comphelper/processfactory.hxx>
+
+// #90477#
+#include <tools/tenccvt.hxx>
+#include <unotools/syslocale.hxx>
+
+// #95114#
+#include <vcl/svapp.hxx>
+#include <svx/sdr/properties/properties.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/itemset.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+struct SdrModelImpl
+{
+ SfxUndoManager* mpUndoManager;
+ SdrUndoFactory* mpUndoFactory;
+ bool mbAllowShapePropertyChangeListener;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+DBG_NAME(SdrModel)
+TYPEINIT1(SdrModel,SfxBroadcaster);
+void SdrModel::ImpCtor(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* _pEmbeddedHelper,
+ bool bUseExtColorTable, bool bLoadRefCounts)
+{
+ mpImpl = new SdrModelImpl;
+ mpImpl->mpUndoManager=0;
+ mpImpl->mpUndoFactory=0;
+ mpImpl->mbAllowShapePropertyChangeListener=false;
+ mbInDestruction=false;
+ aObjUnit=SdrEngineDefaults::GetMapFraction();
+ eObjUnit=SdrEngineDefaults::GetMapUnit();
+ eUIUnit=FUNIT_MM;
+ aUIScale=Fraction(1,1);
+ nUIUnitKomma=0;
+ bUIOnlyKomma=FALSE;
+ pLayerAdmin=NULL;
+ pItemPool=pPool;
+ bMyPool=FALSE;
+ m_pEmbeddedHelper=_pEmbeddedHelper;
+ pDrawOutliner=NULL;
+ pHitTestOutliner=NULL;
+ pRefOutDev=NULL;
+ nProgressAkt=0;
+ nProgressMax=0;
+ nProgressOfs=0;
+ pDefaultStyleSheet=NULL;
+ pLinkManager=NULL;
+ pUndoStack=NULL;
+ pRedoStack=NULL;
+ nMaxUndoCount=16;
+ pAktUndoGroup=NULL;
+ nUndoLevel=0;
+ mbUndoEnabled=true;
+ nProgressPercent=0;
+ nLoadVersion=0;
+ bExtColorTable=FALSE;
+ mbChanged = sal_False;
+ bInfoChanged=FALSE;
+ bPagNumsDirty=FALSE;
+ bMPgNumsDirty=FALSE;
+ bPageNotValid=FALSE;
+ bSavePortable=FALSE;
+ bSaveCompressed=FALSE;
+ bSaveNative=FALSE;
+ bSwapGraphics=FALSE;
+ nSwapGraphicsMode=SDR_SWAPGRAPHICSMODE_DEFAULT;
+ bSaveOLEPreview=FALSE;
+ bPasteResize=FALSE;
+ bNoBitmapCaching=FALSE;
+ bReadOnly=FALSE;
+ nStreamCompressMode=COMPRESSMODE_NONE;
+ nStreamNumberFormat=NUMBERFORMAT_INT_BIGENDIAN;
+ nDefaultTabulator=0;
+ pColorTable=NULL;
+ pDashList=NULL;
+ pLineEndList=NULL;
+ pHatchList=NULL;
+ pGradientList=NULL;
+ pBitmapList=NULL;
+ mpNumberFormatter = NULL;
+ bTransparentTextFrames=FALSE;
+ bStarDrawPreviewMode = FALSE;
+ nStarDrawPreviewMasterPageNum = SDRPAGE_NOTFOUND;
+ pModelStorage = NULL;
+ mpForbiddenCharactersTable = NULL;
+ mbModelLocked = FALSE;
+ mpOutlinerCache = NULL;
+ mbKernAsianPunctuation = sal_False;
+ mbAddExtLeading = sal_False;
+
+ SvxAsianConfig aAsian;
+ mnCharCompressType = aAsian.GetCharDistanceCompression();
+
+#ifdef OSL_LITENDIAN
+ nStreamNumberFormat=NUMBERFORMAT_INT_LITTLEENDIAN;
+#endif
+ bExtColorTable=bUseExtColorTable;
+
+ if ( pPool == NULL )
+ {
+ pItemPool=new SdrItemPool(0L, bLoadRefCounts);
+ // Der Outliner hat keinen eigenen Pool, deshalb den der EditEngine
+ SfxItemPool* pOutlPool=EditEngine::CreatePool( bLoadRefCounts );
+ // OutlinerPool als SecondaryPool des SdrPool
+ pItemPool->SetSecondaryPool(pOutlPool);
+ // Merken, dass ich mir die beiden Pools selbst gemacht habe
+ bMyPool=TRUE;
+ }
+ pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
+
+// SJ: #95129# using static SdrEngineDefaults only if default SvxFontHeight item is not available
+ const SfxPoolItem* pPoolItem = pItemPool->GetPoolDefaultItem( EE_CHAR_FONTHEIGHT );
+ if ( pPoolItem )
+ nDefTextHgt = ((SvxFontHeightItem*)pPoolItem)->GetHeight();
+ else
+ nDefTextHgt = SdrEngineDefaults::GetFontHeight();
+
+ SetTextDefaults();
+ pLayerAdmin=new SdrLayerAdmin;
+ pLayerAdmin->SetModel(this);
+ ImpSetUIUnit();
+
+ // den DrawOutliner OnDemand erzeugen geht noch nicht, weil ich den Pool
+ // sonst nicht kriege (erst ab 302!)
+ pDrawOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
+ ImpSetOutlinerDefaults(pDrawOutliner, TRUE);
+
+ pHitTestOutliner = SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this );
+ ImpSetOutlinerDefaults(pHitTestOutliner, TRUE);
+
+ ImpCreateTables();
+}
+
+SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
+ maMaPag(1024,32,32),
+ maPages(1024,32,32)
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
+#endif
+
+ DBG_CTOR(SdrModel,NULL);
+ ImpCtor(pPool,pPers,FALSE, (FASTBOOL)bLoadRefCounts);
+}
+
+SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, sal_Bool bLoadRefCounts):
+ maMaPag(1024,32,32),
+ maPages(1024,32,32),
+ aTablePath(rPath)
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
+#endif
+
+ DBG_CTOR(SdrModel,NULL);
+ ImpCtor(pPool,pPers,FALSE, (FASTBOOL)bLoadRefCounts);
+}
+
+SdrModel::SdrModel(SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, FASTBOOL bUseExtColorTable, sal_Bool bLoadRefCounts):
+ maMaPag(1024,32,32),
+ maPages(1024,32,32)
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
+#endif
+
+ DBG_CTOR(SdrModel,NULL);
+ ImpCtor(pPool,pPers,bUseExtColorTable, (FASTBOOL)bLoadRefCounts);
+}
+
+SdrModel::SdrModel(const String& rPath, SfxItemPool* pPool, ::comphelper::IEmbeddedHelper* pPers, FASTBOOL bUseExtColorTable, sal_Bool bLoadRefCounts):
+ maMaPag(1024,32,32),
+ maPages(1024,32,32),
+ aTablePath(rPath)
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
+#endif
+
+ DBG_CTOR(SdrModel,NULL);
+ ImpCtor(pPool,pPers,bUseExtColorTable, (FASTBOOL)bLoadRefCounts);
+}
+
+SdrModel::SdrModel(const SdrModel& /*rSrcModel*/):
+ SfxBroadcaster(),
+ tools::WeakBase< SdrModel >(),
+ maMaPag(1024,32,32),
+ maPages(1024,32,32)
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::SdrModel(...)" );
+#endif
+
+ // noch nicht implementiert
+ DBG_ERROR("SdrModel::CopyCtor() ist noch nicht implementiert");
+}
+
+SdrModel::~SdrModel()
+{
+#ifdef TIMELOG
+ RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "svx", "aw93748", "SdrModel::~SdrModel(...)" );
+#endif
+
+ DBG_DTOR(SdrModel,NULL);
+
+ mbInDestruction = true;
+
+ Broadcast(SdrHint(HINT_MODELCLEARED));
+
+ delete mpOutlinerCache;
+
+ ClearUndoBuffer();
+#ifdef DBG_UTIL
+ if(pAktUndoGroup)
+ {
+ ByteString aStr("Im Dtor des SdrModel steht noch ein offenes Undo rum: \"");
+
+ aStr += ByteString(pAktUndoGroup->GetComment(), gsl_getSystemTextEncoding());
+ aStr += '\"';
+
+ DBG_ERROR(aStr.GetBuffer());
+ }
+#endif
+ if (pAktUndoGroup!=NULL)
+ delete pAktUndoGroup;
+
+ // #116168#
+ ClearModel(sal_True);
+
+ delete pLayerAdmin;
+
+ // Den DrawOutliner erst nach dem ItemPool loeschen, da
+ // der ItemPool Items des DrawOutliners referenziert !!! (<- das war mal)
+ // Wg. Problem bei Malte Reihenfolge wieder umgestellt.
+ // Loeschen des Outliners vor dem loeschen des ItemPools
+ delete pHitTestOutliner;
+ delete pDrawOutliner;
+
+ // delete StyleSheetPool, derived classes should not do this since
+ // the DrawingEngine may need it in its destrctor (SB)
+ if( mxStyleSheetPool.is() )
+ {
+ Reference< XComponent > xComponent( dynamic_cast< cppu::OWeakObject* >( mxStyleSheetPool.get() ), UNO_QUERY );
+ if( xComponent.is() ) try
+ {
+ xComponent->dispose();
+ }
+ catch( RuntimeException& )
+ {
+ }
+ mxStyleSheetPool.clear();
+ }
+
+ if (bMyPool)
+ {
+ // Pools loeschen, falls es meine sind
+ SfxItemPool* pOutlPool=pItemPool->GetSecondaryPool();
+ SfxItemPool::Free(pItemPool);
+ // Der OutlinerPool muss nach dem ItemPool plattgemacht werden, da der
+ // ItemPool SetItems enthaelt die ihrerseits Items des OutlinerPools
+ // referenzieren (Joe)
+ SfxItemPool::Free(pOutlPool);
+ }
+
+ if( mpForbiddenCharactersTable )
+ mpForbiddenCharactersTable->release();
+
+ // Tabellen, Listen und Paletten loeschen
+ if (!bExtColorTable)
+ delete pColorTable;
+ delete pDashList;
+ delete pLineEndList;
+ delete pHatchList;
+ delete pGradientList;
+ delete pBitmapList;
+
+ if(mpNumberFormatter)
+ delete mpNumberFormatter;
+
+ delete mpImpl->mpUndoFactory;
+ delete mpImpl;
+}
+
+bool SdrModel::IsInDestruction() const
+{
+ return mbInDestruction;
+}
+
+const SvNumberFormatter& SdrModel::GetNumberFormatter() const
+{
+ if(!mpNumberFormatter)
+ {
+ // use cast here since from outside view this IS a const method
+ ((SdrModel*)this)->mpNumberFormatter = new SvNumberFormatter(
+ ::comphelper::getProcessServiceFactory(), LANGUAGE_SYSTEM);
+ }
+
+ return *mpNumberFormatter;
+}
+
+// noch nicht implementiert:
+void SdrModel::operator=(const SdrModel& /*rSrcModel*/)
+{
+ DBG_ERROR("SdrModel::operator=() ist noch nicht implementiert");
+}
+
+FASTBOOL SdrModel::operator==(const SdrModel& /*rCmpModel*/) const
+{
+ DBG_ERROR("SdrModel::operator==() ist noch nicht implementiert");
+ return FALSE;
+}
+
+void SdrModel::SetSwapGraphics( FASTBOOL bSwap )
+{
+ bSwapGraphics = bSwap;
+}
+
+FASTBOOL SdrModel::IsReadOnly() const
+{
+ return bReadOnly;
+}
+
+void SdrModel::SetReadOnly(FASTBOOL bYes)
+{
+ bReadOnly=bYes;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrModel::SetMaxUndoActionCount(ULONG nAnz)
+{
+ if (nAnz<1) nAnz=1;
+ nMaxUndoCount=nAnz;
+ if (pUndoStack!=NULL) {
+ while (pUndoStack->Count()>nMaxUndoCount) {
+ delete (SfxUndoAction*) pUndoStack->Remove(pUndoStack->Count());
+ }
+ }
+}
+
+void SdrModel::ClearUndoBuffer()
+{
+ if (pUndoStack!=NULL) {
+ while (pUndoStack->Count()!=0) {
+ delete (SfxUndoAction*) pUndoStack->Remove(pUndoStack->Count()-1);
+ }
+ delete pUndoStack;
+ pUndoStack=NULL;
+ }
+ if (pRedoStack!=NULL) {
+ while (pRedoStack->Count()!=0) {
+ delete (SfxUndoAction*) pRedoStack->Remove(pRedoStack->Count()-1);
+ }
+ delete pRedoStack;
+ pRedoStack=NULL;
+ }
+}
+
+FASTBOOL SdrModel::Undo()
+{
+ FASTBOOL bRet=FALSE;
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::Undo(), method not supported with application undo manager!");
+ }
+ else
+ {
+ SfxUndoAction* pDo=(SfxUndoAction*)GetUndoAction(0);
+ if(pDo!=NULL)
+ {
+ const bool bWasUndoEnabled = mbUndoEnabled;
+ mbUndoEnabled = false;
+ pDo->Undo();
+ if(pRedoStack==NULL)
+ pRedoStack=new Container(1024,16,16);
+ pRedoStack->Insert(pUndoStack->Remove((ULONG)0),(ULONG)0);
+ mbUndoEnabled = bWasUndoEnabled;
+ }
+ }
+ return bRet;
+}
+
+FASTBOOL SdrModel::Redo()
+{
+ FASTBOOL bRet=FALSE;
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::Redo(), method not supported with application undo manager!");
+ }
+ else
+ {
+ SfxUndoAction* pDo=(SfxUndoAction*)GetRedoAction(0);
+ if(pDo!=NULL)
+ {
+ const bool bWasUndoEnabled = mbUndoEnabled;
+ mbUndoEnabled = false;
+ pDo->Redo();
+ if(pUndoStack==NULL)
+ pUndoStack=new Container(1024,16,16);
+ pUndoStack->Insert(pRedoStack->Remove((ULONG)0),(ULONG)0);
+ mbUndoEnabled = bWasUndoEnabled;
+ }
+ }
+ return bRet;
+}
+
+FASTBOOL SdrModel::Repeat(SfxRepeatTarget& rView)
+{
+ FASTBOOL bRet=FALSE;
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::Redo(), method not supported with application undo manager!");
+ }
+ else
+ {
+ SfxUndoAction* pDo=(SfxUndoAction*)GetUndoAction(0);
+ if(pDo!=NULL)
+ {
+ if(pDo->CanRepeat(rView))
+ {
+ pDo->Repeat(rView);
+ bRet=TRUE;
+ }
+ }
+ }
+ return bRet;
+}
+
+void SdrModel::ImpPostUndoAction(SdrUndoAction* pUndo)
+{
+ DBG_ASSERT( mpImpl->mpUndoManager == 0, "svx::SdrModel::ImpPostUndoAction(), method not supported with application undo manager!" );
+ if( IsUndoEnabled() )
+ {
+ if (aUndoLink.IsSet())
+ {
+ aUndoLink.Call(pUndo);
+ }
+ else
+ {
+ if (pUndoStack==NULL)
+ pUndoStack=new Container(1024,16,16);
+ pUndoStack->Insert(pUndo,(ULONG)0);
+ while (pUndoStack->Count()>nMaxUndoCount)
+ {
+ delete (SfxUndoAction*)pUndoStack->Remove(pUndoStack->Count()-1);
+ }
+ if (pRedoStack!=NULL)
+ pRedoStack->Clear();
+ }
+ }
+ else
+ {
+ delete pUndo;
+ }
+}
+
+void SdrModel::BegUndo()
+{
+ if( mpImpl->mpUndoManager )
+ {
+ const String aEmpty;
+ mpImpl->mpUndoManager->EnterListAction(aEmpty,aEmpty);
+ nUndoLevel++;
+ }
+ else if( IsUndoEnabled() )
+ {
+ if(pAktUndoGroup==NULL)
+ {
+ pAktUndoGroup = new SdrUndoGroup(*this);
+ nUndoLevel=1;
+ }
+ else
+ {
+ nUndoLevel++;
+ }
+ }
+}
+
+void SdrModel::BegUndo(const XubString& rComment)
+{
+ if( mpImpl->mpUndoManager )
+ {
+ const String aEmpty;
+ mpImpl->mpUndoManager->EnterListAction( rComment, aEmpty );
+ nUndoLevel++;
+ }
+ else if( IsUndoEnabled() )
+ {
+ BegUndo();
+ if (nUndoLevel==1)
+ {
+ pAktUndoGroup->SetComment(rComment);
+ }
+ }
+}
+
+void SdrModel::BegUndo(const XubString& rComment, const XubString& rObjDescr, SdrRepeatFunc eFunc)
+{
+ if( mpImpl->mpUndoManager )
+ {
+ String aComment(rComment);
+ if( aComment.Len() && rObjDescr.Len() )
+ {
+ String aSearchString(RTL_CONSTASCII_USTRINGPARAM("%1"));
+ aComment.SearchAndReplace(aSearchString, rObjDescr);
+ }
+ const String aEmpty;
+ mpImpl->mpUndoManager->EnterListAction( aComment,aEmpty );
+ nUndoLevel++;
+ }
+ else if( IsUndoEnabled() )
+ {
+ BegUndo();
+ if (nUndoLevel==1)
+ {
+ pAktUndoGroup->SetComment(rComment);
+ pAktUndoGroup->SetObjDescription(rObjDescr);
+ pAktUndoGroup->SetRepeatFunction(eFunc);
+ }
+ }
+}
+
+void SdrModel::BegUndo(SdrUndoGroup* pUndoGrp)
+{
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::BegUndo(), method not supported with application undo manager!" );
+ nUndoLevel++;
+ }
+ else if( IsUndoEnabled() )
+ {
+ if (pAktUndoGroup==NULL)
+ {
+ pAktUndoGroup=pUndoGrp;
+ nUndoLevel=1;
+ }
+ else
+ {
+ delete pUndoGrp;
+ nUndoLevel++;
+ }
+ }
+ else
+ {
+ delete pUndoGrp;
+ }
+}
+
+void SdrModel::EndUndo()
+{
+ DBG_ASSERT(nUndoLevel!=0,"SdrModel::EndUndo(): UndoLevel is already 0!");
+ if( mpImpl->mpUndoManager )
+ {
+ if( nUndoLevel )
+ {
+ nUndoLevel--;
+ mpImpl->mpUndoManager->LeaveListAction();
+ }
+ }
+ else
+ {
+ if(pAktUndoGroup!=NULL && IsUndoEnabled())
+ {
+ nUndoLevel--;
+ if(nUndoLevel==0)
+ {
+ if(pAktUndoGroup->GetActionCount()!=0)
+ {
+ SdrUndoAction* pUndo=pAktUndoGroup;
+ pAktUndoGroup=NULL;
+ ImpPostUndoAction(pUndo);
+ }
+ else
+ {
+ // was empty
+ delete pAktUndoGroup;
+ pAktUndoGroup=NULL;
+ }
+ }
+ }
+ }
+}
+
+void SdrModel::SetUndoComment(const XubString& rComment)
+{
+ DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is on level 0!");
+
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
+ }
+ else if( IsUndoEnabled() )
+ {
+ if(nUndoLevel==1)
+ {
+ pAktUndoGroup->SetComment(rComment);
+ }
+ }
+}
+
+void SdrModel::SetUndoComment(const XubString& rComment, const XubString& rObjDescr)
+{
+ DBG_ASSERT(nUndoLevel!=0,"SdrModel::SetUndoComment(): UndoLevel is 0!");
+ if( mpImpl->mpUndoManager )
+ {
+ DBG_ERROR("svx::SdrModel::SetUndoComment(), method not supported with application undo manager!" );
+ }
+ else
+ {
+ if (nUndoLevel==1)
+ {
+ pAktUndoGroup->SetComment(rComment);
+ pAktUndoGroup->SetObjDescription(rObjDescr);
+ }
+ }
+}
+
+void SdrModel::AddUndo(SdrUndoAction* pUndo)
+{
+ if( mpImpl->mpUndoManager )
+ {
+ mpImpl->mpUndoManager->AddUndoAction( pUndo );
+ }
+ else if( !IsUndoEnabled() )
+ {
+ delete pUndo;
+ }
+ else
+ {
+ if (pAktUndoGroup!=NULL)
+ {
+ pAktUndoGroup->AddAction(pUndo);
+ }
+ else
+ {
+ ImpPostUndoAction(pUndo);
+ }
+ }
+}
+
+void SdrModel::EnableUndo( bool bEnable )
+{
+ if( mpImpl->mpUndoManager )
+ {
+ mpImpl->mpUndoManager->EnableUndo( bEnable );
+ }
+ else
+ {
+ mbUndoEnabled = bEnable;
+ }
+}
+
+bool SdrModel::IsUndoEnabled() const
+{
+ if( mpImpl->mpUndoManager )
+ {
+ return mpImpl->mpUndoManager->IsUndoEnabled();
+ }
+ else
+ {
+ return mbUndoEnabled;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrModel::ImpCreateTables()
+{
+ // der Writer hat seinen eigenen ColorTable
+ if (!bExtColorTable) pColorTable=new XColorTable(aTablePath,(XOutdevItemPool*)pItemPool);
+ pDashList =new XDashList (aTablePath,(XOutdevItemPool*)pItemPool);
+ pLineEndList =new XLineEndList (aTablePath,(XOutdevItemPool*)pItemPool);
+ pHatchList =new XHatchList (aTablePath,(XOutdevItemPool*)pItemPool);
+ pGradientList=new XGradientList(aTablePath,(XOutdevItemPool*)pItemPool);
+ pBitmapList =new XBitmapList (aTablePath,(XOutdevItemPool*)pItemPool);
+}
+
+// #116168#
+void SdrModel::ClearModel(sal_Bool bCalledFromDestructor)
+{
+ if(bCalledFromDestructor)
+ {
+ mbInDestruction = true;
+ }
+
+ sal_Int32 i;
+ // delete all drawing pages
+ sal_Int32 nAnz=GetPageCount();
+ for (i=nAnz-1; i>=0; i--)
+ {
+ DeletePage( (USHORT)i );
+ }
+ maPages.Clear();
+ // #109538#
+ PageListChanged();
+
+ // delete all Masterpages
+ nAnz=GetMasterPageCount();
+ for(i=nAnz-1; i>=0; i--)
+ {
+ DeleteMasterPage( (USHORT)i );
+ }
+ maMaPag.Clear();
+ // #109538#
+ MasterPageListChanged();
+
+ pLayerAdmin->ClearLayer();
+}
+
+SdrModel* SdrModel::AllocModel() const
+{
+ SdrModel* pModel=new SdrModel;
+ pModel->SetScaleUnit(eObjUnit,aObjUnit);
+ return pModel;
+}
+
+SdrPage* SdrModel::AllocPage(FASTBOOL bMasterPage)
+{
+ return new SdrPage(*this,bMasterPage);
+}
+
+void SdrModel::SetTextDefaults() const
+{
+ SetTextDefaults( pItemPool, nDefTextHgt );
+}
+
+void ImpGetDefaultFontsLanguage( SvxFontItem& rLatin, SvxFontItem& rAsian, SvxFontItem& rComplex)
+{
+ const USHORT nItemCnt = 3;
+ static struct {
+ USHORT nFntType, nLanguage;
+ } aOutTypeArr[ nItemCnt ] = {
+ { DEFAULTFONT_LATIN_TEXT, LANGUAGE_ENGLISH_US },
+ { DEFAULTFONT_CJK_TEXT, LANGUAGE_ENGLISH_US },
+ { DEFAULTFONT_CTL_TEXT, LANGUAGE_ARABIC_SAUDI_ARABIA }
+ };
+ SvxFontItem* aItemArr[ nItemCnt ] = { &rLatin, &rAsian, &rComplex };
+
+ for( USHORT n = 0; n < nItemCnt; ++n )
+ {
+ Font aFnt( OutputDevice::GetDefaultFont(
+ aOutTypeArr[ n ].nFntType, aOutTypeArr[ n ].nLanguage,
+ DEFAULTFONT_FLAGS_ONLYONE, 0 ));
+ SvxFontItem* pI = aItemArr[ n ];
+ pI->GetFamily() = aFnt.GetFamily();
+ pI->GetFamilyName() = aFnt.GetName();
+ pI->GetStyleName().Erase();
+ pI->GetPitch() = aFnt.GetPitch();
+ pI->GetCharSet() = aFnt.GetCharSet();
+ }
+}
+
+void SdrModel::SetTextDefaults( SfxItemPool* pItemPool, ULONG nDefTextHgt )
+{
+ // #95114# set application-language specific dynamic pool language defaults
+ SvxFontItem aSvxFontItem( EE_CHAR_FONTINFO) ;
+ SvxFontItem aSvxFontItemCJK(EE_CHAR_FONTINFO_CJK);
+ SvxFontItem aSvxFontItemCTL(EE_CHAR_FONTINFO_CTL);
+ sal_uInt16 nLanguage(Application::GetSettings().GetLanguage());
+
+ // get DEFAULTFONT_LATIN_TEXT and set at pool as dynamic default
+ Font aFont(OutputDevice::GetDefaultFont(DEFAULTFONT_LATIN_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
+ aSvxFontItem.GetFamily() = aFont.GetFamily();
+ aSvxFontItem.GetFamilyName() = aFont.GetName();
+ aSvxFontItem.GetStyleName().Erase();
+ aSvxFontItem.GetPitch() = aFont.GetPitch();
+ aSvxFontItem.GetCharSet() = aFont.GetCharSet();
+ pItemPool->SetPoolDefaultItem(aSvxFontItem);
+
+ // get DEFAULTFONT_CJK_TEXT and set at pool as dynamic default
+ Font aFontCJK(OutputDevice::GetDefaultFont(DEFAULTFONT_CJK_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
+ aSvxFontItemCJK.GetFamily() = aFontCJK.GetFamily();
+ aSvxFontItemCJK.GetFamilyName() = aFontCJK.GetName();
+ aSvxFontItemCJK.GetStyleName().Erase();
+ aSvxFontItemCJK.GetPitch() = aFontCJK.GetPitch();
+ aSvxFontItemCJK.GetCharSet() = aFontCJK.GetCharSet();
+ pItemPool->SetPoolDefaultItem(aSvxFontItemCJK);
+
+ // get DEFAULTFONT_CTL_TEXT and set at pool as dynamic default
+ Font aFontCTL(OutputDevice::GetDefaultFont(DEFAULTFONT_CTL_TEXT, nLanguage, DEFAULTFONT_FLAGS_ONLYONE, 0));
+ aSvxFontItemCTL.GetFamily() = aFontCTL.GetFamily();
+ aSvxFontItemCTL.GetFamilyName() = aFontCTL.GetName();
+ aSvxFontItemCTL.GetStyleName().Erase();
+ aSvxFontItemCTL.GetPitch() = aFontCTL.GetPitch();
+ aSvxFontItemCTL.GetCharSet() = aFontCTL.GetCharSet();
+ pItemPool->SetPoolDefaultItem(aSvxFontItemCTL);
+
+ // set dynamic FontHeight defaults
+ pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT ) );
+ pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CJK ) );
+ pItemPool->SetPoolDefaultItem( SvxFontHeightItem(nDefTextHgt, 100, EE_CHAR_FONTHEIGHT_CTL ) );
+
+ // set FontColor defaults
+ pItemPool->SetPoolDefaultItem( SvxColorItem(SdrEngineDefaults::GetFontColor(), EE_CHAR_COLOR) );
+}
+
+SdrOutliner& SdrModel::GetDrawOutliner(const SdrTextObj* pObj) const
+{
+ pDrawOutliner->SetTextObj(pObj);
+ return *pDrawOutliner;
+}
+
+boost::shared_ptr< SdrOutliner > SdrModel::CreateDrawOutliner(const SdrTextObj* pObj)
+{
+ boost::shared_ptr< SdrOutliner > xDrawOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, this ) );
+ ImpSetOutlinerDefaults(xDrawOutliner.get(), TRUE);
+ xDrawOutliner->SetTextObj(pObj);
+ return xDrawOutliner;
+}
+
+const SdrTextObj* SdrModel::GetFormattingTextObj() const
+{
+ if (pDrawOutliner!=NULL) {
+ return pDrawOutliner->GetTextObj();
+ }
+ return NULL;
+}
+
+void SdrModel::ImpSetOutlinerDefaults( SdrOutliner* pOutliner, BOOL bInit )
+{
+ /**************************************************************************
+ * Initialisierung der Outliner fuer Textausgabe und HitTest
+ **************************************************************************/
+ if( bInit )
+ {
+ pOutliner->EraseVirtualDevice();
+ pOutliner->SetUpdateMode(FALSE);
+ pOutliner->SetEditTextObjectPool(pItemPool);
+ pOutliner->SetDefTab(nDefaultTabulator);
+ }
+
+ pOutliner->SetRefDevice(GetRefDevice());
+ pOutliner->SetForbiddenCharsTable(GetForbiddenCharsTable());
+ pOutliner->SetAsianCompressionMode( mnCharCompressType );
+ pOutliner->SetKernAsianPunctuation( IsKernAsianPunctuation() );
+ pOutliner->SetAddExtLeading( IsAddExtLeading() );
+
+ if ( !GetRefDevice() )
+ {
+ MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
+ pOutliner->SetRefMapMode(aMapMode);
+ }
+}
+
+void SdrModel::SetRefDevice(OutputDevice* pDev)
+{
+ pRefOutDev=pDev;
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ RefDeviceChanged();
+}
+
+void SdrModel::ImpReformatAllTextObjects()
+{
+ if( isLocked() )
+ return;
+
+ USHORT nAnz=GetMasterPageCount();
+ USHORT nNum;
+ for (nNum=0; nNum<nAnz; nNum++) {
+ GetMasterPage(nNum)->ReformatAllTextObjects();
+ }
+ nAnz=GetPageCount();
+ for (nNum=0; nNum<nAnz; nNum++) {
+ GetPage(nNum)->ReformatAllTextObjects();
+ }
+}
+
+/** #103122#
+ steps over all available pages and sends notify messages to
+ all edge objects that are connected to other objects so that
+ they may reposition itselfs
+*/
+void SdrModel::ImpReformatAllEdgeObjects()
+{
+ if( isLocked() )
+ return;
+
+ sal_uInt16 nAnz=GetMasterPageCount();
+ sal_uInt16 nNum;
+ for (nNum=0; nNum<nAnz; nNum++)
+ {
+ GetMasterPage(nNum)->ReformatAllEdgeObjects();
+ }
+ nAnz=GetPageCount();
+ for (nNum=0; nNum<nAnz; nNum++)
+ {
+ GetPage(nNum)->ReformatAllEdgeObjects();
+ }
+}
+
+SvStream* SdrModel::GetDocumentStream(SdrDocumentStreamInfo& /*rStreamInfo*/) const
+{
+ return NULL;
+}
+
+// Die Vorlagenattribute der Zeichenobjekte in harte Attribute verwandeln.
+void SdrModel::BurnInStyleSheetAttributes()
+{
+ USHORT nAnz=GetMasterPageCount();
+ USHORT nNum;
+ for (nNum=0; nNum<nAnz; nNum++) {
+ GetMasterPage(nNum)->BurnInStyleSheetAttributes();
+ }
+ nAnz=GetPageCount();
+ for (nNum=0; nNum<nAnz; nNum++) {
+ GetPage(nNum)->BurnInStyleSheetAttributes();
+ }
+}
+
+void SdrModel::RefDeviceChanged()
+{
+ Broadcast(SdrHint(HINT_REFDEVICECHG));
+ ImpReformatAllTextObjects();
+}
+
+void SdrModel::SetDefaultFontHeight(ULONG nVal)
+{
+ if (nVal!=nDefTextHgt) {
+ nDefTextHgt=nVal;
+ Broadcast(SdrHint(HINT_DEFFONTHGTCHG));
+ ImpReformatAllTextObjects();
+ }
+}
+
+void SdrModel::SetDefaultTabulator(USHORT nVal)
+{
+ if (nDefaultTabulator!=nVal) {
+ nDefaultTabulator=nVal;
+ Outliner& rOutliner=GetDrawOutliner();
+ rOutliner.SetDefTab(nVal);
+ Broadcast(SdrHint(HINT_DEFAULTTABCHG));
+ ImpReformatAllTextObjects();
+ }
+}
+
+void SdrModel::ImpSetUIUnit()
+{
+ if(0 == aUIScale.GetNumerator() || 0 == aUIScale.GetDenominator())
+ {
+ aUIScale = Fraction(1,1);
+ }
+
+ // set start values
+ nUIUnitKomma = 0;
+ sal_Int64 nMul(1);
+ sal_Int64 nDiv(1);
+
+ // normalize on meters resp. inch
+ switch (eObjUnit)
+ {
+ case MAP_100TH_MM : nUIUnitKomma+=5; break;
+ case MAP_10TH_MM : nUIUnitKomma+=4; break;
+ case MAP_MM : nUIUnitKomma+=3; break;
+ case MAP_CM : nUIUnitKomma+=2; break;
+ case MAP_1000TH_INCH: nUIUnitKomma+=3; break;
+ case MAP_100TH_INCH : nUIUnitKomma+=2; break;
+ case MAP_10TH_INCH : nUIUnitKomma+=1; break;
+ case MAP_INCH : nUIUnitKomma+=0; break;
+ case MAP_POINT : nDiv=72; break; // 1Pt = 1/72"
+ case MAP_TWIP : nDiv=144; nUIUnitKomma++; break; // 1Twip = 1/1440"
+ case MAP_PIXEL : break;
+ case MAP_SYSFONT : break;
+ case MAP_APPFONT : break;
+ case MAP_RELATIVE : break;
+ default: break;
+ } // switch
+
+ // 1 mile = 8 furlong = 63.360" = 1.609.344,0mm
+ // 1 furlong = 10 chains = 7.920" = 201.168,0mm
+ // 1 chain = 4 poles = 792" = 20.116,8mm
+ // 1 pole = 5 1/2 yd = 198" = 5.029,2mm
+ // 1 yd = 3 ft = 36" = 914,4mm
+ // 1 ft = 12 " = 1" = 304,8mm
+ switch (eUIUnit)
+ {
+ case FUNIT_NONE : break;
+ // Metrisch
+ case FUNIT_100TH_MM: nUIUnitKomma-=5; break;
+ case FUNIT_MM : nUIUnitKomma-=3; break;
+ case FUNIT_CM : nUIUnitKomma-=2; break;
+ case FUNIT_M : nUIUnitKomma+=0; break;
+ case FUNIT_KM : nUIUnitKomma+=3; break;
+ // Inch
+ case FUNIT_TWIP : nMul=144; nUIUnitKomma--; break; // 1Twip = 1/1440"
+ case FUNIT_POINT : nMul=72; break; // 1Pt = 1/72"
+ case FUNIT_PICA : nMul=6; break; // 1Pica = 1/6" ?
+ case FUNIT_INCH : break; // 1" = 1"
+ case FUNIT_FOOT : nDiv*=12; break; // 1Ft = 12"
+ case FUNIT_MILE : nDiv*=6336; nUIUnitKomma++; break; // 1mile = 63360"
+ // sonstiges
+ case FUNIT_CUSTOM : break;
+ case FUNIT_PERCENT: nUIUnitKomma+=2; break;
+ } // switch
+
+ // check if mapping is from metric to inch and adapt
+ const bool bMapInch(IsInch(eObjUnit));
+ const bool bUIMetr(IsMetric(eUIUnit));
+
+ if (bMapInch && bUIMetr)
+ {
+ nUIUnitKomma += 4;
+ nMul *= 254;
+ }
+
+ // check if mapping is from inch to metric and adapt
+ const bool bMapMetr(IsMetric(eObjUnit));
+ const bool bUIInch(IsInch(eUIUnit));
+
+ if (bMapMetr && bUIInch)
+ {
+ nUIUnitKomma -= 4;
+ nDiv *= 254;
+ }
+
+ // use temporary fraction for reduction (fallback to 32bit here),
+ // may need to be changed in the future, too
+ if(1 != nMul || 1 != nDiv)
+ {
+ const Fraction aTemp(static_cast< long >(nMul), static_cast< long >(nDiv));
+ nMul = aTemp.GetNumerator();
+ nDiv = aTemp.GetDenominator();
+ }
+
+ // #i89872# take Unit of Measurement into account
+ if(1 != aUIScale.GetDenominator() || 1 != aUIScale.GetNumerator())
+ {
+ // divide by UIScale
+ nMul *= aUIScale.GetDenominator();
+ nDiv *= aUIScale.GetNumerator();
+ }
+
+ // shorten trailing zeroes for dividend
+ while(0 == (nMul % 10))
+ {
+ nUIUnitKomma--;
+ nMul /= 10;
+ }
+
+ // shorten trailing zeroes for divisor
+ while(0 == (nDiv % 10))
+ {
+ nUIUnitKomma++;
+ nDiv /= 10;
+ }
+
+ // end preparations, set member values
+ aUIUnitFact = Fraction(sal_Int32(nMul), sal_Int32(nDiv));
+ bUIOnlyKomma = (nMul == nDiv);
+ TakeUnitStr(eUIUnit, aUIUnitStr);
+}
+
+void SdrModel::SetScaleUnit(MapUnit eMap, const Fraction& rFrac)
+{
+ if (eObjUnit!=eMap || aObjUnit!=rFrac) {
+ eObjUnit=eMap;
+ aObjUnit=rFrac;
+ pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
+ ImpSetUIUnit();
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::SetScaleUnit(MapUnit eMap)
+{
+ if (eObjUnit!=eMap) {
+ eObjUnit=eMap;
+ pItemPool->SetDefaultMetric((SfxMapUnit)eObjUnit);
+ ImpSetUIUnit();
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::SetScaleFraction(const Fraction& rFrac)
+{
+ if (aObjUnit!=rFrac) {
+ aObjUnit=rFrac;
+ ImpSetUIUnit();
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::SetUIUnit(FieldUnit eUnit)
+{
+ if (eUIUnit!=eUnit) {
+ eUIUnit=eUnit;
+ ImpSetUIUnit();
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::SetUIScale(const Fraction& rScale)
+{
+ if (aUIScale!=rScale) {
+ aUIScale=rScale;
+ ImpSetUIUnit();
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::SetUIUnit(FieldUnit eUnit, const Fraction& rScale)
+{
+ if (eUIUnit!=eUnit || aUIScale!=rScale) {
+ eUIUnit=eUnit;
+ aUIScale=rScale;
+ ImpSetUIUnit();
+ ImpReformatAllTextObjects(); // #40424#
+ }
+}
+
+void SdrModel::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
+{
+ switch(eUnit)
+ {
+ default:
+ case FUNIT_NONE :
+ case FUNIT_CUSTOM :
+ {
+ rStr = String();
+ break;
+ }
+ case FUNIT_100TH_MM:
+ {
+ sal_Char aText[] = "/100mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_MM :
+ {
+ sal_Char aText[] = "mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_CM :
+ {
+ sal_Char aText[] = "cm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_M :
+ {
+ rStr = String();
+ rStr += sal_Unicode('m');
+ break;
+ }
+ case FUNIT_KM :
+ {
+ sal_Char aText[] = "km";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_TWIP :
+ {
+ sal_Char aText[] = "twip";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_POINT :
+ {
+ sal_Char aText[] = "pt";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_PICA :
+ {
+ sal_Char aText[] = "pica";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_INCH :
+ {
+ rStr = String();
+ rStr += sal_Unicode('"');
+ break;
+ }
+ case FUNIT_FOOT :
+ {
+ sal_Char aText[] = "ft";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_MILE :
+ {
+ sal_Char aText[] = "mile(s)";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_PERCENT:
+ {
+ rStr = String();
+ rStr += sal_Unicode('%');
+ break;
+ }
+ }
+}
+
+void SdrModel::TakeMetricStr(long nVal, XubString& rStr, FASTBOOL bNoUnitChars, sal_Int32 nNumDigits) const
+{
+ // #i22167#
+ // change to double precision usage to not loose decimal places after comma
+ const bool bNegative(nVal < 0L);
+ SvtSysLocale aSysLoc;
+ const LocaleDataWrapper& rLoc(aSysLoc.GetLocaleData());
+ double fLocalValue(double(nVal) * double(aUIUnitFact));
+
+ if(bNegative)
+ {
+ fLocalValue = -fLocalValue;
+ }
+
+ if( -1 == nNumDigits )
+ {
+ nNumDigits = rLoc.getNumDigits();
+ }
+
+ sal_Int32 nKomma(nUIUnitKomma);
+
+ if(nKomma > nNumDigits)
+ {
+ const sal_Int32 nDiff(nKomma - nNumDigits);
+ const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
+
+ fLocalValue /= fFactor;
+ nKomma = nNumDigits;
+ }
+ else if(nKomma < nNumDigits)
+ {
+ const sal_Int32 nDiff(nNumDigits - nKomma);
+ const double fFactor(pow(10.0, static_cast<const int>(nDiff)));
+
+ fLocalValue *= fFactor;
+ nKomma = nNumDigits;
+ }
+
+ rStr = UniString::CreateFromInt32(static_cast<sal_Int32>(fLocalValue + 0.5));
+
+ if(nKomma < 0)
+ {
+ // Negatives Komma bedeutet: Nullen dran
+ sal_Int32 nAnz(-nKomma);
+
+ for(sal_Int32 i=0; i<nAnz; i++)
+ rStr += sal_Unicode('0');
+
+ nKomma = 0;
+ }
+
+ // #83257# the second condition needs to be <= since inside this loop
+ // also the leading zero is inserted.
+ if(nKomma > 0 && rStr.Len() <= nKomma)
+ {
+ // Fuer Komma evtl. vorne Nullen dran
+ sal_Int32 nAnz(nKomma - rStr.Len());
+
+ if(nAnz >= 0 && rLoc.isNumLeadingZero())
+ nAnz++;
+
+ for(sal_Int32 i=0; i<nAnz; i++)
+ rStr.Insert(sal_Unicode('0'), 0);
+ }
+
+ sal_Unicode cDec( rLoc.getNumDecimalSep().GetChar(0) );
+
+ // KommaChar einfuegen
+ sal_Int32 nVorKomma(rStr.Len() - nKomma);
+
+ if(nKomma > 0)
+ rStr.Insert(cDec, (xub_StrLen) nVorKomma);
+
+ if(!rLoc.isNumTrailingZeros())
+ {
+ while(rStr.Len() && rStr.GetChar(rStr.Len() - 1) == sal_Unicode('0'))
+ rStr.Erase(rStr.Len() - 1);
+
+ if(rStr.Len() && rStr.GetChar(rStr.Len() - 1) == cDec)
+ rStr.Erase(rStr.Len() - 1);
+ }
+
+ // ggf. Trennpunkte bei jedem Tausender einfuegen
+ if( nVorKomma > 3 )
+ {
+ String aThoSep( rLoc.getNumThousandSep() );
+ if ( aThoSep.Len() > 0 )
+ {
+ sal_Unicode cTho( aThoSep.GetChar(0) );
+ sal_Int32 i(nVorKomma - 3);
+
+ while(i > 0) // #78311#
+ {
+ rStr.Insert(cTho, (xub_StrLen)i);
+ i -= 3;
+ }
+ }
+ }
+
+ if(!rStr.Len())
+ {
+ rStr = String();
+ rStr += sal_Unicode('0');
+ }
+
+ if(bNegative)
+ {
+ rStr.Insert(sal_Unicode('-'), 0);
+ }
+
+ if(!bNoUnitChars)
+ rStr += aUIUnitStr;
+}
+
+void SdrModel::TakeWinkStr(long nWink, XubString& rStr, FASTBOOL bNoDegChar) const
+{
+ BOOL bNeg(nWink < 0);
+
+ if(bNeg)
+ nWink = -nWink;
+
+ rStr = UniString::CreateFromInt32(nWink);
+
+ SvtSysLocale aSysLoc;
+ const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
+ xub_StrLen nAnz(2);
+
+ if(rLoc.isNumLeadingZero())
+ nAnz++;
+
+ while(rStr.Len() < nAnz)
+ rStr.Insert(sal_Unicode('0'), 0);
+
+ rStr.Insert(rLoc.getNumDecimalSep().GetChar(0), rStr.Len() - 2);
+
+ if(bNeg)
+ rStr.Insert(sal_Unicode('-'), 0);
+
+ if(!bNoDegChar)
+ rStr += DEGREE_CHAR;
+}
+
+void SdrModel::TakePercentStr(const Fraction& rVal, XubString& rStr, FASTBOOL bNoPercentChar) const
+{
+ INT32 nMul(rVal.GetNumerator());
+ INT32 nDiv(rVal.GetDenominator());
+ BOOL bNeg(nMul < 0);
+
+ if(nDiv < 0)
+ bNeg = !bNeg;
+
+ if(nMul < 0)
+ nMul = -nMul;
+
+ if(nDiv < 0)
+ nDiv = -nDiv;
+
+ nMul *= 100;
+ nMul += nDiv/2;
+ nMul /= nDiv;
+
+ rStr = UniString::CreateFromInt32(nMul);
+
+ if(bNeg)
+ rStr.Insert(sal_Unicode('-'), 0);
+
+ if(!bNoPercentChar)
+ rStr += sal_Unicode('%');
+}
+
+void SdrModel::SetChanged(sal_Bool bFlg)
+{
+ mbChanged = bFlg;
+}
+
+void SdrModel::RecalcPageNums(FASTBOOL bMaster)
+{
+ Container& rPL=*(bMaster ? &maMaPag : &maPages);
+ USHORT nAnz=USHORT(rPL.Count());
+ USHORT i;
+ for (i=0; i<nAnz; i++) {
+ SdrPage* pPg=(SdrPage*)(rPL.GetObject(i));
+ pPg->SetPageNum(i);
+ }
+ if (bMaster) bMPgNumsDirty=FALSE;
+ else bPagNumsDirty=FALSE;
+}
+
+void SdrModel::InsertPage(SdrPage* pPage, USHORT nPos)
+{
+ USHORT nAnz=GetPageCount();
+ if (nPos>nAnz) nPos=nAnz;
+ maPages.Insert(pPage,nPos);
+ // #109538#
+ PageListChanged();
+ pPage->SetInserted(TRUE);
+ pPage->SetPageNum(nPos);
+ pPage->SetModel(this);
+ if (nPos<nAnz) bPagNumsDirty=TRUE;
+ SetChanged();
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(pPage);
+ Broadcast(aHint);
+}
+
+void SdrModel::DeletePage(USHORT nPgNum)
+{
+ SdrPage* pPg=RemovePage(nPgNum);
+ delete pPg;
+}
+
+SdrPage* SdrModel::RemovePage(USHORT nPgNum)
+{
+ SdrPage* pPg=(SdrPage*)maPages.Remove(nPgNum);
+ // #109538#
+ PageListChanged();
+ if (pPg!=NULL) {
+ pPg->SetInserted(FALSE);
+ }
+ bPagNumsDirty=TRUE;
+ SetChanged();
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(pPg);
+ Broadcast(aHint);
+ return pPg;
+}
+
+void SdrModel::MovePage(USHORT nPgNum, USHORT nNewPos)
+{
+ SdrPage* pPg=(SdrPage*)maPages.Remove(nPgNum);
+ // #109538#
+ PageListChanged();
+ if (pPg!=NULL) {
+ pPg->SetInserted(FALSE);
+ InsertPage(pPg,nNewPos);
+ }
+}
+
+void SdrModel::InsertMasterPage(SdrPage* pPage, USHORT nPos)
+{
+ USHORT nAnz=GetMasterPageCount();
+ if (nPos>nAnz) nPos=nAnz;
+ maMaPag.Insert(pPage,nPos);
+ // #109538#
+ MasterPageListChanged();
+ pPage->SetInserted(TRUE);
+ pPage->SetPageNum(nPos);
+ pPage->SetModel(this);
+ if (nPos<nAnz) {
+ bMPgNumsDirty=TRUE;
+ }
+ SetChanged();
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(pPage);
+ Broadcast(aHint);
+}
+
+void SdrModel::DeleteMasterPage(USHORT nPgNum)
+{
+ SdrPage* pPg=RemoveMasterPage(nPgNum);
+ if (pPg!=NULL) delete pPg;
+}
+
+SdrPage* SdrModel::RemoveMasterPage(USHORT nPgNum)
+{
+ SdrPage* pRetPg=(SdrPage*)maMaPag.Remove(nPgNum);
+ // #109538#
+ MasterPageListChanged();
+
+ if(pRetPg)
+ {
+ // Nun die Verweise der normalen Zeichenseiten auf die entfernte MasterPage loeschen
+ sal_uInt16 nPageAnz(GetPageCount());
+
+ for(sal_uInt16 np(0); np < nPageAnz; np++)
+ {
+ GetPage(np)->TRG_ImpMasterPageRemoved(*pRetPg);
+ }
+
+ pRetPg->SetInserted(FALSE);
+ }
+
+ bMPgNumsDirty=TRUE;
+ SetChanged();
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(pRetPg);
+ Broadcast(aHint);
+ return pRetPg;
+}
+
+void SdrModel::MoveMasterPage(USHORT nPgNum, USHORT nNewPos)
+{
+ SdrPage* pPg=(SdrPage*)maMaPag.Remove(nPgNum);
+ // #109538#
+ MasterPageListChanged();
+ if (pPg!=NULL) {
+ pPg->SetInserted(FALSE);
+ maMaPag.Insert(pPg,nNewPos);
+ // #109538#
+ MasterPageListChanged();
+ }
+ bMPgNumsDirty=TRUE;
+ SetChanged();
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(pPg);
+ Broadcast(aHint);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrModel::CheckConsistence() const
+{
+ FASTBOOL bRet=TRUE;
+#ifdef DBG_UTIL
+ DBG_CHKTHIS(SdrModel,NULL);
+#endif
+ return bRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// #48289#
+void SdrModel::CopyPages(USHORT nFirstPageNum, USHORT nLastPageNum,
+ USHORT nDestPos,
+ FASTBOOL bUndo, FASTBOOL bMoveNoCopy)
+{
+ if( bUndo && !IsUndoEnabled() )
+ bUndo = false;
+
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_UndoMergeModel));
+
+ USHORT nPageAnz=GetPageCount();
+ USHORT nMaxPage=nPageAnz;
+
+ if (nMaxPage!=0)
+ nMaxPage--;
+ if (nFirstPageNum>nMaxPage)
+ nFirstPageNum=nMaxPage;
+ if (nLastPageNum>nMaxPage)
+ nLastPageNum =nMaxPage;
+ FASTBOOL bReverse=nLastPageNum<nFirstPageNum;
+ if (nDestPos>nPageAnz)
+ nDestPos=nPageAnz;
+
+ // Zunaechst die Zeiger der betroffenen Seiten in einem Array sichern
+ USHORT nPageNum=nFirstPageNum;
+ USHORT nCopyAnz=((!bReverse)?(nLastPageNum-nFirstPageNum):(nFirstPageNum-nLastPageNum))+1;
+ SdrPage** pPagePtrs=new SdrPage*[nCopyAnz];
+ USHORT nCopyNum;
+ for(nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
+ {
+ pPagePtrs[nCopyNum]=GetPage(nPageNum);
+ if (bReverse)
+ nPageNum--;
+ else
+ nPageNum++;
+ }
+
+ // Jetzt die Seiten kopieren
+ USHORT nDestNum=nDestPos;
+ for (nCopyNum=0; nCopyNum<nCopyAnz; nCopyNum++)
+ {
+ SdrPage* pPg=pPagePtrs[nCopyNum];
+ USHORT nPageNum2=pPg->GetPageNum();
+ if (!bMoveNoCopy)
+ {
+ const SdrPage* pPg1=GetPage(nPageNum2);
+ pPg=pPg1->Clone();
+ InsertPage(pPg,nDestNum);
+ if (bUndo)
+ AddUndo(GetSdrUndoFactory().CreateUndoCopyPage(*pPg));
+ nDestNum++;
+ }
+ else
+ {
+ // Move ist nicht getestet!
+ if (nDestNum>nPageNum2)
+ nDestNum--;
+
+ if(bUndo)
+ AddUndo(GetSdrUndoFactory().CreateUndoSetPageNum(*GetPage(nPageNum2),nPageNum2,nDestNum));
+
+ pPg=RemovePage(nPageNum2);
+ InsertPage(pPg,nDestNum);
+ nDestNum++;
+ }
+
+ if(bReverse)
+ nPageNum2--;
+ else
+ nPageNum2++;
+ }
+
+ delete[] pPagePtrs;
+ if(bUndo)
+ EndUndo();
+}
+
+void SdrModel::Merge(SdrModel& rSourceModel,
+ USHORT nFirstPageNum, USHORT nLastPageNum,
+ USHORT nDestPos,
+ FASTBOOL bMergeMasterPages, FASTBOOL bAllMasterPages,
+ FASTBOOL bUndo, FASTBOOL bTreadSourceAsConst)
+{
+ if (&rSourceModel==this)
+ { // #48289#
+ CopyPages(nFirstPageNum,nLastPageNum,nDestPos,bUndo,!bTreadSourceAsConst);
+ return;
+ }
+
+ if( bUndo && !IsUndoEnabled() )
+ bUndo = false;
+
+ if (bUndo)
+ BegUndo(ImpGetResStr(STR_UndoMergeModel));
+
+ USHORT nSrcPageAnz=rSourceModel.GetPageCount();
+ USHORT nSrcMasterPageAnz=rSourceModel.GetMasterPageCount();
+ USHORT nDstMasterPageAnz=GetMasterPageCount();
+ FASTBOOL bInsPages=(nFirstPageNum<nSrcPageAnz || nLastPageNum<nSrcPageAnz);
+ USHORT nMaxSrcPage=nSrcPageAnz; if (nMaxSrcPage!=0) nMaxSrcPage--;
+ if (nFirstPageNum>nMaxSrcPage) nFirstPageNum=nMaxSrcPage;
+ if (nLastPageNum>nMaxSrcPage) nLastPageNum =nMaxSrcPage;
+ FASTBOOL bReverse=nLastPageNum<nFirstPageNum;
+
+ USHORT* pMasterMap=NULL;
+ FASTBOOL* pMasterNeed=NULL;
+ USHORT nMasterNeed=0;
+ if (bMergeMasterPages && nSrcMasterPageAnz!=0) {
+ // Feststellen, welche MasterPages aus rSrcModel benoetigt werden
+ pMasterMap=new USHORT[nSrcMasterPageAnz];
+ pMasterNeed=new FASTBOOL[nSrcMasterPageAnz];
+ memset(pMasterMap,0xFF,nSrcMasterPageAnz*sizeof(USHORT));
+ if (bAllMasterPages) {
+ memset(pMasterNeed,TRUE,nSrcMasterPageAnz*sizeof(FASTBOOL));
+ } else {
+ memset(pMasterNeed,FALSE,nSrcMasterPageAnz*sizeof(FASTBOOL));
+ USHORT nAnf= bReverse ? nLastPageNum : nFirstPageNum;
+ USHORT nEnd= bReverse ? nFirstPageNum : nLastPageNum;
+ for (USHORT i=nAnf; i<=nEnd; i++) {
+ const SdrPage* pPg=rSourceModel.GetPage(i);
+ if(pPg->TRG_HasMasterPage())
+ {
+ SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
+ sal_uInt16 nMPgNum(rMasterPage.GetPageNum());
+
+ if(nMPgNum < nSrcMasterPageAnz)
+ {
+ pMasterNeed[nMPgNum] = TRUE;
+ }
+ }
+ }
+ }
+ // Nun das Mapping der MasterPages bestimmen
+ USHORT nAktMaPagNum=nDstMasterPageAnz;
+ for (USHORT i=0; i<nSrcMasterPageAnz; i++) {
+ if (pMasterNeed[i]) {
+ pMasterMap[i]=nAktMaPagNum;
+ nAktMaPagNum++;
+ nMasterNeed++;
+ }
+ }
+ }
+
+ // rueberholen der Masterpages
+ if (pMasterMap!=NULL && pMasterNeed!=NULL && nMasterNeed!=0) {
+ for (USHORT i=nSrcMasterPageAnz; i>0;) {
+ i--;
+ if (pMasterNeed[i]) {
+ SdrPage* pPg=NULL;
+ if (bTreadSourceAsConst) {
+ const SdrPage* pPg1=rSourceModel.GetMasterPage(i);
+ pPg=pPg1->Clone();
+ } else {
+ pPg=rSourceModel.RemoveMasterPage(i);
+ }
+ if (pPg!=NULL) {
+ // und alle ans einstige Ende des DstModel reinschieben.
+ // nicht InsertMasterPage() verwenden da die Sache
+ // inkonsistent ist bis alle drin sind
+ maMaPag.Insert(pPg,nDstMasterPageAnz);
+ // #109538#
+ MasterPageListChanged();
+ pPg->SetInserted(TRUE);
+ pPg->SetModel(this);
+ bMPgNumsDirty=TRUE;
+ if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
+ } else {
+ DBG_ERROR("SdrModel::Merge(): MasterPage im SourceModel nicht gefunden");
+ }
+ }
+ }
+ }
+
+ // rueberholen der Zeichenseiten
+ if (bInsPages) {
+ USHORT nSourcePos=nFirstPageNum;
+ USHORT nMergeCount=USHORT(Abs((long)((long)nFirstPageNum-nLastPageNum))+1);
+ if (nDestPos>GetPageCount()) nDestPos=GetPageCount();
+ while (nMergeCount>0) {
+ SdrPage* pPg=NULL;
+ if (bTreadSourceAsConst) {
+ const SdrPage* pPg1=rSourceModel.GetPage(nSourcePos);
+ pPg=pPg1->Clone();
+ } else {
+ pPg=rSourceModel.RemovePage(nSourcePos);
+ }
+ if (pPg!=NULL) {
+ InsertPage(pPg,nDestPos);
+ if (bUndo) AddUndo(GetSdrUndoFactory().CreateUndoNewPage(*pPg));
+ // und nun zu den MasterPageDescriptoren
+
+ if(pPg->TRG_HasMasterPage())
+ {
+ SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
+ sal_uInt16 nMaPgNum(rMasterPage.GetPageNum());
+
+ if (bMergeMasterPages)
+ {
+ sal_uInt16 nNeuNum(0xFFFF);
+
+ if(pMasterMap)
+ {
+ nNeuNum = pMasterMap[nMaPgNum];
+ }
+
+ if(nNeuNum != 0xFFFF)
+ {
+ if(bUndo)
+ {
+ AddUndo(GetSdrUndoFactory().CreateUndoPageChangeMasterPage(*pPg));
+ }
+
+ pPg->TRG_SetMasterPage(*GetMasterPage(nNeuNum));
+ }
+ DBG_ASSERT(nNeuNum!=0xFFFF,"SdrModel::Merge(): Irgendwas ist krumm beim Mappen der MasterPages");
+ } else {
+ if (nMaPgNum>=nDstMasterPageAnz) {
+ // Aha, die ist ausserbalb des urspruenglichen Bereichs der Masterpages des DstModel
+ pPg->TRG_ClearMasterPage();
+ }
+ }
+ }
+
+ } else {
+ DBG_ERROR("SdrModel::Merge(): Zeichenseite im SourceModel nicht gefunden");
+ }
+ nDestPos++;
+ if (bReverse) nSourcePos--;
+ else if (bTreadSourceAsConst) nSourcePos++;
+ nMergeCount--;
+ }
+ }
+
+ delete [] pMasterMap;
+ delete [] pMasterNeed;
+
+ bMPgNumsDirty=TRUE;
+ bPagNumsDirty=TRUE;
+
+ SetChanged();
+ // Fehlt: Mergen und Mapping der Layer
+ // an den Objekten sowie an den MasterPageDescriptoren
+ if (bUndo) EndUndo();
+}
+
+void SdrModel::SetStarDrawPreviewMode(BOOL bPreview)
+{
+ if (!bPreview && bStarDrawPreviewMode && GetPageCount())
+ {
+ // Das Zuruecksetzen ist nicht erlaubt, da das Model ev. nicht vollstaendig geladen wurde
+ DBG_ASSERT(FALSE,"SdrModel::SetStarDrawPreviewMode(): Zuruecksetzen nicht erlaubt, da Model ev. nicht vollstaendig");
+ }
+ else
+ {
+ bStarDrawPreviewMode = bPreview;
+ }
+}
+
+uno::Reference< uno::XInterface > SdrModel::getUnoModel()
+{
+ if( !mxUnoModel.is() )
+ mxUnoModel = createUnoModel();
+
+ return mxUnoModel;
+}
+
+void SdrModel::setUnoModel( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xModel )
+{
+ mxUnoModel = xModel;
+}
+
+uno::Reference< uno::XInterface > SdrModel::createUnoModel()
+{
+ DBG_ERROR( "SdrModel::createUnoModel() - base implementation should not be called!" );
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInt;
+ return xInt;
+}
+
+void SdrModel::setLock( BOOL bLock )
+{
+ if( mbModelLocked != bLock )
+ {
+ if( sal_False == bLock )
+ {
+ // ReformatAllTextObjects(); #103122# due to a typo in the above if, this code was never
+ // executed, so I remove it until we discover that we need it here
+ ImpReformatAllEdgeObjects(); // #103122#
+ }
+ mbModelLocked = bLock;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrModel::MigrateItemSet( const SfxItemSet* pSourceSet, SfxItemSet* pDestSet, SdrModel* pNewModel )
+{
+ if( pSourceSet && pDestSet && (pSourceSet != pDestSet ) )
+ {
+ if( pNewModel == NULL )
+ pNewModel = this;
+
+ SfxWhichIter aWhichIter(*pSourceSet);
+ sal_uInt16 nWhich(aWhichIter.FirstWhich());
+ const SfxPoolItem *pPoolItem;
+
+ while(nWhich)
+ {
+ if(SFX_ITEM_SET == pSourceSet->GetItemState(nWhich, FALSE, &pPoolItem))
+ {
+ const SfxPoolItem* pItem = pPoolItem;
+
+ switch( nWhich )
+ {
+ case XATTR_FILLBITMAP:
+ pItem = ((XFillBitmapItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_LINEDASH:
+ pItem = ((XLineDashItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_LINESTART:
+ pItem = ((XLineStartItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_LINEEND:
+ pItem = ((XLineEndItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_FILLGRADIENT:
+ pItem = ((XFillGradientItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_FILLFLOATTRANSPARENCE:
+ // #85953# allow all kinds of XFillFloatTransparenceItem to be set
+ pItem = ((XFillFloatTransparenceItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ case XATTR_FILLHATCH:
+ pItem = ((XFillHatchItem*)pItem)->checkForUniqueItem( pNewModel );
+ break;
+ }
+
+ // set item
+ if( pItem )
+ {
+ pDestSet->Put(*pItem);
+
+ // delete item if it was a generated one
+ if( pItem != pPoolItem)
+ delete (SfxPoolItem*)pItem;
+ }
+ }
+ nWhich = aWhichIter.NextWhich();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrModel::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
+{
+ if( mpForbiddenCharactersTable )
+ mpForbiddenCharactersTable->release();
+
+ mpForbiddenCharactersTable = xForbiddenChars.getBodyPtr();
+
+ if( mpForbiddenCharactersTable )
+ mpForbiddenCharactersTable->acquire();
+
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+}
+
+vos::ORef<SvxForbiddenCharactersTable> SdrModel::GetForbiddenCharsTable() const
+{
+ return mpForbiddenCharactersTable;
+}
+
+void SdrModel::SetCharCompressType( UINT16 nType )
+{
+ if( nType != mnCharCompressType )
+ {
+ mnCharCompressType = nType;
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ }
+}
+
+void SdrModel::SetKernAsianPunctuation( sal_Bool bEnabled )
+{
+ if( mbKernAsianPunctuation != bEnabled )
+ {
+ mbKernAsianPunctuation = bEnabled;
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ }
+}
+
+void SdrModel::SetAddExtLeading( sal_Bool bEnabled )
+{
+ if( mbAddExtLeading != bEnabled )
+ {
+ mbAddExtLeading = bEnabled;
+ ImpSetOutlinerDefaults( pDrawOutliner );
+ ImpSetOutlinerDefaults( pHitTestOutliner );
+ }
+}
+
+void SdrModel::ReformatAllTextObjects()
+{
+ ImpReformatAllTextObjects();
+}
+
+FASTBOOL SdrModel::HasTransparentObjects( BOOL bCheckForAlphaChannel ) const
+{
+ FASTBOOL bRet = FALSE;
+ USHORT n, nCount;
+
+ for( n = 0, nCount = GetMasterPageCount(); ( n < nCount ) && !bRet; n++ )
+ if( GetMasterPage( n )->HasTransparentObjects( bCheckForAlphaChannel ) )
+ bRet = TRUE;
+
+ if( !bRet )
+ {
+ for( n = 0, nCount = GetPageCount(); ( n < nCount ) && !bRet; n++ )
+ if( GetPage( n )->HasTransparentObjects( bCheckForAlphaChannel ) )
+ bRet = TRUE;
+ }
+
+ return bRet;
+}
+
+SdrOutliner* SdrModel::createOutliner( USHORT nOutlinerMode )
+{
+ if( NULL == mpOutlinerCache )
+ mpOutlinerCache = new SdrOutlinerCache(this);
+
+ return mpOutlinerCache->createOutliner( nOutlinerMode );
+}
+
+void SdrModel::disposeOutliner( SdrOutliner* pOutliner )
+{
+ if( mpOutlinerCache )
+ {
+ mpOutlinerCache->disposeOutliner( pOutliner );
+ }
+ else
+ {
+ delete pOutliner;
+ }
+}
+
+SvxNumType SdrModel::GetPageNumType() const
+{
+ return SVX_ARABIC;
+}
+
+const SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum) const
+{
+ DBG_ASSERT(nPgNum < maPages.Count(), "SdrModel::GetPage: Access out of range (!)");
+ return (SdrPage*)(maPages.GetObject(nPgNum));
+}
+
+SdrPage* SdrModel::GetPage(sal_uInt16 nPgNum)
+{
+ DBG_ASSERT(nPgNum < maPages.Count(), "SdrModel::GetPage: Access out of range (!)");
+ return (SdrPage*)(maPages.GetObject(nPgNum));
+}
+
+sal_uInt16 SdrModel::GetPageCount() const
+{
+ return sal_uInt16(maPages.Count());
+}
+
+void SdrModel::PageListChanged()
+{
+}
+
+const SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum) const
+{
+ DBG_ASSERT(nPgNum < maMaPag.Count(), "SdrModel::GetMasterPage: Access out of range (!)");
+ return (SdrPage*)(maMaPag.GetObject(nPgNum));
+}
+
+SdrPage* SdrModel::GetMasterPage(sal_uInt16 nPgNum)
+{
+ DBG_ASSERT(nPgNum < maMaPag.Count(), "SdrModel::GetMasterPage: Access out of range (!)");
+ return (SdrPage*)(maMaPag.GetObject(nPgNum));
+}
+
+sal_uInt16 SdrModel::GetMasterPageCount() const
+{
+ return sal_uInt16(maMaPag.Count());
+}
+
+void SdrModel::MasterPageListChanged()
+{
+}
+
+void SdrModel::SetSdrUndoManager( SfxUndoManager* pUndoManager )
+{
+ mpImpl->mpUndoManager = pUndoManager;
+}
+
+SdrUndoFactory& SdrModel::GetSdrUndoFactory() const
+{
+ if( !mpImpl->mpUndoFactory )
+ mpImpl->mpUndoFactory = new SdrUndoFactory;
+ return *mpImpl->mpUndoFactory;
+}
+
+void SdrModel::SetSdrUndoFactory( SdrUndoFactory* pUndoFactory )
+{
+ if( pUndoFactory && (pUndoFactory != mpImpl->mpUndoFactory) )
+ {
+ delete mpImpl->mpUndoFactory;
+ mpImpl->mpUndoFactory = pUndoFactory;
+ }
+}
+
+/** cl: added this for OJ to complete his reporting engine, does not work
+ correctly so only enable it for his model */
+bool SdrModel::IsAllowShapePropertyChangeListener() const
+{
+ return mpImpl && mpImpl->mbAllowShapePropertyChangeListener;
+}
+
+void SdrModel::SetAllowShapePropertyChangeListener( bool bAllow )
+{
+ if( mpImpl )
+ {
+ mpImpl->mbAllowShapePropertyChangeListener = bAllow;
+ }
+}
+
+const ::com::sun::star::uno::Sequence< sal_Int8 >& SdrModel::getUnoTunnelImplementationId()
+{
+ static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = 0;
+ if( !pSeq )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrHint,SfxHint);
+
+SdrHint::SdrHint()
+: mpPage(0L),
+ mpObj(0L),
+ mpObjList(0L),
+ meHint(HINT_UNKNOWN)
+{
+}
+
+SdrHint::SdrHint(SdrHintKind eNewHint)
+: mpPage(0L),
+ mpObj(0L),
+ mpObjList(0L),
+ meHint(eNewHint)
+{
+}
+
+SdrHint::SdrHint(const SdrObject& rNewObj)
+: mpPage(rNewObj.GetPage()),
+ mpObj(&rNewObj),
+ mpObjList(rNewObj.GetObjList()),
+ meHint(HINT_OBJCHG)
+{
+ maRectangle = rNewObj.GetLastBoundRect();
+}
+
+SdrHint::SdrHint(const SdrObject& rNewObj, const Rectangle& rRect)
+: mpPage(rNewObj.GetPage()),
+ mpObj(&rNewObj),
+ mpObjList(rNewObj.GetObjList()),
+ meHint(HINT_OBJCHG)
+{
+ maRectangle = rRect;
+}
+
+void SdrHint::SetPage(const SdrPage* pNewPage)
+{
+ mpPage = pNewPage;
+}
+
+void SdrHint::SetObjList(const SdrObjList* pNewOL)
+{
+ mpObjList = pNewOL;
+}
+
+void SdrHint::SetObject(const SdrObject* pNewObj)
+{
+ mpObj = pNewObj;
+}
+
+void SdrHint::SetKind(SdrHintKind eNewKind)
+{
+ meHint = eNewKind;
+}
+
+void SdrHint::SetRect(const Rectangle& rNewRect)
+{
+ maRectangle = rNewRect;
+}
+
+const SdrPage* SdrHint::GetPage() const
+{
+ return mpPage;
+}
+
+const SdrObjList* SdrHint::GetObjList() const
+{
+ return mpObjList;
+}
+
+const SdrObject* SdrHint::GetObject() const
+{
+ return mpObj;
+}
+
+SdrHintKind SdrHint::GetKind() const
+{
+ return meHint;
+}
+
+const Rectangle& SdrHint::GetRect() const
+{
+ return maRectangle;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
new file mode 100644
index 000000000000..fffcac00e46c
--- /dev/null
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -0,0 +1,2176 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdmrkv.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdoedge.hxx>
+#include "svdglob.hxx"
+#include "svditext.hxx"
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include "svddrgm1.hxx"
+
+#ifdef DBG_UTIL
+#include <svdibrow.hxx>
+#endif
+
+#include <svx/svdoole2.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xflgrit.hxx>
+#include "gradtrns.hxx"
+#include <svx/xflftrit.hxx>
+#include <svx/dialmgr.hxx>
+#include "svdstr.hrc"
+#include <svx/svdundo.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/scene3d.hxx>
+#include <svx/svdovirt.hxx>
+#include <svx/sdr/overlay/overlayrollingrectangle.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <sdrpaintwindow.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// predefines
+
+class SdrUnoControlList;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #114409#-3 Migrate Marking of Objects, Points and GluePoints
+
+class ImplMarkingOverlay
+{
+ // The OverlayObjects
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+ // The remembered second position in logical coodinates
+ basegfx::B2DPoint maSecondPosition;
+
+ // bitfield
+ // A flag to remember if the action is for unmarking.
+ unsigned mbUnmarking : 1;
+
+public:
+ ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking = sal_False);
+ ~ImplMarkingOverlay();
+
+ void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
+ sal_Bool IsUnmarking() const { return mbUnmarking; }
+};
+
+ImplMarkingOverlay::ImplMarkingOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos, sal_Bool bUnmarking)
+: maSecondPosition(rStartPos),
+ mbUnmarking(bUnmarking)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ ::sdr::overlay::OverlayRollingRectangleStriped* pNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
+ rStartPos, rStartPos, false);
+ pTargetOverlay->add(*pNew);
+ maObjects.append(*pNew);
+ }
+ }
+}
+
+ImplMarkingOverlay::~ImplMarkingOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+void ImplMarkingOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
+{
+ if(rNewPosition != maSecondPosition)
+ {
+ // apply to OverlayObjects
+ for(sal_uInt32 a(0L); a < maObjects.count(); a++)
+ {
+ ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a);
+ rCandidate.setSecondPosition(rNewPosition);
+ }
+
+ // remember new position
+ maSecondPosition = rNewPosition;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@ @@@@ @@@@@ @@ @@ @@ @@ @@ @@@@@ @@ @@
+// @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@@@@@@ @@@@@@ @@@@@ @@@@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::ImpClearVars()
+{
+ eDragMode=SDRDRAG_MOVE;
+ //HMHbHdlShown=FALSE;
+ bRefHdlShownOnly=FALSE;
+ eEditMode=SDREDITMODE_EDIT;
+ eEditMode0=SDREDITMODE_EDIT;
+ bDesignMode=FALSE;
+ pMarkedObj=NULL;
+ pMarkedPV=NULL;
+ bForceFrameHandles=FALSE;
+ bPlusHdlAlways=FALSE;
+ nFrameHandlesLimit=50;
+ bInsPolyPoint=FALSE;
+ mnInsPointNum = 0L;
+ bMarkedObjRectDirty=FALSE;
+ bMarkedPointsRectsDirty=FALSE;
+ mbMarkHandlesHidden = false;
+ bMrkPntDirty=FALSE;
+ bMarkHdlWhenTextEdit=FALSE;
+ bMarkableObjCountDirty=FALSE; // noch nicht implementiert
+ nMarkableObjCount=0; // noch nicht implementiert
+
+ // #114409#-3 Migrate selections
+ BrkMarkObj();
+ BrkMarkPoints();
+ BrkMarkGluePoints();
+}
+
+SdrMarkView::SdrMarkView(SdrModel* pModel1, OutputDevice* pOut)
+: SdrSnapView(pModel1,pOut),
+ mpMarkObjOverlay(0L),
+ mpMarkPointsOverlay(0L),
+ mpMarkGluePointsOverlay(0L),
+ aHdl(this),
+ mpSdrViewSelection(new sdr::ViewSelection())
+{
+ ImpClearVars();
+ StartListening(*pModel1);
+}
+
+SdrMarkView::~SdrMarkView()
+{
+ // #114409#-3 Migrate selections
+ BrkMarkObj();
+ BrkMarkPoints();
+ BrkMarkGluePoints();
+ delete mpSdrViewSelection;
+}
+
+void __EXPORT SdrMarkView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
+ if (pSdrHint!=NULL)
+ {
+ SdrHintKind eKind=pSdrHint->GetKind();
+
+ if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED)
+ {
+ bMarkedObjRectDirty=TRUE;
+ bMarkedPointsRectsDirty=TRUE;
+ }
+/* removed for now since this breaks existing code who iterates over the mark list and sequentially replaces objects
+ if( eKind==HINT_OBJREMOVED && IsObjMarked( const_cast<SdrObject*>(pSdrHint->GetObject()) ) )
+ {
+ MarkObj( const_cast<SdrObject*>(pSdrHint->GetObject()), GetSdrPageView(), TRUE );
+ }
+*/
+ }
+ SdrSnapView::Notify(rBC,rHint);
+}
+
+void SdrMarkView::ModelHasChanged()
+{
+ SdrPaintView::ModelHasChanged();
+ GetMarkedObjectListWriteAccess().SetNameDirty();
+ bMarkedObjRectDirty=TRUE;
+ bMarkedPointsRectsDirty=TRUE;
+ // Es sind beispielsweise Obj markiert und maMarkedObjectListist Sorted.
+ // In einer anderen View 2 wird die ObjOrder veraendert
+ // (z.B. MovToTop()). Dann ist Neusortieren der MarkList erforderlich.
+ GetMarkedObjectListWriteAccess().SetUnsorted();
+ SortMarkedObjects();
+ bMrkPntDirty=TRUE;
+ UndirtyMrkPnt();
+ SdrView* pV=(SdrView*)this;
+ if (pV!=NULL && !pV->IsDragObj() && !pV->IsInsObjPoint()) { // an dieser Stelle habe ich ein ziemliches Problem !!!
+ AdjustMarkHdl();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrMarkView::IsAction() const
+{
+ return SdrSnapView::IsAction() || IsMarkObj() || IsMarkPoints() || IsMarkGluePoints();
+}
+
+void SdrMarkView::MovAction(const Point& rPnt)
+{
+ SdrSnapView::MovAction(rPnt);
+
+ if(IsMarkObj())
+ {
+ MovMarkObj(rPnt);
+ }
+ else if(IsMarkPoints())
+ {
+ MovMarkPoints(rPnt);
+ }
+ else if(IsMarkGluePoints())
+ {
+ MovMarkGluePoints(rPnt);
+ }
+}
+
+void SdrMarkView::EndAction()
+{
+ if(IsMarkObj())
+ {
+ EndMarkObj();
+ }
+ else if(IsMarkPoints())
+ {
+ EndMarkPoints();
+ }
+ else if(IsMarkGluePoints())
+ {
+ EndMarkGluePoints();
+ }
+
+ SdrSnapView::EndAction();
+}
+
+void SdrMarkView::BckAction()
+{
+ SdrSnapView::BckAction();
+ BrkMarkObj();
+ BrkMarkPoints();
+ BrkMarkGluePoints();
+}
+
+void SdrMarkView::BrkAction()
+{
+ SdrSnapView::BrkAction();
+ BrkMarkObj();
+ BrkMarkPoints();
+ BrkMarkGluePoints();
+}
+
+void SdrMarkView::TakeActionRect(Rectangle& rRect) const
+{
+ if(IsMarkObj() || IsMarkPoints() || IsMarkGluePoints())
+ {
+ rRect = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
+ }
+ else
+ {
+ SdrSnapView::TakeActionRect(rRect);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::ClearPageView()
+{
+ UnmarkAllObj();
+ SdrSnapView::ClearPageView();
+}
+
+void SdrMarkView::HideSdrPage()
+{
+ bool bMrkChg(false);
+ //HMHbool bVis(false);
+
+ if(mpPageView)
+ {
+ // break all creation actions when hiding page (#75081#)
+ BrkAction();
+ //HMHbVis = IsMarkHdlShown();
+
+ //HMHif(bVis)
+ //HMH{
+ //HMH HideMarkHdl();
+ //HMH}
+
+ // Alle Markierungen dieser Seite verwerfen
+ bMrkChg = GetMarkedObjectListWriteAccess().DeletePageView(*mpPageView);
+ }
+
+ SdrSnapView::HideSdrPage();
+
+ if(bMrkChg)
+ {
+ MarkListHasChanged();
+ AdjustMarkHdl();
+ }
+
+ //HMHif(bVis)
+ //HMH{
+ //HMH ShowMarkHdl();
+ //HMH}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrMarkView::BegMarkObj(const Point& rPnt, sal_Bool bUnmark)
+{
+ BrkAction();
+
+ DBG_ASSERT(0L == mpMarkObjOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkObjOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpMarkObjOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
+
+ aDragStat.Reset(rPnt);
+ aDragStat.NextPoint();
+ aDragStat.SetMinMove(nMinMovLog);
+
+ return sal_True;
+}
+
+void SdrMarkView::MovMarkObj(const Point& rPnt)
+{
+ if(IsMarkObj() && aDragStat.CheckMinMoved(rPnt))
+ {
+ aDragStat.NextMove(rPnt);
+ DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
+ mpMarkObjOverlay->SetSecondPosition(aNewPos);
+ }
+}
+
+sal_Bool SdrMarkView::EndMarkObj()
+{
+ sal_Bool bRetval(sal_False);
+
+ if(IsMarkObj())
+ {
+ if(aDragStat.IsMinMoved())
+ {
+ Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
+ aRect.Justify();
+ MarkObj(aRect, mpMarkObjOverlay->IsUnmarking());
+ bRetval = sal_True;
+ }
+
+ // cleanup
+ BrkMarkObj();
+ }
+
+ return bRetval;
+}
+
+void SdrMarkView::BrkMarkObj()
+{
+ if(IsMarkObj())
+ {
+ DBG_ASSERT(mpMarkObjOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ delete mpMarkObjOverlay;
+ mpMarkObjOverlay = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrMarkView::BegMarkPoints(const Point& rPnt, sal_Bool bUnmark)
+{
+ if(HasMarkablePoints())
+ {
+ BrkAction();
+
+ DBG_ASSERT(0L == mpMarkPointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkPointsOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpMarkPointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
+
+ aDragStat.Reset(rPnt);
+ aDragStat.NextPoint();
+ aDragStat.SetMinMove(nMinMovLog);
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void SdrMarkView::MovMarkPoints(const Point& rPnt)
+{
+ if(IsMarkPoints() && aDragStat.CheckMinMoved(rPnt))
+ {
+ aDragStat.NextMove(rPnt);
+
+ DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
+ mpMarkPointsOverlay->SetSecondPosition(aNewPos);
+ }
+}
+
+sal_Bool SdrMarkView::EndMarkPoints()
+{
+ sal_Bool bRetval(sal_False);
+
+ if(IsMarkPoints())
+ {
+ if(aDragStat.IsMinMoved())
+ {
+ Rectangle aRect(aDragStat.GetStart(), aDragStat.GetNow());
+ aRect.Justify();
+ MarkPoints(aRect, mpMarkPointsOverlay->IsUnmarking());
+
+ bRetval = sal_True;
+ }
+
+ // cleanup
+ BrkMarkPoints();
+ }
+
+ return bRetval;
+}
+
+void SdrMarkView::BrkMarkPoints()
+{
+ if(IsMarkPoints())
+ {
+ DBG_ASSERT(mpMarkPointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ delete mpMarkPointsOverlay;
+ mpMarkPointsOverlay = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark)
+{
+ if(HasMarkableGluePoints())
+ {
+ BrkAction();
+
+ DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark);
+
+ aDragStat.Reset(rPnt);
+ aDragStat.NextPoint();
+ aDragStat.SetMinMove(nMinMovLog);
+
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+void SdrMarkView::MovMarkGluePoints(const Point& rPnt)
+{
+ if(IsMarkGluePoints() && aDragStat.CheckMinMoved(rPnt))
+ {
+ aDragStat.NextMove(rPnt);
+
+ DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
+ mpMarkGluePointsOverlay->SetSecondPosition(aNewPos);
+ }
+}
+
+sal_Bool SdrMarkView::EndMarkGluePoints()
+{
+ sal_Bool bRetval(sal_False);
+
+ if(IsMarkGluePoints())
+ {
+ if(aDragStat.IsMinMoved())
+ {
+ Rectangle aRect(aDragStat.GetStart(),aDragStat.GetNow());
+ aRect.Justify();
+ MarkGluePoints(&aRect, mpMarkGluePointsOverlay->IsUnmarking());
+
+ bRetval = sal_True;
+ }
+
+ // cleanup
+ BrkMarkGluePoints();
+ }
+
+ return bRetval;
+}
+
+void SdrMarkView::BrkMarkGluePoints()
+{
+ if(IsMarkGluePoints())
+ {
+ DBG_ASSERT(mpMarkGluePointsOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ delete mpMarkGluePointsOverlay;
+ mpMarkGluePointsOverlay = 0L;
+ }
+}
+
+BOOL SdrMarkView::HasMarkableObj() const
+{
+ ULONG nCount=0;
+
+ SdrPageView* pPV = GetSdrPageView();
+ if(pPV)
+ {
+ SdrObjList* pOL=pPV->GetObjList();
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG nObjNum=0; nObjNum<nObjAnz && nCount==0; nObjNum++) {
+ SdrObject* pObj=pOL->GetObj(nObjNum);
+ if (IsObjMarkable(pObj,pPV)) {
+ nCount++;
+ }
+ }
+ }
+ return nCount!=0;
+}
+
+ULONG SdrMarkView::GetMarkableObjCount() const
+{
+ ULONG nCount=0;
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ SdrObjList* pOL=pPV->GetObjList();
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
+ SdrObject* pObj=pOL->GetObj(nObjNum);
+ if (IsObjMarkable(pObj,pPV)) {
+ nCount++;
+ }
+ }
+ }
+ return nCount;
+}
+
+//HMHvoid SdrMarkView::ImpShowMarkHdl(bool /*bNoRefHdl*/)
+//HMH{
+//HMH bNoRefHdl=FALSE; // geht leider erstmal nicht anders
+//HMH if (!bHdlShown) {
+//HMH bRefHdlShownOnly=FALSE;
+//HMH bHdlShown=TRUE;
+//HMH }
+//HMH}
+
+//HMHvoid SdrMarkView::ShowMarkHdl(bool /*bNoRefHdl*/)
+//HMH{
+//HMH bNoRefHdl=FALSE; // geht leider erstmal nicht anders
+//HMH ImpShowMarkHdl(bNoRefHdl);
+//HMH}
+
+
+//HMHvoid SdrMarkView::HideMarkHdl(bool /*bNoRefHdl*/)
+//HMH{
+//HMH bNoRefHdl=FALSE; // geht leider erstmal nicht anders
+//HMH if (bHdlShown) {
+//HMH bRefHdlShownOnly=bNoRefHdl;
+//HMH bHdlShown=FALSE;
+//HMH }
+//HMH}
+
+void SdrMarkView::hideMarkHandles()
+{
+ if(!mbMarkHandlesHidden)
+ {
+ mbMarkHandlesHidden = true;
+ AdjustMarkHdl();
+ }
+}
+
+void SdrMarkView::showMarkHandles()
+{
+ if(mbMarkHandlesHidden)
+ {
+ mbMarkHandlesHidden = false;
+ AdjustMarkHdl();
+ }
+}
+
+BOOL SdrMarkView::ImpIsFrameHandles() const
+{
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ BOOL bFrmHdl=nMarkAnz>nFrameHandlesLimit || bForceFrameHandles;
+ BOOL bStdDrag=eDragMode==SDRDRAG_MOVE;
+ if (nMarkAnz==1 && bStdDrag && bFrmHdl)
+ {
+ const SdrObject* pObj=GetMarkedObjectByIndex(0);
+ if (pObj->GetObjInventor()==SdrInventor)
+ {
+ UINT16 nIdent=pObj->GetObjIdentifier();
+ if (nIdent==OBJ_LINE || nIdent==OBJ_EDGE || nIdent==OBJ_CAPTION || nIdent==OBJ_MEASURE || nIdent==OBJ_CUSTOMSHAPE || nIdent==OBJ_TABLE )
+ {
+ bFrmHdl=FALSE;
+ }
+ }
+ }
+ if (!bStdDrag && !bFrmHdl) {
+ // Grundsaetzlich erstmal alle anderen Dragmodi nur mit FrameHandles
+ bFrmHdl=TRUE;
+ if (eDragMode==SDRDRAG_ROTATE) {
+ // bei Rotate ObjOwn-Drag, wenn mind. 1 PolyObj
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && bFrmHdl; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ bFrmHdl=!pObj->IsPolyObj();
+ }
+ }
+ }
+ if (!bFrmHdl) {
+ // FrameHandles, wenn wenigstens 1 Obj kein SpecialDrag kann
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && !bFrmHdl; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ bFrmHdl=!pObj->hasSpecialDrag();
+ }
+ }
+ return bFrmHdl;
+}
+
+void SdrMarkView::SetMarkHandles()
+{
+ // #105722# remember old focus handle values to search for it again
+ const SdrHdl* pSaveOldFocusHdl = aHdl.GetFocusHdl();
+ sal_Bool bSaveOldFocus(sal_False);
+ sal_uInt32 nSavePolyNum(0L), nSavePointNum(0L);
+ SdrHdlKind eSaveKind(HDL_MOVE);
+ SdrObject* pSaveObj = NULL;
+
+ if(pSaveOldFocusHdl
+ && pSaveOldFocusHdl->GetObj()
+ && pSaveOldFocusHdl->GetObj()->ISA(SdrPathObj)
+ && (pSaveOldFocusHdl->GetKind() == HDL_POLY || pSaveOldFocusHdl->GetKind() == HDL_BWGT))
+ {
+ bSaveOldFocus = sal_True;
+ nSavePolyNum = pSaveOldFocusHdl->GetPolyNum();
+ nSavePointNum = pSaveOldFocusHdl->GetPointNum();
+ pSaveObj = pSaveOldFocusHdl->GetObj();
+ eSaveKind = pSaveOldFocusHdl->GetKind();
+ }
+
+ // delete/clear all handles. This will always be done, even with areMarkHandlesHidden()
+ aHdl.Clear();
+ aHdl.SetRotateShear(eDragMode==SDRDRAG_ROTATE);
+ aHdl.SetDistortShear(eDragMode==SDRDRAG_SHEAR);
+ pMarkedObj=NULL;
+ pMarkedPV=NULL;
+
+ // are handles enabled at all? Create only then
+ if(!areMarkHandlesHidden())
+ {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ BOOL bStdDrag=eDragMode==SDRDRAG_MOVE;
+ BOOL bSingleTextObjMark=FALSE;
+
+ if (nMarkAnz==1)
+ {
+ pMarkedObj=GetMarkedObjectByIndex(0);
+ bSingleTextObjMark =
+ pMarkedObj &&
+ pMarkedObj->ISA(SdrTextObj) &&
+ static_cast<SdrTextObj*>(pMarkedObj)->IsTextFrame();
+ }
+
+ BOOL bFrmHdl=ImpIsFrameHandles();
+
+ if (nMarkAnz>0)
+ {
+ pMarkedPV=GetSdrPageViewOfMarkedByIndex(0);
+
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && (pMarkedPV!=NULL || !bFrmHdl); nMarkNum++)
+ {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+
+ if (pMarkedPV!=pM->GetPageView())
+ {
+ pMarkedPV=NULL;
+ }
+ }
+ }
+
+ if (bFrmHdl)
+ {
+ Rectangle aRect(GetMarkedObjRect());
+
+ // #i33755#
+ const sal_Bool bHideHandlesWhenInTextEdit(
+ ((SdrView*)this)->IsTextEdit()
+ && pMarkedObj
+ && pMarkedObj->ISA(SdrTextObj)
+ && ((SdrTextObj*)pMarkedObj)->IsInEditMode());
+
+ if(!aRect.IsEmpty() && !bHideHandlesWhenInTextEdit)
+ { // sonst nix gefunden
+ if( bSingleTextObjMark )
+ {
+ const ULONG nSiz0=aHdl.GetHdlCount();
+ pMarkedObj->AddToHdlList(aHdl);
+ const ULONG nSiz1=aHdl.GetHdlCount();
+ for (ULONG i=nSiz0; i<nSiz1; i++)
+ {
+ SdrHdl* pHdl=aHdl.GetHdl(i);
+ pHdl->SetObj(pMarkedObj);
+ pHdl->SetPageView(pMarkedPV);
+ pHdl->SetObjHdlNum(USHORT(i-nSiz0));
+ }
+ }
+ else if( eDragMode==SDRDRAG_CROP )
+ {
+ aHdl.AddHdl(new SdrCropHdl(aRect.TopLeft() ,HDL_UPLFT));
+ aHdl.AddHdl(new SdrCropHdl(aRect.TopCenter() ,HDL_UPPER));
+ aHdl.AddHdl(new SdrCropHdl(aRect.TopRight() ,HDL_UPRGT));
+ aHdl.AddHdl(new SdrCropHdl(aRect.LeftCenter() ,HDL_LEFT ));
+ aHdl.AddHdl(new SdrCropHdl(aRect.RightCenter() ,HDL_RIGHT));
+ aHdl.AddHdl(new SdrCropHdl(aRect.BottomLeft() ,HDL_LWLFT));
+ aHdl.AddHdl(new SdrCropHdl(aRect.BottomCenter(),HDL_LOWER));
+ aHdl.AddHdl(new SdrCropHdl(aRect.BottomRight() ,HDL_LWRGT));
+ }
+ else
+ {
+ BOOL bWdt0=aRect.Left()==aRect.Right();
+ BOOL bHgt0=aRect.Top()==aRect.Bottom();
+ if (bWdt0 && bHgt0)
+ {
+ aHdl.AddHdl(new SdrHdl(aRect.TopLeft(),HDL_UPLFT));
+ }
+ else if (!bStdDrag && (bWdt0 || bHgt0))
+ {
+ aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
+ aHdl.AddHdl(new SdrHdl(aRect.BottomRight(),HDL_LWRGT));
+ }
+ else
+ {
+ if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopLeft() ,HDL_UPLFT));
+ if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopCenter() ,HDL_UPPER));
+ if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.TopRight() ,HDL_UPRGT));
+ if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.LeftCenter() ,HDL_LEFT ));
+ if (!bWdt0 ) aHdl.AddHdl(new SdrHdl(aRect.RightCenter() ,HDL_RIGHT));
+ if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomLeft() ,HDL_LWLFT));
+ if ( !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomCenter(),HDL_LOWER));
+ if (!bWdt0 && !bHgt0) aHdl.AddHdl(new SdrHdl(aRect.BottomRight() ,HDL_LWRGT));
+ }
+ }
+ }
+ }
+ else
+ {
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
+ {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ const ULONG nSiz0=aHdl.GetHdlCount();
+ pObj->AddToHdlList(aHdl);
+ const ULONG nSiz1=aHdl.GetHdlCount();
+ bool bPoly=pObj->IsPolyObj();
+ const SdrUShortCont* pMrkPnts=pM->GetMarkedPoints();
+ for (ULONG i=nSiz0; i<nSiz1; i++)
+ {
+ SdrHdl* pHdl=aHdl.GetHdl(i);
+ pHdl->SetObj(pObj);
+ pHdl->SetPageView(pPV);
+ pHdl->SetObjHdlNum(USHORT(i-nSiz0));
+ if (bPoly)
+ {
+ BOOL bSelected=pMrkPnts!=NULL && pMrkPnts->Exist(USHORT(i-nSiz0));
+ pHdl->SetSelected(bSelected);
+ //BOOL bPlus=bPlusHdlAlways;
+ if (bPlusHdlAlways || bSelected)
+ {
+ sal_uInt32 nPlusAnz=pObj->GetPlusHdlCount(*pHdl);
+ for (sal_uInt32 nPlusNum=0; nPlusNum<nPlusAnz; nPlusNum++)
+ {
+ SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,nPlusNum);
+ if (pPlusHdl!=NULL)
+ {
+ pPlusHdl->SetObj(pObj);
+ pPlusHdl->SetPageView(pPV);
+ pPlusHdl->SetPlusHdl(TRUE);
+ aHdl.AddHdl(pPlusHdl);
+ }
+ }
+ }
+ }
+ }
+ } // for nMarkNum
+ } // if bFrmHdl else
+
+ // GluePoint-Handles
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++)
+ {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ const SdrUShortCont* pMrkGlue=pM->GetMarkedGluePoints();
+ if (pMrkGlue!=NULL)
+ {
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=NULL)
+ {
+ //USHORT nGlueAnz=pGPL->GetCount();
+ USHORT nAnz=(USHORT)pMrkGlue->GetCount();
+ for (USHORT nNum=0; nNum<nAnz; nNum++)
+ {
+ USHORT nId=pMrkGlue->GetObject(nNum);
+ //nNum changed to nNumGP because already used in for loop
+ USHORT nNumGP=pGPL->FindGluePoint(nId);
+ if (nNumGP!=SDRGLUEPOINT_NOTFOUND)
+ {
+ const SdrGluePoint& rGP=(*pGPL)[nNumGP];
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ SdrHdl* pGlueHdl=new SdrHdl(aPos,HDL_GLUE);
+ pGlueHdl->SetObj(pObj);
+ pGlueHdl->SetPageView(pPV);
+ pGlueHdl->SetObjHdlNum(nId);
+ aHdl.AddHdl(pGlueHdl);
+ }
+ }
+ }
+ }
+ }
+
+ // Drehpunkt/Spiegelachse
+ AddDragModeHdl(eDragMode);
+
+ // add custom handles (used by other apps, e.g. AnchorPos)
+ AddCustomHdl();
+
+ // sort handles
+ aHdl.Sort();
+
+ // #105722# try to restore focus handle index from remembered values
+ if(bSaveOldFocus)
+ {
+ for(sal_uInt32 a(0); a < aHdl.GetHdlCount(); a++)
+ {
+ SdrHdl* pCandidate = aHdl.GetHdl(a);
+
+ if(pCandidate->GetObj()
+ && pCandidate->GetObj() == pSaveObj
+ && pCandidate->GetKind() == eSaveKind
+ && pCandidate->GetPolyNum() == nSavePolyNum
+ && pCandidate->GetPointNum() == nSavePointNum)
+ {
+ aHdl.SetFocusHdl(pCandidate);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void SdrMarkView::AddCustomHdl()
+{
+ // add custom handles (used by other apps, e.g. AnchorPos)
+}
+
+void SdrMarkView::SetDragMode(SdrDragMode eMode)
+{
+ SdrDragMode eMode0=eDragMode;
+ eDragMode=eMode;
+ if (eDragMode==SDRDRAG_RESIZE) eDragMode=SDRDRAG_MOVE;
+ if (eDragMode!=eMode0) {
+ //HMHBOOL bVis=IsMarkHdlShown();
+ //HMHif (bVis) HideMarkHdl();
+ ForceRefToMarked();
+ SetMarkHandles();
+ //HMHif (bVis) ShowMarkHdl();
+ {
+ if (AreObjectsMarked()) MarkListHasChanged();
+ }
+ }
+}
+
+void SdrMarkView::AddDragModeHdl(SdrDragMode eMode)
+{
+ switch(eMode)
+ {
+ case SDRDRAG_ROTATE:
+ {
+ // add rotation center
+ SdrHdl* pHdl = new SdrHdl(aRef1, HDL_REF1);
+
+ aHdl.AddHdl(pHdl);
+
+ break;
+ }
+ case SDRDRAG_MIRROR:
+ {
+ // add mirror axis
+ SdrHdl* pHdl3 = new SdrHdl(aRef2, HDL_REF2);
+ SdrHdl* pHdl2 = new SdrHdl(aRef1, HDL_REF1);
+ SdrHdl* pHdl1 = new SdrHdlLine(*pHdl2, *pHdl3, HDL_MIRX);
+
+ pHdl1->SetObjHdlNum(1); // fuer Sortierung
+ pHdl2->SetObjHdlNum(2); // fuer Sortierung
+ pHdl3->SetObjHdlNum(3); // fuer Sortierung
+
+ aHdl.AddHdl(pHdl1); // Linie als erstes, damit als letztes im HitTest
+ aHdl.AddHdl(pHdl2);
+ aHdl.AddHdl(pHdl3);
+
+ break;
+ }
+ case SDRDRAG_TRANSPARENCE:
+ {
+ // add interactive transparence handle
+ ULONG nMarkAnz = GetMarkedObjectCount();
+ if(nMarkAnz == 1)
+ {
+ SdrObject* pObj = GetMarkedObjectByIndex(0);
+ SdrModel* pModel = GetModel();
+ const SfxItemSet& rSet = pObj->GetMergedItemSet();
+
+ if(SFX_ITEM_SET != rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, FALSE))
+ {
+ // add this item, it's not yet there
+ XFillFloatTransparenceItem aNewItem(
+ (const XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE));
+ XGradient aGrad = aNewItem.GetGradientValue();
+
+ aNewItem.SetEnabled(TRUE);
+ aGrad.SetStartIntens(100);
+ aGrad.SetEndIntens(100);
+ aNewItem.SetGradientValue(aGrad);
+
+ // add undo to allow user to take back this step
+ if( pModel->IsUndoEnabled() )
+ {
+ pModel->BegUndo(SVX_RESSTR(SIP_XA_FILLTRANSPARENCE));
+ pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj));
+ pModel->EndUndo();
+ }
+
+ //pObj->SetItemAndBroadcast(aNewItem);
+ SfxItemSet aNewSet(pModel->GetItemPool());
+ aNewSet.Put(aNewItem);
+ pObj->SetMergedItemSetAndBroadcast(aNewSet);
+ }
+
+ // set values and transform to vector set
+ GradTransformer aGradTransformer;
+ GradTransVector aGradTransVector;
+ GradTransGradient aGradTransGradient;
+
+ aGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
+ aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
+
+ // build handles
+ const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
+ const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
+ SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, SDR_HANDLE_COLOR_SIZE_NORMAL, TRUE);
+ SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, SDR_HANDLE_COLOR_SIZE_NORMAL, TRUE);
+ SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, FALSE);
+ DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
+
+ // link them
+ pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
+ pGradHdl->SetObj(pObj);
+ pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
+ pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
+
+ // insert them
+ aHdl.AddHdl(pColHdl1);
+ aHdl.AddHdl(pColHdl2);
+ aHdl.AddHdl(pGradHdl);
+ }
+ break;
+ }
+ case SDRDRAG_GRADIENT:
+ {
+ // add interactive gradient handle
+ ULONG nMarkAnz = GetMarkedObjectCount();
+ if(nMarkAnz == 1)
+ {
+ SdrObject* pObj = GetMarkedObjectByIndex(0);
+ const SfxItemSet& rSet = pObj->GetMergedItemSet();
+ XFillStyle eFillStyle = ((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
+
+ if(eFillStyle == XFILL_GRADIENT)
+ {
+ // set values and transform to vector set
+ GradTransformer aGradTransformer;
+ GradTransVector aGradTransVector;
+ GradTransGradient aGradTransGradient;
+ Size aHdlSize(15, 15);
+
+ aGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
+ aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, pObj);
+
+ // build handles
+ const Point aTmpPos1(basegfx::fround(aGradTransVector.maPositionA.getX()), basegfx::fround(aGradTransVector.maPositionA.getY()));
+ const Point aTmpPos2(basegfx::fround(aGradTransVector.maPositionB.getX()), basegfx::fround(aGradTransVector.maPositionB.getY()));
+ SdrHdlColor* pColHdl1 = new SdrHdlColor(aTmpPos1, aGradTransVector.aCol1, aHdlSize, FALSE);
+ SdrHdlColor* pColHdl2 = new SdrHdlColor(aTmpPos2, aGradTransVector.aCol2, aHdlSize, FALSE);
+ SdrHdlGradient* pGradHdl = new SdrHdlGradient(aTmpPos1, aTmpPos2, TRUE);
+ DBG_ASSERT(pColHdl1 && pColHdl2 && pGradHdl, "Got not all necessary handles!!");
+
+ // link them
+ pGradHdl->SetColorHandles(pColHdl1, pColHdl2);
+ pGradHdl->SetObj(pObj);
+ pColHdl1->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
+ pColHdl2->SetColorChangeHdl(LINK(pGradHdl, SdrHdlGradient, ColorChangeHdl));
+
+ // insert them
+ aHdl.AddHdl(pColHdl1);
+ aHdl.AddHdl(pColHdl2);
+ aHdl.AddHdl(pGradHdl);
+ }
+ }
+ break;
+ }
+ case SDRDRAG_CROP:
+ {
+ // todo
+ break;
+ }
+ default: break;
+ }
+}
+
+/** handle mouse over effects for handles */
+BOOL SdrMarkView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
+{
+ const ULONG nHdlCount = aHdl.GetHdlCount();
+ if( nHdlCount )
+ {
+ SdrHdl* pMouseOverHdl = 0;
+ if( !rMEvt.IsLeaveWindow() && pWin )
+ {
+ Point aMDPos( pWin->PixelToLogic( rMEvt.GetPosPixel() ) );
+ pMouseOverHdl = PickHandle(aMDPos);
+ }
+
+ // notify last mouse over handle that he lost the mouse
+ for(ULONG nHdl = 0; nHdl < nHdlCount; nHdl++ )
+ {
+ SdrHdl* pCurrentHdl = GetHdl(nHdl);
+ if( pCurrentHdl->mbMouseOver )
+ {
+ if( pCurrentHdl != pMouseOverHdl )
+ {
+ pCurrentHdl->mbMouseOver = false;
+ pCurrentHdl->onMouseLeave();
+ }
+ break;
+ }
+ }
+
+ // notify current mouse over handle
+ if( pMouseOverHdl /* && !pMouseOverHdl->mbMouseOver */ )
+ {
+ pMouseOverHdl->mbMouseOver = true;
+ pMouseOverHdl->onMouseEnter(rMEvt);
+ }
+ }
+ return SdrSnapView::MouseMove(rMEvt, pWin);
+}
+
+void SdrMarkView::ForceRefToMarked()
+{
+ switch(eDragMode)
+ {
+ case SDRDRAG_ROTATE:
+ {
+ Rectangle aR(GetMarkedObjRect());
+ aRef1 = aR.Center();
+
+ break;
+ }
+
+ case SDRDRAG_MIRROR:
+ {
+ // Erstmal die laenge der Spiegelachsenlinie berechnen
+ long nOutMin=0;
+ long nOutMax=0;
+ long nMinLen=0;
+ long nObjDst=0;
+ long nOutHgt=0;
+ OutputDevice* pOut=GetFirstOutputDevice();
+ //OutputDevice* pOut=GetWin(0);
+ if (pOut!=NULL) {
+ // Mindestlaenge 50 Pixel
+ nMinLen=pOut->PixelToLogic(Size(0,50)).Height();
+ // 20 Pixel fuer RefPt-Abstand vom Obj
+ nObjDst=pOut->PixelToLogic(Size(0,20)).Height();
+ // MinY/MaxY
+ // Abstand zum Rand = Mindestlaenge = 10 Pixel
+ long nDst=pOut->PixelToLogic(Size(0,10)).Height();
+ nOutMin=-pOut->GetMapMode().GetOrigin().Y();
+ nOutMax=pOut->GetOutputSize().Height()-1+nOutMin;
+ nOutMin+=nDst;
+ nOutMax-=nDst;
+ // Absolute Mindestlaenge jedoch 10 Pixel
+ if (nOutMax-nOutMin<nDst) {
+ nOutMin+=nOutMax+1;
+ nOutMin/=2;
+ nOutMin-=(nDst+1)/2;
+ nOutMax=nOutMin+nDst;
+ }
+ nOutHgt=nOutMax-nOutMin;
+ // Sonst Mindestlaenge = 1/4 OutHgt
+ long nTemp=nOutHgt/4;
+ if (nTemp>nMinLen) nMinLen=nTemp;
+ }
+
+ Rectangle aR(GetMarkedObjBoundRect());
+ Point aCenter(aR.Center());
+ long nMarkHgt=aR.GetHeight()-1;
+ long nHgt=nMarkHgt+nObjDst*2; // 20 Pixel obej und unten ueberstehend
+ if (nHgt<nMinLen) nHgt=nMinLen; // Mindestlaenge 50 Pixel bzw. 1/4 OutHgt
+
+ long nY1=aCenter.Y()-(nHgt+1)/2;
+ long nY2=nY1+nHgt;
+
+ if (pOut!=NULL && nMinLen>nOutHgt) nMinLen=nOutHgt; // evtl. noch etwas verkuerzen
+
+ if (pOut!=NULL) { // nun vollstaendig in den sichtbaren Bereich schieben
+ if (nY1<nOutMin) {
+ nY1=nOutMin;
+ if (nY2<nY1+nMinLen) nY2=nY1+nMinLen;
+ }
+ if (nY2>nOutMax) {
+ nY2=nOutMax;
+ if (nY1>nY2-nMinLen) nY1=nY2-nMinLen;
+ }
+ }
+
+ aRef1.X()=aCenter.X();
+ aRef1.Y()=nY1;
+ aRef2.X()=aCenter.X();
+ aRef2.Y()=nY2;
+
+ break;
+ }
+
+ case SDRDRAG_TRANSPARENCE:
+ case SDRDRAG_GRADIENT:
+ case SDRDRAG_CROP:
+ {
+ Rectangle aRect(GetMarkedObjBoundRect());
+ aRef1 = aRect.TopLeft();
+ aRef2 = aRect.BottomRight();
+ break;
+ }
+ default: break;
+ }
+}
+
+void SdrMarkView::SetRef1(const Point& rPt)
+{
+ if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
+ {
+ aRef1 = rPt;
+ SdrHdl* pH = aHdl.GetHdl(HDL_REF1);
+ if(pH)
+ pH->SetPos(rPt);
+ //HMHShowMarkHdl();
+ }
+}
+
+void SdrMarkView::SetRef2(const Point& rPt)
+{
+ if(eDragMode == SDRDRAG_MIRROR)
+ {
+ aRef2 = rPt;
+ SdrHdl* pH = aHdl.GetHdl(HDL_REF2);
+ if(pH)
+ pH->SetPos(rPt);
+ //HMHShowMarkHdl();
+ }
+}
+
+void SdrMarkView::CheckMarked()
+{
+ for (ULONG nm=GetMarkedObjectCount(); nm>0;) {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ SdrLayerID nLay=pObj->GetLayer();
+ BOOL bRaus=!pObj->IsInserted(); // Obj geloescht?
+ if (!pObj->Is3DObj()) {
+ bRaus=bRaus || pObj->GetPage()!=pPV->GetPage(); // Obj ploetzlich in anderer Page oder Group
+ }
+ bRaus=bRaus || pPV->GetLockedLayers().IsSet(nLay) || // Layer gesperrt?
+ !pPV->GetVisibleLayers().IsSet(nLay); // Layer nicht sichtbar?
+
+ if( !bRaus )
+ bRaus = !pObj->IsVisible(); // not visible objects can not be marked
+
+ if (!bRaus) {
+ // Joe am 9.3.1997: Gruppierte Objekten koennen nun auch
+ // markiert werden. Nach EnterGroup muessen aber die Objekte
+ // der hoeheren Ebene deselektiert werden.
+ const SdrObjList* pOOL=pObj->GetObjList();
+ const SdrObjList* pVOL=pPV->GetObjList();
+ while (pOOL!=NULL && pOOL!=pVOL) {
+ pOOL=pOOL->GetUpList();
+ }
+ bRaus=pOOL!=pVOL;
+ }
+
+ if (bRaus)
+ {
+ GetMarkedObjectListWriteAccess().DeleteMark(nm);
+ }
+ else
+ {
+ if (!IsGluePointEditMode()) { // Markierte GluePoints nur im GlueEditMode
+ SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ if (pPts!=NULL && pPts->GetCount()!=0) {
+ pPts->Clear();
+ }
+ }
+ }
+ }
+
+ // #97995# at least reset the remembered BoundRect to prevent handle
+ // generation if bForceFrameHandles is TRUE.
+ bMarkedObjRectDirty = TRUE;
+}
+
+void SdrMarkView::SetMarkRects()
+{
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ pPV->SetHasMarkedObj(GetSnapRectFromMarkedObjects(pPV, pPV->MarkSnap()));
+ GetBoundRectFromMarkedObjects(pPV, pPV->MarkBound());
+ }
+}
+
+void SdrMarkView::SetFrameHandles(BOOL bOn)
+{
+ if (bOn!=bForceFrameHandles) {
+ BOOL bOld=ImpIsFrameHandles();
+ bForceFrameHandles=bOn;
+ BOOL bNew=ImpIsFrameHandles();
+ if (bNew!=bOld) {
+ AdjustMarkHdl(); //HMHTRUE);
+ MarkListHasChanged();
+ }
+ }
+}
+
+void SdrMarkView::SetEditMode(SdrViewEditMode eMode)
+{
+ if (eMode!=eEditMode) {
+ BOOL bGlue0=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
+ BOOL bEdge0=((SdrCreateView*)this)->IsEdgeTool();
+ eEditMode0=eEditMode;
+ eEditMode=eMode;
+ BOOL bGlue1=eEditMode==SDREDITMODE_GLUEPOINTEDIT;
+ BOOL bEdge1=((SdrCreateView*)this)->IsEdgeTool();
+ // etwas Aufwand um Flackern zu verhindern beim Umschalten
+ // zwischen GlueEdit und EdgeTool
+ if (bGlue1 && !bGlue0) ImpSetGlueVisible2(bGlue1);
+ if (bEdge1!=bEdge0) ImpSetGlueVisible3(bEdge1);
+ if (!bGlue1 && bGlue0) ImpSetGlueVisible2(bGlue1);
+ if (bGlue0 && !bGlue1) UnmarkAllGluePoints();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrMarkView::IsObjMarkable(SdrObject* pObj, SdrPageView* pPV) const
+{
+ if (pObj)
+ {
+ if (pObj->IsMarkProtect() ||
+ (!bDesignMode && pObj->IsUnoObj()))
+ {
+ // Objekt nicht selektierbar oder
+ // SdrUnoObj nicht im DesignMode
+ return FALSE;
+ }
+ }
+ return pPV!=NULL ? pPV->IsObjMarkable(pObj) : TRUE;
+}
+
+BOOL SdrMarkView::IsMarkedObjHit(const Point& rPnt, short nTol) const
+{
+ BOOL bRet=FALSE;
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ Point aPt(rPnt);
+ for (ULONG nm=0; nm<GetMarkedObjectCount() && !bRet; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ bRet = 0 != CheckSingleSdrObjectHit(aPt,USHORT(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0);
+ }
+ return bRet;
+}
+
+SdrHdl* SdrMarkView::PickHandle(const Point& rPnt, ULONG nOptions, SdrHdl* pHdl0) const
+{
+ if (bSomeObjChgdFlag) { // ggf. Handles neu berechnen lassen!
+ FlushComeBackTimer();
+ }
+ BOOL bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
+ BOOL bNext=(nOptions & SDRSEARCH_NEXT) !=0;
+ Point aPt(rPnt);
+ return aHdl.IsHdlListHit(aPt,bBack,bNext,pHdl0);
+}
+
+BOOL SdrMarkView::MarkObj(const Point& rPnt, short nTol, BOOL bToggle, BOOL bDeep)
+{
+ SdrObject* pObj;
+ SdrPageView* pPV;
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ ULONG nOptions=SDRSEARCH_PICKMARKABLE;
+ if (bDeep) nOptions=nOptions|SDRSEARCH_DEEP;
+ BOOL bRet=PickObj(rPnt,(USHORT)nTol,pObj,pPV,nOptions);
+ if (bRet) {
+ BOOL bUnmark=bToggle && IsObjMarked(pObj);
+ MarkObj(pObj,pPV,bUnmark);
+ }
+ return bRet;
+}
+
+BOOL SdrMarkView::MarkNextObj(BOOL bPrev)
+{
+ SdrPageView* pPageView = GetSdrPageView();
+
+ if(!pPageView)
+ {
+ return FALSE;
+ }
+
+ SortMarkedObjects();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ ULONG nChgMarkNum = ULONG_MAX; // Nummer des zu ersetzenden MarkEntries
+ ULONG nSearchObjNum = bPrev ? 0 : ULONG_MAX;
+ if (nMarkAnz!=0) {
+ nChgMarkNum=bPrev ? 0 : ULONG(nMarkAnz-1);
+ SdrMark* pM=GetSdrMarkByIndex(nChgMarkNum);
+ OSL_ASSERT(pM!=NULL);
+ if (pM->GetMarkedSdrObj() != NULL)
+ nSearchObjNum = pM->GetMarkedSdrObj()->GetNavigationPosition();
+ }
+
+ SdrObject* pMarkObj=NULL;
+ SdrObjList* pSearchObjList=pPageView->GetObjList();
+ ULONG nObjAnz=pSearchObjList->GetObjCount();
+ if (nObjAnz!=0) {
+ if (nSearchObjNum>nObjAnz) nSearchObjNum=nObjAnz;
+ while (pMarkObj==NULL && ((!bPrev && nSearchObjNum>0) || (bPrev && nSearchObjNum<nObjAnz)))
+ {
+ if (!bPrev)
+ nSearchObjNum--;
+ SdrObject* pSearchObj = pSearchObjList->GetObjectForNavigationPosition(nSearchObjNum);
+ if (IsObjMarkable(pSearchObj,pPageView))
+ {
+ if (TryToFindMarkedObject(pSearchObj)==CONTAINER_ENTRY_NOTFOUND)
+ {
+ pMarkObj=pSearchObj;
+ }
+ }
+ if (bPrev) nSearchObjNum++;
+ }
+ }
+
+ if(!pMarkObj)
+ {
+ return FALSE;
+ }
+
+ if (nChgMarkNum!=ULONG_MAX)
+ {
+ GetMarkedObjectListWriteAccess().DeleteMark(nChgMarkNum);
+ }
+ MarkObj(pMarkObj,pPageView); // ruft auch MarkListHasChanged(), AdjustMarkHdl()
+ return TRUE;
+}
+
+BOOL SdrMarkView::MarkNextObj(const Point& rPnt, short nTol, BOOL bPrev)
+{
+ SortMarkedObjects();
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ Point aPt(rPnt);
+ SdrMark* pTopMarkHit=NULL;
+ SdrMark* pBtmMarkHit=NULL;
+ ULONG nTopMarkHit=0;
+ ULONG nBtmMarkHit=0;
+ // oberstes der markierten Objekte suchen, das von rPnt getroffen wird
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ ULONG nm=0;
+ for (nm=nMarkAnz; nm>0 && pTopMarkHit==NULL;) {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ if(CheckSingleSdrObjectHit(aPt,USHORT(nTol),pM->GetMarkedSdrObj(),pM->GetPageView(),0,0))
+ {
+ pTopMarkHit=pM;
+ nTopMarkHit=nm;
+ }
+ }
+ // Nichts gefunden, dann ganz normal ein Obj markieren.
+ if (pTopMarkHit==NULL) return MarkObj(rPnt,USHORT(nTol),FALSE);
+
+ SdrObject* pTopObjHit=pTopMarkHit->GetMarkedSdrObj();
+ SdrObjList* pObjList=pTopObjHit->GetObjList();
+ SdrPageView* pPV=pTopMarkHit->GetPageView();
+ // unterstes der markierten Objekte suchen, das von rPnt getroffen wird
+ // und auf der gleichen PageView liegt wie pTopMarkHit
+ for (nm=0; nm<nMarkAnz && pBtmMarkHit==NULL; nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrPageView* pPV2=pM->GetPageView();
+ if (pPV2==pPV && CheckSingleSdrObjectHit(aPt,USHORT(nTol),pM->GetMarkedSdrObj(),pPV2,0,0))
+ {
+ pBtmMarkHit=pM;
+ nBtmMarkHit=nm;
+ }
+ }
+ if (pBtmMarkHit==NULL) { pBtmMarkHit=pTopMarkHit; nBtmMarkHit=nTopMarkHit; }
+ SdrObject* pBtmObjHit=pBtmMarkHit->GetMarkedSdrObj();
+ ULONG nObjAnz=pObjList->GetObjCount();
+
+ // #110988#
+ //ULONG nSearchBeg=bPrev ? pBtmObjHit->GetOrdNum()+1 : pTopObjHit->GetOrdNum();
+ sal_uInt32 nSearchBeg;
+ E3dScene* pScene = NULL;
+ SdrObject* pObjHit = (bPrev) ? pBtmObjHit : pTopObjHit;
+ sal_Bool bRemap = pObjHit->ISA(E3dCompoundObject)
+ ? ((E3dCompoundObject*)pObjHit)->IsAOrdNumRemapCandidate(pScene)
+ : sal_False;
+
+ if(bPrev)
+ {
+ sal_uInt32 nOrdNumBtm(pBtmObjHit->GetOrdNum());
+
+ if(bRemap)
+ {
+ nOrdNumBtm = pScene->RemapOrdNum(nOrdNumBtm);
+ }
+
+ nSearchBeg = nOrdNumBtm + 1;
+ }
+ else
+ {
+ sal_uInt32 nOrdNumTop(pTopObjHit->GetOrdNum());
+
+ if(bRemap)
+ {
+ nOrdNumTop = pScene->RemapOrdNum(nOrdNumTop);
+ }
+
+ nSearchBeg = nOrdNumTop;
+ }
+
+ ULONG no=nSearchBeg;
+ SdrObject* pFndObj=NULL;
+ //SdrObject* pAktObj=NULL;
+ while (pFndObj==NULL && ((!bPrev && no>0) || (bPrev && no<nObjAnz))) {
+ if (!bPrev) no--;
+ SdrObject* pObj;
+
+ if(bRemap)
+ {
+ pObj = pObjList->GetObj(pScene->RemapOrdNum(no));
+ }
+ else
+ {
+ pObj = pObjList->GetObj(no);
+ }
+
+ if (CheckSingleSdrObjectHit(aPt,USHORT(nTol),pObj,pPV,SDRSEARCH_TESTMARKABLE,0))
+ {
+ if (TryToFindMarkedObject(pObj)==CONTAINER_ENTRY_NOTFOUND) {
+ pFndObj=pObj;
+ } else {
+ // hier wg. Performance ggf. noch no auf Top bzw. auf Btm stellen
+ }
+ }
+ if (bPrev) no++;
+ }
+ if (pFndObj!=NULL)
+ {
+ GetMarkedObjectListWriteAccess().DeleteMark(bPrev?nBtmMarkHit:nTopMarkHit);
+ GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pFndObj,pPV));
+ MarkListHasChanged();
+ AdjustMarkHdl(); //HMHTRUE);
+ }
+ return pFndObj!=NULL;
+}
+
+BOOL SdrMarkView::MarkObj(const Rectangle& rRect, BOOL bUnmark)
+{
+ BOOL bFnd=FALSE;
+ Rectangle aR(rRect);
+ SdrObject* pObj;
+ SdrObjList* pObjList;
+ BrkAction();
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ pObjList=pPV->GetObjList();
+ Rectangle aFrm1(aR);
+ ULONG nObjAnz=pObjList->GetObjCount();
+ for (ULONG nO=0; nO<nObjAnz; nO++) {
+ pObj=pObjList->GetObj(nO);
+ Rectangle aRect(pObj->GetCurrentBoundRect());
+ if (aFrm1.IsInside(aRect)) {
+ if (!bUnmark) {
+ if (IsObjMarkable(pObj,pPV))
+ {
+ GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
+ bFnd=TRUE;
+ }
+ } else {
+ ULONG nPos=TryToFindMarkedObject(pObj);
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ GetMarkedObjectListWriteAccess().DeleteMark(nPos);
+ bFnd=TRUE;
+ }
+ }
+ }
+ }
+ }
+ if (bFnd) {
+ SortMarkedObjects();
+ MarkListHasChanged();
+ AdjustMarkHdl(); //HMHTRUE);
+ //HMHShowMarkHdl();
+ }
+ return bFnd;
+}
+
+void SdrMarkView::MarkObj(SdrObject* pObj, SdrPageView* pPV, BOOL bUnmark, BOOL bImpNoSetMarkHdl)
+{
+ if (pObj!=NULL && pPV!=NULL && IsObjMarkable(pObj, pPV)) {
+ BrkAction();
+ if (!bUnmark)
+ {
+ GetMarkedObjectListWriteAccess().InsertEntry(SdrMark(pObj,pPV));
+ }
+ else
+ {
+ ULONG nPos=TryToFindMarkedObject(pObj);
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ GetMarkedObjectListWriteAccess().DeleteMark(nPos);
+ }
+ }
+ if (!bImpNoSetMarkHdl) {
+ MarkListHasChanged();
+ AdjustMarkHdl(); //HMHTRUE);
+ //HMHif (!bSomeObjChgdFlag) {
+ // ShowMarkHdl kommt sonst mit dem AfterPaintTimer
+ //HMHShowMarkHdl();
+ //HMH}
+ }
+ }
+}
+
+BOOL SdrMarkView::IsObjMarked(SdrObject* pObj) const
+{
+ // nicht so ganz die feine Art: Da FindObject() nicht const ist
+ // muss ich mich hier auf non-const casten.
+ ULONG nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj);
+ return nPos!=CONTAINER_ENTRY_NOTFOUND;
+}
+
+USHORT SdrMarkView::GetMarkHdlSizePixel() const
+{
+ return aHdl.GetHdlSize()*2+1;
+}
+
+void SdrMarkView::SetSolidMarkHdl(BOOL bOn)
+{
+ if (bOn!=aHdl.IsFineHdl()) {
+ //HMHBOOL bMerk=IsMarkHdlShown();
+ //HMHif (bMerk) HideMarkHdl();
+ aHdl.SetFineHdl(bOn);
+ //HMHif (bMerk) ShowMarkHdl();
+ }
+}
+
+void SdrMarkView::SetMarkHdlSizePixel(USHORT nSiz)
+{
+ if (nSiz<3) nSiz=3;
+ nSiz/=2;
+ if (nSiz!=aHdl.GetHdlSize()) {
+ //HMHBOOL bMerk=IsMarkHdlShown();
+ //HMHif (bMerk) HideMarkHdl();
+ aHdl.SetHdlSize(nSiz);
+ //HMHif (bMerk) ShowMarkHdl();
+ }
+}
+
+#define SDRSEARCH_IMPISMASTER 0x80000000 /* MasterPage wird gerade durchsucht */
+SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, USHORT nTol, SdrObject* pObj, SdrPageView* pPV, ULONG nOptions, const SetOfByte* pMVisLay) const
+{
+ if(((nOptions & SDRSEARCH_IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
+ {
+ return NULL;
+ }
+
+ const bool bCheckIfMarkable(nOptions & SDRSEARCH_TESTMARKABLE);
+ const bool bDeep(nOptions & SDRSEARCH_DEEP);
+ const bool bOLE(pObj->ISA(SdrOle2Obj));
+ const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame());
+ SdrObject* pRet=NULL;
+ Rectangle aRect(pObj->GetCurrentBoundRect());
+ USHORT nTol2(nTol);
+
+ // double tolerance for OLE, text frames and objects in
+ // active text edit
+ if(bOLE || bTXT || pObj==((SdrObjEditView*)this)->GetTextEditObject())
+ {
+ nTol2*=2;
+ }
+
+ aRect.Left ()-=nTol2; // Einmal Toleranz drauf fuer alle Objekte
+ aRect.Top ()-=nTol2;
+ aRect.Right ()+=nTol2;
+ aRect.Bottom()+=nTol2;
+
+ if (aRect.IsInside(rPnt))
+ {
+ if ((!bCheckIfMarkable || IsObjMarkable(pObj,pPV)))
+ {
+ SdrObjList* pOL=pObj->GetSubList();
+
+ if (pOL!=NULL && pOL->GetObjCount()!=0)
+ {
+ SdrObject* pTmpObj;
+ // OD 30.06.2003 #108784# - adjustment hit point for virtual
+ // objects.
+ Point aPnt( rPnt );
+
+ if ( pObj->ISA(SdrVirtObj) )
+ {
+ Point aOffset = static_cast<SdrVirtObj*>(pObj)->GetOffset();
+ aPnt.Move( -aOffset.X(), -aOffset.Y() );
+ }
+
+ pRet=CheckSingleSdrObjectHit(aPnt,nTol,pOL,pPV,nOptions,pMVisLay,pTmpObj);
+ }
+ else
+ {
+ if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
+ {
+ pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
+ }
+ }
+ }
+ }
+
+ if (!bDeep && pRet!=NULL)
+ {
+ pRet=pObj;
+ }
+
+ return pRet;
+}
+
+SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, USHORT nTol, SdrObjList* pOL, SdrPageView* pPV, ULONG nOptions, const SetOfByte* pMVisLay, SdrObject*& rpRootObj) const
+{
+ BOOL bBack=(nOptions & SDRSEARCH_BACKWARD)!=0;
+ SdrObject* pRet=NULL;
+ rpRootObj=NULL;
+ if (pOL!=NULL)
+ {
+ // #110988#
+ sal_Bool bRemap(pOL->GetOwnerObj() && pOL->GetOwnerObj()->ISA(E3dScene));
+ E3dScene* pRemapScene = (bRemap ? (E3dScene*)pOL->GetOwnerObj() : 0L);
+
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG nObjNum=bBack ? 0 : nObjAnz;
+ while (pRet==NULL && (bBack ? nObjNum<nObjAnz : nObjNum>0)) {
+ if (!bBack) nObjNum--;
+ SdrObject* pObj;
+
+ // #110988#
+ if(bRemap)
+ {
+ pObj = pOL->GetObj(pRemapScene->RemapOrdNum(nObjNum));
+ }
+ else
+ {
+ pObj = pOL->GetObj(nObjNum);
+ }
+
+ pRet=CheckSingleSdrObjectHit(rPnt,nTol,pObj,pPV,nOptions,pMVisLay);
+ if (pRet!=NULL) rpRootObj=pObj;
+ if (bBack) nObjNum++;
+ }
+ }
+ return pRet;
+}
+
+BOOL SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, ULONG nOptions) const
+{
+ return PickObj(rPnt,nTol,rpObj,rpPV,nOptions,NULL,NULL,NULL);
+}
+
+BOOL SdrMarkView::PickObj(const Point& rPnt, short nTol, SdrObject*& rpObj, SdrPageView*& rpPV, ULONG nOptions, SdrObject** ppRootObj, ULONG* pnMarkNum, USHORT* pnPassNum) const
+{ // Fehlt noch Pass2,Pass3
+ SortMarkedObjects();
+ if (ppRootObj!=NULL) *ppRootObj=NULL;
+ if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
+ if (pnPassNum!=NULL) *pnPassNum=0;
+ rpObj=NULL;
+ rpPV=NULL;
+ BOOL bWholePage=(nOptions & SDRSEARCH_WHOLEPAGE) !=0;
+ BOOL bMarked=(nOptions & SDRSEARCH_MARKED) !=0;
+ BOOL bMasters=!bMarked && (nOptions & SDRSEARCH_ALSOONMASTER) !=0;
+ BOOL bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
+#if OSL_DEBUG_LEVEL > 0
+ BOOL bNext=(nOptions & SDRSEARCH_NEXT) !=0; (void)bNext; // n.i.
+ BOOL bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0; (void)bBoundCheckOn2ndPass;// n.i.
+ BOOL bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0; (void)bCheckNearestOn3rdPass;// n.i.
+#endif
+ if (nTol<0) nTol=ImpGetHitTolLogic(nTol,NULL);
+ Point aPt(rPnt);
+ SdrObject* pObj=NULL;
+ SdrObject* pHitObj=NULL;
+ SdrPageView* pPV=NULL;
+ if (!bBack && ((SdrObjEditView*)this)->IsTextEditFrameHit(rPnt)) {
+ pObj=((SdrObjEditView*)this)->GetTextEditObject();
+ pHitObj=pObj;
+ pPV=((SdrObjEditView*)this)->GetTextEditPageView();
+ }
+ if (bMarked) {
+ ULONG nMrkAnz=GetMarkedObjectCount();
+ ULONG nMrkNum=bBack ? 0 : nMrkAnz;
+ while (pHitObj==NULL && (bBack ? nMrkNum<nMrkAnz : nMrkNum>0)) {
+ if (!bBack) nMrkNum--;
+ SdrMark* pM=GetSdrMarkByIndex(nMrkNum);
+ pObj=pM->GetMarkedSdrObj();
+ pPV=pM->GetPageView();
+ pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,nOptions,NULL);
+ if (bBack) nMrkNum++;
+ }
+ }
+ else
+ {
+ pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ SdrPage* pPage=pPV->GetPage();
+ USHORT nPgAnz=1;
+
+ if(bMasters && pPage->TRG_HasMasterPage())
+ {
+ nPgAnz++;
+ }
+
+ BOOL bExtraPassForWholePage=bWholePage && pPage!=pPV->GetObjList();
+ if (bExtraPassForWholePage) nPgAnz++; // Suche erst in AktObjList, dann auf der gesamten Page
+ USHORT nPgNum=bBack ? 0 : nPgAnz;
+ while (pHitObj==NULL && (bBack ? nPgNum<nPgAnz : nPgNum>0)) {
+ ULONG nTmpOptions=nOptions;
+ if (!bBack) nPgNum--;
+ const SetOfByte* pMVisLay=NULL;
+ SdrObjList* pObjList=NULL;
+ if (pnPassNum!=NULL) *pnPassNum&=~(SDRSEARCHPASS_MASTERPAGE|SDRSEARCHPASS_INACTIVELIST);
+ if (nPgNum>=nPgAnz-1 || (bExtraPassForWholePage && nPgNum>=nPgAnz-2))
+ {
+ pObjList=pPV->GetObjList();
+ if (bExtraPassForWholePage && nPgNum==nPgAnz-2) {
+ pObjList=pPage;
+ if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_INACTIVELIST;
+ }
+ }
+ else
+ {
+ // sonst MasterPage
+ SdrPage& rMasterPage = pPage->TRG_GetMasterPage();
+ pMVisLay = &pPage->TRG_GetMasterPageVisibleLayers();
+ pObjList = &rMasterPage;
+
+ if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_MASTERPAGE;
+ nTmpOptions=nTmpOptions | SDRSEARCH_IMPISMASTER;
+ }
+ pHitObj=CheckSingleSdrObjectHit(aPt,nTol,pObjList,pPV,nTmpOptions,pMVisLay,pObj);
+ if (bBack) nPgNum++;
+ }
+ }
+ }
+ if (pHitObj!=NULL) {
+ if (ppRootObj!=NULL) *ppRootObj=pObj;
+ if ((nOptions & SDRSEARCH_DEEP) !=0) pObj=pHitObj;
+ if ((nOptions & SDRSEARCH_TESTTEXTEDIT) !=0) {
+ if (!pObj->HasTextEdit() || pPV->GetLockedLayers().IsSet(pObj->GetLayer())) {
+ pObj=NULL;
+ }
+ }
+ if (pObj!=NULL && (nOptions & SDRSEARCH_TESTMACRO) !=0) {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=aPt;
+ aHitRec.aDownPos=aPt;
+ aHitRec.nTol=nTol;
+ aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
+ aHitRec.pPageView=pPV;
+ if (!pObj->HasMacro() || !pObj->IsMacroHit(aHitRec)) pObj=NULL;
+ }
+ if (pObj!=NULL && (nOptions & SDRSEARCH_WITHTEXT) !=0 && pObj->GetOutlinerParaObject()==NULL) pObj=NULL;
+ if (pObj!=NULL && (nOptions & SDRSEARCH_TESTTEXTAREA) !=0)
+ {
+ if(!SdrObjectPrimitiveHit(*pObj, aPt, 0, *pPV, 0, true))
+ {
+ pObj = 0;
+ }
+ }
+ if (pObj!=NULL) {
+ rpObj=pObj;
+ rpPV=pPV;
+ if (pnPassNum!=NULL) *pnPassNum|=SDRSEARCHPASS_DIRECT;
+ }
+ }
+ return rpObj!=NULL;
+}
+
+BOOL SdrMarkView::PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, ULONG* pnMarkNum, ULONG nOptions) const
+{
+ SortMarkedObjects();
+ BOOL bBoundCheckOn2ndPass=(nOptions & SDRSEARCH_PASS2BOUND) !=0;
+ BOOL bCheckNearestOn3rdPass=(nOptions & SDRSEARCH_PASS3NEAREST) !=0;
+ rpObj=NULL;
+ rpPV=NULL;
+ if (pnMarkNum!=NULL) *pnMarkNum=CONTAINER_ENTRY_NOTFOUND;
+ Point aPt(rPnt);
+ USHORT nTol=(USHORT)nHitTolLog;
+ BOOL bFnd=FALSE;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ ULONG nMarkNum;
+ for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
+ nMarkNum--;
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrPageView* pPV=pM->GetPageView();
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ bFnd = 0 != CheckSingleSdrObjectHit(aPt,nTol,pObj,pPV,SDRSEARCH_TESTMARKABLE,0);
+ if (bFnd) {
+ rpObj=pObj;
+ rpPV=pPV;
+ if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
+ }
+ }
+ if ((bBoundCheckOn2ndPass || bCheckNearestOn3rdPass) && !bFnd) {
+ SdrObject* pBestObj=NULL;
+ SdrPageView* pBestPV=NULL;
+ ULONG nBestMarkNum=0;
+ ULONG nBestDist=ULONG_MAX;
+ for (nMarkNum=nMarkAnz; nMarkNum>0 && !bFnd;) {
+ nMarkNum--;
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrPageView* pPV=pM->GetPageView();
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ Rectangle aRect(pObj->GetCurrentBoundRect());
+ aRect.Left ()-=nTol;
+ aRect.Top ()-=nTol;
+ aRect.Right ()+=nTol;
+ aRect.Bottom()+=nTol;
+ if (aRect.IsInside(aPt)) {
+ bFnd=TRUE;
+ rpObj=pObj;
+ rpPV=pPV;
+ if (pnMarkNum!=NULL) *pnMarkNum=nMarkNum;
+ } else if (bCheckNearestOn3rdPass) {
+ ULONG nDist=0;
+ if (aPt.X()<aRect.Left()) nDist+=aRect.Left()-aPt.X();
+ if (aPt.X()>aRect.Right()) nDist+=aPt.X()-aRect.Right();
+ if (aPt.Y()<aRect.Top()) nDist+=aRect.Top()-aPt.Y();
+ if (aPt.Y()>aRect.Bottom()) nDist+=aPt.Y()-aRect.Bottom();
+ if (nDist<nBestDist) {
+ pBestObj=pObj;
+ pBestPV=pPV;
+ nBestMarkNum=nMarkNum;
+ }
+ }
+ }
+ if (bCheckNearestOn3rdPass && !bFnd) {
+ rpObj=pBestObj;
+ rpPV=pBestPV;
+ if (pnMarkNum!=NULL) *pnMarkNum=nBestMarkNum;
+ bFnd=pBestObj!=NULL;
+ }
+ }
+ return bFnd;
+}
+
+SdrHitKind SdrMarkView::PickSomething(const Point& rPnt, short nTol) const
+{
+ nTol=ImpGetHitTolLogic(nTol,NULL);
+ SdrHitKind eRet=SDRHIT_NONE;
+ Point aPt(rPnt);
+ SdrObject* pObj=NULL;
+ SdrPageView* pPV=NULL;
+ if (eRet==SDRHIT_NONE && PickObj(rPnt,USHORT(nTol),pObj,pPV,SDRSEARCH_PICKMARKABLE)) {
+ Rectangle aRct1(aPt-Point(nTol,nTol),aPt+Point(nTol,nTol)); // HitRect fuer Toleranz
+ Rectangle aBR(pObj->GetCurrentBoundRect());
+ if (aRct1.IsInside(aBR.TopLeft())) eRet=SDRHIT_BOUNDTL;
+ else if (aRct1.IsInside(aBR.TopCenter())) eRet=SDRHIT_BOUNDTC;
+ else if (aRct1.IsInside(aBR.TopRight())) eRet=SDRHIT_BOUNDTR;
+ else if (aRct1.IsInside(aBR.LeftCenter())) eRet=SDRHIT_BOUNDCL;
+ else if (aRct1.IsInside(aBR.RightCenter())) eRet=SDRHIT_BOUNDCR;
+ else if (aRct1.IsInside(aBR.BottomLeft())) eRet=SDRHIT_BOUNDBL;
+ else if (aRct1.IsInside(aBR.BottomCenter())) eRet=SDRHIT_BOUNDBC;
+ else if (aRct1.IsInside(aBR.BottomRight())) eRet=SDRHIT_BOUNDBR;
+ else eRet=SDRHIT_OBJECT;
+ }
+ return eRet;
+}
+
+void SdrMarkView::UnmarkAllObj(SdrPageView* pPV)
+{
+ if (GetMarkedObjectCount()!=0) {
+ BrkAction();
+ //HMHBOOL bVis=bHdlShown;
+ //HMHif (bVis) HideMarkHdl();
+ if (pPV!=NULL)
+ {
+ GetMarkedObjectListWriteAccess().DeletePageView(*pPV);
+ }
+ else
+ {
+ GetMarkedObjectListWriteAccess().Clear();
+ }
+ pMarkedObj=NULL;
+ pMarkedPV=NULL;
+ MarkListHasChanged();
+ AdjustMarkHdl(); //HMHTRUE);
+ //HMHif (bVis) ShowMarkHdl(); // ggf. fuer die RefPoints
+ }
+}
+
+void SdrMarkView::MarkAllObj(SdrPageView* _pPV)
+{
+ BrkAction();
+ //HMHHideMarkHdl();
+
+ if(!_pPV)
+ {
+ _pPV = GetSdrPageView();
+ }
+
+ // #i69171# _pPV may still be NULL if there is no SDrPageView (!), e.g. when inserting
+ // other files
+ if(_pPV)
+ {
+ const bool bMarkChg(GetMarkedObjectListWriteAccess().InsertPageView(*_pPV));
+
+ if(bMarkChg)
+ {
+ MarkListHasChanged();
+ }
+ }
+
+ if(GetMarkedObjectCount())
+ {
+ AdjustMarkHdl(); //HMHTRUE);
+ //HMHShowMarkHdl();
+ }
+}
+
+void SdrMarkView::AdjustMarkHdl() //HMHBOOL bRestraintPaint)
+{
+ //HMHBOOL bVis=bHdlShown;
+ //HMHif (bVis) HideMarkHdl();
+ CheckMarked();
+ SetMarkRects();
+ SetMarkHandles();
+ //HMHif(bRestraintPaint && bVis)
+ //HMH{
+ //HMH ShowMarkHdl();
+ //HMH}
+}
+
+Rectangle SdrMarkView::GetMarkedObjBoundRect() const
+{
+ Rectangle aRect;
+ for (ULONG nm=0; nm<GetMarkedObjectCount(); nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ Rectangle aR1(pO->GetCurrentBoundRect());
+ if (aRect.IsEmpty()) aRect=aR1;
+ else aRect.Union(aR1);
+ }
+ return aRect;
+}
+
+const Rectangle& SdrMarkView::GetMarkedObjRect() const
+{
+ if (bMarkedObjRectDirty) {
+ ((SdrMarkView*)this)->bMarkedObjRectDirty=FALSE;
+ Rectangle aRect;
+ for (ULONG nm=0; nm<GetMarkedObjectCount(); nm++) {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ Rectangle aR1(pO->GetSnapRect());
+ if (aRect.IsEmpty()) aRect=aR1;
+ else aRect.Union(aR1);
+ }
+ ((SdrMarkView*)this)->aMarkedObjRect=aRect;
+ }
+ return aMarkedObjRect;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::ImpTakeDescriptionStr(USHORT nStrCacheID, XubString& rStr, USHORT nVal, USHORT nOpt) const
+{
+ rStr = ImpGetResStr(nStrCacheID);
+ xub_StrLen nPos = rStr.SearchAscii("%1");
+
+ if(nPos != STRING_NOTFOUND)
+ {
+ rStr.Erase(nPos, 2);
+
+ if(nOpt == IMPSDR_POINTSDESCRIPTION)
+ {
+ rStr.Insert(GetDescriptionOfMarkedPoints(), nPos);
+ }
+ else if(nOpt == IMPSDR_GLUEPOINTSDESCRIPTION)
+ {
+ rStr.Insert(GetDescriptionOfMarkedGluePoints(), nPos);
+ }
+ else
+ {
+ rStr.Insert(GetDescriptionOfMarkedObjects(), nPos);
+ }
+ }
+
+ nPos = rStr.SearchAscii("%2");
+
+ if(nPos != STRING_NOTFOUND)
+ {
+ rStr.Erase(nPos, 2);
+ rStr.Insert(UniString::CreateFromInt32(nVal), nPos);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrMarkView::EnterMarkedGroup()
+{
+ BOOL bRet=FALSE;
+ // Es wird nur die erste gefundene Gruppe (also nur in einer PageView) geentert
+ // Weil PageView::EnterGroup ein AdjustMarkHdl ruft.
+ // Das muss ich per Flag mal unterbinden vvvvvvvv
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ BOOL bEnter=FALSE;
+ for (sal_uInt32 nm(GetMarkedObjectCount()); nm > 0 && !bEnter;)
+ {
+ nm--;
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ if (pM->GetPageView()==pPV) {
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (pObj->IsGroupObject()) {
+ if (pPV->EnterGroup(pObj)) {
+ bRet=TRUE;
+ bEnter=TRUE;
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::MarkListHasChanged()
+{
+ GetMarkedObjectListWriteAccess().SetNameDirty();
+ SetEdgesOfMarkedNodesDirty(); // bEdgesOfMarkedNodesDirty=TRUE;
+
+ bMarkedObjRectDirty=TRUE;
+ bMarkedPointsRectsDirty=TRUE;
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ BOOL bOneEdgeMarked=FALSE;
+ if (GetMarkedObjectCount()==1) {
+ const SdrObject* pObj=GetMarkedObjectByIndex(0);
+ if (pObj->GetObjInventor()==SdrInventor) {
+ UINT16 nIdent=pObj->GetObjIdentifier();
+ bOneEdgeMarked=nIdent==OBJ_EDGE;
+ }
+ }
+ ImpSetGlueVisible4(bOneEdgeMarked);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::SetMoveOutside(BOOL bOn)
+{
+ aHdl.SetMoveOutside(bOn);
+}
+
+BOOL SdrMarkView::IsMoveOutside() const
+{
+ return aHdl.IsMoveOutside();
+}
+
+void SdrMarkView::SetDesignMode( BOOL _bOn )
+{
+ if ( bDesignMode != _bOn )
+ {
+ bDesignMode = _bOn;
+ SdrPageView* pPageView = GetSdrPageView();
+ if ( pPageView )
+ pPageView->SetDesignMode( _bOn );
+ }
+}
+
+// MarkHandles Objektaenderung:
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// - Bei Notify mit HINT_OBJCHG (oder so) werden die Handles erstmal versteckt
+// (wenn nicht schon wegen Dragging versteckt).
+// - XorHdl: Bei ModelHasChanged() werden sie dann wieder angezeigt.
+// - PaintEvents kommen nun durch.
+// - Die XorHandles werden z.T. wieder uebermalt.
+// - Xor: Nach dem Painten werden die Handles im (vom PaintHandler gerufenen)
+// CompleteRedraw per ToggleShownXor bei gesetzter ClipRegion nochmal gemalt
+// und damit ist alles in Butter.
+// - ToggleShownXor macht bei SolidHdl nix weil bHdlShown=FALSE
+// - Der AfterPaintTimer wird gestartet.
+// - SolidHdl: Im AfterPaintHandler wird ShowMarkHdl gerufen.
+// Da die Handles zu diesem Zeitpunkt nicht angezeigt sind wird:
+// - SaveBackground durchgefuehrt.
+// - DrawMarkHdl gerufen und bHdlShown gesetzt.
+//
+// MarkHandles bei sonstigem Invalidate:
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// In diesem Fall bekomme ich kein Notify und beim Aufruf des
+// PaintHandlers->CompleteRedraw() sind auch die SolidHandles sichtbar.
+
diff --git a/svx/source/svdraw/svdmrkv1.cxx b/svx/source/svdraw/svdmrkv1.cxx
new file mode 100644
index 000000000000..fe271c80534d
--- /dev/null
+++ b/svx/source/svdraw/svdmrkv1.cxx
@@ -0,0 +1,724 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdmrkv.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdoedge.hxx>
+#include "svdglob.hxx"
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include "svddrgm1.hxx"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@ @@ @@ @@ @@ @@ @@@@@@ @@ @@ @@@@ @@@@@ @@ @@ @@ @@@@@ @@@@@ @@ @@ @@ @@ @@@@
+// @@ @@ @@ @@ @@@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@
+// @@ @@ @@ @@ @@@@@@ @@ @@ @@ @@@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@
+// @@@@@ @@ @@ @@@@@@ @@@@ @@ @@@@@@@ @@@@@@ @@@@@ @@@@ @@ @@@@ @@@@@ @@ @@ @@@@@@ @@ @@@
+// @@ @@ @@ @@ @@@ @@ @@ @@ @@ @ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@ @@ @@@@ @@ @@ @@@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrMarkView::HasMarkablePoints() const
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ if (!ImpIsFrameHandles()) {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz<=nFrameHandlesLimit) {
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ bRet=pObj->IsPolyObj();
+ }
+ }
+ }
+ return bRet;
+}
+
+ULONG SdrMarkView::GetMarkablePointCount() const
+{
+ ForceUndirtyMrkPnt();
+ ULONG nAnz=0;
+ if (!ImpIsFrameHandles()) {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz<=nFrameHandlesLimit) {
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (pObj->IsPolyObj()) {
+ nAnz+=pObj->GetPointCount();
+ }
+ }
+ }
+ }
+ return nAnz;
+}
+
+BOOL SdrMarkView::HasMarkedPoints() const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bRet=FALSE;
+ if (!ImpIsFrameHandles()) {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz<=nFrameHandlesLimit) {
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont* pPts=pM->GetMarkedPoints();
+ bRet=pPts!=NULL && pPts->GetCount()!=0;
+ }
+ }
+ }
+ return bRet;
+}
+
+ULONG SdrMarkView::GetMarkedPointCount() const
+{
+ ForceUndirtyMrkPnt();
+ ULONG nAnz=0;
+ if (!ImpIsFrameHandles()) {
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ if (nMarkAnz<=nFrameHandlesLimit) {
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont* pPts=pM->GetMarkedPoints();
+ if (pPts!=NULL) nAnz+=pPts->GetCount();
+ }
+ }
+ }
+ return nAnz;
+}
+
+BOOL SdrMarkView::IsPointMarkable(const SdrHdl& rHdl) const
+{
+ return !ImpIsFrameHandles() && &rHdl!=NULL && !rHdl.IsPlusHdl() && rHdl.GetKind()!=HDL_GLUE && rHdl.GetKind()!=HDL_SMARTTAG && rHdl.GetObj()!=NULL && rHdl.GetObj()->IsPolyObj();
+}
+
+BOOL SdrMarkView::MarkPointHelper(SdrHdl* pHdl, SdrMark* pMark, BOOL bUnmark)
+{
+ return ImpMarkPoint( pHdl, pMark, bUnmark );
+}
+
+BOOL SdrMarkView::ImpMarkPoint(SdrHdl* pHdl, SdrMark* pMark, BOOL bUnmark)
+{
+ if (pHdl==NULL || pHdl->IsPlusHdl() || pHdl->GetKind()==HDL_GLUE)
+ return FALSE;
+
+ if (pHdl->IsSelected() != bUnmark)
+ return FALSE;
+
+ SdrObject* pObj=pHdl->GetObj();
+ if (pObj==NULL || !pObj->IsPolyObj())
+ return FALSE;
+
+ if (pMark==NULL)
+ {
+ ULONG nMarkNum=TryToFindMarkedObject(pObj);
+ if (nMarkNum==CONTAINER_ENTRY_NOTFOUND)
+ return FALSE;
+ pMark=GetSdrMarkByIndex(nMarkNum);
+ }
+ const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
+ SdrUShortCont* pPts=pMark->ForceMarkedPoints();
+ if (!bUnmark)
+ {
+ pPts->Insert((sal_uInt16)nHdlNum);
+ }
+ else
+ {
+ ULONG nBla=pPts->GetPos((sal_uInt16)nHdlNum);
+ if (nBla!=CONTAINER_ENTRY_NOTFOUND)
+ {
+ pPts->Remove(nBla);
+ }
+ else
+ {
+ return FALSE; // Fehlerfall!
+ }
+ }
+
+ pHdl->SetSelected(!bUnmark);
+ if (!bPlusHdlAlways)
+ {
+ if (!bUnmark)
+ {
+ sal_uInt32 nAnz(pObj->GetPlusHdlCount(*pHdl));
+ for (sal_uInt32 i=0; i<nAnz; i++)
+ {
+ SdrHdl* pPlusHdl=pObj->GetPlusHdl(*pHdl,i);
+ if (pPlusHdl!=NULL)
+ {
+ pPlusHdl->SetObj(pObj);
+ pPlusHdl->SetPageView(pMark->GetPageView());
+ pPlusHdl->SetPlusHdl(TRUE);
+ aHdl.AddHdl(pPlusHdl);
+ }
+ }
+ }
+ else
+ {
+ for (ULONG i = aHdl.GetHdlCount(); i>0;)
+ {
+ i--;
+ SdrHdl* pPlusHdl=aHdl.GetHdl(i);
+ if (pPlusHdl->IsPlusHdl() && pPlusHdl->GetSourceHdlNum()==nHdlNum)
+ {
+ aHdl.RemoveHdl(i);
+ delete pPlusHdl;
+ }
+ }
+ }
+ }
+
+ // #97016# II: Sort handles. This was missing in ImpMarkPoint all the time.
+ aHdl.Sort();
+
+ return TRUE;
+}
+
+
+BOOL SdrMarkView::MarkPoint(SdrHdl& rHdl, BOOL bUnmark)
+{
+ if (&rHdl==NULL) return FALSE;
+ ForceUndirtyMrkPnt();
+ BOOL bRet=FALSE;
+ const SdrObject* pObj=rHdl.GetObj();
+ if (IsPointMarkable(rHdl) && rHdl.IsSelected()==bUnmark) {
+ ULONG nMarkNum=TryToFindMarkedObject(pObj);
+ if (nMarkNum!=CONTAINER_ENTRY_NOTFOUND) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrUShortCont* pPts=pM->ForceMarkedPoints();
+ pPts->ForceSort();
+ if (ImpMarkPoint(&rHdl,pM,bUnmark)) {
+ pPts->ForceSort();
+ MarkListHasChanged();
+ bRet=TRUE;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+BOOL SdrMarkView::MarkPoints(const Rectangle* pRect, BOOL bUnmark)
+{
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ const SdrObject* pObj0=NULL;
+ const SdrPageView* pPV0=NULL;
+ SdrMark* pM=NULL;
+ aHdl.Sort();
+ //HMHBOOL bHideHdl=IsMarkHdlShown() && IsSolidMarkHdl() && !bPlusHdlAlways;
+ ULONG nHdlAnz=aHdl.GetHdlCount();
+ for (ULONG nHdlNum=nHdlAnz; nHdlNum>0;) {
+ nHdlNum--;
+ SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
+ if (IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) {
+ const SdrObject* pObj=pHdl->GetObj();
+ const SdrPageView* pPV=pHdl->GetPageView();
+ if (pObj!=pObj0 || pPV!=pPV0 || pM==NULL) { // Dieser Abschnitt dient zur Optimierung,
+ if (pM!=NULL) {
+ SdrUShortCont* pPts=pM->GetMarkedPoints();
+ if (pPts!=NULL) pPts->ForceSort();
+ }
+ ULONG nMarkNum=TryToFindMarkedObject(pObj); // damit ImpMarkPoint() nicht staendig das
+ if (nMarkNum!=CONTAINER_ENTRY_NOTFOUND) { // Objekt in der MarkList suchen muss.
+ pM=GetSdrMarkByIndex(nMarkNum);
+ pObj0=pObj;
+ pPV0=pPV;
+ SdrUShortCont* pPts=pM->ForceMarkedPoints();
+ pPts->ForceSort();
+ } else {
+#ifdef DBG_UTIL
+ if (pObj->IsInserted()) {
+ DBG_ERROR("SdrMarkView::MarkPoints(const Rectangle* pRect): Markiertes Objekt nicht gefunden");
+ }
+#endif
+ pM=NULL;
+ }
+ }
+ Point aPos(pHdl->GetPos());
+ if (pM!=NULL && (pRect==NULL || pRect->IsInside(aPos))) {
+ //HMHif (bHideHdl && IsMarkHdlShown() && pHdl->GetObj()!=NULL) {
+ //HMHsal_uInt32 nAnz=pHdl->GetObj()->GetPlusHdlCount(*pHdl);
+ //HMHif (nAnz!=0L) HideMarkHdl(); // #36987#
+ //HMH}
+ if (ImpMarkPoint(pHdl,pM,bUnmark)) bChgd=TRUE;
+ }
+ }
+ }
+ if (pM!=NULL) { // Den zuletzt geaenderten MarkEntry ggf. noch aufraeumen
+ SdrUShortCont* pPts=pM->GetMarkedPoints();
+ if (pPts!=NULL) pPts->ForceSort();
+ }
+ //HMHif (bHideHdl) ShowMarkHdl(); // #36987#
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+
+ return bChgd;
+}
+
+BOOL SdrMarkView::MarkNextPoint(BOOL /*bPrev*/)
+{
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ // ...
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+BOOL SdrMarkView::MarkNextPoint(const Point& /*rPnt*/, BOOL /*bPrev*/)
+{
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ // ...
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+const Rectangle& SdrMarkView::GetMarkedPointsRect() const
+{
+ ForceUndirtyMrkPnt();
+ if (bMarkedPointsRectsDirty) ImpSetPointsRects();
+ return aMarkedPointsRect;
+}
+
+void SdrMarkView::SetPlusHandlesAlwaysVisible(BOOL bOn)
+{ // HandlePaint optimieren !!!!!!!
+ ForceUndirtyMrkPnt();
+ if (bOn!=bPlusHdlAlways) {
+ //HMHBOOL bVis=IsMarkHdlShown();
+ //HMHif (bVis) HideMarkHdl();
+ bPlusHdlAlways=bOn;
+ SetMarkHandles();
+ //HMHif (bVis) ShowMarkHdl();
+ MarkListHasChanged();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// ImpSetPointsRects() ist fuer PolyPoints und GluePoints!
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::ImpSetPointsRects() const
+{
+ Rectangle aPnts;
+ Rectangle aGlue;
+ ULONG nHdlAnz=aHdl.GetHdlCount();
+ for (ULONG nHdlNum=0; nHdlNum<nHdlAnz; nHdlNum++) {
+ const SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
+ SdrHdlKind eKind=pHdl->GetKind();
+ if ((eKind==HDL_POLY && pHdl->IsSelected()) || eKind==HDL_GLUE) {
+ Point aPt(pHdl->GetPos());
+ Rectangle& rR=eKind==HDL_GLUE ? aGlue : aPnts;
+ if (rR.IsEmpty()) {
+ rR=Rectangle(aPt,aPt);
+ } else {
+ if (aPt.X()<rR.Left ()) rR.Left ()=aPt.X();
+ if (aPt.X()>rR.Right ()) rR.Right ()=aPt.X();
+ if (aPt.Y()<rR.Top ()) rR.Top ()=aPt.Y();
+ if (aPt.Y()>rR.Bottom()) rR.Bottom()=aPt.Y();
+ }
+ }
+ }
+ ((SdrMarkView*)this)->aMarkedPointsRect=aPnts;
+ ((SdrMarkView*)this)->aMarkedGluePointsRect=aGlue;
+ ((SdrMarkView*)this)->bMarkedPointsRectsDirty=FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// UndirtyMrkPnt() ist fuer PolyPoints und GluePoints!
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrMarkView::UndirtyMrkPnt() const
+{
+ BOOL bChg=FALSE;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ // PolyPoints
+ SdrUShortCont* pPts=pM->GetMarkedPoints();
+ if (pPts!=NULL) {
+ if (pObj->IsPolyObj()) {
+ // Ungueltig markierte Punkte entfernen, also alle
+ // Eintraege die groesser sind als die Punktanzahl des Objekts
+ sal_uInt32 nMax(pObj->GetPointCount());
+ sal_uInt32 nPtNum(0xffffffff);
+
+ pPts->ForceSort();
+
+ for (sal_uInt32 nIndex(pPts->GetCount()); nIndex > 0L && nPtNum >= nMax;)
+ {
+ nIndex--;
+ nPtNum = pPts->GetObject(nIndex);
+
+ if(nPtNum >= nMax)
+ {
+ pPts->Remove(nIndex);
+ bChg = TRUE;
+ }
+ }
+ }
+ else
+ {
+ DBG_ERROR("SdrMarkView::UndirtyMrkPnt(): Markierte Punkte an einem Objekt, dass kein PolyObj ist!");
+ if(pPts && pPts->GetCount())
+ {
+ pPts->Clear();
+ bChg = TRUE;
+ }
+ }
+ }
+
+ // GluePoints
+ pPts=pM->GetMarkedGluePoints();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pPts!=NULL) {
+ if (pGPL!=NULL) {
+ // Ungueltig markierte Klebepunkte entfernen, also alle
+ // Eintraege (Id's) die nicht in der GluePointList des
+ // Objekts enthalten sind
+ pPts->ForceSort();
+ for (ULONG nIndex=pPts->GetCount(); nIndex>0;) {
+ nIndex--;
+ USHORT nId=pPts->GetObject(nIndex);
+ if (pGPL->FindGluePoint(nId)==SDRGLUEPOINT_NOTFOUND) {
+ pPts->Remove(nIndex);
+ bChg=TRUE;
+ }
+ }
+ } else {
+ if (pPts!=NULL && pPts->GetCount()!=0) {
+ pPts->Clear(); // Objekt hat keine Klebepunkte (mehr)
+ bChg=TRUE;
+ }
+ }
+ }
+ }
+ if (bChg) ((SdrMarkView*)this)->bMarkedPointsRectsDirty=TRUE;
+ ((SdrMarkView*)this)->bMrkPntDirty=FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrMarkView::HasMarkableGluePoints() const
+{
+ BOOL bRet=FALSE;
+ if (IsGluePointEditMode()) {
+ ForceUndirtyMrkPnt();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+
+ // #i38892#
+ if(pGPL && pGPL->GetCount())
+ {
+ for(sal_uInt16 a(0); !bRet && a < pGPL->GetCount(); a++)
+ {
+ if((*pGPL)[a].IsUserDefined())
+ {
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+ULONG SdrMarkView::GetMarkableGluePointCount() const
+{
+ ULONG nAnz=0;
+ if (IsGluePointEditMode()) {
+ ForceUndirtyMrkPnt();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+
+ // #i38892#
+ if(pGPL && pGPL->GetCount())
+ {
+ for(sal_uInt16 a(0); a < pGPL->GetCount(); a++)
+ {
+ if((*pGPL)[a].IsUserDefined())
+ {
+ nAnz++;
+ }
+ }
+ }
+ }
+ }
+ return nAnz;
+}
+
+BOOL SdrMarkView::HasMarkedGluePoints() const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bRet=FALSE;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz && !bRet; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ bRet=pPts!=NULL && pPts->GetCount()!=0;
+ }
+ return bRet;
+}
+
+ULONG SdrMarkView::GetMarkedGluePointCount() const
+{
+ ForceUndirtyMrkPnt();
+ ULONG nAnz=0;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ if (pPts!=NULL) nAnz+=pPts->GetCount();
+ }
+ return nAnz;
+}
+
+BOOL SdrMarkView::MarkGluePoints(const Rectangle* pRect, BOOL bUnmark)
+{
+ if (!IsGluePointEditMode() && !bUnmark) return FALSE;
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nMarkNum=0; nMarkNum<nMarkAnz; nMarkNum++) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ if (bUnmark && pRect==NULL) { // UnmarkAll
+ if (pPts!=NULL && pPts->GetCount()!=0) {
+ pPts->Clear();
+ bChgd=TRUE;
+ }
+ } else {
+ if (pGPL!=NULL && (pPts!=NULL || !bUnmark)) {
+ USHORT nGPAnz=pGPL->GetCount();
+ for (USHORT nGPNum=0; nGPNum<nGPAnz; nGPNum++) {
+ const SdrGluePoint& rGP=(*pGPL)[nGPNum];
+
+ // #i38892#
+ if(rGP.IsUserDefined())
+ {
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ if (pRect==NULL || pRect->IsInside(aPos)) {
+ if (pPts==NULL) pPts=pM->ForceMarkedGluePoints();
+ else pPts->ForceSort();
+ ULONG nPos=pPts->GetPos(rGP.GetId());
+ if (!bUnmark && nPos==CONTAINER_ENTRY_NOTFOUND) {
+ bChgd=TRUE;
+ pPts->Insert(rGP.GetId());
+ }
+ if (bUnmark && nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ bChgd=TRUE;
+ pPts->Remove(nPos);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (bChgd) {
+ AdjustMarkHdl();
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+BOOL SdrMarkView::PickGluePoint(const Point& rPnt, SdrObject*& rpObj, USHORT& rnId, SdrPageView*& rpPV, ULONG nOptions) const
+{
+ SdrObject* pObj0=rpObj;
+ //SdrPageView* pPV0=rpPV;
+ USHORT nId0=rnId;
+ rpObj=NULL; rpPV=NULL; rnId=0;
+ if (!IsGluePointEditMode()) return FALSE;
+ BOOL bBack=(nOptions & SDRSEARCH_BACKWARD) !=0;
+ BOOL bNext=(nOptions & SDRSEARCH_NEXT) !=0;
+ OutputDevice* pOut=(OutputDevice*)pActualOutDev;
+ if (pOut==NULL) pOut=GetFirstOutputDevice(); //GetWin(0);
+ if (pOut==NULL) return FALSE;
+ SortMarkedObjects();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ ULONG nMarkNum=bBack ? 0 : nMarkAnz;
+ if (bNext) {
+ nMarkNum=((SdrMarkView*)this)->TryToFindMarkedObject(pObj0);
+ if (nMarkNum==CONTAINER_ENTRY_NOTFOUND) return FALSE;
+ if (!bBack) nMarkNum++;
+ }
+ while (bBack ? nMarkNum<nMarkAnz : nMarkNum>0) {
+ if (!bBack) nMarkNum--;
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=NULL) {
+ USHORT nNum=pGPL->HitTest(rPnt,*pOut,pObj,bBack,bNext,nId0);
+ if (nNum!=SDRGLUEPOINT_NOTFOUND)
+ {
+ // #i38892#
+ const SdrGluePoint& rCandidate = (*pGPL)[nNum];
+
+ if(rCandidate.IsUserDefined())
+ {
+ rpObj=pObj;
+ rnId=(*pGPL)[nNum].GetId();
+ rpPV=pPV;
+ return TRUE;
+ }
+ }
+ }
+ bNext=FALSE; // HitNextGluePoint nur beim ersten Obj
+ if (bBack) nMarkNum++;
+ }
+ return FALSE;
+}
+
+BOOL SdrMarkView::MarkGluePoint(const SdrObject* pObj, USHORT nId, const SdrPageView* /*pPV*/, BOOL bUnmark)
+{
+ if (!IsGluePointEditMode()) return FALSE;
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ if (pObj!=NULL) {
+ ULONG nMarkPos=TryToFindMarkedObject(pObj);
+ if (nMarkPos!=CONTAINER_ENTRY_NOTFOUND) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkPos);
+ SdrUShortCont* pPts=bUnmark ? pM->GetMarkedGluePoints() : pM->ForceMarkedGluePoints();
+ if (pPts!=NULL) {
+ ULONG nPointPos=pPts->GetPos(nId);
+ if (!bUnmark && nPointPos==CONTAINER_ENTRY_NOTFOUND) {
+ bChgd=TRUE;
+ pPts->Insert(nId);
+ }
+ if (bUnmark && nPointPos!=CONTAINER_ENTRY_NOTFOUND) {
+ bChgd=TRUE;
+ pPts->Remove(nPointPos);
+ }
+ }
+ } else {
+ // Objekt implizit markieren ...
+ // ... fehlende Implementation
+ }
+ }
+ if (bChgd) {
+ AdjustMarkHdl();
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+BOOL SdrMarkView::IsGluePointMarked(const SdrObject* pObj, USHORT nId) const
+{
+ ForceUndirtyMrkPnt();
+ BOOL bRet=FALSE;
+ ULONG nPos=((SdrMarkView*)this)->TryToFindMarkedObject(pObj); // casting auf NonConst
+ if (nPos!=CONTAINER_ENTRY_NOTFOUND) {
+ const SdrMark* pM=GetSdrMarkByIndex(nPos);
+ const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
+ if (pPts!=NULL) {
+ bRet=pPts->Exist(nId);
+ }
+ }
+ return bRet;
+}
+
+BOOL SdrMarkView::UnmarkGluePoint(const SdrHdl& rHdl)
+{
+ if (&rHdl!=NULL && rHdl.GetKind()==HDL_GLUE && rHdl.GetObj()!=NULL) {
+ return MarkGluePoint(rHdl.GetObj(),(sal_uInt16)rHdl.GetObjHdlNum(),rHdl.GetPageView(),TRUE);
+ } else return FALSE;
+}
+
+SdrHdl* SdrMarkView::GetGluePointHdl(const SdrObject* pObj, USHORT nId) const
+{
+ ForceUndirtyMrkPnt();
+ ULONG nHdlAnz=aHdl.GetHdlCount();
+ for (ULONG nHdlNum=0; nHdlNum<nHdlAnz; nHdlNum++) {
+ SdrHdl* pHdl=aHdl.GetHdl(nHdlNum);
+ if (pHdl->GetObj()==pObj &&
+ pHdl->GetKind()==HDL_GLUE &&
+ pHdl->GetObjHdlNum()==nId ) return pHdl;
+ }
+ return NULL;
+}
+
+BOOL SdrMarkView::MarkNextGluePoint(BOOL /*bPrev*/)
+{
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ // ...
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+BOOL SdrMarkView::MarkNextGluePoint(const Point& /*rPnt*/, BOOL /*bPrev*/)
+{
+ ForceUndirtyMrkPnt();
+ BOOL bChgd=FALSE;
+ SortMarkedObjects();
+ // ...
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+const Rectangle& SdrMarkView::GetMarkedGluePointsRect() const
+{
+ ForceUndirtyMrkPnt();
+ if (bMarkedPointsRectsDirty) ImpSetPointsRects();
+ return aMarkedGluePointsRect;
+}
+
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
new file mode 100644
index 000000000000..6ab27c85aaf0
--- /dev/null
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -0,0 +1,3504 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/svdoashp.hxx>
+#include "unoapi.hxx"
+#include <svx/unoshape.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/datetime.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <tools/urlobj.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XCustomShapeEngine.hpp>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include "unopolyhelper.hxx"
+#include <comphelper/processfactory.hxx>
+#include <svl/urihelper.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <svx/svdogrp.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <svx/svddrag.hxx>
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include "svditer.hxx"
+#include <svx/svdobj.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdattrx.hxx> // NotPersistItems
+#include <svx/svdoedge.hxx> // #32383# Die Verbinder nach Move nochmal anbroadcasten
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <editeng/eeitem.hxx>
+#include "editeng/editstat.hxx"
+#include <svx/svdoutl.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/sdtfchim.hxx>
+#include "../customshapes/EnhancedCustomShapeGeometry.hxx"
+#include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
+#include "../customshapes/EnhancedCustomShape2d.hxx"
+#include <com/sun/star/beans/PropertyValues.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <editeng/writingmodeitem.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/svxids.hrc>
+#include <svl/whiter.hxx>
+#include <svx/sdr/properties/customshapeproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <vcl/bmpacc.hxx>
+#include <svx/svdview.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+// #104018# replace macros above with type-safe methods
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+
+static MSO_SPT ImpGetCustomShapeType( const SdrObjCustomShape& rCustoShape )
+{
+ MSO_SPT eRetValue = mso_sptNil;
+
+ rtl::OUString aEngine( ( (SdrCustomShapeEngineItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE ) ).GetValue() );
+ if ( !aEngine.getLength() || aEngine.equalsAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) )
+ {
+ rtl::OUString sShapeType;
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)rCustoShape.GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny && ( *pAny >>= sShapeType ) )
+ eRetValue = EnhancedCustomShapeTypeNames::Get( sShapeType );
+ }
+ return eRetValue;
+};
+
+static sal_Bool ImpVerticalSwitch( const SdrObjCustomShape& rCustoShape )
+{
+ sal_Bool bRet = sal_False;
+ MSO_SPT eShapeType( ImpGetCustomShapeType( rCustoShape ) );
+ switch( eShapeType )
+ {
+ case mso_sptAccentBorderCallout90 : // 2 ortho
+ case mso_sptBorderCallout1 : // 2 diag
+ case mso_sptBorderCallout2 : // 3
+ {
+ bRet = sal_True;
+ }
+ break;
+/*
+ case mso_sptCallout1 :
+ case mso_sptAccentCallout1 :
+ case mso_sptAccentBorderCallout1 :
+ case mso_sptBorderCallout90 :
+ case mso_sptCallout90 :
+ case mso_sptAccentCallout90 :
+ case mso_sptCallout2 :
+ case mso_sptCallout3 :
+ case mso_sptAccentCallout2 :
+ case mso_sptAccentCallout3 :
+ case mso_sptBorderCallout3 :
+ case mso_sptAccentBorderCallout2 :
+ case mso_sptAccentBorderCallout3 :
+*/
+ default: break;
+ }
+ return bRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i37011# create a clone with all attributes changed to shadow attributes
+// and translation executed, too.
+SdrObject* ImpCreateShadowObjectClone(const SdrObject& rOriginal, const SfxItemSet& rOriginalSet)
+{
+ SdrObject* pRetval = 0L;
+ const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get(SDRATTR_SHADOW)).GetValue());
+
+ if(bShadow)
+ {
+ // create a shadow representing object
+ const sal_Int32 nXDist(((SdrShadowXDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWXDIST))).GetValue());
+ const sal_Int32 nYDist(((SdrShadowYDistItem&)(rOriginalSet.Get(SDRATTR_SHADOWYDIST))).GetValue());
+ const ::Color aShadowColor(((SdrShadowColorItem&)(rOriginalSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue());
+ const sal_uInt16 nShadowTransparence(((SdrShadowTransparenceItem&)(rOriginalSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue());
+ pRetval = rOriginal.Clone();
+ DBG_ASSERT(pRetval, "ImpCreateShadowObjectClone: Could not clone object (!)");
+
+ // look for used stuff
+ SdrObjListIter aIterator(rOriginal);
+ sal_Bool bLineUsed(sal_False);
+ sal_Bool bAllFillUsed(sal_False);
+ sal_Bool bSolidFillUsed(sal_False);
+ sal_Bool bGradientFillUsed(sal_False);
+ sal_Bool bHatchFillUsed(sal_False);
+ sal_Bool bBitmapFillUsed(sal_False);
+
+ while(aIterator.IsMore())
+ {
+ SdrObject* pObj = aIterator.Next();
+ XFillStyle eFillStyle = ((XFillStyleItem&)(pObj->GetMergedItem(XATTR_FILLSTYLE))).GetValue();
+
+ if(!bLineUsed)
+ {
+ XLineStyle eLineStyle = ((XLineStyleItem&)(pObj->GetMergedItem(XATTR_LINESTYLE))).GetValue();
+
+ if(XLINE_NONE != eLineStyle)
+ {
+ bLineUsed = sal_True;
+ }
+ }
+
+ if(!bAllFillUsed)
+ {
+ if(!bSolidFillUsed && XFILL_SOLID == eFillStyle)
+ {
+ bSolidFillUsed = sal_True;
+ bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
+ }
+ if(!bGradientFillUsed && XFILL_GRADIENT == eFillStyle)
+ {
+ bGradientFillUsed = sal_True;
+ bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
+ }
+ if(!bHatchFillUsed && XFILL_HATCH == eFillStyle)
+ {
+ bHatchFillUsed = sal_True;
+ bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
+ }
+ if(!bBitmapFillUsed && XFILL_BITMAP == eFillStyle)
+ {
+ bBitmapFillUsed = sal_True;
+ bAllFillUsed = (bSolidFillUsed || bGradientFillUsed || bHatchFillUsed || bBitmapFillUsed);
+ }
+ }
+ }
+
+ // translate to shadow coordinates
+ pRetval->NbcMove(Size(nXDist, nYDist));
+
+ // set items as needed
+ SfxItemSet aTempSet(rOriginalSet);
+
+ // SJ: #40108# :-( if a SvxWritingModeItem (Top->Bottom) is set the text object
+ // is creating a paraobject, but paraobjects can not be created without model. So
+ // we are preventing the crash by setting the writing mode always left to right,
+ // this is not bad since our shadow geometry does not contain text.
+ aTempSet.Put( SvxWritingModeItem( com::sun::star::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ) );
+
+ // no shadow
+ aTempSet.Put(SdrShadowItem(sal_False));
+ aTempSet.Put(SdrShadowXDistItem(0L));
+ aTempSet.Put(SdrShadowYDistItem(0L));
+
+ // line color and transparence like shadow
+ if(bLineUsed)
+ {
+ aTempSet.Put(XLineColorItem(String(), aShadowColor));
+ aTempSet.Put(XLineTransparenceItem(nShadowTransparence));
+ }
+
+ // fill color and transparence like shadow
+ if(bSolidFillUsed)
+ {
+ aTempSet.Put(XFillColorItem(String(), aShadowColor));
+ aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
+ }
+
+ // gradient and transparence like shadow
+ if(bGradientFillUsed)
+ {
+ XGradient aGradient(((XFillGradientItem&)(rOriginalSet.Get(XATTR_FILLGRADIENT))).GetGradientValue());
+ sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
+ sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
+
+ if(aGradient.GetStartIntens() != 100)
+ {
+ nStartLuminance = (sal_uInt8)(nStartLuminance * ((double)aGradient.GetStartIntens() / 100.0));
+ }
+
+ if(aGradient.GetEndIntens() != 100)
+ {
+ nEndLuminance = (sal_uInt8)(nEndLuminance * ((double)aGradient.GetEndIntens() / 100.0));
+ }
+
+ ::Color aStartColor(
+ (sal_uInt8)((nStartLuminance * aShadowColor.GetRed()) / 256),
+ (sal_uInt8)((nStartLuminance * aShadowColor.GetGreen()) / 256),
+ (sal_uInt8)((nStartLuminance * aShadowColor.GetBlue()) / 256));
+
+ ::Color aEndColor(
+ (sal_uInt8)((nEndLuminance * aShadowColor.GetRed()) / 256),
+ (sal_uInt8)((nEndLuminance * aShadowColor.GetGreen()) / 256),
+ (sal_uInt8)((nEndLuminance * aShadowColor.GetBlue()) / 256));
+
+ aGradient.SetStartColor(aStartColor);
+ aGradient.SetEndColor(aEndColor);
+ aTempSet.Put(XFillGradientItem(aTempSet.GetPool(), aGradient));
+ aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
+ }
+
+ // hatch and transparence like shadow
+ if(bHatchFillUsed)
+ {
+ XHatch aHatch(((XFillHatchItem&)(rOriginalSet.Get(XATTR_FILLHATCH))).GetHatchValue());
+ aHatch.SetColor(aShadowColor);
+ aTempSet.Put(XFillHatchItem(aTempSet.GetPool(), aHatch));
+ aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
+ }
+
+ // bitmap and transparence like shadow
+ if(bBitmapFillUsed)
+ {
+ XOBitmap aFillBitmap(((XFillBitmapItem&)(rOriginalSet.Get(XATTR_FILLBITMAP))).GetBitmapValue());
+ Bitmap aSourceBitmap(aFillBitmap.GetBitmap());
+ BitmapReadAccess* pReadAccess = aSourceBitmap.AcquireReadAccess();
+
+ if(!aSourceBitmap.IsEmpty())
+ {
+ if(pReadAccess)
+ {
+ Bitmap aDestBitmap(aSourceBitmap.GetSizePixel(), 24L);
+ BitmapWriteAccess* pWriteAccess = aDestBitmap.AcquireWriteAccess();
+
+ if(pWriteAccess)
+ {
+ for(sal_Int32 y(0L); y < pReadAccess->Height(); y++)
+ {
+ for(sal_Int32 x(0L); x < pReadAccess->Width(); x++)
+ {
+ sal_uInt16 nLuminance((sal_uInt16)pReadAccess->GetLuminance(y, x) + 1);
+ const BitmapColor aDestColor(
+ (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetRed()) >> 8L),
+ (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetGreen()) >> 8L),
+ (sal_uInt8)((nLuminance * (sal_uInt16)aShadowColor.GetBlue()) >> 8L));
+ pWriteAccess->SetPixel(y, x, aDestColor);
+ }
+ }
+
+ aDestBitmap.ReleaseAccess(pWriteAccess);
+ aFillBitmap.SetBitmap(aDestBitmap);
+ }
+
+ aSourceBitmap.ReleaseAccess(pReadAccess);
+ }
+ }
+
+ aTempSet.Put(XFillBitmapItem(aTempSet.GetPool(), aFillBitmap));
+ aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
+ }
+
+ // set attributes and paint shadow object
+ pRetval->SetMergedItemSet( aTempSet );
+ }
+ return pRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Reference< XCustomShapeEngine > SdrObjCustomShape::GetCustomShapeEngine( const SdrObjCustomShape* pCustomShape )
+{
+ Reference< XCustomShapeEngine > xCustomShapeEngine;
+ String aEngine(((SdrCustomShapeEngineItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_ENGINE )).GetValue());
+ if ( !aEngine.Len() )
+ aEngine = String( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) );
+
+ Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ Reference< XShape > aXShape = GetXShapeForSdrObject( (SdrObjCustomShape*)pCustomShape );
+ if ( aXShape.is() )
+ {
+ if ( aEngine.Len() && xFactory.is() )
+ {
+ Sequence< Any > aArgument( 1 );
+ Sequence< PropertyValue > aPropValues( 1 );
+ aPropValues[ 0 ].Name = rtl::OUString::createFromAscii( "CustomShape" );
+ aPropValues[ 0 ].Value <<= aXShape;
+ aArgument[ 0 ] <<= aPropValues;
+ Reference< XInterface > xInterface( xFactory->createInstanceWithArguments( aEngine, aArgument ) );
+ if ( xInterface.is() )
+ xCustomShapeEngine = Reference< XCustomShapeEngine >( xInterface, UNO_QUERY );
+ }
+ }
+ return xCustomShapeEngine;
+}
+const SdrObject* SdrObjCustomShape::GetSdrObjectFromCustomShape() const
+{
+ if ( !mXRenderedCustomShape.is() )
+ {
+ Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) );
+ if ( xCustomShapeEngine.is() )
+ ((SdrObjCustomShape*)this)->mXRenderedCustomShape = xCustomShapeEngine->render();
+ }
+ SdrObject* pRenderedCustomShape = mXRenderedCustomShape.is()
+ ? GetSdrObjectFromXShape( mXRenderedCustomShape )
+ : NULL;
+ return pRenderedCustomShape;
+}
+
+// #i37011# Shadow geometry creation
+const SdrObject* SdrObjCustomShape::GetSdrObjectShadowFromCustomShape() const
+{
+ if(!mpLastShadowGeometry)
+ {
+ const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
+ if(pSdrObject)
+ {
+ const SfxItemSet& rOriginalSet = GetObjectItemSet();
+ const sal_Bool bShadow(((SdrShadowItem&)rOriginalSet.Get( SDRATTR_SHADOW )).GetValue());
+
+ if(bShadow)
+ {
+ // create a clone with all attributes changed to shadow attributes
+ // and translation executed, too.
+ ((SdrObjCustomShape*)this)->mpLastShadowGeometry = ImpCreateShadowObjectClone(*pSdrObject, rOriginalSet);
+ }
+ }
+ }
+
+ return mpLastShadowGeometry;
+}
+
+sal_Bool SdrObjCustomShape::IsTextPath() const
+{
+ const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
+ sal_Bool bTextPathOn = sal_False;
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sTextPath );
+ if ( pAny )
+ *pAny >>= bTextPathOn;
+ return bTextPathOn;
+}
+
+sal_Bool SdrObjCustomShape::UseNoFillStyle() const
+{
+ sal_Bool bRet = sal_False;
+ rtl::OUString sShapeType;
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ SdrCustomShapeGeometryItem& rGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ Any* pAny = rGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny )
+ *pAny >>= sShapeType;
+ bRet = IsCustomShapeFilledByDefault( EnhancedCustomShapeTypeNames::Get( sType ) ) == 0;
+
+ return bRet;
+}
+
+sal_Bool SdrObjCustomShape::IsMirroredX() const
+{
+ sal_Bool bMirroredX = sal_False;
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
+ if ( pAny )
+ *pAny >>= bMirroredX;
+ return bMirroredX;
+}
+sal_Bool SdrObjCustomShape::IsMirroredY() const
+{
+ sal_Bool bMirroredY = sal_False;
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
+ if ( pAny )
+ *pAny >>= bMirroredY;
+ return bMirroredY;
+}
+void SdrObjCustomShape::SetMirroredX( const sal_Bool bMirrorX )
+{
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
+ PropertyValue aPropVal;
+ aPropVal.Name = sMirroredX;
+ aPropVal.Value <<= bMirrorX;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ SetMergedItem( aGeometryItem );
+}
+void SdrObjCustomShape::SetMirroredY( const sal_Bool bMirrorY )
+{
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ //com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
+ PropertyValue aPropVal;
+ aPropVal.Name = sMirroredY;
+ aPropVal.Value <<= bMirrorY;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ SetMergedItem( aGeometryItem );
+}
+
+double SdrObjCustomShape::GetObjectRotation() const
+{
+ return fObjectRotation;
+}
+
+double SdrObjCustomShape::GetExtraTextRotation() const
+{
+ const com::sun::star::uno::Any* pAny;
+ SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ pAny = rGeometryItem.GetPropertyValueByName( sTextRotateAngle );
+ double fExtraTextRotateAngle = 0.0;
+ if ( pAny )
+ *pAny >>= fExtraTextRotateAngle;
+ return fExtraTextRotateAngle;
+}
+sal_Bool SdrObjCustomShape::GetTextBounds( Rectangle& rTextBound ) const
+{
+ sal_Bool bRet = sal_False;
+ Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( this ) ); // a candidate for being cached
+ if ( xCustomShapeEngine.is() )
+ {
+ awt::Rectangle aR( xCustomShapeEngine->getTextBounds() );
+ if ( aR.Width || aR.Height )
+ {
+ rTextBound = Rectangle( Point( aR.X, aR.Y ), Size( aR.Width, aR.Height ) );
+ bRet = sal_True;
+ }
+ }
+ return bRet;
+}
+basegfx::B2DPolyPolygon SdrObjCustomShape::GetLineGeometry( const SdrObjCustomShape* pCustomShape, const sal_Bool bBezierAllowed )
+{
+ basegfx::B2DPolyPolygon aRetval;
+ sal_Bool bRet = sal_False;
+ Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
+ if ( xCustomShapeEngine.is() )
+ {
+ com::sun::star::drawing::PolyPolygonBezierCoords aBezierCoords = xCustomShapeEngine->getLineGeometry();
+ try
+ {
+ aRetval = SvxConvertPolyPolygonBezierToB2DPolyPolygon( &aBezierCoords );
+ if ( !bBezierAllowed && aRetval.areControlPointsUsed())
+ {
+ aRetval = basegfx::tools::adaptiveSubdivideByAngle(aRetval);
+ }
+ bRet = sal_True;
+ }
+ catch ( const com::sun::star::lang::IllegalArgumentException )
+ {
+ }
+ }
+ return aRetval;
+}
+
+std::vector< SdrCustomShapeInteraction > SdrObjCustomShape::GetInteractionHandles( const SdrObjCustomShape* pCustomShape ) const
+{
+ std::vector< SdrCustomShapeInteraction > xRet;
+ try
+ {
+ Reference< XCustomShapeEngine > xCustomShapeEngine( GetCustomShapeEngine( pCustomShape ) );
+ if ( xCustomShapeEngine.is() )
+ {
+ int i;
+ Sequence< Reference< XCustomShapeHandle > > xInteractionHandles( xCustomShapeEngine->getInteraction() );
+ for ( i = 0; i < xInteractionHandles.getLength(); i++ )
+ {
+ if ( xInteractionHandles[ i ].is() )
+ {
+ SdrCustomShapeInteraction aSdrCustomShapeInteraction;
+ aSdrCustomShapeInteraction.xInteraction = xInteractionHandles[ i ];
+ aSdrCustomShapeInteraction.aPosition = xInteractionHandles[ i ]->getPosition();
+
+ sal_Int32 nMode = 0;
+ switch( ImpGetCustomShapeType( *this ) )
+ {
+ case mso_sptAccentBorderCallout90 : // 2 ortho
+ {
+ if ( !i )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
+ else if ( i == 1)
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE | CUSTOMSHAPE_HANDLE_ORTHO4;
+ }
+ break;
+
+ case mso_sptWedgeRectCallout :
+ case mso_sptWedgeRRectCallout :
+ case mso_sptCloudCallout :
+ case mso_sptWedgeEllipseCallout :
+ {
+ if ( !i )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED;
+ }
+ break;
+
+ case mso_sptBorderCallout1 : // 2 diag
+ {
+ if ( !i )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
+ else if ( i == 1 )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
+ }
+ break;
+ case mso_sptBorderCallout2 : // 3
+ {
+ if ( !i )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
+ else if ( i == 2 )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X | CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y | CUSTOMSHAPE_HANDLE_MOVE_SHAPE;
+ }
+ break;
+ case mso_sptCallout90 :
+ case mso_sptAccentCallout90 :
+ case mso_sptBorderCallout90 :
+ case mso_sptCallout1 :
+ case mso_sptCallout2 :
+ case mso_sptCallout3 :
+ case mso_sptAccentCallout1 :
+ case mso_sptAccentCallout2 :
+ case mso_sptAccentCallout3 :
+ case mso_sptBorderCallout3 :
+ case mso_sptAccentBorderCallout1 :
+ case mso_sptAccentBorderCallout2 :
+ case mso_sptAccentBorderCallout3 :
+ {
+ if ( !i )
+ nMode |= CUSTOMSHAPE_HANDLE_RESIZE_FIXED | CUSTOMSHAPE_HANDLE_CREATE_FIXED;
+ }
+ break;
+ default: break;
+ }
+ aSdrCustomShapeInteraction.nMode = nMode;
+ xRet.push_back( aSdrCustomShapeInteraction );
+ }
+ }
+ }
+ }
+ catch( const uno::RuntimeException& )
+ {
+ }
+ return xRet;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+#define DEFAULT_MINIMUM_SIGNED_COMPARE ((sal_Int32)0x80000000)
+#define DEFAULT_MAXIMUM_SIGNED_COMPARE ((sal_Int32)0x7fffffff)
+
+sdr::properties::BaseProperties* SdrObjCustomShape::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::CustomShapeProperties(*this);
+}
+
+TYPEINIT1(SdrObjCustomShape,SdrTextObj);
+SdrObjCustomShape::SdrObjCustomShape() :
+ SdrTextObj(),
+ fObjectRotation( 0.0 ),
+ mpLastShadowGeometry(0L)
+{
+ bTextFrame = TRUE;
+}
+
+SdrObjCustomShape::~SdrObjCustomShape()
+{
+ // delete buffered display geometry
+ InvalidateRenderGeometry();
+}
+
+void SdrObjCustomShape::MergeDefaultAttributes( const rtl::OUString* pType )
+{
+ PropertyValue aPropVal;
+ rtl::OUString sShapeType;
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+ if ( pType && pType->getLength() )
+ {
+ sal_Int32 nType = pType->toInt32();
+ if ( nType )
+ sShapeType = EnhancedCustomShapeTypeNames::Get( static_cast< MSO_SPT >( nType ) );
+ else
+ sShapeType = *pType;
+
+ aPropVal.Name = sType;
+ aPropVal.Value <<= sShapeType;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+ else
+ {
+ Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny )
+ *pAny >>= sShapeType;
+ }
+ MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+
+ const sal_Int32* pDefData = NULL;
+ const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
+ if ( pDefCustomShape )
+ pDefData = pDefCustomShape->pDefData;
+
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
+
+ //////////////////////
+ // AdjustmentValues //
+ //////////////////////
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ const Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
+ if ( pAny )
+ *pAny >>= seqAdjustmentValues;
+ if ( pDefCustomShape && pDefData ) // now check if we have to default some adjustment values
+ {
+ // first check if there are adjustment values are to be appended
+ sal_Int32 i, nAdjustmentValues = seqAdjustmentValues.getLength();
+ sal_Int32 nAdjustmentDefaults = *pDefData++;
+ if ( nAdjustmentDefaults > nAdjustmentValues )
+ {
+ seqAdjustmentValues.realloc( nAdjustmentDefaults );
+ for ( i = nAdjustmentValues; i < nAdjustmentDefaults; i++ )
+ {
+ seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
+ seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // com::sun::star::beans::PropertyState_DEFAULT_VALUE;
+ }
+ }
+ // check if there are defaulted adjustment values that should be filled the hard coded defaults (pDefValue)
+ sal_Int32 nCount = nAdjustmentValues > nAdjustmentDefaults ? nAdjustmentDefaults : nAdjustmentValues;
+ for ( i = 0; i < nCount; i++ )
+ {
+ if ( seqAdjustmentValues[ i ].State != com::sun::star::beans::PropertyState_DIRECT_VALUE )
+ {
+ seqAdjustmentValues[ i ].Value <<= pDefData[ i ];
+ seqAdjustmentValues[ i ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
+ }
+ }
+ }
+ aPropVal.Name = sAdjustmentValues;
+ aPropVal.Value <<= seqAdjustmentValues;
+ aGeometryItem.SetPropertyValue( aPropVal );
+
+ ///////////////
+ // Coordsize //
+ ///////////////
+ const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
+ const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
+ com::sun::star::awt::Rectangle aViewBox;
+ if ( !pViewBox || !(*pViewBox >>= aViewBox ) )
+ {
+ if ( pDefCustomShape )
+ {
+ aViewBox.X = 0;
+ aViewBox.Y = 0;
+ aViewBox.Width = pDefCustomShape->nCoordWidth;
+ aViewBox.Height= pDefCustomShape->nCoordHeight;
+ aPropVal.Name = sViewBox;
+ aPropVal.Value <<= aViewBox;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+ }
+
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+
+ //////////////////////
+ // Path/Coordinates //
+ //////////////////////
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
+
+ sal_Int32 i, nCount = pDefCustomShape->nVertices;
+ seqCoordinates.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
+ }
+ aPropVal.Name = sCoordinates;
+ aPropVal.Value <<= seqCoordinates;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+
+ /////////////////////
+ // Path/GluePoints //
+ /////////////////////
+ const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints;
+ sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
+ seqGluePoints.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
+ }
+ aPropVal.Name = sGluePoints;
+ aPropVal.Value <<= seqGluePoints;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+
+ ///////////////////
+ // Path/Segments //
+ ///////////////////
+ const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments;
+
+ sal_Int32 i, nCount = pDefCustomShape->nElements;
+ seqSegments.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShapeSegment& rSegInfo = seqSegments[ i ];
+ sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
+ switch( nSDat >> 8 )
+ {
+ case 0x00 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x20 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x40 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x60 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0x80 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0xa1 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
+ rSegInfo.Count = ( nSDat & 0xff ) / 3;
+ }
+ break;
+ case 0xa2 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
+ rSegInfo.Count = ( nSDat & 0xff ) / 3;
+ }
+ break;
+ case 0xa3 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa4 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa5 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa6 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa7 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
+ rSegInfo.Count = nSDat & 0xff;
+ }
+ break;
+ case 0xa8 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
+ rSegInfo.Count = nSDat & 0xff;
+ }
+ break;
+ case 0xaa :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0xab :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
+ rSegInfo.Count = 0;
+ }
+ break;
+ default:
+ case 0xf8 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
+ rSegInfo.Count = nSDat;
+ }
+ break;
+ }
+ }
+ aPropVal.Name = sSegments;
+ aPropVal.Value <<= seqSegments;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+
+ ///////////////////
+ // Path/StretchX //
+ ///////////////////
+ const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
+ if ( !pAny && pDefCustomShape )
+ {
+ sal_Int32 nXRef = pDefCustomShape->nXRef;
+ if ( ( nXRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
+ {
+ aPropVal.Name = sStretchX;
+ aPropVal.Value <<= nXRef;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+ }
+
+ ///////////////////
+ // Path/StretchY //
+ ///////////////////
+ const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
+ if ( !pAny && pDefCustomShape )
+ {
+ sal_Int32 nYRef = pDefCustomShape->nYRef;
+ if ( ( nYRef != DEFAULT_MINIMUM_SIGNED_COMPARE ) )
+ {
+ aPropVal.Name = sStretchY;
+ aPropVal.Value <<= nYRef;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+ }
+
+ /////////////////////
+ // Path/TextFrames //
+ /////////////////////
+ const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames;
+
+ sal_Int32 i, nCount = pDefCustomShape->nTextRect;
+ seqTextFrames.realloc( nCount );
+ const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
+ for ( i = 0; i < nCount; i++, pRectangles++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.First, pRectangles->nPairA.nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.First, pRectangles->nPairB.nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
+ }
+ aPropVal.Name = sTextFrames;
+ aPropVal.Value <<= seqTextFrames;
+ aGeometryItem.SetPropertyValue( sPath, aPropVal );
+ }
+
+ ///////////////
+ // Equations //
+ ///////////////
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
+ {
+ com::sun::star::uno::Sequence< rtl::OUString > seqEquations;
+
+ sal_Int32 i, nCount = pDefCustomShape->nCalculation;
+ seqEquations.realloc( nCount );
+ const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
+ for ( i = 0; i < nCount; i++, pData++ )
+ seqEquations[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
+ aPropVal.Name = sEquations;
+ aPropVal.Value <<= seqEquations;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+
+ /////////////
+ // Handles //
+ /////////////
+ const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
+ if ( !pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles;
+
+ sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
+ const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
+ seqHandles.realloc( nCount );
+ for ( i = 0; i < nCount; i++, pData++ )
+ {
+ sal_Int32 nPropertiesNeeded = 1; // position is always needed
+ sal_Int32 nFlags = pData->nFlags;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ }
+ }
+ else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ }
+
+ n = 0;
+ com::sun::star::beans::PropertyValues& rPropValues = seqHandles[ i ];
+ rPropValues.realloc( nPropertiesNeeded );
+
+ // POSITION
+ {
+ const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
+ rPropValues[ n ].Name = sPosition;
+ rPropValues[ n++ ].Value <<= aPosition;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
+ {
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ sal_Bool bMirroredX = sal_True;
+ rPropValues[ n ].Name = sMirroredX;
+ rPropValues[ n++ ].Value <<= bMirroredX;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
+ {
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ sal_Bool bMirroredY = sal_True;
+ rPropValues[ n ].Name = sMirroredY;
+ rPropValues[ n++ ].Value <<= bMirroredY;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
+ {
+ const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
+ sal_Bool bSwitched = sal_True;
+ rPropValues[ n ].Name = sSwitched;
+ rPropValues[ n++ ].Value <<= bSwitched;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
+ ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
+ ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sPolar;
+ rPropValues[ n++ ].Value <<= aCenter;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRadiusRangeMinimum;
+ rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
+ }
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRadiusRangeMaximum;
+ rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
+ }
+ }
+ }
+ else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRangeXMinimum;
+ rPropValues[ n++ ].Value <<= aRangeXMinimum;
+ }
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRangeXMaximum;
+ rPropValues[ n++ ].Value <<= aRangeXMaximum;
+ }
+ if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRangeYMinimum;
+ rPropValues[ n++ ].Value <<= aRangeYMinimum;
+ }
+ if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRangeYMaximum;
+ rPropValues[ n++ ].Value <<= aRangeYMaximum;
+ }
+ }
+ }
+ aPropVal.Name = sHandles;
+ aPropVal.Value <<= seqHandles;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+ SetMergedItem( aGeometryItem );
+}
+
+sal_Bool SdrObjCustomShape::IsDefaultGeometry( const DefaultType eDefaultType ) const
+{
+ sal_Bool bIsDefaultGeometry = sal_False;
+
+ PropertyValue aPropVal;
+ rtl::OUString sShapeType;
+ const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+
+ Any *pAny = aGeometryItem.GetPropertyValueByName( sType );
+ if ( pAny )
+ *pAny >>= sShapeType;
+
+ MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+
+ const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eSpType );
+ const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+ switch( eDefaultType )
+ {
+ case DEFAULT_VIEWBOX :
+ {
+ const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
+ const Any* pViewBox = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sViewBox );
+ com::sun::star::awt::Rectangle aViewBox;
+ if ( pViewBox && ( *pViewBox >>= aViewBox ) )
+ {
+ if ( ( aViewBox.Width == pDefCustomShape->nCoordWidth )
+ && ( aViewBox.Height == pDefCustomShape->nCoordHeight ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ break;
+
+ case DEFAULT_PATH :
+ {
+ const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
+ if ( pAny && pDefCustomShape && pDefCustomShape->nVertices && pDefCustomShape->pVertices )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates1, seqCoordinates2;
+ if ( *pAny >>= seqCoordinates1 )
+ {
+ sal_Int32 i, nCount = pDefCustomShape->nVertices;
+ seqCoordinates2.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].First, pDefCustomShape->pVertices[ i ].nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqCoordinates2[ i ].Second, pDefCustomShape->pVertices[ i ].nValB );
+ }
+ if ( seqCoordinates1 == seqCoordinates2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( ( pDefCustomShape->nVertices == 0 ) || ( pDefCustomShape->pVertices == 0 ) ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_GLUEPOINTS :
+ {
+ const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sGluePoints );
+ if ( pAny && pDefCustomShape && pDefCustomShape->nGluePoints && pDefCustomShape->pGluePoints )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqGluePoints1, seqGluePoints2;
+ if ( *pAny >>= seqGluePoints1 )
+ {
+ sal_Int32 i, nCount = pDefCustomShape->nGluePoints;
+ seqGluePoints2.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].First, pDefCustomShape->pGluePoints[ i ].nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqGluePoints2[ i ].Second, pDefCustomShape->pGluePoints[ i ].nValB );
+ }
+ if ( seqGluePoints1 == seqGluePoints2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( pDefCustomShape->nGluePoints == 0 ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_SEGMENTS :
+ {
+ ///////////////////
+ // Path/Segments //
+ ///////////////////
+ const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sSegments );
+ if ( pAny )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > seqSegments1, seqSegments2;
+ if ( *pAny >>= seqSegments1 )
+ {
+ if ( pDefCustomShape && pDefCustomShape->nElements && pDefCustomShape->pElements )
+ {
+ sal_Int32 i, nCount = pDefCustomShape->nElements;
+ if ( nCount )
+ {
+ seqSegments2.realloc( nCount );
+ for ( i = 0; i < nCount; i++ )
+ {
+ EnhancedCustomShapeSegment& rSegInfo = seqSegments2[ i ];
+ sal_uInt16 nSDat = pDefCustomShape->pElements[ i ];
+ switch( nSDat >> 8 )
+ {
+ case 0x00 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::LINETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x20 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CURVETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x40 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::MOVETO;
+ rSegInfo.Count = nSDat & 0xff;
+ if ( !rSegInfo.Count )
+ rSegInfo.Count = 1;
+ }
+ break;
+ case 0x60 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0x80 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0xa1 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
+ rSegInfo.Count = ( nSDat & 0xff ) / 3;
+ }
+ break;
+ case 0xa2 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
+ rSegInfo.Count = ( nSDat & 0xff ) / 3;
+ }
+ break;
+ case 0xa3 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARCTO;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa4 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ARC;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa5 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa6 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
+ rSegInfo.Count = ( nSDat & 0xff ) >> 2;
+ }
+ break;
+ case 0xa7 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
+ rSegInfo.Count = nSDat & 0xff;
+ }
+ break;
+ case 0xa8 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
+ rSegInfo.Count = nSDat & 0xff;
+ }
+ break;
+ case 0xaa :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOFILL;
+ rSegInfo.Count = 0;
+ }
+ break;
+ case 0xab :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::NOSTROKE;
+ rSegInfo.Count = 0;
+ }
+ break;
+ default:
+ case 0xf8 :
+ {
+ rSegInfo.Command = EnhancedCustomShapeSegmentCommand::UNKNOWN;
+ rSegInfo.Count = nSDat;
+ }
+ break;
+ }
+ }
+ if ( seqSegments1 == seqSegments2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else
+ {
+ // check if its the default segment description ( M L Z N )
+ if ( seqSegments1.getLength() == 4 )
+ {
+ if ( ( seqSegments1[ 0 ].Command == EnhancedCustomShapeSegmentCommand::MOVETO )
+ && ( seqSegments1[ 1 ].Command == EnhancedCustomShapeSegmentCommand::LINETO )
+ && ( seqSegments1[ 2 ].Command == EnhancedCustomShapeSegmentCommand::CLOSESUBPATH )
+ && ( seqSegments1[ 3 ].Command == EnhancedCustomShapeSegmentCommand::ENDSUBPATH ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ }
+ }
+ else if ( pDefCustomShape && ( ( pDefCustomShape->nElements == 0 ) || ( pDefCustomShape->pElements == 0 ) ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_STRETCHX :
+ {
+ const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchX );
+ if ( pAny && pDefCustomShape )
+ {
+ sal_Int32 nStretchX = 0;
+ if ( *pAny >>= nStretchX )
+ {
+ if ( pDefCustomShape->nXRef == nStretchX )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( pDefCustomShape->nXRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_STRETCHY :
+ {
+ const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sStretchY );
+ if ( pAny && pDefCustomShape )
+ {
+ sal_Int32 nStretchY = 0;
+ if ( *pAny >>= nStretchY )
+ {
+ if ( pDefCustomShape->nYRef == nStretchY )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( pDefCustomShape->nYRef == DEFAULT_MINIMUM_SIGNED_COMPARE ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_EQUATIONS :
+ {
+ const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM( "Equations" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sEquations );
+ if ( pAny && pDefCustomShape && pDefCustomShape->nCalculation && pDefCustomShape->pCalculation )
+ {
+ com::sun::star::uno::Sequence< rtl::OUString > seqEquations1, seqEquations2;
+ if ( *pAny >>= seqEquations1 )
+ {
+ sal_Int32 i, nCount = pDefCustomShape->nCalculation;
+ seqEquations2.realloc( nCount );
+
+ const SvxMSDffCalculationData* pData = pDefCustomShape->pCalculation;
+ for ( i = 0; i < nCount; i++, pData++ )
+ seqEquations2[ i ] = EnhancedCustomShape2d::GetEquation( pData->nFlags, pData->nVal[ 0 ], pData->nVal[ 1 ], pData->nVal[ 2 ] );
+
+ if ( seqEquations1 == seqEquations2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( ( pDefCustomShape->nCalculation == 0 ) || ( pDefCustomShape->pCalculation == 0 ) ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_TEXTFRAMES :
+ {
+ const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM( "TextFrames" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sTextFrames );
+ if ( pAny && pDefCustomShape && pDefCustomShape->nTextRect && pDefCustomShape->pTextRect )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > seqTextFrames1, seqTextFrames2;
+ if ( *pAny >>= seqTextFrames1 )
+ {
+ sal_Int32 i, nCount = pDefCustomShape->nTextRect;
+ seqTextFrames2.realloc( nCount );
+ const SvxMSDffTextRectangles* pRectangles = pDefCustomShape->pTextRect;
+ for ( i = 0; i < nCount; i++, pRectangles++ )
+ {
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.First, pRectangles->nPairA.nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].TopLeft.Second, pRectangles->nPairA.nValB );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.First, pRectangles->nPairB.nValA );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( seqTextFrames2[ i ].BottomRight.Second, pRectangles->nPairB.nValB );
+ }
+ if ( seqTextFrames1 == seqTextFrames2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( ( pDefCustomShape->nTextRect == 0 ) || ( pDefCustomShape->pTextRect == 0 ) ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+
+ case DEFAULT_HANDLES :
+ {
+ const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM( "Handles" ) );
+ pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sHandles );
+ if ( pAny && pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
+ {
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValues > seqHandles1, seqHandles2;
+ if ( *pAny >>= seqHandles1 )
+ {
+ sal_Int32 i, n, nCount = pDefCustomShape->nHandles;
+ const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
+ seqHandles2.realloc( nCount );
+ for ( i = 0; i < nCount; i++, pData++ )
+ {
+ sal_Int32 nPropertiesNeeded = 1; // position is always needed
+ sal_Int32 nFlags = pData->nFlags;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ nPropertiesNeeded++;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ }
+ }
+ else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ nPropertiesNeeded++;
+ }
+
+ n = 0;
+ com::sun::star::beans::PropertyValues& rPropValues = seqHandles2[ i ];
+ rPropValues.realloc( nPropertiesNeeded );
+
+ // POSITION
+ {
+ const rtl::OUString sPosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aPosition;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, pData->nPositionX, sal_True, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, pData->nPositionY, sal_True, sal_False );
+ rPropValues[ n ].Name = sPosition;
+ rPropValues[ n++ ].Value <<= aPosition;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
+ {
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ sal_Bool bMirroredX = sal_True;
+ rPropValues[ n ].Name = sMirroredX;
+ rPropValues[ n++ ].Value <<= bMirroredX;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
+ {
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ sal_Bool bMirroredY = sal_True;
+ rPropValues[ n ].Name = sMirroredY;
+ rPropValues[ n++ ].Value <<= bMirroredY;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
+ {
+ const rtl::OUString sSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
+ sal_Bool bSwitched = sal_True;
+ rPropValues[ n ].Name = sSwitched;
+ rPropValues[ n++ ].Value <<= bSwitched;
+ }
+ if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
+ {
+ const rtl::OUString sPolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameterPair aCenter;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.First, pData->nCenterX,
+ ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_X_IS_SPECIAL ) != 0, sal_True );
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aCenter.Second, pData->nCenterY,
+ ( nFlags & MSDFF_HANDLE_FLAGS_CENTER_Y_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sPolar;
+ rPropValues[ n++ ].Value <<= aCenter;
+ if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, pData->nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRadiusRangeMinimum;
+ rPropValues[ n++ ].Value <<= aRadiusRangeMinimum;
+ }
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRadiusRangeMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, pData->nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRadiusRangeMaximum;
+ rPropValues[ n++ ].Value <<= aRadiusRangeMaximum;
+ }
+ }
+ }
+ else if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
+ {
+ if ( pData->nRangeXMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, pData->nRangeXMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRangeXMinimum;
+ rPropValues[ n++ ].Value <<= aRangeXMinimum;
+ }
+ if ( pData->nRangeXMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeXMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, pData->nRangeXMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRangeXMaximum;
+ rPropValues[ n++ ].Value <<= aRangeXMaximum;
+ }
+ if ( pData->nRangeYMin != DEFAULT_MINIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMinimum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, pData->nRangeYMin,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
+ rPropValues[ n ].Name = sRangeYMinimum;
+ rPropValues[ n++ ].Value <<= aRangeYMinimum;
+ }
+ if ( pData->nRangeYMax != DEFAULT_MAXIMUM_SIGNED_COMPARE )
+ {
+ const rtl::OUString sRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
+ ::com::sun::star::drawing::EnhancedCustomShapeParameter aRangeYMaximum;
+ EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, pData->nRangeYMax,
+ ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
+ rPropValues[ n ].Name = sRangeYMaximum;
+ rPropValues[ n++ ].Value <<= aRangeYMaximum;
+ }
+ }
+ }
+ if ( seqHandles1 == seqHandles2 )
+ bIsDefaultGeometry = sal_True;
+ }
+ }
+ else if ( pDefCustomShape && ( ( pDefCustomShape->nHandles == 0 ) || ( pDefCustomShape->pHandles == 0 ) ) )
+ bIsDefaultGeometry = sal_True;
+ }
+ break;
+ }
+ return bIsDefaultGeometry;
+}
+
+void SdrObjCustomShape::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bResizeFreeAllowed=fObjectRotation == 0.0;
+ rInfo.bResizePropAllowed=TRUE;
+ rInfo.bRotateFreeAllowed=TRUE;
+ rInfo.bRotate90Allowed =TRUE;
+ rInfo.bMirrorFreeAllowed=TRUE;
+ rInfo.bMirror45Allowed =TRUE;
+ rInfo.bMirror90Allowed =TRUE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =TRUE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bNoContortion =TRUE;
+
+ // #i37011#
+ if ( mXRenderedCustomShape.is() )
+ {
+ const SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
+ if ( pRenderedCustomShape )
+ {
+ // #i37262#
+ // Iterate self over the contained objects, since there are combinations of
+ // polygon and curve objects. In that case, aInfo.bCanConvToPath and
+ // aInfo.bCanConvToPoly would be false. What is needed here is an or, not an and.
+ SdrObjListIter aIterator(*pRenderedCustomShape);
+ while(aIterator.IsMore())
+ {
+ SdrObject* pCandidate = aIterator.Next();
+ SdrObjTransformInfoRec aInfo;
+ pCandidate->TakeObjInfo(aInfo);
+
+ // set path and poly conversion if one is possible since
+ // this object will first be broken
+ const sal_Bool bCanConvToPathOrPoly(aInfo.bCanConvToPath || aInfo.bCanConvToPoly);
+ if(rInfo.bCanConvToPath != bCanConvToPathOrPoly)
+ {
+ rInfo.bCanConvToPath = bCanConvToPathOrPoly;
+ }
+
+ if(rInfo.bCanConvToPoly != bCanConvToPathOrPoly)
+ {
+ rInfo.bCanConvToPoly = bCanConvToPathOrPoly;
+ }
+
+ if(rInfo.bCanConvToContour != aInfo.bCanConvToContour)
+ {
+ rInfo.bCanConvToContour = aInfo.bCanConvToContour;
+ }
+ }
+ }
+ }
+}
+
+void SdrObjCustomShape::SetModel(SdrModel* pNewModel)
+{
+ SdrTextObj::SetModel(pNewModel);
+ mXRenderedCustomShape.clear();
+}
+
+UINT16 SdrObjCustomShape::GetObjIdentifier() const
+{
+ return UINT16(OBJ_CUSTOMSHAPE);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObjCustomShape::RecalcSnapRect()
+{
+ SdrTextObj::RecalcSnapRect();
+}
+const Rectangle& SdrObjCustomShape::GetSnapRect() const
+{
+ return SdrTextObj::GetSnapRect();
+}
+const Rectangle& SdrObjCustomShape::GetCurrentBoundRect() const
+{
+ return SdrTextObj::GetCurrentBoundRect();
+}
+const Rectangle& SdrObjCustomShape::GetLogicRect() const
+{
+ return SdrTextObj::GetLogicRect();
+}
+void SdrObjCustomShape::NbcSetSnapRect( const Rectangle& rRect )
+{
+ aRect=rRect;
+ ImpJustifyRect(aRect);
+ InvalidateRenderGeometry();
+ Rectangle aTextBound( aRect );
+ if ( GetTextBounds( aTextBound ) )
+ {
+ if ( pModel==NULL || !pModel->IsPasteResize() )
+ {
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ long nTWdt=aTextBound.GetWidth ()-1-nHDist; if (nTWdt<0) nTWdt=0;
+ long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
+ if ( IsAutoGrowWidth() )
+ NbcSetMinTextFrameWidth( nTWdt );
+ if ( IsAutoGrowHeight() )
+ NbcSetMinTextFrameHeight( nTHgt );
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ }
+ ImpCheckShear();
+ SetRectsDirty();
+ SetChanged();
+}
+void SdrObjCustomShape::SetSnapRect( const Rectangle& rRect )
+{
+ Rectangle aBoundRect0;
+ if ( pUserCall )
+ aBoundRect0 = GetLastBoundRect();
+ NbcSetSnapRect( rRect );
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+void SdrObjCustomShape::NbcSetLogicRect( const Rectangle& rRect )
+{
+ aRect = rRect;
+ ImpJustifyRect( aRect );
+ InvalidateRenderGeometry();
+ Rectangle aTextBound( aRect );
+ if ( GetTextBounds( aTextBound ) )
+ {
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+
+ long nTWdt=aTextBound.GetWidth()-1-nHDist; if (nTWdt<0) nTWdt=0;
+ long nTHgt=aTextBound.GetHeight()-1-nVDist; if (nTHgt<0) nTHgt=0;
+ if ( IsAutoGrowWidth() )
+ NbcSetMinTextFrameWidth( nTWdt );
+ if ( IsAutoGrowHeight() )
+ NbcSetMinTextFrameHeight( nTHgt );
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ SetRectsDirty();
+ SetChanged();
+}
+void SdrObjCustomShape::SetLogicRect( const Rectangle& rRect )
+{
+ Rectangle aBoundRect0;
+ if ( pUserCall )
+ aBoundRect0 = GetLastBoundRect();
+ NbcSetLogicRect(rRect);
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+void SdrObjCustomShape::Move( const Size& rSiz )
+{
+ if ( rSiz.Width() || rSiz.Height() )
+ {
+ Rectangle aBoundRect0;
+ if ( pUserCall )
+ aBoundRect0 = GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcMove(rSiz);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+void SdrObjCustomShape::NbcMove( const Size& rSiz )
+{
+ SdrTextObj::NbcMove( rSiz );
+ if ( mXRenderedCustomShape.is() )
+ {
+ SdrObject* pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
+ if ( pRenderedCustomShape )
+ {
+ // #i97149# the visualisation shape needs to be informed
+ // about change, too
+ pRenderedCustomShape->ActionChanged();
+ pRenderedCustomShape->NbcMove( rSiz );
+ }
+ }
+
+ // #i37011# adapt geometry shadow
+ if(mpLastShadowGeometry)
+ {
+ mpLastShadowGeometry->NbcMove( rSiz );
+ }
+}
+void SdrObjCustomShape::Resize( const Point& rRef, const Fraction& xFact, const Fraction& yFact )
+{
+ SdrTextObj::Resize( rRef, xFact, yFact );
+}
+
+void SdrObjCustomShape::NbcResize( const Point& rRef, const Fraction& rxFact, const Fraction& ryFact )
+{
+ Fraction xFact( rxFact );
+ Fraction yFact( ryFact );
+
+ // taking care of handles that should not been changed
+ Rectangle aOld( aRect );
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+
+ SdrTextObj::NbcResize( rRef, xFact, yFact );
+
+ if ( ( xFact.GetNumerator() != xFact.GetDenominator() )
+ || ( yFact.GetNumerator()!= yFact.GetDenominator() ) )
+ {
+ if ( ( ( xFact.GetNumerator() < 0 ) && ( xFact.GetDenominator() > 0 ) ) ||
+ ( ( xFact.GetNumerator() > 0 ) && ( xFact.GetDenominator() < 0 ) ) )
+ {
+ SetMirroredX( IsMirroredX() == sal_False );
+ }
+ if ( ( ( yFact.GetNumerator() < 0 ) && ( yFact.GetDenominator() > 0 ) ) ||
+ ( ( yFact.GetNumerator() > 0 ) && ( yFact.GetDenominator() < 0 ) ) )
+ {
+ SetMirroredY( IsMirroredY() == sal_False );
+ }
+ }
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ try
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
+ aIter->xInteraction->setControllerPosition( aIter->aPosition );
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
+ {
+ sal_Int32 nX = ( aIter->aPosition.X - aOld.Left() ) + aRect.Left();
+ aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
+ }
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
+ {
+ sal_Int32 nY = ( aIter->aPosition.Y - aOld.Top() ) + aRect.Top();
+ aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
+ }
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ aIter++;
+ }
+ InvalidateRenderGeometry();
+}
+void SdrObjCustomShape::NbcRotate( const Point& rRef, long nWink, double sn, double cs )
+{
+ sal_Bool bMirroredX = IsMirroredX();
+ sal_Bool bMirroredY = IsMirroredY();
+
+ fObjectRotation = fmod( fObjectRotation, 360.0 );
+ if ( fObjectRotation < 0 )
+ fObjectRotation = 360 + fObjectRotation;
+
+ // the rotation angle for ashapes is stored in fObjectRotation, this rotation
+ // has to be applied to the text object (which is internally using aGeo.nWink).
+ SdrTextObj::NbcRotate( aRect.TopLeft(), -aGeo.nDrehWink, // retrieving the unrotated text object
+ sin( (-aGeo.nDrehWink) * F_PI18000 ),
+ cos( (-aGeo.nDrehWink) * F_PI18000 ) );
+ aGeo.nDrehWink = 0; // resetting aGeo data
+ aGeo.RecalcSinCos();
+
+ long nW = (long)( fObjectRotation * 100 ); // applying our object rotation
+ if ( bMirroredX )
+ nW = 36000 - nW;
+ if ( bMirroredY )
+ nW = 18000 - nW;
+ nW = nW % 36000;
+ if ( nW < 0 )
+ nW = 36000 + nW;
+ SdrTextObj::NbcRotate( aRect.TopLeft(), nW, // applying text rotation
+ sin( nW * F_PI18000 ),
+ cos( nW * F_PI18000 ) );
+
+ int nSwap = 0;
+ if ( bMirroredX )
+ nSwap ^= 1;
+ if ( bMirroredY )
+ nSwap ^= 1;
+
+ double fWink = nWink; // updating to our new object rotation
+ fWink /= 100.0;
+ fObjectRotation = fmod( nSwap ? fObjectRotation - fWink : fObjectRotation + fWink, 360.0 );
+ if ( fObjectRotation < 0 )
+ fObjectRotation = 360 + fObjectRotation;
+
+ SdrTextObj::NbcRotate( rRef, nWink, sn, cs ); // applying text rotation
+ InvalidateRenderGeometry();
+}
+
+void SdrObjCustomShape::NbcMirror( const Point& rRef1, const Point& rRef2 )
+{
+ // storing horizontal and vertical flipping without modifying the rotate angle
+
+ sal_Bool bHorz = sal_False;
+ sal_Bool bVert = sal_False;
+ if ( rRef1.X() == rRef2.X() )
+ bHorz = sal_True;
+ if ( rRef1.Y() == rRef2.Y() )
+ bVert = sal_True;
+ if ( !bHorz && !bVert )
+ bHorz = bVert = sal_True;
+
+ if ( bHorz || bVert )
+ {
+ SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+
+ /////////////////
+ // "MirroredX" //
+ /////////////////
+ if ( bHorz )
+ {
+ const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
+ com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredX );
+ if ( pAny )
+ {
+ sal_Bool bFlip = sal_Bool();
+ if ( *pAny >>= bFlip )
+ {
+ if ( bFlip )
+ bHorz = sal_False;
+ }
+ }
+ PropertyValue aPropVal;
+ aPropVal.Name = sMirroredX;
+ aPropVal.Value <<= bHorz;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+
+ /////////////////
+ // "MirroredY" //
+ /////////////////
+ if ( bVert )
+ {
+ const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
+ com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sMirroredY );
+ if ( pAny )
+ {
+ sal_Bool bFlip = sal_Bool();
+ if ( *pAny >>= bFlip )
+ {
+ if ( bFlip )
+ bVert = sal_False;
+ }
+ }
+ PropertyValue aPropVal;
+ aPropVal.Name = sMirroredY;
+ aPropVal.Value <<= bVert;
+ aGeometryItem.SetPropertyValue( aPropVal );
+ }
+ SetMergedItem( aGeometryItem );
+ }
+ SdrTextObj::NbcMirror( rRef1, rRef2 );
+ InvalidateRenderGeometry();
+}
+
+void SdrObjCustomShape::Shear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
+{
+ SdrTextObj::Shear( rRef, nWink, tn, bVShear );
+ InvalidateRenderGeometry();
+}
+void SdrObjCustomShape::NbcShear( const Point& rRef, long nWink, double tn, FASTBOOL bVShear )
+{
+ long nDrehWink = aGeo.nDrehWink;
+ if ( nDrehWink )
+ {
+ aGeo.nDrehWink = -nDrehWink;
+ aGeo.RecalcSinCos();
+ NbcRotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
+ }
+ SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
+ if ( nDrehWink )
+ {
+ aGeo.nDrehWink = nDrehWink;
+ aGeo.RecalcSinCos();
+ Rotate( rRef, aGeo.nDrehWink, aGeo.nSin, aGeo.nCos );
+ }
+ InvalidateRenderGeometry();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(USHORT nPosNum) const
+{
+ INT32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
+
+ // #i25616#
+ if(!LineIsOutsideGeometry())
+ {
+ nWdt++;
+ nWdt /= 2;
+ }
+
+ Point aPt;
+ switch (nPosNum) {
+ case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break;
+ case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break;
+ case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
+ case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break;
+ }
+ if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ aPt-=GetSnapRect().Center();
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+ return aGP;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// #i38892#
+void SdrObjCustomShape::ImpCheckCustomGluePointsAreAdded()
+{
+ const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
+
+ if(pSdrObject)
+ {
+ const SdrGluePointList* pSource = pSdrObject->GetGluePointList();
+
+ if(pSource && pSource->GetCount())
+ {
+ if(!SdrTextObj::GetGluePointList())
+ {
+ SdrTextObj::ForceGluePointList();
+ }
+
+ const SdrGluePointList* pList = SdrTextObj::GetGluePointList();
+
+ if(pList)
+ {
+ SdrGluePointList aNewList;
+ sal_uInt16 a;
+
+ for(a = 0; a < pSource->GetCount(); a++)
+ {
+ SdrGluePoint aCopy((*pSource)[a]);
+ aCopy.SetUserDefined(FALSE);
+ aNewList.Insert(aCopy);
+ }
+
+ sal_Bool bMirroredX = IsMirroredX();
+ sal_Bool bMirroredY = IsMirroredY();
+
+ long nShearWink = aGeo.nShearWink;
+ double fTan = aGeo.nTan;
+
+ if ( aGeo.nDrehWink || nShearWink || bMirroredX || bMirroredY )
+ {
+ Polygon aPoly( aRect );
+ if( nShearWink )
+ {
+ USHORT nPointCount=aPoly.GetSize();
+ for (USHORT i=0; i<nPointCount; i++)
+ ShearPoint(aPoly[i],aRect.Center(), fTan, FALSE );
+ }
+ if ( aGeo.nDrehWink )
+ aPoly.Rotate( aRect.Center(), aGeo.nDrehWink / 10 );
+
+ Rectangle aBoundRect( aPoly.GetBoundRect() );
+ sal_Int32 nXDiff = aBoundRect.Left() - aRect.Left();
+ sal_Int32 nYDiff = aBoundRect.Top() - aRect.Top();
+
+ if (nShearWink&&((bMirroredX&&!bMirroredY)||(bMirroredY&&!bMirroredX)))
+ {
+ nShearWink = -nShearWink;
+ fTan = -fTan;
+ }
+
+ Point aRef( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
+ for ( a = 0; a < aNewList.GetCount(); a++ )
+ {
+ SdrGluePoint& rPoint = aNewList[ a ];
+ Point aGlue( rPoint.GetPos() );
+ if ( nShearWink )
+ ShearPoint( aGlue, aRef, fTan );
+
+ RotatePoint( aGlue, aRef, sin( fObjectRotation * F_PI180 ), cos( fObjectRotation * F_PI180 ) );
+ if ( bMirroredX )
+ aGlue.X() = aRect.GetWidth() - aGlue.X();
+ if ( bMirroredY )
+ aGlue.Y() = aRect.GetHeight() - aGlue.Y();
+ aGlue.X() -= nXDiff;
+ aGlue.Y() -= nYDiff;
+ rPoint.SetPos( aGlue );
+ }
+ }
+
+ for(a = 0; a < pList->GetCount(); a++)
+ {
+ const SdrGluePoint& rCandidate = (*pList)[a];
+
+ if(rCandidate.IsUserDefined())
+ {
+ aNewList.Insert(rCandidate);
+ }
+ }
+
+ // copy new list to local. This is NOT very convenient behaviour, the local
+ // GluePointList should not be set, but be delivered by using GetGluePointList(),
+ // maybe on demand. Since the local object is changed here, this is assumed to
+ // be a result of GetGluePointList and thus the list is copied
+ if(pPlusData)
+ {
+ *pPlusData->pGluePoints = aNewList;
+ }
+ }
+ }
+ }
+}
+
+// #i38892#
+const SdrGluePointList* SdrObjCustomShape::GetGluePointList() const
+{
+ ((SdrObjCustomShape*)this)->ImpCheckCustomGluePointsAreAdded();
+ return SdrTextObj::GetGluePointList();
+}
+
+// #i38892#
+//SdrGluePointList* SdrObjCustomShape::GetGluePointList()
+//{
+// ImpCheckCustomGluePointsAreAdded();
+// return SdrTextObj::GetGluePointList();
+//}
+
+// #i38892#
+SdrGluePointList* SdrObjCustomShape::ForceGluePointList()
+{
+ if(SdrTextObj::ForceGluePointList())
+ {
+ ImpCheckCustomGluePointsAreAdded();
+ return SdrTextObj::ForceGluePointList();
+ }
+ else
+ {
+ return 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_uInt32 SdrObjCustomShape::GetHdlCount() const
+{
+ const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+ return ( aInteractionHandles.size() + nBasicHdlCount );
+}
+
+SdrHdl* SdrObjCustomShape::GetHdl( sal_uInt32 nHdlNum ) const
+{
+ SdrHdl* pH = NULL;
+ const sal_uInt32 nBasicHdlCount(SdrTextObj::GetHdlCount());
+
+ if ( nHdlNum < nBasicHdlCount )
+ pH = SdrTextObj::GetHdl( nHdlNum );
+ else
+ {
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+ const sal_uInt32 nCustomShapeHdlNum(nHdlNum - nBasicHdlCount);
+
+ if ( nCustomShapeHdlNum < aInteractionHandles.size() )
+ {
+ if ( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction.is() )
+ {
+ try
+ {
+ com::sun::star::awt::Point aPosition( aInteractionHandles[ nCustomShapeHdlNum ].xInteraction->getPosition() );
+ pH = new SdrHdl( Point( aPosition.X, aPosition.Y ), HDL_CUSTOMSHAPE1 );
+ pH->SetPointNum( nCustomShapeHdlNum );
+ pH->SetObj( (SdrObject*)this );
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ }
+ }
+ }
+ return pH;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrObjCustomShape::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrObjCustomShape::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ if(pHdl && HDL_CUSTOMSHAPE1 == pHdl->GetKind())
+ {
+ rDrag.SetEndDragChangesAttributes(true);
+ rDrag.SetNoSnap(true);
+ }
+ else
+ {
+ const SdrHdl* pHdl2 = rDrag.GetHdl();
+ const SdrHdlKind eHdl((pHdl2 == NULL) ? HDL_MOVE : pHdl2->GetKind());
+
+ switch( eHdl )
+ {
+ case HDL_UPLFT :
+ case HDL_UPPER :
+ case HDL_UPRGT :
+ case HDL_LEFT :
+ case HDL_RIGHT :
+ case HDL_LWLFT :
+ case HDL_LOWER :
+ case HDL_LWRGT :
+ case HDL_MOVE :
+ {
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void SdrObjCustomShape::DragResizeCustomShape( const Rectangle& rNewRect, SdrObjCustomShape* pObj ) const
+{
+ Rectangle aOld( pObj->aRect );
+ sal_Bool bOldMirroredX( pObj->IsMirroredX() );
+ sal_Bool bOldMirroredY( pObj->IsMirroredY() );
+
+ Rectangle aNewRect( rNewRect );
+ aNewRect.Justify();
+
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
+
+ GeoStat aGeoStat( pObj->GetGeoStat() );
+ if ( aNewRect.TopLeft()!= pObj->aRect.TopLeft() &&
+ ( pObj->aGeo.nDrehWink || pObj->aGeo.nShearWink ) )
+ {
+ Point aNewPos( aNewRect.TopLeft() );
+ if ( pObj->aGeo.nShearWink ) ShearPoint( aNewPos, aOld.TopLeft(), aGeoStat.nTan );
+ if ( pObj->aGeo.nDrehWink ) RotatePoint(aNewPos, aOld.TopLeft(), aGeoStat.nSin, aGeoStat.nCos );
+ aNewRect.SetPos( aNewPos );
+ }
+ if ( aNewRect != pObj->aRect )
+ {
+ pObj->SetLogicRect( aNewRect );
+ pObj->InvalidateRenderGeometry();
+
+ if ( rNewRect.Left() > rNewRect.Right() )
+ {
+ Point aTop( ( pObj->GetSnapRect().Left() + pObj->GetSnapRect().Right() ) >> 1, pObj->GetSnapRect().Top() );
+ Point aBottom( aTop.X(), aTop.Y() + 1000 );
+ pObj->NbcMirror( aTop, aBottom );
+ }
+ if ( rNewRect.Top() > rNewRect.Bottom() )
+ {
+ Point aLeft( pObj->GetSnapRect().Left(), ( pObj->GetSnapRect().Top() + pObj->GetSnapRect().Bottom() ) >> 1 );
+ Point aRight( aLeft.X() + 1000, aLeft.Y() );
+ pObj->NbcMirror( aLeft, aRight );
+ }
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ try
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
+ aIter->xInteraction->setControllerPosition( aIter->aPosition );
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_X )
+ {
+ sal_Int32 nX;
+ if ( bOldMirroredX )
+ {
+ nX = ( aIter->aPosition.X - aOld.Right() );
+ if ( rNewRect.Left() > rNewRect.Right() )
+ nX = pObj->aRect.Left() - nX;
+ else
+ nX += pObj->aRect.Right();
+ }
+ else
+ {
+ nX = ( aIter->aPosition.X - aOld.Left() );
+ if ( rNewRect.Left() > rNewRect.Right() )
+ nX = pObj->aRect.Right() - nX;
+ else
+ nX += pObj->aRect.Left();
+ }
+ aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( nX, aIter->xInteraction->getPosition().Y ) );
+ }
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_ABSOLUTE_Y )
+ {
+ sal_Int32 nY;
+ if ( bOldMirroredY )
+ {
+ nY = ( aIter->aPosition.Y - aOld.Bottom() );
+ if ( rNewRect.Top() > rNewRect.Bottom() )
+ nY = pObj->aRect.Top() - nY;
+ else
+ nY += pObj->aRect.Bottom();
+ }
+ else
+ {
+ nY = ( aIter->aPosition.Y - aOld.Top() );
+ if ( rNewRect.Top() > rNewRect.Bottom() )
+ nY = pObj->aRect.Bottom() - nY;
+ else
+ nY += pObj->aRect.Top();
+ }
+ aIter->xInteraction->setControllerPosition( com::sun::star::awt::Point( aIter->xInteraction->getPosition().X, nY ) );
+ }
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ aIter++;
+ }
+ }
+}
+
+void SdrObjCustomShape::DragMoveCustomShapeHdl( const Point aDestination, const sal_uInt16 nCustomShapeHdlNum, SdrObjCustomShape* pObj ) const
+{
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( pObj ) );
+ if ( nCustomShapeHdlNum < aInteractionHandles.size() )
+ {
+ SdrCustomShapeInteraction aInteractionHandle( aInteractionHandles[ nCustomShapeHdlNum ] );
+ if ( aInteractionHandle.xInteraction.is() )
+ {
+ try
+ {
+ com::sun::star::awt::Point aPt( aDestination.X(), aDestination.Y() );
+ if ( aInteractionHandle.nMode & CUSTOMSHAPE_HANDLE_MOVE_SHAPE )
+ {
+ sal_Int32 nXDiff = aPt.X - aInteractionHandle.aPosition.X;
+ sal_Int32 nYDiff = aPt.Y - aInteractionHandle.aPosition.Y;
+
+ pObj->aRect.Move( nXDiff, nYDiff );
+ pObj->aOutRect.Move( nXDiff, nYDiff );
+ pObj->maSnapRect.Move( nXDiff, nYDiff );
+ pObj->SetRectsDirty(sal_True);
+ pObj->InvalidateRenderGeometry();
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
+ {
+ if ( aIter->xInteraction.is() )
+ aIter->xInteraction->setControllerPosition( aIter->aPosition );
+ }
+ aIter++;
+ }
+ }
+ aInteractionHandle.xInteraction->setControllerPosition( aPt );
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ }
+ }
+}
+
+bool SdrObjCustomShape::applySpecialDrag(SdrDragStat& rDrag)
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ const SdrHdlKind eHdl((pHdl == NULL) ? HDL_MOVE : pHdl->GetKind());
+
+ switch(eHdl)
+ {
+ case HDL_CUSTOMSHAPE1 :
+ {
+ rDrag.SetEndDragChangesGeoAndAttributes(true);
+ DragMoveCustomShapeHdl( rDrag.GetNow(), (sal_uInt16)pHdl->GetPointNum(), this );
+ SetRectsDirty();
+ InvalidateRenderGeometry();
+ SetChanged();
+ break;
+ }
+
+ case HDL_UPLFT :
+ case HDL_UPPER :
+ case HDL_UPRGT :
+ case HDL_LEFT :
+ case HDL_RIGHT :
+ case HDL_LWLFT :
+ case HDL_LOWER :
+ case HDL_LWRGT :
+ {
+ DragResizeCustomShape(ImpDragCalcRect(rDrag), this);
+ break;
+ }
+ case HDL_MOVE :
+ {
+ Move(Size(rDrag.GetDX(), rDrag.GetDY()));
+ break;
+ }
+ default: break;
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObjCustomShape::DragCreateObject( SdrDragStat& rStat )
+{
+ Rectangle aRect1;
+ rStat.TakeCreateRect( aRect1 );
+
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+
+ sal_uInt32 nDefaultObjectSizeWidth = 3000; // default width from SDOptions ?
+ sal_uInt32 nDefaultObjectSizeHeight= 3000;
+
+ if ( ImpVerticalSwitch( *this ) )
+ {
+ SetMirroredX( aRect1.Left() > aRect1.Right() );
+
+ aRect1 = Rectangle( rStat.GetNow(), Size( nDefaultObjectSizeWidth, nDefaultObjectSizeHeight ) );
+ // subtracting the horizontal difference of the latest handle from shape position
+ if ( aInteractionHandles.size() )
+ {
+ sal_Int32 nHandlePos = aInteractionHandles[ aInteractionHandles.size() - 1 ].xInteraction->getPosition().X;
+ aRect1.Move( aRect.Left() - nHandlePos, 0 );
+ }
+ }
+ ImpJustifyRect( aRect1 );
+ rStat.SetActionRect( aRect1 );
+ aRect = aRect1;
+ SetRectsDirty();
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ try
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_CREATE_FIXED )
+ aIter->xInteraction->setControllerPosition( awt::Point( rStat.GetStart().X(), rStat.GetStart().Y() ) );
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ aIter++;
+ }
+
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+}
+
+FASTBOOL SdrObjCustomShape::BegCreate( SdrDragStat& rDrag )
+{
+ return SdrTextObj::BegCreate( rDrag );
+}
+
+FASTBOOL SdrObjCustomShape::MovCreate(SdrDragStat& rStat)
+{
+ SdrView* pView = rStat.GetView(); // #i37448#
+ if( pView && pView->IsSolidDragging() )
+ {
+ InvalidateRenderGeometry();
+ }
+ DragCreateObject( rStat );
+ SetRectsDirty();
+ return TRUE;
+}
+
+FASTBOOL SdrObjCustomShape::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd )
+{
+ DragCreateObject( rStat );
+
+ if ( bTextFrame )
+ {
+ if ( IsAutoGrowHeight() )
+ {
+ // MinTextHeight
+ long nHgt=aRect.GetHeight()-1;
+ if (nHgt==1) nHgt=0;
+ NbcSetMinTextFrameHeight( nHgt );
+ }
+ if ( IsAutoGrowWidth() )
+ {
+ // MinTextWidth
+ long nWdt=aRect.GetWidth()-1;
+ if (nWdt==1) nWdt=0;
+ NbcSetMinTextFrameWidth( nWdt );
+ }
+ // Textrahmen neu berechnen
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ SetRectsDirty();
+ return ( eCmd == SDRCREATE_FORCEEND || rStat.GetPointAnz() >= 2 );
+}
+
+basegfx::B2DPolyPolygon SdrObjCustomShape::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
+{
+ return GetLineGeometry( this, sal_False );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// in context with the SdrObjCustomShape the SdrTextAutoGrowHeightItem == true -> Resize Shape to fit text,
+// the SdrTextAutoGrowWidthItem == true -> Word wrap text in Shape
+FASTBOOL SdrObjCustomShape::IsAutoGrowHeight() const
+{
+ const SfxItemSet& rSet = GetMergedItemSet();
+ FASTBOOL bIsAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
+ if ( bIsAutoGrowHeight && IsVerticalWriting() )
+ bIsAutoGrowHeight = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == FALSE;
+ return bIsAutoGrowHeight;
+}
+FASTBOOL SdrObjCustomShape::IsAutoGrowWidth() const
+{
+ const SfxItemSet& rSet = GetMergedItemSet();
+ FASTBOOL bIsAutoGrowWidth = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
+ if ( bIsAutoGrowWidth && !IsVerticalWriting() )
+ bIsAutoGrowWidth = ((SdrTextWordWrapItem&)(rSet.Get(SDRATTR_TEXT_WORDWRAP))).GetValue() == FALSE;
+ return bIsAutoGrowWidth;
+}
+
+/* The following method is identical to the SdrTextObj::SetVerticalWriting method, the only difference
+ is that the SdrAutoGrowWidthItem and SdrAutoGrowHeightItem are not exchanged if the vertical writing
+ mode has been changed */
+
+void SdrObjCustomShape::SetVerticalWriting( sal_Bool bVertical )
+{
+ ForceOutlinerParaObject();
+
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+
+ DBG_ASSERT( pOutlinerParaObject, "SdrTextObj::SetVerticalWriting() without OutlinerParaObject!" );
+
+ if( pOutlinerParaObject )
+ {
+ if(pOutlinerParaObject->IsVertical() != (bool)bVertical)
+ {
+ // get item settings
+ const SfxItemSet& rSet = GetObjectItemSet();
+
+ // #103516# Also exchange hor/ver adjust items
+ SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
+ SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
+
+ // rescue object size
+ Rectangle aObjectRect = GetSnapRect();
+
+ // prepare ItemSet to set exchanged width and height items
+ SfxItemSet aNewSet(*rSet.GetPool(),
+ SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
+ // #103516# Expanded item ranges to also support hor and ver adjust.
+ SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
+ SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
+ 0, 0);
+
+ aNewSet.Put(rSet);
+
+ // #103516# Exchange horz and vert adjusts
+ switch(eVert)
+ {
+ case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
+ case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
+ case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
+ case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
+ }
+ switch(eHorz)
+ {
+ case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
+ case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
+ case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
+ case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
+ }
+
+ SetObjectItemSet( aNewSet );
+ pOutlinerParaObject = GetOutlinerParaObject();
+ if ( pOutlinerParaObject )
+ pOutlinerParaObject->SetVertical(bVertical);
+
+ // restore object size
+ SetSnapRect(aObjectRect);
+ }
+ }
+}
+FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const
+{
+ if ( pModel && HasText() && !rR.IsEmpty() )
+ {
+ FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth();
+ FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight();
+ if ( bWdtGrow || bHgtGrow )
+ {
+ Rectangle aR0(rR);
+ long nHgt=0,nMinHgt=0,nMaxHgt=0;
+ long nWdt=0,nMinWdt=0,nMaxWdt=0;
+ Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
+ Size aMaxSiz(100000,100000);
+ Size aTmpSiz(pModel->GetMaxObjSize());
+ if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
+ if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
+ if (bWdtGrow)
+ {
+ nMinWdt=GetMinTextFrameWidth();
+ nMaxWdt=GetMaxTextFrameWidth();
+ if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
+ if (nMinWdt<=0) nMinWdt=1;
+ aSiz.Width()=nMaxWdt;
+ }
+ if (bHgtGrow)
+ {
+ nMinHgt=GetMinTextFrameHeight();
+ nMaxHgt=GetMaxTextFrameHeight();
+ if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
+ if (nMinHgt<=0) nMinHgt=1;
+ aSiz.Height()=nMaxHgt;
+ }
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ aSiz.Width()-=nHDist;
+ aSiz.Height()-=nVDist;
+ if ( aSiz.Width() < 2 )
+ aSiz.Width() = 2; // Mindestgroesse 2
+ if ( aSiz.Height() < 2 )
+ aSiz.Height() = 2; // Mindestgroesse 2
+
+ if(pEdtOutl)
+ {
+ pEdtOutl->SetMaxAutoPaperSize( aSiz );
+ if (bWdtGrow)
+ {
+ Size aSiz2(pEdtOutl->CalcTextSize());
+ nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
+ if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
+ } else
+ {
+ nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz
+ }
+ }
+ else
+ {
+ Outliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetPaperSize(aSiz);
+ rOutliner.SetUpdateMode(TRUE);
+ // !!! hier sollte ich wohl auch noch mal die Optimierung mit
+ // bPortionInfoChecked usw einbauen
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if( pOutlinerParaObject != NULL )
+ {
+ rOutliner.SetText(*pOutlinerParaObject);
+ rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ }
+ if ( bWdtGrow )
+ {
+ Size aSiz2(rOutliner.CalcTextSize());
+ nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
+ if ( bHgtGrow )
+ nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
+ }
+ else
+ nHgt = rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz
+ rOutliner.Clear();
+ }
+ if ( nWdt < nMinWdt )
+ nWdt = nMinWdt;
+ if ( nWdt > nMaxWdt )
+ nWdt = nMaxWdt;
+ nWdt += nHDist;
+ if ( nWdt < 1 )
+ nWdt = 1; // nHDist kann auch negativ sein
+ if ( nHgt < nMinHgt )
+ nHgt = nMinHgt;
+ if ( nHgt > nMaxHgt )
+ nHgt = nMaxHgt;
+ nHgt+=nVDist;
+ if ( nHgt < 1 )
+ nHgt = 1; // nVDist kann auch negativ sein
+ long nWdtGrow = nWdt-(rR.Right()-rR.Left());
+ long nHgtGrow = nHgt-(rR.Bottom()-rR.Top());
+ if ( nWdtGrow == 0 )
+ bWdtGrow = FALSE;
+ if ( nHgtGrow == 0 )
+ bHgtGrow=FALSE;
+ if ( bWdtGrow || bHgtGrow )
+ {
+ if ( bWdtGrow )
+ {
+ SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
+ if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
+ rR.Right()+=nWdtGrow;
+ else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
+ rR.Left()-=nWdtGrow;
+ else
+ {
+ long nWdtGrow2=nWdtGrow/2;
+ rR.Left()-=nWdtGrow2;
+ rR.Right()=rR.Left()+nWdt;
+ }
+ }
+ if ( bHgtGrow )
+ {
+ SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
+ if ( eVAdj == SDRTEXTVERTADJUST_TOP )
+ rR.Bottom()+=nHgtGrow;
+ else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
+ rR.Top()-=nHgtGrow;
+ else
+ {
+ long nHgtGrow2=nHgtGrow/2;
+ rR.Top()-=nHgtGrow2;
+ rR.Bottom()=rR.Top()+nHgt;
+ }
+ }
+ if ( aGeo.nDrehWink )
+ {
+ Point aD1(rR.TopLeft());
+ aD1-=aR0.TopLeft();
+ Point aD2(aD1);
+ RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
+ aD2-=aD1;
+ rR.Move(aD2.X(),aD2.Y());
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+Rectangle SdrObjCustomShape::ImpCalculateTextFrame( const FASTBOOL bHgt, const FASTBOOL bWdt )
+{
+ Rectangle aReturnValue;
+
+ Rectangle aOldTextRect( aRect ); // <- initial text rectangle
+
+ Rectangle aNewTextRect( aRect ); // <- new text rectangle returned from the custom shape renderer,
+ GetTextBounds( aNewTextRect ); // it depends to the current logical shape size
+
+ Rectangle aAdjustedTextRect( aNewTextRect ); // <- new text rectangle is being tested by AdjustTextFrameWidthAndHeight to ensure
+ if ( AdjustTextFrameWidthAndHeight( aAdjustedTextRect, bHgt, bWdt ) ) // that the new text rectangle is matching the current text size from the outliner
+ {
+ if ( ( aAdjustedTextRect != aNewTextRect ) && ( aOldTextRect != aAdjustedTextRect ) )
+ {
+ aReturnValue = aRect;
+ double fXScale = (double)aOldTextRect.GetWidth() / (double)aNewTextRect.GetWidth();
+ double fYScale = (double)aOldTextRect.GetHeight() / (double)aNewTextRect.GetHeight();
+ double fRightDiff = (double)( aAdjustedTextRect.Right() - aNewTextRect.Right() ) * fXScale;
+ double fLeftDiff = (double)( aAdjustedTextRect.Left() - aNewTextRect.Left() ) * fXScale;
+ double fTopDiff = (double)( aAdjustedTextRect.Top() - aNewTextRect.Top() ) * fYScale;
+ double fBottomDiff= (double)( aAdjustedTextRect.Bottom()- aNewTextRect.Bottom()) * fYScale;
+ aReturnValue.Left() += (sal_Int32)fLeftDiff;
+ aReturnValue.Right() += (sal_Int32)fRightDiff;
+ aReturnValue.Top() += (sal_Int32)fTopDiff;
+ aReturnValue.Bottom() += (sal_Int32)fBottomDiff;
+ }
+ }
+ return aReturnValue;
+}
+
+FASTBOOL SdrObjCustomShape::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
+{
+ Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
+ sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
+ if ( bRet )
+ {
+ // taking care of handles that should not been changed
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+
+ aRect = aNewTextRect;
+ SetRectsDirty();
+ SetChanged();
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ try
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
+ aIter->xInteraction->setControllerPosition( aIter->aPosition );
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ aIter++;
+ }
+ InvalidateRenderGeometry();
+ }
+ return bRet;
+}
+FASTBOOL SdrObjCustomShape::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
+{
+ Rectangle aNewTextRect = ImpCalculateTextFrame( bHgt, bWdt );
+ sal_Bool bRet = !aNewTextRect.IsEmpty() && ( aNewTextRect != aRect );
+ if ( bRet )
+ {
+ Rectangle aBoundRect0;
+ if ( pUserCall )
+ aBoundRect0 = GetCurrentBoundRect();
+
+ // taking care of handles that should not been changed
+ std::vector< SdrCustomShapeInteraction > aInteractionHandles( GetInteractionHandles( this ) );
+
+// SendRepaintBroadcast();
+ aRect = aNewTextRect;
+ SetRectsDirty();
+
+ std::vector< SdrCustomShapeInteraction >::iterator aIter( aInteractionHandles.begin() );
+ while ( aIter != aInteractionHandles.end() )
+ {
+ try
+ {
+ if ( aIter->nMode & CUSTOMSHAPE_HANDLE_RESIZE_FIXED )
+ aIter->xInteraction->setControllerPosition( aIter->aPosition );
+ }
+ catch ( const uno::RuntimeException& )
+ {
+ }
+ aIter++;
+ }
+
+ InvalidateRenderGeometry();
+ SetChanged();
+// SendRepaintBroadcast();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+ return bRet;
+}
+sal_Bool SdrObjCustomShape::BegTextEdit( SdrOutliner& rOutl )
+{
+ return SdrTextObj::BegTextEdit( rOutl );
+}
+void SdrObjCustomShape::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
+{
+ Size aPaperMin,aPaperMax;
+ Rectangle aViewInit;
+ TakeTextAnchorRect( aViewInit );
+ if ( aGeo.nDrehWink )
+ {
+ Point aCenter(aViewInit.Center());
+ aCenter-=aViewInit.TopLeft();
+ Point aCenter0(aCenter);
+ RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
+ aCenter-=aCenter0;
+ aViewInit.Move(aCenter.X(),aCenter.Y());
+ }
+ Size aAnkSiz(aViewInit.GetSize());
+ aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
+ Size aMaxSiz(1000000,1000000);
+ if (pModel!=NULL) {
+ Size aTmpSiz(pModel->GetMaxObjSize());
+ if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
+ if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
+ }
+ SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
+ SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
+
+ long nMinWdt = GetMinTextFrameWidth();
+ long nMinHgt = GetMinTextFrameHeight();
+ long nMaxWdt = GetMaxTextFrameWidth();
+ long nMaxHgt = GetMaxTextFrameHeight();
+ if (nMinWdt<1) nMinWdt=1;
+ if (nMinHgt<1) nMinHgt=1;
+ if ( nMaxWdt == 0 || nMaxWdt > aMaxSiz.Width() )
+ nMaxWdt = aMaxSiz.Width();
+ if ( nMaxHgt == 0 || nMaxHgt > aMaxSiz.Height() )
+ nMaxHgt=aMaxSiz.Height();
+
+ if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
+ {
+ if ( IsVerticalWriting() )
+ {
+ nMaxHgt = aAnkSiz.Height();
+ nMinHgt = nMaxHgt;
+ }
+ else
+ {
+ nMaxWdt = aAnkSiz.Width();
+ nMinWdt = nMaxWdt;
+ }
+ }
+ aPaperMax.Width()=nMaxWdt;
+ aPaperMax.Height()=nMaxHgt;
+
+ aPaperMin.Width()=nMinWdt;
+ aPaperMin.Height()=nMinHgt;
+
+ if ( pViewMin )
+ {
+ *pViewMin = aViewInit;
+
+ long nXFree = aAnkSiz.Width() - aPaperMin.Width();
+ if ( eHAdj == SDRTEXTHORZADJUST_LEFT )
+ pViewMin->Right() -= nXFree;
+ else if ( eHAdj == SDRTEXTHORZADJUST_RIGHT )
+ pViewMin->Left() += nXFree;
+ else { pViewMin->Left() += nXFree / 2; pViewMin->Right() = pViewMin->Left() + aPaperMin.Width(); }
+
+ long nYFree = aAnkSiz.Height() - aPaperMin.Height();
+ if ( eVAdj == SDRTEXTVERTADJUST_TOP )
+ pViewMin->Bottom() -= nYFree;
+ else if ( eVAdj == SDRTEXTVERTADJUST_BOTTOM )
+ pViewMin->Top() += nYFree;
+ else { pViewMin->Top() += nYFree / 2; pViewMin->Bottom() = pViewMin->Top() + aPaperMin.Height(); }
+ }
+
+ if( IsVerticalWriting() )
+ aPaperMin.Width() = 0;
+ else
+ aPaperMin.Height() = 0; // #33102#
+
+ if( eHAdj != SDRTEXTHORZADJUST_BLOCK )
+ aPaperMin.Width()=0;
+
+ // #103516# For complete ver adjust support, set paper min height to 0, here.
+ if(SDRTEXTVERTADJUST_BLOCK != eVAdj )
+ aPaperMin.Height() = 0;
+
+ if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
+ if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
+ if (pViewInit!=NULL) *pViewInit=aViewInit;
+}
+void SdrObjCustomShape::EndTextEdit( SdrOutliner& rOutl )
+{
+ SdrTextObj::EndTextEdit( rOutl );
+ InvalidateRenderGeometry();
+}
+void SdrObjCustomShape::TakeTextAnchorRect( Rectangle& rAnchorRect ) const
+{
+ if ( GetTextBounds( rAnchorRect ) )
+ {
+ Point aRotateRef( maSnapRect.Center() );
+ rAnchorRect.Left() += GetTextLeftDistance();
+ rAnchorRect.Top() += GetTextUpperDistance();
+ rAnchorRect.Right() -= GetTextRightDistance();
+ rAnchorRect.Bottom() -= GetTextLowerDistance();
+ ImpJustifyRect( rAnchorRect );
+
+ if ( rAnchorRect.GetWidth() < 2 )
+ rAnchorRect.Right() = rAnchorRect.Left() + 1; // minimal width is 2
+ if ( rAnchorRect.GetHeight() < 2 )
+ rAnchorRect.Bottom() = rAnchorRect.Top() + 1; // minimal height is 2
+ if ( aGeo.nDrehWink )
+ {
+ Point aP( rAnchorRect.TopLeft() );
+ RotatePoint( aP, aRotateRef, aGeo.nSin, aGeo. nCos );
+ rAnchorRect.SetPos( aP );
+ }
+ }
+ else
+ SdrTextObj::TakeTextAnchorRect( rAnchorRect );
+}
+void SdrObjCustomShape::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
+ Rectangle* pAnchorRect, BOOL /*bLineWidth*/) const
+{
+ Rectangle aAnkRect; // Rect innerhalb dem geankert wird
+ TakeTextAnchorRect(aAnkRect);
+ SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
+ SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
+ ULONG nStat0=rOutliner.GetControlWord();
+ Size aNullSize;
+
+ rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
+ rOutliner.SetMinAutoPaperSize(aNullSize);
+ sal_Int32 nMaxAutoPaperWidth = 1000000;
+ sal_Int32 nMaxAutoPaperHeight= 1000000;
+
+ long nAnkWdt=aAnkRect.GetWidth();
+ long nAnkHgt=aAnkRect.GetHeight();
+
+ if (((SdrTextWordWrapItem&)(GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue())
+ {
+ if ( IsVerticalWriting() )
+ nMaxAutoPaperHeight = nAnkHgt;
+ else
+ nMaxAutoPaperWidth = nAnkWdt;
+ }
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
+ {
+ rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
+ }
+
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
+ {
+ rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
+ }
+ rOutliner.SetMaxAutoPaperSize( Size( nMaxAutoPaperWidth, nMaxAutoPaperHeight ) );
+ rOutliner.SetPaperSize( aNullSize );
+
+ // Text in den Outliner stecken - ggf. den aus dem EditOutliner
+ OutlinerParaObject* pPara= GetOutlinerParaObject();
+ if (pEdtOutl && !bNoEditText)
+ pPara=pEdtOutl->CreateParaObject();
+
+ if (pPara)
+ {
+ BOOL bHitTest = FALSE;
+ if( pModel )
+ bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
+
+ const SdrTextObj* pTestObj = rOutliner.GetTextObj();
+ if( !pTestObj || !bHitTest || pTestObj != this ||
+ pTestObj->GetOutlinerParaObject() != GetOutlinerParaObject() )
+ {
+ if( bHitTest )
+ rOutliner.SetTextObj( this );
+
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetText(*pPara);
+ }
+ }
+ else
+ {
+ rOutliner.SetTextObj( NULL );
+ }
+ if (pEdtOutl && !bNoEditText && pPara)
+ delete pPara;
+
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetControlWord(nStat0);
+
+ SdrText* pText = getActiveText();
+ if( pText )
+ pText->CheckPortionInfo( rOutliner );
+
+ Point aTextPos(aAnkRect.TopLeft());
+ Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
+
+ // #106653#
+ // For draw objects containing text correct hor/ver alignment if text is bigger
+ // than the object itself. Without that correction, the text would always be
+ // formatted to the left edge (or top edge when vertical) of the draw object.
+
+ if( !IsTextFrame() )
+ {
+ if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
+ {
+ // #110129#
+ // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
+ {
+ eHAdj = SDRTEXTHORZADJUST_CENTER;
+ }
+ }
+
+ if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
+ {
+ // #110129#
+ // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
+ {
+ eVAdj = SDRTEXTVERTADJUST_CENTER;
+ }
+ }
+ }
+
+ if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
+ {
+ long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
+ if (eHAdj==SDRTEXTHORZADJUST_CENTER)
+ aTextPos.X()+=nFreeWdt/2;
+ if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
+ aTextPos.X()+=nFreeWdt;
+ }
+ if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
+ {
+ long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
+ if (eVAdj==SDRTEXTVERTADJUST_CENTER)
+ aTextPos.Y()+=nFreeHgt/2;
+ if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
+ aTextPos.Y()+=nFreeHgt;
+ }
+ if (aGeo.nDrehWink!=0)
+ RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+
+ if (pAnchorRect)
+ *pAnchorRect=aAnkRect;
+
+ // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
+ rTextRect=Rectangle(aTextPos,aTextSiz);
+}
+
+void SdrObjCustomShape::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
+{
+ SdrTextObj::NbcSetOutlinerParaObject( pTextObject );
+ SetBoundRectDirty();
+ SetRectsDirty(TRUE);
+ InvalidateRenderGeometry();
+}
+
+void SdrObjCustomShape::operator=(const SdrObject& rObj)
+{
+ SdrTextObj::operator=( rObj );
+ aName =((SdrObjCustomShape&)rObj).aName;
+ fObjectRotation = ((SdrObjCustomShape&)rObj).fObjectRotation;
+ InvalidateRenderGeometry();
+}
+
+
+void SdrObjCustomShape::TakeObjNameSingul(XubString& rName) const
+{
+ rName = ImpGetResStr(STR_ObjNameSingulCUSTOMSHAPE);
+ String aNm( GetName() );
+ if( aNm.Len() )
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aNm;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrObjCustomShape::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralCUSTOMSHAPE);
+}
+
+basegfx::B2DPolyPolygon SdrObjCustomShape::TakeXorPoly() const
+{
+ return GetLineGeometry( (SdrObjCustomShape*)this, sal_False );
+}
+
+basegfx::B2DPolyPolygon SdrObjCustomShape::TakeContour() const
+{
+ const SdrObject* pSdrObject = GetSdrObjectFromCustomShape();
+ if ( pSdrObject )
+ return pSdrObject->TakeContour();
+ return basegfx::B2DPolyPolygon();
+}
+
+SdrObject* SdrObjCustomShape::DoConvertToPolyObj(BOOL bBezier) const
+{
+ // #i37011#
+ SdrObject* pRetval = 0L;
+ SdrObject* pRenderedCustomShape = 0L;
+
+ if ( !mXRenderedCustomShape.is() )
+ {
+ // force CustomShape
+ ((SdrObjCustomShape*)this)->GetSdrObjectFromCustomShape();
+ }
+
+ if ( mXRenderedCustomShape.is() )
+ {
+ pRenderedCustomShape = GetSdrObjectFromXShape( mXRenderedCustomShape );
+ }
+
+ if ( pRenderedCustomShape )
+ {
+ SdrObject* pCandidate = pRenderedCustomShape->Clone();
+ DBG_ASSERT(pCandidate, "SdrObjCustomShape::DoConvertToPolyObj: Could not clone SdrObject (!)");
+ pCandidate->SetModel(GetModel());
+ pRetval = pCandidate->DoConvertToPolyObj(bBezier);
+ SdrObject::Free( pCandidate );
+
+ if(pRetval)
+ {
+ const sal_Bool bShadow(((SdrShadowItem&)GetMergedItem(SDRATTR_SHADOW)).GetValue());
+ if(bShadow)
+ {
+ pRetval->SetMergedItem(SdrShadowItem(sal_True));
+ }
+ }
+
+ if(HasText() && !IsTextPath())
+ {
+ pRetval = ImpConvertAddText(pRetval, bBezier);
+ }
+ }
+
+ return pRetval;
+}
+
+void SdrObjCustomShape::NbcSetStyleSheet( SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr )
+{
+ // #i40944#
+ InvalidateRenderGeometry();
+ SdrObject::NbcSetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr );
+}
+
+void SdrObjCustomShape::SetPage( SdrPage* pNewPage )
+{
+ SdrTextObj::SetPage( pNewPage );
+
+ if( pNewPage )
+ {
+ // invalidating rectangles by SetRectsDirty is not sufficient,
+ // AdjustTextFrameWidthAndHeight() also has to be made, both
+ // actions are done by NbcSetSnapRect
+ Rectangle aTmp( aRect ); //creating temporary rectangle #i61108#
+ NbcSetSnapRect( aTmp );
+ }
+}
+
+SdrObjGeoData* SdrObjCustomShape::NewGeoData() const
+{
+ return new SdrAShapeObjGeoData;
+}
+
+void SdrObjCustomShape::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrTextObj::SaveGeoData( rGeo );
+ SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
+ rAGeo.fObjectRotation = fObjectRotation;
+ rAGeo.bMirroredX = IsMirroredX();
+ rAGeo.bMirroredY = IsMirroredY();
+
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ Any* pAny( ( (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) ).GetPropertyValueByName( sAdjustmentValues ) );
+ if ( pAny )
+ *pAny >>= rAGeo.aAdjustmentSeq;
+}
+
+void SdrObjCustomShape::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrTextObj::RestGeoData( rGeo );
+ SdrAShapeObjGeoData& rAGeo=(SdrAShapeObjGeoData&)rGeo;
+ fObjectRotation = rAGeo.fObjectRotation;
+ SetMirroredX( rAGeo.bMirroredX );
+ SetMirroredY( rAGeo.bMirroredY );
+
+ SdrCustomShapeGeometryItem rGeometryItem = (SdrCustomShapeGeometryItem&)GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
+ PropertyValue aPropVal;
+ aPropVal.Name = sAdjustmentValues;
+ aPropVal.Value <<= rAGeo.aAdjustmentSeq;
+ rGeometryItem.SetPropertyValue( aPropVal );
+ SetMergedItem( rGeometryItem );
+
+ InvalidateRenderGeometry();
+}
+
+void SdrObjCustomShape::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+ // break up matrix
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate, fShearX;
+ rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
+ // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale.setX(fabs(aScale.getX()));
+ aScale.setY(fabs(aScale.getY()));
+ fRotate = fmod(fRotate + F_PI, F_2PI);
+ }
+
+ // reset object shear and rotations
+ aGeo.nDrehWink = 0;
+ aGeo.RecalcSinCos();
+ aGeo.nShearWink = 0;
+ aGeo.RecalcTan();
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
+ aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplMMToTwips(aScale.getX()));
+ aScale.setY(ImplMMToTwips(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ // if anchor is used, make position relative to it
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // build and set BaseRect (use scale)
+ Point aPoint = Point();
+ Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
+ Rectangle aBaseRect(aPoint, aSize);
+ SetSnapRect(aBaseRect);
+
+ // shear?
+ if(!basegfx::fTools::equalZero(fShearX))
+ {
+ GeoStat aGeoStat;
+ aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
+ aGeoStat.RecalcTan();
+ Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE);
+ }
+
+ // rotation?
+ if(!basegfx::fTools::equalZero(fRotate))
+ {
+ GeoStat aGeoStat;
+
+ // #i78696#
+ // fRotate is mathematically correct, but aGeoStat.nDrehWink is
+ // mirrored -> mirror value here
+ aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
+ aGeoStat.RecalcSinCos();
+ Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
+ }
+
+ // translate?
+ if(!aTranslate.equalZero())
+ {
+ Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
+ }
+}
+
+// taking fObjectRotation instead of aGeo.nWink
+sal_Bool SdrObjCustomShape::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
+{
+ // get turn and shear
+// double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
+ double fRotate = fObjectRotation * F_PI180;
+ double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
+
+ // get aRect, this is the unrotated snaprect
+ Rectangle aRectangle(aRect);
+
+ sal_Bool bMirroredX = IsMirroredX();
+ sal_Bool bMirroredY = IsMirroredY();
+ if ( bMirroredX || bMirroredY )
+ { // we have to retrieve the unmirrored rect
+
+ GeoStat aNewGeo( aGeo );
+
+ if ( bMirroredX )
+ {
+ Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
+ Rectangle aBoundRect( aPol.GetBoundRect() );
+
+ Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
+ Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
+ USHORT i;
+ USHORT nPntAnz=aPol.GetSize();
+ for (i=0; i<nPntAnz; i++)
+ {
+ MirrorPoint(aPol[i],aRef1,aRef2);
+ }
+ // Polygon wenden und etwas schieben
+ Polygon aPol0(aPol);
+ aPol[0]=aPol0[1];
+ aPol[1]=aPol0[0];
+ aPol[2]=aPol0[3];
+ aPol[3]=aPol0[2];
+ aPol[4]=aPol0[1];
+ Poly2Rect(aPol,aRectangle,aNewGeo);
+ }
+ if ( bMirroredY )
+ {
+ Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
+ Rectangle aBoundRect( aPol.GetBoundRect() );
+
+ Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
+ Point aRef2( aRef1.X() + 1000, aRef1.Y() );
+ USHORT i;
+ USHORT nPntAnz=aPol.GetSize();
+ for (i=0; i<nPntAnz; i++)
+ {
+ MirrorPoint(aPol[i],aRef1,aRef2);
+ }
+ // Polygon wenden und etwas schieben
+ Polygon aPol0(aPol);
+ aPol[0]=aPol0[1];
+ aPol[1]=aPol0[0];
+ aPol[2]=aPol0[3];
+ aPol[3]=aPol0[2];
+ aPol[4]=aPol0[1];
+ Poly2Rect(aPol,aRectangle,aNewGeo);
+ }
+ }
+
+ // fill other values
+ basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
+ basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
+
+ // position maybe relative to anchorpos, convert
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // force MapUnit to 100th mm
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // postion
+ aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
+ aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplTwipsToMM(aScale.getX()));
+ aScale.setY(ImplTwipsToMM(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
+ }
+ }
+ }
+
+ // build matrix
+ rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ aScale,
+ basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
+ basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
+ aTranslate);
+
+ return sal_False;
+}
+
+sdr::contact::ViewContact* SdrObjCustomShape::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrObjCustomShape(*this);
+}
+
+// #i33136#
+bool SdrObjCustomShape::doConstructOrthogonal(const ::rtl::OUString& rName)
+{
+ bool bRetval(false);
+ static ::rtl::OUString Imps_sNameASOrtho_quadrat( RTL_CONSTASCII_USTRINGPARAM( "quadrat" ) );
+ static ::rtl::OUString Imps_sNameASOrtho_round_quadrat( RTL_CONSTASCII_USTRINGPARAM( "round-quadrat" ) );
+ static ::rtl::OUString Imps_sNameASOrtho_circle( RTL_CONSTASCII_USTRINGPARAM( "circle" ) );
+ static ::rtl::OUString Imps_sNameASOrtho_circle_pie( RTL_CONSTASCII_USTRINGPARAM( "circle-pie" ) );
+ static ::rtl::OUString Imps_sNameASOrtho_ring( RTL_CONSTASCII_USTRINGPARAM( "ring" ) );
+
+ if(Imps_sNameASOrtho_quadrat.equalsIgnoreAsciiCase(rName))
+ {
+ bRetval = true;
+ }
+ else if(Imps_sNameASOrtho_round_quadrat.equalsIgnoreAsciiCase(rName))
+ {
+ bRetval = true;
+ }
+ else if(Imps_sNameASOrtho_circle.equalsIgnoreAsciiCase(rName))
+ {
+ bRetval = true;
+ }
+ else if(Imps_sNameASOrtho_circle_pie.equalsIgnoreAsciiCase(rName))
+ {
+ bRetval = true;
+ }
+ else if(Imps_sNameASOrtho_ring.equalsIgnoreAsciiCase(rName))
+ {
+ bRetval = true;
+ }
+
+ return bRetval;
+}
+
+// #i37011# centralize throw-away of render geometry
+void SdrObjCustomShape::InvalidateRenderGeometry()
+{
+ mXRenderedCustomShape = 0L;
+ SdrObject::Free( mpLastShadowGeometry );
+ mpLastShadowGeometry = 0L;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdoattr.cxx b/svx/source/svdraw/svdoattr.cxx
new file mode 100644
index 000000000000..81c1ca029ede
--- /dev/null
+++ b/svx/source/svdraw/svdoattr.cxx
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdoattr.hxx>
+#include <svx/xpool.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdomeas.hxx>
+#include <svl/smplhint.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/xenum.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xtextit0.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <svx/xftshit.hxx>
+
+
+#include <editeng/colritem.hxx>
+#include "editeng/fontitem.hxx"
+#include <editeng/fhgtitem.hxx>
+
+//#include <editeng/charscaleitem.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svl/style.hxx>
+#include <svl/style.hxx>
+#include <svl/whiter.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xlnedcit.hxx>
+#include <editeng/adjitem.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/sdr/properties/attributeproperties.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include "svx/xlinjoit.hxx"
+#include <svdoimp.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+sdr::properties::BaseProperties* SdrAttrObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::AttributeProperties(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrAttrObj,SdrObject);
+
+SdrAttrObj::SdrAttrObj()
+{
+}
+
+SdrAttrObj::~SdrAttrObj()
+{
+}
+
+const Rectangle& SdrAttrObj::GetSnapRect() const
+{
+ if(bSnapRectDirty)
+ {
+ ((SdrAttrObj*)this)->RecalcSnapRect();
+ ((SdrAttrObj*)this)->bSnapRectDirty = false;
+ }
+
+ return maSnapRect;
+}
+
+void SdrAttrObj::SetModel(SdrModel* pNewModel)
+{
+ SdrModel* pOldModel = pModel;
+
+ // test for correct pool in ItemSet; move to new pool if necessary
+ if(pNewModel && GetObjectItemPool() && GetObjectItemPool() != &pNewModel->GetItemPool())
+ {
+ MigrateItemPool(GetObjectItemPool(), &pNewModel->GetItemPool(), pNewModel);
+ }
+
+ // call parent
+ SdrObject::SetModel(pNewModel);
+
+ // modify properties
+ GetProperties().SetModel(pOldModel, pNewModel);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// syntactical sugar for ItemSet accesses
+
+void __EXPORT SdrAttrObj::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ SfxSimpleHint *pSimple = PTR_CAST(SfxSimpleHint, &rHint);
+ BOOL bDataChg(pSimple && SFX_HINT_DATACHANGED == pSimple->GetId());
+
+ if(bDataChg)
+ {
+ Rectangle aBoundRect = GetLastBoundRect();
+ SetBoundRectDirty();
+ SetRectsDirty(sal_True);
+
+ // This may have lead to object change
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect);
+ }
+}
+
+sal_Int32 SdrAttrObj::ImpGetLineWdt() const
+{
+ sal_Int32 nRetval(0);
+
+ if(XLINE_NONE != ((XLineStyleItem&)(GetObjectItem(XATTR_LINESTYLE))).GetValue())
+ {
+ nRetval = ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
+ }
+
+ return nRetval;
+}
+
+BOOL SdrAttrObj::HasFill() const
+{
+ return bClosedObj && ((XFillStyleItem&)(GetProperties().GetObjectItemSet().Get(XATTR_FILLSTYLE))).GetValue()!=XFILL_NONE;
+}
+
+BOOL SdrAttrObj::HasLine() const
+{
+ return ((XLineStyleItem&)(GetProperties().GetObjectItemSet().Get(XATTR_LINESTYLE))).GetValue()!=XLINE_NONE;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
new file mode 100644
index 000000000000..b9d3e24592ee
--- /dev/null
+++ b/svx/source/svdraw/svdobj.cxx
@@ -0,0 +1,3310 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <com/sun/star/lang/XComponent.hpp>
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <vcl/metaact.hxx> // fuer TakeContour
+#include <vcl/cvtsvm.hxx>
+#include <tools/line.hxx>
+#include <tools/bigint.hxx>
+#include <tools/diagnose_ex.h>
+#include <vector>
+#include <svx/svdobj.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdovirt.hxx> // Fuer Add/Del Ref
+#include <svx/svdview.hxx> // fuer Dragging (Ortho abfragen)
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdogrp.hxx> // Factory
+#include <svx/svdopath.hxx> // Factory
+#include <svx/svdoedge.hxx> // Factory
+#include <svx/svdorect.hxx> // Factory
+#include <svx/svdocirc.hxx> // Factory
+#include <svx/svdotext.hxx> // Factory
+#include <svx/svdomeas.hxx> // Factory
+#include <svx/svdograf.hxx> // Factory
+#include <svx/svdoole2.hxx> // Factory
+#include <svx/svdocapt.hxx> // Factory
+#include <svx/svdopage.hxx> // Factory
+#include <svx/svdouno.hxx> // Factory
+#include <svx/svdattrx.hxx> // NotPersistItems
+#include <svx/svdoashp.hxx>
+#include <svx/svdomedia.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xflclit.hxx>
+#include "svditer.hxx"
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <svx/xflftrit.hxx>
+#include "svx/xlinjoit.hxx"
+#include <svx/unopage.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/xenum.hxx>
+#include <svx/xgrad.hxx>
+#include <svx/xhatch.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/svdpool.hxx>
+#include <editeng/editeng.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <svl/whiter.hxx>
+
+// #97849#
+#include <svx/fmmodel.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/objface.hxx>
+#include "svdoimp.hxx"
+#include <vcl/graphictools.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svx/sdr/properties/emptyproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdrobj.hxx>
+#include <svx/sdr/contact/viewcontactofgraphic.hxx>
+#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <svx/unoshape.hxx>
+#include <vcl/virdev.hxx>
+#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <drawinglayer/processor2d/contourextractor2d.hxx>
+#include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
+#include <svx/polysc3d.hxx>
+#include "svx/svdotable.hxx"
+#include "svx/shapepropertynotifier.hxx"
+#include <svx/sdrhittesthelper.hxx>
+#include <svx/svdundo.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/sdrobjectfilter.hxx>
+
+using namespace ::com::sun::star;
+
+// #104018# replace macros above with type-detecting methods
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT0(SdrObjUserCall);
+
+SdrObjUserCall::~SdrObjUserCall()
+{
+}
+
+void SdrObjUserCall::Changed(const SdrObject& /*rObj*/, SdrUserCallType /*eType*/, const Rectangle& /*rOldBoundRect*/)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT0(SdrObjUserData);
+
+void SdrObjUserData::operator=(const SdrObjUserData& /*rData*/) // nicht implementiert
+{
+}
+
+sal_Bool SdrObjUserData::operator==(const SdrObjUserData& /*rData*/) const // nicht implementiert
+{
+ return FALSE;
+}
+
+sal_Bool SdrObjUserData::operator!=(const SdrObjUserData& /*rData*/) const // nicht implementiert
+{
+ return FALSE;
+}
+
+SdrObjUserData::~SdrObjUserData()
+{
+}
+
+FASTBOOL SdrObjUserData::HasMacro(const SdrObject* /*pObj*/) const
+{
+ return FALSE;
+}
+
+SdrObject* SdrObjUserData::CheckMacroHit(const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const
+{
+ if(pObj)
+ {
+ if(rRec.pPageView)
+ {
+ return SdrObjectPrimitiveHit(*pObj, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
+ }
+ }
+
+ return 0;
+}
+
+Pointer SdrObjUserData::GetMacroPointer(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
+{
+ return Pointer(POINTER_REFHAND);
+}
+
+void SdrObjUserData::PaintMacro(OutputDevice& rOut, const Rectangle& /*rDirtyRect*/, const SdrObjMacroHitRec& /*rRec*/, const SdrObject* pObj) const
+{
+ if(!pObj)
+ return;
+
+ const RasterOp eRop(rOut.GetRasterOp());
+ const basegfx::B2DPolyPolygon aPolyPolygon(pObj->TakeXorPoly());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ rOut.SetLineColor(COL_BLACK);
+ rOut.SetFillColor();
+ rOut.SetRasterOp(ROP_INVERT);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
+ }
+
+ rOut.SetRasterOp(eRop);
+}
+
+FASTBOOL SdrObjUserData::DoMacro(const SdrObjMacroHitRec& /*rRec*/, SdrObject* /*pObj*/)
+{
+ return FALSE;
+}
+
+XubString SdrObjUserData::GetMacroPopupComment(const SdrObjMacroHitRec& /*rRec*/, const SdrObject* /*pObj*/) const
+{
+ return String();
+}
+
+void SdrObjUserDataList::Clear()
+{
+ USHORT nAnz=GetUserDataCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ delete GetUserData(i);
+ }
+ aList.Clear();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+DBG_NAME(SdrObjGeoData);
+
+SdrObjGeoData::SdrObjGeoData():
+ pGPL(NULL),
+ bMovProt(FALSE),
+ bSizProt(FALSE),
+ bNoPrint(FALSE),
+ bClosedObj(FALSE),
+ mbVisible(true),
+ mnLayerID(0)
+{
+ DBG_CTOR(SdrObjGeoData,NULL);
+}
+
+SdrObjGeoData::~SdrObjGeoData()
+{
+ DBG_DTOR(SdrObjGeoData,NULL);
+ delete pGPL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT0(SdrObjPlusData);
+
+SdrObjPlusData::SdrObjPlusData():
+ pBroadcast(NULL),
+ pUserDataList(NULL),
+ pGluePoints(NULL),
+ pAutoTimer(NULL)
+{
+}
+
+SdrObjPlusData::~SdrObjPlusData()
+{
+ if (pBroadcast !=NULL) delete pBroadcast;
+ if (pUserDataList!=NULL) delete pUserDataList;
+ if (pGluePoints !=NULL) delete pGluePoints;
+ if (pAutoTimer !=NULL) delete pAutoTimer;
+}
+
+SdrObjPlusData* SdrObjPlusData::Clone(SdrObject* pObj1) const
+{
+ SdrObjPlusData* pNeuPlusData=new SdrObjPlusData;
+ if (pUserDataList!=NULL) {
+ USHORT nAnz=pUserDataList->GetUserDataCount();
+ if (nAnz!=0) {
+ pNeuPlusData->pUserDataList=new SdrObjUserDataList;
+ for (USHORT i=0; i<nAnz; i++) {
+ SdrObjUserData* pNeuUserData=pUserDataList->GetUserData(i)->Clone(pObj1);
+ if (pNeuUserData!=NULL) {
+ pNeuPlusData->pUserDataList->InsertUserData(pNeuUserData);
+ } else {
+ DBG_ERROR("SdrObjPlusData::Clone(): UserData.Clone() liefert NULL");
+ }
+ }
+ }
+ }
+ if (pGluePoints!=NULL) pNeuPlusData->pGluePoints=new SdrGluePointList(*pGluePoints);
+ // MtfAnimator wird auch nicht mitkopiert
+
+ // #i68101#
+ // copy object name, title and description
+ pNeuPlusData->aObjName = aObjName;
+ pNeuPlusData->aObjTitle = aObjTitle;
+ pNeuPlusData->aObjDescription = aObjDescription;
+
+ if (pAutoTimer!=NULL) {
+ pNeuPlusData->pAutoTimer=new AutoTimer;
+ // Handler, etc. nicht mitkopieren!
+ }
+
+ // For HTMLName: Do not clone, leave uninitialized (empty string)
+
+ return pNeuPlusData;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@@ @@@@@ @@@@ @@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@@@@ @@@@ @@@@@ @@@@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrObject::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::EmptyProperties(*this);
+}
+
+sdr::properties::BaseProperties& SdrObject::GetProperties() const
+{
+ if(!mpProperties)
+ {
+ const_cast< SdrObject* >(this)->mpProperties =
+ const_cast< SdrObject* >(this)->CreateObjectSpecificProperties();
+ }
+
+ return *mpProperties;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// ObjectUser section
+
+void SdrObject::AddObjectUser(sdr::ObjectUser& rNewUser)
+{
+ maObjectUsers.push_back(&rNewUser);
+}
+
+void SdrObject::RemoveObjectUser(sdr::ObjectUser& rOldUser)
+{
+ const ::sdr::ObjectUserVector::iterator aFindResult = ::std::find(maObjectUsers.begin(), maObjectUsers.end(), &rOldUser);
+ if(aFindResult != maObjectUsers.end())
+ {
+ maObjectUsers.erase(aFindResult);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #110094# DrawContact section
+
+sdr::contact::ViewContact* SdrObject::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrObj(*this);
+}
+
+sdr::contact::ViewContact& SdrObject::GetViewContact() const
+{
+ if(!mpViewContact)
+ {
+ const_cast< SdrObject* >(this)->mpViewContact =
+ const_cast< SdrObject* >(this)->CreateObjectSpecificViewContact();
+ }
+
+ return *mpViewContact;
+}
+
+// DrawContact support: Methods for handling Object changes
+void SdrObject::ActionChanged() const
+{
+ // Do necessary ViewContact actions
+ GetViewContact().ActionChanged();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void SdrObject::SetBoundRectDirty()
+{
+ aOutRect = Rectangle();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+DBG_NAME(SdrObject);
+TYPEINIT1(SdrObject,SfxListener);
+
+SdrObject::SdrObject()
+ :mpProperties(0L)
+ ,mpViewContact(0L)
+ ,pObjList(NULL)
+ ,pPage(NULL)
+ ,pModel(NULL)
+ ,pUserCall(NULL)
+ ,pPlusData(NULL)
+ ,nOrdNum(0)
+ ,mnNavigationPosition(SAL_MAX_UINT32)
+ ,mnLayerID(0)
+ ,mpSvxShape( NULL )
+ ,maWeakUnoShape()
+{
+ DBG_CTOR(SdrObject,NULL);
+ bVirtObj =FALSE;
+ bSnapRectDirty =TRUE;
+ bNetLock =FALSE;
+ bInserted =FALSE;
+ bGrouped =FALSE;
+ bMovProt =FALSE;
+ bSizProt =FALSE;
+ bNoPrint =FALSE;
+ bEmptyPresObj =FALSE;
+ bNotVisibleAsMaster=FALSE;
+ bClosedObj =FALSE;
+ mbVisible = true;
+
+ // #i25616#
+ mbLineIsOutsideGeometry = sal_False;
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+
+ //#110094#-1
+ //bWriterFlyFrame =FALSE;
+
+ bNotMasterCachable=FALSE;
+ bIsEdge=FALSE;
+ bIs3DObj=FALSE;
+ bMarkProt=FALSE;
+ bIsUnoObj=FALSE;
+}
+
+SdrObject::~SdrObject()
+{
+ // tell all the registered ObjectUsers that the page is in destruction
+ ::sdr::ObjectUserVector aListCopy(maObjectUsers.begin(), maObjectUsers.end());
+ for(::sdr::ObjectUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); aIterator++)
+ {
+ sdr::ObjectUser* pObjectUser = *aIterator;
+ DBG_ASSERT(pObjectUser, "SdrObject::~SdrObject: corrupt ObjectUser list (!)");
+ pObjectUser->ObjectInDestruction(*this);
+ }
+
+ // Clear the vector. This means that user do not need to call RemoveObjectUser()
+ // when they get called from ObjectInDestruction().
+ maObjectUsers.clear();
+
+ try
+ {
+ SvxShape* pSvxShape = getSvxShape();
+ if ( pSvxShape )
+ {
+ OSL_ENSURE(!pSvxShape->HasSdrObjectOwnership(),"Please check where this call come from and replace it with SdrObject::Free");
+ pSvxShape->InvalidateSdrObject();
+ uno::Reference< lang::XComponent > xShapeComp( getWeakUnoShape(), uno::UNO_QUERY_THROW );
+ xShapeComp->dispose();
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ DBG_DTOR(SdrObject,NULL);
+ SendUserCall(SDRUSERCALL_DELETE, GetLastBoundRect());
+ if (pPlusData!=NULL) delete pPlusData;
+
+ if(mpProperties)
+ {
+ delete mpProperties;
+ mpProperties = 0L;
+ }
+
+ // #110094#
+ if(mpViewContact)
+ {
+ delete mpViewContact;
+ mpViewContact = 0L;
+ }
+}
+
+void SdrObject::Free( SdrObject*& _rpObject )
+{
+ SdrObject* pObject = _rpObject; _rpObject = NULL;
+ if ( pObject == NULL )
+ // nothing to do
+ return;
+
+ SvxShape* pShape = pObject->getSvxShape();
+ if ( pShape && pShape->HasSdrObjectOwnership() )
+ // only the shape is allowed to delete me, and will reset the ownership before doing so
+ return;
+
+ delete pObject;
+}
+
+SdrObjPlusData* SdrObject::NewPlusData() const
+{
+ return new SdrObjPlusData;
+}
+
+void SdrObject::SetRectsDirty(sal_Bool bNotMyself)
+{
+ if (!bNotMyself) {
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ }
+ if (pObjList!=NULL) {
+ pObjList->SetRectsDirty();
+ }
+}
+
+void SdrObject::SetModel(SdrModel* pNewModel)
+{
+ if(pNewModel && pPage)
+ {
+ if(pPage->GetModel() != pNewModel)
+ {
+ pPage = NULL;
+ }
+ }
+
+ // update listeners at possible api wrapper object
+ if( pModel != pNewModel )
+ {
+ SvxShape* pShape = getSvxShape();
+ if( pShape )
+ pShape->ChangeModel( pNewModel );
+ }
+
+ pModel = pNewModel;
+}
+
+void SdrObject::SetObjList(SdrObjList* pNewObjList)
+{
+ pObjList=pNewObjList;
+}
+
+void SdrObject::SetPage(SdrPage* pNewPage)
+{
+ pPage=pNewPage;
+ if (pPage!=NULL) {
+ SdrModel* pMod=pPage->GetModel();
+ if (pMod!=pModel && pMod!=NULL) {
+ SetModel(pMod);
+ }}
+}
+
+// init global static itempool
+SdrItemPool* SdrObject::mpGlobalItemPool = NULL;
+
+SdrItemPool& SdrObject::GetGlobalDrawObjectItemPool()
+{
+ if(!mpGlobalItemPool)
+ {
+ mpGlobalItemPool = new SdrItemPool();
+ SfxItemPool* pGlobalOutlPool = EditEngine::CreatePool();
+ mpGlobalItemPool->SetSecondaryPool(pGlobalOutlPool);
+ mpGlobalItemPool->SetDefaultMetric((SfxMapUnit)SdrEngineDefaults::GetMapUnit());
+ mpGlobalItemPool->FreezeIdRanges();
+ }
+
+ return *mpGlobalItemPool;
+}
+
+void SdrObject::FreeGlobalDrawObjectItemPool()
+{
+ // code for deletion of GlobalItemPool
+ if(mpGlobalItemPool)
+ {
+ SfxItemPool* pGlobalOutlPool = mpGlobalItemPool->GetSecondaryPool();
+ SfxItemPool::Free(mpGlobalItemPool);
+ SfxItemPool::Free(pGlobalOutlPool);
+ }
+}
+
+SdrItemPool* SdrObject::GetObjectItemPool() const
+{
+ if(pModel)
+ return (SdrItemPool*)(&pModel->GetItemPool());
+
+ // use a static global default pool
+ return &SdrObject::GetGlobalDrawObjectItemPool();
+}
+
+UINT32 SdrObject::GetObjInventor() const
+{
+ return SdrInventor;
+}
+
+UINT16 SdrObject::GetObjIdentifier() const
+{
+ return UINT16(OBJ_NONE);
+}
+
+void SdrObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bCanConvToPath =FALSE;
+ rInfo.bCanConvToPoly =FALSE;
+ rInfo.bCanConvToContour = FALSE;
+ rInfo.bCanConvToPathLineToArea=FALSE;
+ rInfo.bCanConvToPolyLineToArea=FALSE;
+}
+
+SdrLayerID SdrObject::GetLayer() const
+{
+ return mnLayerID;
+}
+
+void SdrObject::getMergedHierarchyLayerSet(SetOfByte& rSet) const
+{
+ rSet.Set(GetLayer());
+ SdrObjList* pOL=GetSubList();
+ if (pOL!=NULL) {
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
+ pOL->GetObj(nObjNum)->getMergedHierarchyLayerSet(rSet);
+ }
+ }
+}
+
+void SdrObject::NbcSetLayer(SdrLayerID nLayer)
+{
+ if(GetLayer() != nLayer)
+ {
+ mnLayerID = nLayer;
+ }
+}
+
+void SdrObject::SetLayer(SdrLayerID nLayer)
+{
+ NbcSetLayer(nLayer);
+ SetChanged();
+ BroadcastObjectChange();
+}
+
+void SdrObject::AddListener(SfxListener& rListener)
+{
+ ImpForcePlusData();
+ if (pPlusData->pBroadcast==NULL) pPlusData->pBroadcast=new SfxBroadcaster;
+ rListener.StartListening(*pPlusData->pBroadcast);
+}
+
+void SdrObject::RemoveListener(SfxListener& rListener)
+{
+ if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
+ rListener.EndListening(*pPlusData->pBroadcast);
+ if (!pPlusData->pBroadcast->HasListeners()) {
+ delete pPlusData->pBroadcast;
+ pPlusData->pBroadcast=NULL;
+ }
+ }
+}
+
+void SdrObject::AddReference(SdrVirtObj& rVrtObj)
+{
+ AddListener(rVrtObj);
+}
+
+void SdrObject::DelReference(SdrVirtObj& rVrtObj)
+{
+ RemoveListener(rVrtObj);
+}
+
+AutoTimer* SdrObject::ForceAutoTimer()
+{
+ ImpForcePlusData();
+ if (pPlusData->pAutoTimer==NULL) pPlusData->pAutoTimer=new AutoTimer;
+ return pPlusData->pAutoTimer;
+}
+
+FASTBOOL SdrObject::HasRefPoint() const
+{
+ return FALSE;
+}
+
+Point SdrObject::GetRefPoint() const
+{
+ return GetCurrentBoundRect().Center();
+}
+
+void SdrObject::SetRefPoint(const Point& /*rPnt*/)
+{
+}
+
+SdrObjList* SdrObject::GetSubList() const
+{
+ return NULL;
+}
+
+SdrObject* SdrObject::GetUpGroup() const
+{
+ return pObjList!=NULL ? pObjList->GetOwnerObj() : NULL;
+}
+
+void SdrObject::SetName(const String& rStr)
+{
+ if(rStr.Len() && !pPlusData)
+ {
+ ImpForcePlusData();
+ }
+
+ if(pPlusData && pPlusData->aObjName != rStr)
+ {
+ // --> OD 2009-07-09 #i73249#
+ // Undo/Redo for setting object's name
+ bool bUndo( false );
+ if ( GetModel() && GetModel()->IsUndoEnabled() )
+ {
+ bUndo = true;
+ SdrUndoAction* pUndoAction =
+ GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
+ *this,
+ SdrUndoObjStrAttr::OBJ_NAME,
+ GetName(),
+ rStr );
+ GetModel()->BegUndo( pUndoAction->GetComment() );
+ GetModel()->AddUndo( pUndoAction );
+ }
+ // <--
+ pPlusData->aObjName = rStr;
+ // --> OD 2009-07-09 #i73249#
+ if ( bUndo )
+ {
+ GetModel()->EndUndo();
+ }
+ // <--
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+String SdrObject::GetName() const
+{
+ if(pPlusData)
+ {
+ return pPlusData->aObjName;
+ }
+
+ return String();
+}
+
+void SdrObject::SetTitle(const String& rStr)
+{
+ if(rStr.Len() && !pPlusData)
+ {
+ ImpForcePlusData();
+ }
+
+ if(pPlusData && pPlusData->aObjTitle != rStr)
+ {
+ // --> OD 2009-07-13 #i73249#
+ // Undo/Redo for setting object's title
+ bool bUndo( false );
+ if ( GetModel() && GetModel()->IsUndoEnabled() )
+ {
+ bUndo = true;
+ SdrUndoAction* pUndoAction =
+ GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
+ *this,
+ SdrUndoObjStrAttr::OBJ_TITLE,
+ GetTitle(),
+ rStr );
+ GetModel()->BegUndo( pUndoAction->GetComment() );
+ GetModel()->AddUndo( pUndoAction );
+ }
+ // <--
+ pPlusData->aObjTitle = rStr;
+ // --> OD 2009-07-13 #i73249#
+ if ( bUndo )
+ {
+ GetModel()->EndUndo();
+ }
+ // <--
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+String SdrObject::GetTitle() const
+{
+ if(pPlusData)
+ {
+ return pPlusData->aObjTitle;
+ }
+
+ return String();
+}
+
+void SdrObject::SetDescription(const String& rStr)
+{
+ if(rStr.Len() && !pPlusData)
+ {
+ ImpForcePlusData();
+ }
+
+ if(pPlusData && pPlusData->aObjDescription != rStr)
+ {
+ // --> OD 2009-07-13 #i73249#
+ // Undo/Redo for setting object's description
+ bool bUndo( false );
+ if ( GetModel() && GetModel()->IsUndoEnabled() )
+ {
+ bUndo = true;
+ SdrUndoAction* pUndoAction =
+ GetModel()->GetSdrUndoFactory().CreateUndoObjectStrAttr(
+ *this,
+ SdrUndoObjStrAttr::OBJ_DESCRIPTION,
+ GetDescription(),
+ rStr );
+ GetModel()->BegUndo( pUndoAction->GetComment() );
+ GetModel()->AddUndo( pUndoAction );
+ }
+ // <--
+ pPlusData->aObjDescription = rStr;
+ // --> OD 2009-07-13 #i73249#
+ if ( bUndo )
+ {
+ GetModel()->EndUndo();
+ }
+ // <--
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+String SdrObject::GetDescription() const
+{
+ if(pPlusData)
+ {
+ return pPlusData->aObjDescription;
+ }
+
+ return String();
+}
+
+void SdrObject::SetHTMLName(const String& rStr)
+{
+ if(rStr.Len() && !pPlusData)
+ {
+ ImpForcePlusData();
+ }
+
+ if(pPlusData && pPlusData->aObjName != rStr)
+ {
+ pPlusData->aHTMLName = rStr;
+ SetChanged();
+ }
+}
+
+String SdrObject::GetHTMLName() const
+{
+ if(pPlusData)
+ {
+ return pPlusData->aHTMLName;
+ }
+
+ return String();
+}
+
+UINT32 SdrObject::GetOrdNum() const
+{
+ if (pObjList!=NULL) {
+ if (pObjList->IsObjOrdNumsDirty()) {
+ pObjList->RecalcObjOrdNums();
+ }
+ } else ((SdrObject*)this)->nOrdNum=0;
+ return nOrdNum;
+}
+
+
+
+
+sal_uInt32 SdrObject::GetNavigationPosition (void)
+{
+ if (pObjList!=NULL && pObjList->RecalcNavigationPositions())
+ {
+ return mnNavigationPosition;
+ }
+ else
+ return GetOrdNum();
+}
+
+
+
+
+void SdrObject::SetNavigationPosition (const sal_uInt32 nNewPosition)
+{
+ mnNavigationPosition = nNewPosition;
+}
+
+
+
+
+// #111111#
+// To make clearer that this method may trigger RecalcBoundRect and thus may be
+// expensive and somtimes problematic (inside a bigger object change You will get
+// non-useful BoundRects sometimes) i rename that method from GetBoundRect() to
+// GetCurrentBoundRect().
+const Rectangle& SdrObject::GetCurrentBoundRect() const
+{
+ if(aOutRect.IsEmpty())
+ {
+ const_cast< SdrObject* >(this)->RecalcBoundRect();
+ }
+
+ return aOutRect;
+}
+
+// #111111#
+// To have a possibility to get the last calculated BoundRect e.g for producing
+// the first rectangle for repaints (old and new need to be used) without forcing
+// a RecalcBoundRect (which may be problematical and expensive sometimes) i add here
+// a new method for accessing the last BoundRect.
+const Rectangle& SdrObject::GetLastBoundRect() const
+{
+ return aOutRect;
+}
+
+void SdrObject::RecalcBoundRect()
+{
+ // #i101680# suppress BoundRect calculations on import(s)
+ if(pModel && pModel->isLocked() )
+ return;
+
+ // central new method which will calculate the BoundRect using primitive geometry
+ if(aOutRect.IsEmpty())
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence xPrimitives(GetViewContact().getViewIndependentPrimitive2DSequence());
+
+ if(xPrimitives.hasElements())
+ {
+ // use neutral ViewInformation and get the range of the primitives
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0);
+ const basegfx::B2DRange aRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xPrimitives, aViewInformation2D));
+
+ if(!aRange.isEmpty())
+ {
+ aOutRect = Rectangle(
+ (sal_Int32)floor(aRange.getMinX()), (sal_Int32)floor(aRange.getMinY()),
+ (sal_Int32)ceil(aRange.getMaxX()), (sal_Int32)ceil(aRange.getMaxY()));
+ return;
+ }
+ }
+ }
+}
+
+void SdrObject::BroadcastObjectChange() const
+{
+ if( pModel && pModel->isLocked() )
+ return;
+
+ sal_Bool bPlusDataBroadcast(pPlusData && pPlusData->pBroadcast);
+ sal_Bool bObjectChange(IsInserted() && pModel);
+
+ if(bPlusDataBroadcast || bObjectChange)
+ {
+ SdrHint aHint(*this);
+
+ if(bPlusDataBroadcast)
+ {
+ pPlusData->pBroadcast->Broadcast(aHint);
+ }
+
+ if(bObjectChange)
+ {
+ pModel->Broadcast(aHint);
+ }
+ }
+}
+
+void SdrObject::SetChanged()
+{
+ // #110094#-11
+ // For test purposes, use the new ViewContact for change
+ // notification now.
+ ActionChanged();
+
+ if(IsInserted() && pModel)
+ {
+ pModel->SetChanged();
+ }
+}
+
+// Tooling for painting a single object to a OutputDevice.
+sal_Bool SdrObject::SingleObjectPainter(OutputDevice& rOut) const
+{
+ sdr::contact::SdrObjectVector aObjectVector;
+ aObjectVector.push_back(const_cast< SdrObject* >(this));
+
+ sdr::contact::ObjectContactOfObjListPainter aPainter(rOut, aObjectVector, GetPage());
+ sdr::contact::DisplayInfo aDisplayInfo;
+
+ // do processing
+ aPainter.ProcessDisplay(aDisplayInfo);
+
+ return sal_True;
+}
+
+BOOL SdrObject::LineGeometryUsageIsNecessary() const
+{
+ XLineStyle eXLS = (XLineStyle)((const XLineStyleItem&)GetMergedItem(XATTR_LINESTYLE)).GetValue();
+ return (eXLS != XLINE_NONE);
+}
+
+SdrObject* SdrObject::Clone() const
+{
+ SdrObject* pObj=SdrObjFactory::MakeNewObject(GetObjInventor(),GetObjIdentifier(),NULL);
+ if (pObj!=NULL) {
+ pObj->pModel=pModel;
+ pObj->pPage=pPage;
+ *pObj=*this;
+ }
+ return pObj;
+}
+
+void SdrObject::operator=(const SdrObject& rObj)
+{
+ if(mpProperties)
+ {
+ delete mpProperties;
+ mpProperties = 0L;
+ }
+
+ // #110094#
+ if(mpViewContact)
+ {
+ delete mpViewContact;
+ mpViewContact = 0L;
+ }
+
+ // The Clone() method uses the local copy constructor from the individual
+ // sdr::properties::BaseProperties class. Since the target class maybe for another
+ // draw object a SdrObject needs to be provided, as in the nromal constructor.
+ mpProperties = &rObj.GetProperties().Clone(*this);
+
+ pModel =rObj.pModel;
+ aOutRect=rObj.aOutRect;
+ mnLayerID = rObj.mnLayerID;
+ aAnchor =rObj.aAnchor;
+ bVirtObj=rObj.bVirtObj;
+ bSizProt=rObj.bSizProt;
+ bMovProt=rObj.bMovProt;
+ bNoPrint=rObj.bNoPrint;
+ mbVisible=rObj.mbVisible;
+ bMarkProt=rObj.bMarkProt;
+ //EmptyPresObj wird nicht kopiert: nun doch! (25-07-1995, Joe)
+ bEmptyPresObj =rObj.bEmptyPresObj;
+ //NotVisibleAsMaster wird nicht kopiert: nun doch! (25-07-1995, Joe)
+ bNotVisibleAsMaster=rObj.bNotVisibleAsMaster;
+ bSnapRectDirty=TRUE; //rObj.bSnapRectDirty;
+ bNotMasterCachable=rObj.bNotMasterCachable;
+ if (pPlusData!=NULL) { delete pPlusData; pPlusData=NULL; }
+ if (rObj.pPlusData!=NULL) {
+ pPlusData=rObj.pPlusData->Clone(this);
+ }
+ if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) {
+ delete pPlusData->pBroadcast; // der Broadcaster wird nicht mitkopiert
+ pPlusData->pBroadcast=NULL;
+ }
+}
+
+void SdrObject::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulNONE);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrObject::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralNONE);
+}
+
+void SdrObject::ImpTakeDescriptionStr(USHORT nStrCacheID, XubString& rStr, USHORT nVal) const
+{
+ rStr = ImpGetResStr(nStrCacheID);
+
+ sal_Char aSearchText1[] = "%1";
+ sal_Char aSearchText2[] = "%2";
+ xub_StrLen nPos = rStr.SearchAscii(aSearchText1);
+
+ if(nPos != STRING_NOTFOUND)
+ {
+ rStr.Erase(nPos, 2);
+
+ XubString aObjName;
+
+ TakeObjNameSingul(aObjName);
+ rStr.Insert(aObjName, nPos);
+ }
+
+ nPos = rStr.SearchAscii(aSearchText2);
+
+ if(nPos != STRING_NOTFOUND)
+ {
+ rStr.Erase(nPos, 2);
+ rStr.Insert(UniString::CreateFromInt32(nVal), nPos);
+ }
+}
+
+XubString SdrObject::GetWinkStr(long nWink, FASTBOOL bNoDegChar) const
+{
+ XubString aStr;
+ if (pModel!=NULL) {
+ pModel->TakeWinkStr(nWink,aStr,bNoDegChar);
+ }
+ return aStr;
+}
+
+XubString SdrObject::GetMetrStr(long nVal, MapUnit /*eWantMap*/, FASTBOOL bNoUnitChars) const
+{
+ XubString aStr;
+ if (pModel!=NULL) {
+ pModel->TakeMetricStr(nVal,aStr,bNoUnitChars);
+ }
+ return aStr;
+}
+
+basegfx::B2DPolyPolygon SdrObject::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ const Rectangle aR(GetCurrentBoundRect());
+ const basegfx::B2DRange aRange(aR.Left(), aR.Top(), aR.Right(), aR.Bottom());
+ aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SdrObject::TakeContour() const
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ // create cloned object without text, but with XLINE_SOLID,
+ // COL_BLACK as line color and XFILL_NONE
+ SdrObject* pClone = Clone();
+
+ if(pClone)
+ {
+ const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >(this);
+
+ if(pTextObj)
+ {
+ // no text and no text animation
+ pClone->SetMergedItem(SdrTextAniKindItem(SDRTEXTANI_NONE));
+ pClone->SetOutlinerParaObject(0);
+ }
+
+ const SdrEdgeObj* pEdgeObj = dynamic_cast< const SdrEdgeObj* >(this);
+
+ if(pEdgeObj)
+ {
+ // create connections if connector, will be cleaned up when
+ // deleting the connector again
+ SdrObject* pLeft = pEdgeObj->GetConnectedNode(TRUE);
+ SdrObject* pRight = pEdgeObj->GetConnectedNode(FALSE);
+
+ if(pLeft)
+ {
+ pClone->ConnectToNode(TRUE, pLeft);
+ }
+
+ if(pRight)
+ {
+ pClone->ConnectToNode(FALSE, pRight);
+ }
+ }
+
+ SfxItemSet aNewSet(*GetObjectItemPool());
+
+ // #i101980# ignore LineWidth; that's what the old implementation
+ // did. With linewidth, the result may be huge due to fat/thick
+ // line decompositions
+ aNewSet.Put(XLineWidthItem(0));
+
+ // solid black lines and no fill
+ aNewSet.Put(XLineStyleItem(XLINE_SOLID));
+ aNewSet.Put(XLineColorItem(String(), Color(COL_BLACK)));
+ aNewSet.Put(XFillStyleItem(XFILL_NONE));
+ pClone->SetMergedItemSet(aNewSet);
+
+ // get sequence from clone
+ const sdr::contact::ViewContact& rVC(pClone->GetViewContact());
+ const drawinglayer::primitive2d::Primitive2DSequence xSequence(rVC.getViewIndependentPrimitive2DSequence());
+
+ if(xSequence.hasElements())
+ {
+ // use neutral ViewInformation
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0);
+
+ // create extractor, process and get result
+ drawinglayer::processor2d::ContourExtractor2D aExtractor(aViewInformation2D);
+ aExtractor.process(xSequence);
+ const std::vector< basegfx::B2DPolyPolygon >& rResult(aExtractor.getExtractedContour());
+ const sal_uInt32 nSize(rResult.size());
+
+ // when count is one, it is implied that the object has only it's normal
+ // contour anyways and TakeCountour() is to return an empty PolyPolygon
+ // (see old implementation for historical reasons)
+ if(nSize > 1)
+ {
+ // the topology for contour is correctly a vector of PolyPolygons; for
+ // historical reasons cut it back to a single PolyPolygon here
+ for(sal_uInt32 a(0); a < nSize; a++)
+ {
+ aRetval.append(rResult[a]);
+ }
+ }
+ }
+
+ delete pClone;
+ }
+
+ return aRetval;
+}
+
+sal_uInt32 SdrObject::GetHdlCount() const
+{
+ return 8L;
+}
+
+SdrHdl* SdrObject::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pH=NULL;
+ const Rectangle& rR=GetSnapRect();
+ switch (nHdlNum) {
+ case 0: pH=new SdrHdl(rR.TopLeft(), HDL_UPLFT); break; // Oben links
+ case 1: pH=new SdrHdl(rR.TopCenter(), HDL_UPPER); break; // Oben
+ case 2: pH=new SdrHdl(rR.TopRight(), HDL_UPRGT); break; // Oben rechts
+ case 3: pH=new SdrHdl(rR.LeftCenter(), HDL_LEFT ); break; // Links
+ case 4: pH=new SdrHdl(rR.RightCenter(), HDL_RIGHT); break; // Rechts
+ case 5: pH=new SdrHdl(rR.BottomLeft(), HDL_LWLFT); break; // Unten links
+ case 6: pH=new SdrHdl(rR.BottomCenter(),HDL_LOWER); break; // Unten
+ case 7: pH=new SdrHdl(rR.BottomRight(), HDL_LWRGT); break; // Unten rechts
+ }
+ return pH;
+}
+
+sal_uInt32 SdrObject::GetPlusHdlCount(const SdrHdl& /*rHdl*/) const
+{
+ return 0L;
+}
+
+SdrHdl* SdrObject::GetPlusHdl(const SdrHdl& /*rHdl*/, sal_uInt32 /*nPlNum*/) const
+{
+ return 0L;
+}
+
+void SdrObject::AddToHdlList(SdrHdlList& rHdlList) const
+{
+ sal_uInt32 nAnz=GetHdlCount();
+ for (sal_uInt32 i=0L; i<nAnz; i++) {
+ SdrHdl* pHdl=GetHdl(i);
+ if (pHdl!=NULL) {
+ rHdlList.AddHdl(pHdl);
+ }
+ }
+}
+
+Rectangle SdrObject::ImpDragCalcRect(const SdrDragStat& rDrag) const
+{
+ Rectangle aTmpRect(GetSnapRect());
+ Rectangle aRect(aTmpRect);
+ const SdrHdl* pHdl=rDrag.GetHdl();
+ SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
+ FASTBOOL bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
+ FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
+ FASTBOOL bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
+ Point aPos(rDrag.GetNow());
+ FASTBOOL bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT || eHdl==HDL_LWLFT);
+ FASTBOOL bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
+ FASTBOOL bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
+ FASTBOOL bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
+ if (bLft) aTmpRect.Left() =aPos.X();
+ if (bRgt) aTmpRect.Right() =aPos.X();
+ if (bTop) aTmpRect.Top() =aPos.Y();
+ if (bBtm) aTmpRect.Bottom()=aPos.Y();
+ if (bOrtho) { // Ortho
+ long nWdt0=aRect.Right() -aRect.Left();
+ long nHgt0=aRect.Bottom()-aRect.Top();
+ long nXMul=aTmpRect.Right() -aTmpRect.Left();
+ long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
+ long nXDiv=nWdt0;
+ long nYDiv=nHgt0;
+ FASTBOOL bXNeg=(nXMul<0)!=(nXDiv<0);
+ FASTBOOL bYNeg=(nYMul<0)!=(nYDiv<0);
+ nXMul=Abs(nXMul);
+ nYMul=Abs(nYMul);
+ nXDiv=Abs(nXDiv);
+ nYDiv=Abs(nYDiv);
+ Fraction aXFact(nXMul,nXDiv); // Fractions zum kuerzen
+ Fraction aYFact(nYMul,nYDiv); // und zum vergleichen
+ nXMul=aXFact.GetNumerator();
+ nYMul=aYFact.GetNumerator();
+ nXDiv=aXFact.GetDenominator();
+ nYDiv=aYFact.GetDenominator();
+ if (bEcke) { // Eckpunkthandles
+ FASTBOOL bUseX=(aXFact<aYFact) != bBigOrtho;
+ if (bUseX) {
+ long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
+ if (bYNeg) nNeed=-nNeed;
+ if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
+ if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
+ } else {
+ long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
+ if (bXNeg) nNeed=-nNeed;
+ if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
+ if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
+ }
+ } else { // Scheitelpunkthandles
+ if ((bLft || bRgt) && nXDiv!=0) {
+ long nHgt0b=aRect.Bottom()-aRect.Top();
+ long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
+ aTmpRect.Top()-=(nNeed-nHgt0b)/2;
+ aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
+ }
+ if ((bTop || bBtm) && nYDiv!=0) {
+ long nWdt0b=aRect.Right()-aRect.Left();
+ long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
+ aTmpRect.Left()-=(nNeed-nWdt0b)/2;
+ aTmpRect.Right()=aTmpRect.Left()+nNeed;
+ }
+ }
+ }
+ aTmpRect.Justify();
+ return aTmpRect;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrObject::hasSpecialDrag() const
+{
+ return false;
+}
+
+bool SdrObject::supportsFullDrag() const
+{
+ return true;
+}
+
+SdrObject* SdrObject::getFullDragClone() const
+{
+ // default uses simple clone
+ return Clone();
+}
+
+bool SdrObject::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ SdrHdlKind eHdl = (pHdl == NULL) ? HDL_MOVE : pHdl->GetKind();
+
+ if(eHdl==HDL_UPLFT || eHdl==HDL_UPPER || eHdl==HDL_UPRGT ||
+ eHdl==HDL_LEFT || eHdl==HDL_RIGHT || eHdl==HDL_LWLFT ||
+ eHdl==HDL_LOWER || eHdl==HDL_LWRGT)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool SdrObject::applySpecialDrag(SdrDragStat& rDrag)
+{
+ Rectangle aNewRect(ImpDragCalcRect(rDrag));
+
+ if(aNewRect != GetSnapRect())
+ {
+ NbcSetSnapRect(aNewRect);
+ }
+
+ return true;
+}
+
+String SdrObject::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
+{
+ return String();
+}
+
+basegfx::B2DPolyPolygon SdrObject::getSpecialDragPoly(const SdrDragStat& /*rDrag*/) const
+{
+ // default has nothing to add
+ return basegfx::B2DPolyPolygon();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Create
+FASTBOOL SdrObject::BegCreate(SdrDragStat& rStat)
+{
+ rStat.SetOrtho4Possible();
+ Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
+ aRect1.Justify();
+ rStat.SetActionRect(aRect1);
+ aOutRect = aRect1;
+ return TRUE;
+}
+
+FASTBOOL SdrObject::MovCreate(SdrDragStat& rStat)
+{
+ rStat.TakeCreateRect(aOutRect);
+ rStat.SetActionRect(aOutRect);
+ aOutRect.Justify();
+
+ // #i101648# for naked (non-derived) SdrObjects, do not invalidate aOutRect
+ // by calling SetBoundRectDirty(); aOutRect IS the geometry for such objects.
+ // No derivation implementation calls the parent implementation, so this will
+ // cause no further prolems
+ //
+ // SetBoundRectDirty();
+ // bSnapRectDirty=TRUE;
+
+ return TRUE;
+}
+
+FASTBOOL SdrObject::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ rStat.TakeCreateRect(aOutRect);
+ aOutRect.Justify();
+
+ // #i101648# see description at MovCreate
+ //
+ // SetRectsDirty();
+
+ return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
+}
+
+void SdrObject::BrkCreate(SdrDragStat& /*rStat*/)
+{
+}
+
+FASTBOOL SdrObject::BckCreate(SdrDragStat& /*rStat*/)
+{
+ return FALSE;
+}
+
+basegfx::B2DPolyPolygon SdrObject::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ Rectangle aRect1;
+ rDrag.TakeCreateRect(aRect1);
+ aRect1.Justify();
+
+ basegfx::B2DPolyPolygon aRetval;
+ const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
+ aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
+ return aRetval;
+}
+
+Pointer SdrObject::GetCreatePointer() const
+{
+ return Pointer(POINTER_CROSS);
+}
+
+// Transformationen
+void SdrObject::NbcMove(const Size& rSiz)
+{
+ MoveRect(aOutRect,rSiz);
+ SetRectsDirty();
+}
+
+void SdrObject::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
+ FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
+ if (bXMirr || bYMirr) {
+ Point aRef1(GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ }
+ ResizeRect(aOutRect,rRef,xFact,yFact);
+ SetRectsDirty();
+}
+
+void SdrObject::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SetGlueReallyAbsolute(TRUE);
+ aOutRect.Move(-rRef.X(),-rRef.Y());
+ Rectangle R(aOutRect);
+ if (sn==1.0 && cs==0.0) { // 90deg
+ aOutRect.Left() =-R.Bottom();
+ aOutRect.Right() =-R.Top();
+ aOutRect.Top() =R.Left();
+ aOutRect.Bottom()=R.Right();
+ } else if (sn==0.0 && cs==-1.0) { // 180deg
+ aOutRect.Left() =-R.Right();
+ aOutRect.Right() =-R.Left();
+ aOutRect.Top() =-R.Bottom();
+ aOutRect.Bottom()=-R.Top();
+ } else if (sn==-1.0 && cs==0.0) { // 270deg
+ aOutRect.Left() =R.Top();
+ aOutRect.Right() =R.Bottom();
+ aOutRect.Top() =-R.Right();
+ aOutRect.Bottom()=-R.Left();
+ }
+ aOutRect.Move(rRef.X(),rRef.Y());
+ aOutRect.Justify(); // Sicherheitshalber
+ SetRectsDirty();
+ NbcRotateGluePoints(rRef,nWink,sn,cs);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+void SdrObject::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SetGlueReallyAbsolute(TRUE);
+ aOutRect.Move(-rRef1.X(),-rRef1.Y());
+ Rectangle R(aOutRect);
+ long dx=rRef2.X()-rRef1.X();
+ long dy=rRef2.Y()-rRef1.Y();
+ if (dx==0) { // Vertikale Achse
+ aOutRect.Left() =-R.Right();
+ aOutRect.Right()=-R.Left();
+ } else if (dy==0) { // Horizontale Achse
+ aOutRect.Top() =-R.Bottom();
+ aOutRect.Bottom()=-R.Top();
+ } else if (dx==dy) { /* 45 Grad Achse \ */
+ aOutRect.Left() =R.Top();
+ aOutRect.Right() =R.Bottom();
+ aOutRect.Top() =R.Left();
+ aOutRect.Bottom()=R.Right();
+ } else if (dx==-dy) { // 45 Grad Achse /
+ aOutRect.Left() =-R.Bottom();
+ aOutRect.Right() =-R.Top();
+ aOutRect.Top() =-R.Right();
+ aOutRect.Bottom()=-R.Left();
+ }
+ aOutRect.Move(rRef1.X(),rRef1.Y());
+ aOutRect.Justify(); // Sicherheitshalber
+ SetRectsDirty();
+ NbcMirrorGluePoints(rRef1,rRef2);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+void SdrObject::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SetGlueReallyAbsolute(TRUE);
+ NbcShearGluePoints(rRef,nWink,tn,bVShear);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+void SdrObject::Move(const Size& rSiz)
+{
+ if (rSiz.Width()!=0 || rSiz.Height()!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcMove(rSiz);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+void SdrObject::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcResize(rRef,xFact,yFact);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrObject::Rotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ if (nWink!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcRotate(rRef,nWink,sn,cs);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrObject::Mirror(const Point& rRef1, const Point& rRef2)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcMirror(rRef1,rRef2);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrObject::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ if (nWink!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcShear(rRef,nWink,tn,bVShear);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrObject::NbcSetRelativePos(const Point& rPnt)
+{
+ Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
+ Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
+ NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
+}
+
+void SdrObject::SetRelativePos(const Point& rPnt)
+{
+ if (rPnt!=GetRelativePos()) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetRelativePos(rPnt);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+Point SdrObject::GetRelativePos() const
+{
+ return GetSnapRect().TopLeft()-aAnchor;
+}
+
+void SdrObject::NbcSetAnchorPos(const Point& rPnt)
+{
+ Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
+ aAnchor=rPnt;
+ NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
+}
+
+void SdrObject::SetAnchorPos(const Point& rPnt)
+{
+ if (rPnt!=aAnchor) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetAnchorPos(rPnt);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+const Point& SdrObject::GetAnchorPos() const
+{
+ return aAnchor;
+}
+
+void SdrObject::RecalcSnapRect()
+{
+}
+
+const Rectangle& SdrObject::GetSnapRect() const
+{
+ return aOutRect;
+}
+
+void SdrObject::NbcSetSnapRect(const Rectangle& rRect)
+{
+ aOutRect=rRect;
+}
+
+const Rectangle& SdrObject::GetLogicRect() const
+{
+ return GetSnapRect();
+}
+
+void SdrObject::NbcSetLogicRect(const Rectangle& rRect)
+{
+ NbcSetSnapRect(rRect);
+}
+
+void SdrObject::AdjustToMaxRect( const Rectangle& rMaxRect, bool /* bShrinkOnly = false */ )
+{
+ SetLogicRect( rMaxRect );
+}
+
+void SdrObject::SetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetSnapRect(rRect);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrObject::SetLogicRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetLogicRect(rRect);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+long SdrObject::GetRotateAngle() const
+{
+ return 0;
+}
+
+long SdrObject::GetShearAngle(FASTBOOL /*bVertical*/) const
+{
+ return 0;
+}
+
+sal_uInt32 SdrObject::GetSnapPointCount() const
+{
+ return GetPointCount();
+}
+
+Point SdrObject::GetSnapPoint(sal_uInt32 i) const
+{
+ return GetPoint(i);
+}
+
+sal_Bool SdrObject::IsPolyObj() const
+{
+ return sal_False;
+}
+
+sal_uInt32 SdrObject::GetPointCount() const
+{
+ return 0L;
+}
+
+Point SdrObject::GetPoint(sal_uInt32 /*i*/) const
+{
+ return Point();
+}
+
+void SdrObject::SetPoint(const Point& rPnt, sal_uInt32 i)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetPoint(rPnt, i);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrObject::NbcSetPoint(const Point& /*rPnt*/, sal_uInt32 /*i*/)
+{
+}
+
+FASTBOOL SdrObject::HasTextEdit() const
+{
+ return FALSE;
+}
+
+sal_Bool SdrObject::BegTextEdit(SdrOutliner& /*rOutl*/)
+{
+ return FALSE;
+}
+
+void SdrObject::EndTextEdit(SdrOutliner& /*rOutl*/)
+{
+}
+
+void SdrObject::SetOutlinerParaObject(OutlinerParaObject* pTextObject)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetOutlinerParaObject(pTextObject);
+ SetChanged();
+ BroadcastObjectChange();
+ if (GetCurrentBoundRect()!=aBoundRect0) {
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrObject::NbcSetOutlinerParaObject(OutlinerParaObject* /*pTextObject*/)
+{
+}
+
+OutlinerParaObject* SdrObject::GetOutlinerParaObject() const
+{
+ return NULL;
+}
+
+void SdrObject::NbcReformatText()
+{
+}
+
+void SdrObject::ReformatText()
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ NbcReformatText();
+ SetChanged();
+ BroadcastObjectChange();
+ if (GetCurrentBoundRect()!=aBoundRect0) {
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrObject::BurnInStyleSheetAttributes()
+{
+ GetProperties().ForceStyleToHardAttributes();
+}
+
+#define Imp2ndKennung (0x434F4D43)
+SdrObjUserData* SdrObject::ImpGetMacroUserData() const
+{
+ SdrObjUserData* pData=NULL;
+ USHORT nAnz=GetUserDataCount();
+ for (USHORT nNum=nAnz; nNum>0 && pData==NULL;) {
+ nNum--;
+ pData=GetUserData(nNum);
+ if (!pData->HasMacro(this)) pData=NULL;
+ }
+ return pData;
+}
+
+FASTBOOL SdrObject::HasMacro() const
+{
+ SdrObjUserData* pData=ImpGetMacroUserData();
+ return pData!=NULL ? pData->HasMacro(this) : FALSE;
+}
+
+SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
+{
+ SdrObjUserData* pData = ImpGetMacroUserData();
+
+ if(pData)
+ {
+ return pData->CheckMacroHit(rRec, this);
+ }
+
+ if(rRec.pPageView)
+ {
+ return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
+ }
+
+ return 0;
+}
+
+Pointer SdrObject::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
+{
+ SdrObjUserData* pData=ImpGetMacroUserData();
+ if (pData!=NULL) {
+ return pData->GetMacroPointer(rRec,this);
+ }
+ return Pointer(POINTER_REFHAND);
+}
+
+void SdrObject::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
+{
+ SdrObjUserData* pData=ImpGetMacroUserData();
+
+ if(pData)
+ {
+ pData->PaintMacro(rOut,rDirtyRect,rRec,this);
+ }
+ else
+ {
+ const RasterOp eRop(rOut.GetRasterOp());
+ const basegfx::B2DPolyPolygon aPolyPolygon(TakeXorPoly());
+ const sal_uInt32 nCount(aPolyPolygon.count());
+
+ rOut.SetLineColor(COL_BLACK);
+ rOut.SetFillColor();
+ rOut.SetRasterOp(ROP_INVERT);
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ rOut.DrawPolyLine(aPolyPolygon.getB2DPolygon(a));
+ }
+
+ rOut.SetRasterOp(eRop);
+ }
+}
+
+FASTBOOL SdrObject::DoMacro(const SdrObjMacroHitRec& rRec)
+{
+ SdrObjUserData* pData=ImpGetMacroUserData();
+ if (pData!=NULL) {
+ return pData->DoMacro(rRec,this);
+ }
+ return FALSE;
+}
+
+XubString SdrObject::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
+{
+ SdrObjUserData* pData=ImpGetMacroUserData();
+ if (pData!=NULL) {
+ return pData->GetMacroPopupComment(rRec,this);
+ }
+ return String();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObjGeoData* SdrObject::NewGeoData() const
+{
+ return new SdrObjGeoData;
+}
+
+void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ rGeo.aBoundRect =GetCurrentBoundRect();
+ rGeo.aAnchor =aAnchor ;
+ rGeo.bMovProt =bMovProt ;
+ rGeo.bSizProt =bSizProt ;
+ rGeo.bNoPrint =bNoPrint ;
+ rGeo.mbVisible =mbVisible ;
+ rGeo.bClosedObj =bClosedObj ;
+ rGeo.mnLayerID = mnLayerID;
+
+ // Benutzerdefinierte Klebepunkte
+ if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
+ if (rGeo.pGPL!=NULL) {
+ *rGeo.pGPL=*pPlusData->pGluePoints;
+ } else {
+ rGeo.pGPL=new SdrGluePointList(*pPlusData->pGluePoints);
+ }
+ } else {
+ if (rGeo.pGPL!=NULL) {
+ delete rGeo.pGPL;
+ rGeo.pGPL=NULL;
+ }
+ }
+}
+
+void SdrObject::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SetRectsDirty();
+ aOutRect =rGeo.aBoundRect ;
+ aAnchor =rGeo.aAnchor ;
+ bMovProt =rGeo.bMovProt ;
+ bSizProt =rGeo.bSizProt ;
+ bNoPrint =rGeo.bNoPrint ;
+ mbVisible =rGeo.mbVisible ;
+ bClosedObj =rGeo.bClosedObj ;
+ mnLayerID = rGeo.mnLayerID;
+
+ // Benutzerdefinierte Klebepunkte
+ if (rGeo.pGPL!=NULL) {
+ ImpForcePlusData();
+ if (pPlusData->pGluePoints!=NULL) {
+ *pPlusData->pGluePoints=*rGeo.pGPL;
+ } else {
+ pPlusData->pGluePoints=new SdrGluePointList(*rGeo.pGPL);
+ }
+ } else {
+ if (pPlusData!=NULL && pPlusData->pGluePoints!=NULL) {
+ delete pPlusData->pGluePoints;
+ pPlusData->pGluePoints=NULL;
+ }
+ }
+}
+
+SdrObjGeoData* SdrObject::GetGeoData() const
+{
+ SdrObjGeoData* pGeo=NewGeoData();
+ SaveGeoData(*pGeo);
+ return pGeo;
+}
+
+void SdrObject::SetGeoData(const SdrObjGeoData& rGeo)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ RestGeoData(rGeo);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// ItemSet access
+
+const SfxItemSet& SdrObject::GetObjectItemSet() const
+{
+ return GetProperties().GetObjectItemSet();
+}
+
+const SfxItemSet& SdrObject::GetMergedItemSet() const
+{
+ return GetProperties().GetMergedItemSet();
+}
+
+void SdrObject::SetObjectItem(const SfxPoolItem& rItem)
+{
+ GetProperties().SetObjectItem(rItem);
+}
+
+void SdrObject::SetMergedItem(const SfxPoolItem& rItem)
+{
+ GetProperties().SetMergedItem(rItem);
+}
+
+void SdrObject::ClearObjectItem(const sal_uInt16 nWhich)
+{
+ GetProperties().ClearObjectItem(nWhich);
+}
+
+void SdrObject::ClearMergedItem(const sal_uInt16 nWhich)
+{
+ GetProperties().ClearMergedItem(nWhich);
+}
+
+void SdrObject::SetObjectItemSet(const SfxItemSet& rSet)
+{
+ GetProperties().SetObjectItemSet(rSet);
+}
+
+void SdrObject::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
+{
+ GetProperties().SetMergedItemSet(rSet, bClearAllItems);
+}
+
+const SfxPoolItem& SdrObject::GetObjectItem(const sal_uInt16 nWhich) const
+{
+ return GetObjectItemSet().Get(nWhich);
+}
+
+const SfxPoolItem& SdrObject::GetMergedItem(const sal_uInt16 nWhich) const
+{
+ return GetMergedItemSet().Get(nWhich);
+}
+
+void SdrObject::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, sal_Bool bClearAllItems)
+{
+ GetProperties().SetMergedItemSetAndBroadcast(rSet, bClearAllItems);
+}
+
+void SdrObject::ApplyNotPersistAttr(const SfxItemSet& rAttr)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ NbcApplyNotPersistAttr(rAttr);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrObject::NbcApplyNotPersistAttr(const SfxItemSet& rAttr)
+{
+ const Rectangle& rSnap=GetSnapRect();
+ const Rectangle& rLogic=GetLogicRect();
+ Point aRef1(rSnap.Center());
+ Point aRef2(aRef1); aRef2.Y()++;
+ const SfxPoolItem *pPoolItem=NULL;
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aRef1.X()=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aRef1.Y()=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aRef2.X()=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
+ }
+ if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aRef2.Y()=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
+ }
+
+ Rectangle aNewSnap(rSnap);
+ if (rAttr.GetItemState(SDRATTR_MOVEX,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrMoveXItem*)pPoolItem)->GetValue();
+ aNewSnap.Move(n,0);
+ }
+ if (rAttr.GetItemState(SDRATTR_MOVEY,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrMoveYItem*)pPoolItem)->GetValue();
+ aNewSnap.Move(0,n);
+ }
+ if (rAttr.GetItemState(SDRATTR_ONEPOSITIONX,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrOnePositionXItem*)pPoolItem)->GetValue();
+ aNewSnap.Move(n-aNewSnap.Left(),0);
+ }
+ if (rAttr.GetItemState(SDRATTR_ONEPOSITIONY,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrOnePositionYItem*)pPoolItem)->GetValue();
+ aNewSnap.Move(0,n-aNewSnap.Top());
+ }
+ if (rAttr.GetItemState(SDRATTR_ONESIZEWIDTH,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrOneSizeWidthItem*)pPoolItem)->GetValue();
+ aNewSnap.Right()=aNewSnap.Left()+n;
+ }
+ if (rAttr.GetItemState(SDRATTR_ONESIZEHEIGHT,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrOneSizeHeightItem*)pPoolItem)->GetValue();
+ aNewSnap.Bottom()=aNewSnap.Top()+n;
+ }
+ if (aNewSnap!=rSnap) {
+ if (aNewSnap.GetSize()==rSnap.GetSize()) {
+ NbcMove(Size(aNewSnap.Left()-rSnap.Left(),aNewSnap.Top()-rSnap.Top()));
+ } else {
+ NbcSetSnapRect(aNewSnap);
+ }
+ }
+
+ if (rAttr.GetItemState(SDRATTR_SHEARANGLE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrShearAngleItem*)pPoolItem)->GetValue();
+ n-=GetShearAngle();
+ if (n!=0) {
+ double nTan=tan(n*nPi180);
+ NbcShear(aRef1,n,nTan,FALSE);
+ }
+ }
+ if (rAttr.GetItemState(SDRATTR_ROTATEANGLE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrRotateAngleItem*)pPoolItem)->GetValue();
+ n-=GetRotateAngle();
+ if (n!=0) {
+ double nSin=sin(n*nPi180);
+ double nCos=cos(n*nPi180);
+ NbcRotate(aRef1,n,nSin,nCos);
+ }
+ }
+ if (rAttr.GetItemState(SDRATTR_ROTATEONE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrRotateOneItem*)pPoolItem)->GetValue();
+ double nSin=sin(n*nPi180);
+ double nCos=cos(n*nPi180);
+ NbcRotate(aRef1,n,nSin,nCos);
+ }
+ if (rAttr.GetItemState(SDRATTR_HORZSHEARONE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrHorzShearOneItem*)pPoolItem)->GetValue();
+ double nTan=tan(n*nPi180);
+ NbcShear(aRef1,n,nTan,FALSE);
+ }
+ if (rAttr.GetItemState(SDRATTR_VERTSHEARONE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrVertShearOneItem*)pPoolItem)->GetValue();
+ double nTan=tan(n*nPi180);
+ NbcShear(aRef1,n,nTan,TRUE);
+ }
+
+ if (rAttr.GetItemState(SDRATTR_OBJMOVEPROTECT,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ bool b=((const SdrObjMoveProtectItem*)pPoolItem)->GetValue();
+ SetMoveProtect(b);
+ }
+ if (rAttr.GetItemState(SDRATTR_OBJSIZEPROTECT,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ bool b=((const SdrObjSizeProtectItem*)pPoolItem)->GetValue();
+ SetResizeProtect(b);
+ }
+
+ /* #67368# move protect always sets size protect */
+ if( IsMoveProtect() )
+ SetResizeProtect( true );
+
+ if (rAttr.GetItemState(SDRATTR_OBJPRINTABLE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ bool b=((const SdrObjPrintableItem*)pPoolItem)->GetValue();
+ SetPrintable(b);
+ }
+
+ if (rAttr.GetItemState(SDRATTR_OBJVISIBLE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ bool b=((const SdrObjVisibleItem*)pPoolItem)->GetValue();
+ SetVisible(b);
+ }
+
+ SdrLayerID nLayer=SDRLAYER_NOTFOUND;
+ if (rAttr.GetItemState(SDRATTR_LAYERID,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ nLayer=((const SdrLayerIdItem*)pPoolItem)->GetValue();
+ }
+ if (rAttr.GetItemState(SDRATTR_LAYERNAME,TRUE,&pPoolItem)==SFX_ITEM_SET && pModel!=NULL) {
+ XubString aLayerName=((const SdrLayerNameItem*)pPoolItem)->GetValue();
+ const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
+ if (pLayAd!=NULL) {
+ const SdrLayer* pLayer=pLayAd->GetLayer(aLayerName, TRUE);
+ if (pLayer!=NULL) {
+ nLayer=pLayer->GetID();
+ }
+ }
+
+ }
+ if (nLayer!=SDRLAYER_NOTFOUND) {
+ NbcSetLayer(nLayer);
+ }
+
+ if (rAttr.GetItemState(SDRATTR_OBJECTNAME,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ XubString aName=((const SdrObjectNameItem*)pPoolItem)->GetValue();
+ SetName(aName);
+ }
+ Rectangle aNewLogic(rLogic);
+ if (rAttr.GetItemState(SDRATTR_LOGICSIZEWIDTH,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrLogicSizeWidthItem*)pPoolItem)->GetValue();
+ aNewLogic.Right()=aNewLogic.Left()+n;
+ }
+ if (rAttr.GetItemState(SDRATTR_LOGICSIZEHEIGHT,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ long n=((const SdrLogicSizeHeightItem*)pPoolItem)->GetValue();
+ aNewLogic.Bottom()=aNewLogic.Top()+n;
+ }
+ if (aNewLogic!=rLogic) {
+ NbcSetLogicRect(aNewLogic);
+ }
+ Fraction aResizeX(1,1);
+ Fraction aResizeY(1,1);
+ if (rAttr.GetItemState(SDRATTR_RESIZEXONE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aResizeX*=((const SdrResizeXOneItem*)pPoolItem)->GetValue();
+ }
+ if (rAttr.GetItemState(SDRATTR_RESIZEYONE,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ aResizeY*=((const SdrResizeYOneItem*)pPoolItem)->GetValue();
+ }
+ if (aResizeX!=Fraction(1,1) || aResizeY!=Fraction(1,1)) {
+ NbcResize(aRef1,aResizeX,aResizeY);
+ }
+}
+
+void lcl_SetItem(SfxItemSet& rAttr, FASTBOOL bMerge, const SfxPoolItem& rItem)
+{
+ if (bMerge) rAttr.MergeValue(rItem,TRUE);
+ else rAttr.Put(rItem);
+}
+
+void SdrObject::TakeNotPersistAttr(SfxItemSet& rAttr, FASTBOOL bMerge) const
+{
+ const Rectangle& rSnap=GetSnapRect();
+ const Rectangle& rLogic=GetLogicRect();
+ lcl_SetItem(rAttr,bMerge,SdrObjMoveProtectItem(IsMoveProtect()));
+ lcl_SetItem(rAttr,bMerge,SdrObjSizeProtectItem(IsResizeProtect()));
+ lcl_SetItem(rAttr,bMerge,SdrObjPrintableItem(IsPrintable()));
+ lcl_SetItem(rAttr,bMerge,SdrObjVisibleItem(IsVisible()));
+ lcl_SetItem(rAttr,bMerge,SdrRotateAngleItem(GetRotateAngle()));
+ lcl_SetItem(rAttr,bMerge,SdrShearAngleItem(GetShearAngle()));
+ lcl_SetItem(rAttr,bMerge,SdrOneSizeWidthItem(rSnap.GetWidth()-1));
+ lcl_SetItem(rAttr,bMerge,SdrOneSizeHeightItem(rSnap.GetHeight()-1));
+ lcl_SetItem(rAttr,bMerge,SdrOnePositionXItem(rSnap.Left()));
+ lcl_SetItem(rAttr,bMerge,SdrOnePositionYItem(rSnap.Top()));
+ if (rLogic.GetWidth()!=rSnap.GetWidth()) {
+ lcl_SetItem(rAttr,bMerge,SdrLogicSizeWidthItem(rLogic.GetWidth()-1));
+ }
+ if (rLogic.GetHeight()!=rSnap.GetHeight()) {
+ lcl_SetItem(rAttr,bMerge,SdrLogicSizeHeightItem(rLogic.GetHeight()-1));
+ }
+ XubString aName(GetName());
+
+ if(aName.Len())
+ {
+ lcl_SetItem(rAttr, bMerge, SdrObjectNameItem(aName));
+ }
+
+ lcl_SetItem(rAttr,bMerge,SdrLayerIdItem(GetLayer()));
+ const SdrLayerAdmin* pLayAd=pPage!=NULL ? &pPage->GetLayerAdmin() : pModel!=NULL ? &pModel->GetLayerAdmin() : NULL;
+ if (pLayAd!=NULL) {
+ const SdrLayer* pLayer=pLayAd->GetLayerPerID(GetLayer());
+ if (pLayer!=NULL) {
+ lcl_SetItem(rAttr,bMerge,SdrLayerNameItem(pLayer->GetName()));
+ }
+ }
+ Point aRef1(rSnap.Center());
+ Point aRef2(aRef1); aRef2.Y()++;
+ lcl_SetItem(rAttr,bMerge,SdrTransformRef1XItem(aRef1.X()));
+ lcl_SetItem(rAttr,bMerge,SdrTransformRef1YItem(aRef1.Y()));
+ lcl_SetItem(rAttr,bMerge,SdrTransformRef2XItem(aRef2.X()));
+ lcl_SetItem(rAttr,bMerge,SdrTransformRef2YItem(aRef2.Y()));
+}
+
+SfxStyleSheet* SdrObject::GetStyleSheet() const
+{
+ return GetProperties().GetStyleSheet();
+}
+
+void SdrObject::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
+{
+ Rectangle aBoundRect0;
+
+ if(pUserCall)
+ aBoundRect0 = GetLastBoundRect();
+
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect0);
+}
+
+void SdrObject::NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
+{
+ // only allow graphic and presentation styles for shapes
+ if( pNewStyleSheet && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PARA) && (pNewStyleSheet->GetFamily() == SFX_STYLE_FAMILY_PAGE) )
+ return;
+
+ GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
+}
+
+// Das Broadcasting beim Setzen der Attribute wird vom AttrObj gemanagt
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrObject::IsNode() const
+{
+ return TRUE;
+}
+
+SdrGluePoint SdrObject::GetVertexGluePoint(USHORT nPosNum) const
+{
+ // #i41936# Use SnapRect for default GluePoints
+ const Rectangle aR(GetSnapRect());
+ Point aPt;
+
+ switch(nPosNum)
+ {
+ case 0 : aPt = aR.TopCenter(); break;
+ case 1 : aPt = aR.RightCenter(); break;
+ case 2 : aPt = aR.BottomCenter(); break;
+ case 3 : aPt = aR.LeftCenter(); break;
+ }
+
+ aPt -= aR.Center();
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+
+ return aGP;
+}
+
+SdrGluePoint SdrObject::GetCornerGluePoint(USHORT nPosNum) const
+{
+ Rectangle aR(GetCurrentBoundRect());
+ Point aPt;
+ switch (nPosNum) {
+ case 0 : aPt=aR.TopLeft(); break;
+ case 1 : aPt=aR.TopRight(); break;
+ case 2 : aPt=aR.BottomRight(); break;
+ case 3 : aPt=aR.BottomLeft(); break;
+ }
+ aPt-=GetSnapRect().Center();
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+ return aGP;
+}
+
+const SdrGluePointList* SdrObject::GetGluePointList() const
+{
+ if (pPlusData!=NULL) return pPlusData->pGluePoints;
+ return NULL;
+}
+
+//SdrGluePointList* SdrObject::GetGluePointList()
+//{
+// if (pPlusData!=NULL) return pPlusData->pGluePoints;
+// return NULL;
+//}
+
+SdrGluePointList* SdrObject::ForceGluePointList()
+{
+ ImpForcePlusData();
+ if (pPlusData->pGluePoints==NULL) {
+ pPlusData->pGluePoints=new SdrGluePointList;
+ }
+ return pPlusData->pGluePoints;
+}
+
+void SdrObject::SetGlueReallyAbsolute(FASTBOOL bOn)
+{
+ // erst Const-Aufruf um zu sehen, ob
+ // ueberhaupt Klebepunkte da sind
+ // const-Aufruf erzwingen!
+ if (GetGluePointList()!=NULL) {
+ SdrGluePointList* pGPL=ForceGluePointList();
+ pGPL->SetReallyAbsolute(bOn,*this);
+ }
+}
+
+void SdrObject::NbcRotateGluePoints(const Point& rRef, long nWink, double sn, double cs)
+{
+ // erst Const-Aufruf um zu sehen, ob
+ // ueberhaupt Klebepunkte da sind
+ // const-Aufruf erzwingen!
+ if (GetGluePointList()!=NULL) {
+ SdrGluePointList* pGPL=ForceGluePointList();
+ pGPL->Rotate(rRef,nWink,sn,cs,this);
+ }
+}
+
+void SdrObject::NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2)
+{
+ // erst Const-Aufruf um zu sehen, ob
+ // ueberhaupt Klebepunkte da sind
+ // const-Aufruf erzwingen!
+ if (GetGluePointList()!=NULL) {
+ SdrGluePointList* pGPL=ForceGluePointList();
+ pGPL->Mirror(rRef1,rRef2,this);
+ }
+}
+
+void SdrObject::NbcShearGluePoints(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ // erst Const-Aufruf um zu sehen, ob
+ // ueberhaupt Klebepunkte da sind
+ // const-Aufruf erzwingen!
+ if (GetGluePointList()!=NULL) {
+ SdrGluePointList* pGPL=ForceGluePointList();
+ pGPL->Shear(rRef,nWink,tn,bVShear,this);
+ }
+}
+
+FASTBOOL SdrObject::IsEdge() const
+{
+ return FALSE;
+}
+
+void SdrObject::ConnectToNode(FASTBOOL /*bTail1*/, SdrObject* /*pObj*/)
+{
+}
+
+void SdrObject::DisconnectFromNode(FASTBOOL /*bTail1*/)
+{
+}
+
+SdrObject* SdrObject::GetConnectedNode(FASTBOOL /*bTail1*/) const
+{
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrObject::ImpConvertToContourObj(SdrObject* pRet, BOOL bForceLineDash) const
+{
+ bool bNoChange(true);
+
+ if(pRet->LineGeometryUsageIsNecessary())
+ {
+ basegfx::B2DPolyPolygon aMergedLineFillPolyPolygon;
+ basegfx::B2DPolyPolygon aMergedHairlinePolyPolygon;
+ const drawinglayer::primitive2d::Primitive2DSequence xSequence(pRet->GetViewContact().getViewIndependentPrimitive2DSequence());
+
+ if(xSequence.hasElements())
+ {
+ // use neutral ViewInformation
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0);
+
+ // create extractor, process and get result
+ drawinglayer::processor2d::LineGeometryExtractor2D aExtractor(aViewInformation2D);
+ aExtractor.process(xSequence);
+
+ // #i102241# check for line results
+ const std::vector< basegfx::B2DPolygon >& rHairlineVector = aExtractor.getExtractedHairlines();
+
+ if(rHairlineVector.size())
+ {
+ // for SdrObject creation, just copy all to a single Hairline-PolyPolygon
+ for(sal_uInt32 a(0); a < rHairlineVector.size(); a++)
+ {
+ aMergedHairlinePolyPolygon.append(rHairlineVector[a]);
+ }
+ }
+
+ // #i102241# check for fill rsults
+ const std::vector< basegfx::B2DPolyPolygon >& rLineFillVector(aExtractor.getExtractedLineFills());
+
+ if(rLineFillVector.size())
+ {
+ // merge to a single PolyPolygon (OR)
+ aMergedLineFillPolyPolygon = basegfx::tools::mergeToSinglePolyPolygon(rLineFillVector);
+ }
+ }
+
+ // || aMergedHairlinePolyPolygon.Count() removed; the conversion is ONLY
+ // useful when new closed filled polygons are created
+ if(aMergedLineFillPolyPolygon.count() || (bForceLineDash && aMergedHairlinePolyPolygon.count()))
+ {
+ SfxItemSet aSet(pRet->GetMergedItemSet());
+ XFillStyle eOldFillStyle = ((const XFillStyleItem&)(aSet.Get(XATTR_FILLSTYLE))).GetValue();
+ SdrPathObj* aLinePolygonPart = NULL;
+ SdrPathObj* aLineHairlinePart = NULL;
+ bool bBuildGroup(false);
+
+ if(aMergedLineFillPolyPolygon.count())
+ {
+ // create SdrObject for filled line geometry
+ aLinePolygonPart = new SdrPathObj(OBJ_PATHFILL, aMergedLineFillPolyPolygon);
+ aLinePolygonPart->SetModel(pRet->GetModel());
+
+ // correct item properties
+ aSet.Put(XLineWidthItem(0L));
+ aSet.Put(XLineStyleItem(XLINE_NONE));
+ Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue();
+ UINT16 nTransLine = ((const XLineTransparenceItem&)(aSet.Get(XATTR_LINETRANSPARENCE))).GetValue();
+ aSet.Put(XFillColorItem(XubString(), aColorLine));
+ aSet.Put(XFillStyleItem(XFILL_SOLID));
+ aSet.Put(XFillTransparenceItem(nTransLine));
+
+ aLinePolygonPart->SetMergedItemSet(aSet);
+ }
+
+ if(aMergedHairlinePolyPolygon.count())
+ {
+ // create SdrObject for hairline geometry
+ // OBJ_PATHLINE is necessary here, not OBJ_PATHFILL. This is intended
+ // to get a non-filled object. If the poly is closed, the PathObj takes care for
+ // the correct closed state.
+ aLineHairlinePart = new SdrPathObj(OBJ_PATHLINE, aMergedHairlinePolyPolygon);
+ aLineHairlinePart->SetModel(pRet->GetModel());
+
+ aSet.Put(XLineWidthItem(0L));
+ aSet.Put(XFillStyleItem(XFILL_NONE));
+ aSet.Put(XLineStyleItem(XLINE_SOLID));
+
+ // it is also necessary to switch off line start and ends here
+ aSet.Put(XLineStartWidthItem(0));
+ aSet.Put(XLineEndWidthItem(0));
+
+ aLineHairlinePart->SetMergedItemSet(aSet);
+
+ if(aLinePolygonPart)
+ {
+ bBuildGroup = true;
+ }
+ }
+
+ // check if original geometry should be added (e.g. filled and closed)
+ bool bAddOriginalGeometry(false);
+ SdrPathObj* pPath = PTR_CAST(SdrPathObj, pRet);
+
+ if(pPath && pPath->IsClosed())
+ {
+ if(eOldFillStyle != XFILL_NONE)
+ {
+ // #107600# use new boolean here
+ bAddOriginalGeometry = true;
+ }
+ }
+
+ // do we need a group?
+ if(bBuildGroup || bAddOriginalGeometry)
+ {
+ SdrObject* pGroup = new SdrObjGroup;
+ pGroup->SetModel(pRet->GetModel());
+
+ if(bAddOriginalGeometry)
+ {
+ // Add a clone of the original geometry.
+ aSet.ClearItem();
+ aSet.Put(pRet->GetMergedItemSet());
+ aSet.Put(XLineStyleItem(XLINE_NONE));
+ aSet.Put(XLineWidthItem(0L));
+
+ SdrObject* pClone = pRet->Clone();
+
+ pClone->SetModel(pRet->GetModel());
+ pClone->SetMergedItemSet(aSet);
+
+ pGroup->GetSubList()->NbcInsertObject(pClone);
+ }
+
+ if(aLinePolygonPart)
+ {
+ pGroup->GetSubList()->NbcInsertObject(aLinePolygonPart);
+ }
+
+ if(aLineHairlinePart)
+ {
+ pGroup->GetSubList()->NbcInsertObject(aLineHairlinePart);
+ }
+
+ pRet = pGroup;
+
+ // be more careful with the state describing bool
+ bNoChange = false;
+ }
+ else
+ {
+ if(aLinePolygonPart)
+ {
+ pRet = aLinePolygonPart;
+ // be more careful with the state describing bool
+ bNoChange = false;
+ }
+ else if(aLineHairlinePart)
+ {
+ pRet = aLineHairlinePart;
+ // be more careful with the state describing bool
+ bNoChange = false;
+ }
+ }
+ }
+ }
+
+ if(bNoChange)
+ {
+ // due to current method usage, create and return a clone when nothing has changed
+ SdrObject* pClone = pRet->Clone();
+ pClone->SetModel(pRet->GetModel());
+ pRet = pClone;
+ }
+
+ return pRet;
+}
+
+// convert this path object to contour object, even when it is a group
+SdrObject* SdrObject::ConvertToContourObj(SdrObject* pRet, BOOL bForceLineDash) const
+{
+ if(pRet->ISA(SdrObjGroup))
+ {
+ SdrObjList* pObjList2 = pRet->GetSubList();
+ SdrObject* pGroup = new SdrObjGroup;
+ pGroup->SetModel(pRet->GetModel());
+
+ for(UINT32 a=0;a<pObjList2->GetObjCount();a++)
+ {
+ SdrObject* pIterObj = pObjList2->GetObj(a);
+ pGroup->GetSubList()->NbcInsertObject(ConvertToContourObj(pIterObj, bForceLineDash));
+ }
+
+ pRet = pGroup;
+ }
+ else
+ {
+ if(pRet && pRet->ISA(SdrPathObj))
+ {
+ SdrPathObj* pPathObj = (SdrPathObj*)pRet;
+
+ // bezier geometry got created, even for straight edges since the given
+ // object is a result of DoConvertToPolyObj. For conversion to contour
+ // this is not really needed and can be reduced again AFAP
+ pPathObj->SetPathPoly(basegfx::tools::simplifyCurveSegments(pPathObj->GetPathPoly()));
+ }
+
+ pRet = ImpConvertToContourObj(pRet, bForceLineDash);
+ }
+
+ // #i73441# preserve LayerID
+ if(pRet && pRet->GetLayer() != GetLayer())
+ {
+ pRet->SetLayer(GetLayer());
+ }
+
+ return pRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrObject::ConvertToPolyObj(BOOL bBezier, BOOL bLineToArea) const
+{
+ SdrObject* pRet = DoConvertToPolyObj(bBezier);
+
+ if(pRet && bLineToArea)
+ {
+ SdrObject* pNewRet = ConvertToContourObj(pRet);
+ delete pRet;
+ pRet = pNewRet;
+ }
+
+ // #i73441# preserve LayerID
+ if(pRet && pRet->GetLayer() != GetLayer())
+ {
+ pRet->SetLayer(GetLayer());
+ }
+
+ return pRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrObject::DoConvertToPolyObj(BOOL /*bBezier*/) const
+{
+ return NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrObject::SetInserted(sal_Bool bIns)
+{
+ if (bIns!=IsInserted()) {
+ bInserted=bIns;
+ Rectangle aBoundRect0(GetLastBoundRect());
+ if (bIns) SendUserCall(SDRUSERCALL_INSERTED,aBoundRect0);
+ else SendUserCall(SDRUSERCALL_REMOVED,aBoundRect0);
+
+ if (pPlusData!=NULL && pPlusData->pBroadcast!=NULL) { // #42522#
+ SdrHint aHint(*this);
+ aHint.SetKind(bIns?HINT_OBJINSERTED:HINT_OBJREMOVED);
+ pPlusData->pBroadcast->Broadcast(aHint);
+ }
+ }
+}
+
+void SdrObject::SetMoveProtect(sal_Bool bProt)
+{
+ if(IsMoveProtect() != bProt)
+ {
+ // #i77187# secured and simplified
+ bMovProt = bProt;
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+void SdrObject::SetResizeProtect(sal_Bool bProt)
+{
+ if(IsResizeProtect() != bProt)
+ {
+ // #i77187# secured and simplified
+ bSizProt = bProt;
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+void SdrObject::SetPrintable(sal_Bool bPrn)
+{
+ if( bPrn == bNoPrint )
+ {
+ bNoPrint=!bPrn;
+ SetChanged();
+ if (IsInserted() && pModel!=NULL)
+ {
+ SdrHint aHint(*this);
+ pModel->Broadcast(aHint);
+ }
+ }
+}
+
+void SdrObject::SetVisible(sal_Bool bVisible)
+{
+ if( bVisible != mbVisible )
+ {
+ mbVisible = bVisible;
+ SetChanged();
+ if (IsInserted() && pModel!=NULL)
+ {
+ SdrHint aHint(*this);
+ pModel->Broadcast(aHint);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+USHORT SdrObject::GetUserDataCount() const
+{
+ if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return 0;
+ return pPlusData->pUserDataList->GetUserDataCount();
+}
+
+SdrObjUserData* SdrObject::GetUserData(USHORT nNum) const
+{
+ if (pPlusData==NULL || pPlusData->pUserDataList==NULL) return NULL;
+ return pPlusData->pUserDataList->GetUserData(nNum);
+}
+
+void SdrObject::InsertUserData(SdrObjUserData* pData, USHORT nPos)
+{
+ if (pData!=NULL) {
+ ImpForcePlusData();
+ if (pPlusData->pUserDataList==NULL) pPlusData->pUserDataList=new SdrObjUserDataList;
+ pPlusData->pUserDataList->InsertUserData(pData,nPos);
+ } else {
+ DBG_ERROR("SdrObject::InsertUserData(): pData ist NULL-Pointer");
+ }
+}
+
+void SdrObject::DeleteUserData(USHORT nNum)
+{
+ USHORT nAnz=GetUserDataCount();
+ if (nNum<nAnz) {
+ pPlusData->pUserDataList->DeleteUserData(nNum);
+ if (nAnz==1) {
+ delete pPlusData->pUserDataList;
+ pPlusData->pUserDataList=NULL;
+ }
+ } else {
+ DBG_ERROR("SdrObject::DeleteUserData(): ungueltiger Index");
+ }
+}
+
+void SdrObject::SendUserCall(SdrUserCallType eUserCall, const Rectangle& rBoundRect) const
+{
+ SdrObjGroup* pGroup = NULL;
+
+ if( pObjList && pObjList->GetListKind() == SDROBJLIST_GROUPOBJ )
+ pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
+
+ if ( pUserCall )
+ {
+ // UserCall ausfuehren
+ pUserCall->Changed( *this, eUserCall, rBoundRect );
+ }
+
+ while( pGroup )
+ {
+ // Gruppe benachrichtigen
+ if( pGroup->GetUserCall() )
+ {
+ SdrUserCallType eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
+
+ switch( eUserCall )
+ {
+ case SDRUSERCALL_MOVEONLY:
+ eChildUserType = SDRUSERCALL_CHILD_MOVEONLY;
+ break;
+
+ case SDRUSERCALL_RESIZE:
+ eChildUserType = SDRUSERCALL_CHILD_RESIZE;
+ break;
+
+ case SDRUSERCALL_CHGATTR:
+ eChildUserType = SDRUSERCALL_CHILD_CHGATTR;
+ break;
+
+ case SDRUSERCALL_DELETE:
+ eChildUserType = SDRUSERCALL_CHILD_DELETE;
+ break;
+
+ case SDRUSERCALL_COPY:
+ eChildUserType = SDRUSERCALL_CHILD_COPY;
+ break;
+
+ case SDRUSERCALL_INSERTED:
+ eChildUserType = SDRUSERCALL_CHILD_INSERTED;
+ break;
+
+ case SDRUSERCALL_REMOVED:
+ eChildUserType = SDRUSERCALL_CHILD_REMOVED;
+ break;
+
+ default: break;
+ }
+
+ pGroup->GetUserCall()->Changed( *this, eChildUserType, rBoundRect );
+ }
+
+ if( pGroup->GetObjList() &&
+ pGroup->GetObjList()->GetListKind() == SDROBJLIST_GROUPOBJ &&
+ pGroup != (SdrObjGroup*) pObjList->GetOwnerObj() )
+ pGroup = (SdrObjGroup*) pObjList->GetOwnerObj();
+ else
+ pGroup = NULL;
+ }
+
+ // notify our UNO shape listeners
+ switch ( eUserCall )
+ {
+ case SDRUSERCALL_RESIZE:
+ notifyShapePropertyChange( ::svx::eShapeSize );
+ // fall through - RESIZE might also imply a change of the position
+ case SDRUSERCALL_MOVEONLY:
+ notifyShapePropertyChange( ::svx::eShapePosition );
+ break;
+ default:
+ // not interested in
+ break;
+ }
+}
+
+// ItemPool fuer dieses Objekt wechseln
+void SdrObject::MigrateItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
+{
+ if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
+ {
+ GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
+ }
+}
+
+sal_Bool SdrObject::IsTransparent( BOOL /*bCheckForAlphaChannel*/) const
+{
+ bool bRet = false;
+
+ if( IsGroupObject() )
+ {
+ SdrObjListIter aIter( *GetSubList(), IM_DEEPNOGROUPS );
+
+ for( SdrObject* pO = aIter.Next(); pO && !bRet; pO = aIter.Next() )
+ {
+ const SfxItemSet& rAttr = pO->GetMergedItemSet();
+
+ if( ( ( (const XFillTransparenceItem&) rAttr.Get( XATTR_FILLTRANSPARENCE ) ).GetValue() ||
+ ( (const XLineTransparenceItem&) rAttr.Get( XATTR_LINETRANSPARENCE ) ).GetValue() ) ||
+ ( ( rAttr.GetItemState( XATTR_FILLFLOATTRANSPARENCE ) == SFX_ITEM_SET ) &&
+ ( (const XFillFloatTransparenceItem&) rAttr.Get( XATTR_FILLFLOATTRANSPARENCE ) ).IsEnabled() ) )
+ {
+ bRet = TRUE;
+ }
+ else if( pO->ISA( SdrGrafObj ) )
+ {
+ SdrGrafObj* pGrafObj = (SdrGrafObj*) pO;
+ if( ( (const SdrGrafTransparenceItem&) rAttr.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ||
+ ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP && pGrafObj->GetGraphic().GetBitmapEx().IsAlpha() ) )
+ {
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ else
+ {
+ const SfxItemSet& rAttr = GetMergedItemSet();
+
+ if( ( ( (const XFillTransparenceItem&) rAttr.Get( XATTR_FILLTRANSPARENCE ) ).GetValue() ||
+ ( (const XLineTransparenceItem&) rAttr.Get( XATTR_LINETRANSPARENCE ) ).GetValue() ) ||
+ ( ( rAttr.GetItemState( XATTR_FILLFLOATTRANSPARENCE ) == SFX_ITEM_SET ) &&
+ ( (const XFillFloatTransparenceItem&) rAttr.Get( XATTR_FILLFLOATTRANSPARENCE ) ).IsEnabled() ) )
+ {
+ bRet = TRUE;
+ }
+ else if( ISA( SdrGrafObj ) )
+ {
+ SdrGrafObj* pGrafObj = (SdrGrafObj*) this;
+
+ // #i25616#
+ bRet = pGrafObj->IsObjectTransparent();
+ }
+ }
+
+ return bRet;
+}
+
+void SdrObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& _rxUnoShape )
+{
+ maWeakUnoShape = _rxUnoShape;
+ mpSvxShape = SvxShape::getImplementation( _rxUnoShape );
+// OSL_ENSURE( mpSvxShape || !_rxUnoShape.is(),
+// "SdrObject::setUnoShape: not sure it's a good idea to have an XShape which is not implemented by SvxShape ..." );
+}
+
+/** only for internal use! */
+SvxShape* SdrObject::getSvxShape() const
+{
+ DBG_TESTSOLARMUTEX();
+ // retrieving the impl pointer and subsequently using it is not thread-safe, of course, so it needs to be
+ // guarded by the SolarMutex
+
+#if OSL_DEBUG_LEVE > 0
+ uno::Reference< uno::XInterface > xShape( maWeakUnoShape );
+ OSL_ENSURE( !( !xShapeGuard.is() && mpSvxShape ),
+ "SdrObject::getSvxShape: still having IMPL-Pointer to dead object!" );
+#endif
+
+ return mpSvxShape;
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SdrObject::getUnoShape()
+{
+ // try weak reference first
+ uno::Reference< uno::XInterface > xShape( getWeakUnoShape() );
+ if( !xShape.is() )
+ {
+ OSL_ENSURE( mpSvxShape == NULL, "SdrObject::getUnoShape: XShape already dead, but still an IMPL pointer!" );
+ if ( pPage )
+ {
+ uno::Reference< uno::XInterface > xPage( pPage->getUnoPage() );
+ if( xPage.is() )
+ {
+ SvxDrawPage* pDrawPage = SvxDrawPage::getImplementation(xPage);
+ if( pDrawPage )
+ {
+ // create one
+ xShape = pDrawPage->_CreateShape( this );
+ impl_setUnoShape( xShape );
+ }
+ }
+ }
+ else
+ {
+ mpSvxShape = SvxDrawPage::CreateShapeByTypeAndInventor( GetObjIdentifier(), GetObjInventor(), this, NULL );
+ maWeakUnoShape = xShape = static_cast< ::cppu::OWeakObject* >( mpSvxShape );
+ }
+ }
+
+ return xShape;
+}
+
+::svx::PropertyChangeNotifier& SdrObject::getShapePropertyChangeNotifier()
+{
+ DBG_TESTSOLARMUTEX();
+
+ SvxShape* pSvxShape = getSvxShape();
+ ENSURE_OR_THROW( pSvxShape, "no SvxShape, yet!" );
+ return pSvxShape->getShapePropertyChangeNotifier();
+}
+
+void SdrObject::notifyShapePropertyChange( const ::svx::ShapeProperty _eProperty ) const
+{
+ DBG_TESTSOLARMUTEX();
+
+ SvxShape* pSvxShape = const_cast< SdrObject* >( this )->getSvxShape();
+ if ( pSvxShape )
+ return pSvxShape->getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty );
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// transformation interface for StarOfficeAPI. This implements support for
+// homogen 3x3 matrices containing the transformation of the SdrObject. At the
+// moment it contains a shearX, rotation and translation, but for setting all linear
+// transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
+// with the base geometry and returns TRUE. Otherwise it returns FALSE.
+sal_Bool SdrObject::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
+{
+ // any kind of SdrObject, just use SnapRect
+ Rectangle aRectangle(GetSnapRect());
+
+ // convert to transformation values
+ basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
+ basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
+
+ // position maybe relative to anchorpos, convert
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // force MapUnit to 100th mm
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // postion
+ aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
+ aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplTwipsToMM(aScale.getX()));
+ aScale.setY(ImplTwipsToMM(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
+ }
+ }
+ }
+
+ // build matrix
+ rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
+
+ return sal_False;
+}
+
+// sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
+// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
+// to use (0,0) as upper left and will be scaled to the given size in the matrix.
+void SdrObject::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+ // break up matrix
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate, fShearX;
+ rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
+ // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale.setX(fabs(aScale.getX()));
+ aScale.setY(fabs(aScale.getY()));
+ fRotate = fmod(fRotate + F_PI, F_2PI);
+ }
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
+ aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplMMToTwips(aScale.getX()));
+ aScale.setY(ImplMMToTwips(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ // if anchor is used, make position relative to it
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // build BaseRect
+ Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
+ Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
+
+ // set BaseRect
+ SetSnapRect(aBaseRect);
+}
+
+// #116168#
+// Give info if object is in destruction
+sal_Bool SdrObject::IsInDestruction() const
+{
+ if(pModel)
+ return pModel->IsInDestruction();
+ return sal_False;
+}
+
+// return if fill is != XFILL_NONE
+bool SdrObject::HasFillStyle() const
+{
+ return (((const XFillStyleItem&)GetObjectItem(XATTR_FILLSTYLE)).GetValue() != XFILL_NONE);
+}
+
+bool SdrObject::HasLineStyle() const
+{
+ return (((const XLineStyleItem&)GetObjectItem(XATTR_LINESTYLE)).GetValue() != XLINE_NONE);
+}
+
+
+// #i52224#
+// on import of OLE object from MS documents the BLIP size might be retrieved,
+// the following four methods are used to control it;
+// usually this data makes no sence after the import is finished, since the object
+// might be resized
+
+Rectangle SdrObject::GetBLIPSizeRectangle() const
+{
+ return maBLIPSizeRectangle;
+}
+
+void SdrObject::SetBLIPSizeRectangle( const Rectangle& aRect )
+{
+ maBLIPSizeRectangle = aRect;
+}
+
+void SdrObject::SetContextWritingMode( const sal_Int16 /*_nContextWritingMode*/ )
+{
+ // this base class does not support different writing modes, so ignore the call
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@@ @@@@@ @@@@ @@@@ @@@@@@ @@@@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@@@ @@@@@@ @@ @@ @@ @@ @@@@@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@@@@ @@@@ @@ @@ @@ @@@@ @@ @@@@ @@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObjFactory::SdrObjFactory(UINT32 nInvent, UINT16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel)
+{
+ nInventor=nInvent;
+ nIdentifier=nIdent;
+ pNewObj=NULL;
+ pPage=pNewPage;
+ pModel=pNewModel;
+ pObj=NULL;
+ pNewData=NULL;
+}
+
+SdrObjFactory::SdrObjFactory(UINT32 nInvent, UINT16 nIdent, SdrObject* pObj1)
+{
+ nInventor=nInvent;
+ nIdentifier=nIdent;
+ pNewObj=NULL;
+ pPage=NULL;
+ pModel=NULL;
+ pObj=pObj1;
+ pNewData=NULL;
+}
+
+SdrObject* SdrObjFactory::MakeNewObject(UINT32 nInvent, UINT16 nIdent, SdrPage* pPage, SdrModel* pModel)
+{
+ if(pModel == NULL && pPage != NULL)
+ pModel = pPage->GetModel();
+ SdrObject* pObj = NULL;
+
+ if(nInvent == SdrInventor)
+ {
+ switch (nIdent)
+ {
+ case USHORT(OBJ_NONE ): pObj=new SdrObject; break;
+ case USHORT(OBJ_GRUP ): pObj=new SdrObjGroup; break;
+ case USHORT(OBJ_LINE ): pObj=new SdrPathObj(OBJ_LINE ); break;
+ case USHORT(OBJ_POLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
+ case USHORT(OBJ_PLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
+ case USHORT(OBJ_PATHLINE ): pObj=new SdrPathObj(OBJ_PATHLINE ); break;
+ case USHORT(OBJ_PATHFILL ): pObj=new SdrPathObj(OBJ_PATHFILL ); break;
+ case USHORT(OBJ_FREELINE ): pObj=new SdrPathObj(OBJ_FREELINE ); break;
+ case USHORT(OBJ_FREEFILL ): pObj=new SdrPathObj(OBJ_FREEFILL ); break;
+ case USHORT(OBJ_PATHPOLY ): pObj=new SdrPathObj(OBJ_POLY ); break;
+ case USHORT(OBJ_PATHPLIN ): pObj=new SdrPathObj(OBJ_PLIN ); break;
+ case USHORT(OBJ_EDGE ): pObj=new SdrEdgeObj; break;
+ case USHORT(OBJ_RECT ): pObj=new SdrRectObj; break;
+ case USHORT(OBJ_CIRC ): pObj=new SdrCircObj(OBJ_CIRC ); break;
+ case USHORT(OBJ_SECT ): pObj=new SdrCircObj(OBJ_SECT ); break;
+ case USHORT(OBJ_CARC ): pObj=new SdrCircObj(OBJ_CARC ); break;
+ case USHORT(OBJ_CCUT ): pObj=new SdrCircObj(OBJ_CCUT ); break;
+ case USHORT(OBJ_TEXT ): pObj=new SdrRectObj(OBJ_TEXT ); break;
+ case USHORT(OBJ_TEXTEXT ): pObj=new SdrRectObj(OBJ_TEXTEXT ); break;
+ case USHORT(OBJ_TITLETEXT ): pObj=new SdrRectObj(OBJ_TITLETEXT ); break;
+ case USHORT(OBJ_OUTLINETEXT): pObj=new SdrRectObj(OBJ_OUTLINETEXT); break;
+ case USHORT(OBJ_MEASURE ): pObj=new SdrMeasureObj; break;
+ case USHORT(OBJ_GRAF ): pObj=new SdrGrafObj; break;
+ case USHORT(OBJ_OLE2 ): pObj=new SdrOle2Obj; break;
+ case USHORT(OBJ_FRAME ): pObj=new SdrOle2Obj(TRUE); break;
+ case USHORT(OBJ_CAPTION ): pObj=new SdrCaptionObj; break;
+ case USHORT(OBJ_PAGE ): pObj=new SdrPageObj; break;
+ case USHORT(OBJ_UNO ): pObj=new SdrUnoObj(String()); break;
+ case USHORT(OBJ_CUSTOMSHAPE ): pObj=new SdrObjCustomShape(); break;
+ case USHORT(OBJ_MEDIA ): pObj=new SdrMediaObj(); break;
+ case USHORT(OBJ_TABLE ): pObj=new ::sdr::table::SdrTableObj(pModel); break;
+ }
+ }
+
+ if(pObj == NULL)
+ {
+ SdrObjFactory* pFact=new SdrObjFactory(nInvent,nIdent,pPage,pModel);
+ SdrLinkList& rLL=ImpGetUserMakeObjHdl();
+ unsigned nAnz=rLL.GetLinkCount();
+ unsigned i=0;
+ while (i<nAnz && pObj==NULL) {
+ rLL.GetLink(i).Call((void*)pFact);
+ pObj=pFact->pNewObj;
+ i++;
+ }
+ delete pFact;
+ }
+
+ if(pObj == NULL)
+ {
+ // Na wenn's denn keiner will ...
+ }
+
+ if(pObj != NULL)
+ {
+ if(pPage != NULL)
+ pObj->SetPage(pPage);
+ else if(pModel != NULL)
+ pObj->SetModel(pModel);
+ }
+
+ return pObj;
+}
+
+SdrObjUserData* SdrObjFactory::MakeNewObjUserData(UINT32 nInvent, UINT16 nIdent, SdrObject* pObj1)
+{
+ SdrObjUserData* pData=NULL;
+ if (nInvent==SdrInventor) {
+ switch (nIdent)
+ {
+ case USHORT(SDRUSERDATA_OBJTEXTLINK) : pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1); break;
+ }
+ }
+ if (pData==NULL) {
+ SdrObjFactory aFact(nInvent,nIdent,pObj1);
+ SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
+ unsigned nAnz=rLL.GetLinkCount();
+ unsigned i=0;
+ while (i<nAnz && pData==NULL) {
+ rLL.GetLink(i).Call((void*)&aFact);
+ pData=aFact.pNewData;
+ i++;
+ }
+ }
+ return pData;
+}
+
+void SdrObjFactory::InsertMakeObjectHdl(const Link& rLink)
+{
+ SdrLinkList& rLL=ImpGetUserMakeObjHdl();
+ rLL.InsertLink(rLink);
+}
+
+void SdrObjFactory::RemoveMakeObjectHdl(const Link& rLink)
+{
+ SdrLinkList& rLL=ImpGetUserMakeObjHdl();
+ rLL.RemoveLink(rLink);
+}
+
+void SdrObjFactory::InsertMakeUserDataHdl(const Link& rLink)
+{
+ SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
+ rLL.InsertLink(rLink);
+}
+
+void SdrObjFactory::RemoveMakeUserDataHdl(const Link& rLink)
+{
+ SdrLinkList& rLL=ImpGetUserMakeObjUserDataHdl();
+ rLL.RemoveLink(rLink);
+}
+
+namespace svx
+{
+ ISdrObjectFilter::~ISdrObjectFilter()
+ {
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx
new file mode 100644
index 000000000000..b92157823081
--- /dev/null
+++ b/svx/source/svdraw/svdocapt.cxx
@@ -0,0 +1,851 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <tools/bigint.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svl/style.hxx>
+#include <svx/svdocapt.hxx>
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdview.hxx> // fuer RectSnap
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdogrp.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xfltrit.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/sdr/properties/captionproperties.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+// #i32599#
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+enum EscDir {LKS,RTS,OBN,UNT};
+
+class ImpCaptParams
+{
+public:
+ SdrCaptionType eType;
+ long nAngle;
+ long nGap;
+ long nEscRel;
+ long nEscAbs;
+ long nLineLen;
+ SdrCaptionEscDir eEscDir;
+ FASTBOOL bFitLineLen;
+ FASTBOOL bEscRel;
+ FASTBOOL bFixedAngle;
+
+public:
+ ImpCaptParams()
+ {
+ eType =SDRCAPT_TYPE3;
+ bFixedAngle=FALSE;
+ nAngle =4500;
+ nGap =0;
+ eEscDir =SDRCAPT_ESCHORIZONTAL;
+ bEscRel =TRUE;
+ nEscRel =5000;
+ nEscAbs =0;
+ nLineLen =0;
+ bFitLineLen=TRUE;
+ }
+ void CalcEscPos(const Point& rTail, const Rectangle& rRect, Point& rPt, EscDir& rDir) const;
+};
+
+void ImpCaptParams::CalcEscPos(const Point& rTailPt, const Rectangle& rRect, Point& rPt, EscDir& rDir) const
+{
+ Point aTl(rTailPt); // lokal kopieren wg. Performance
+ long nX,nY;
+ if (bEscRel) {
+ nX=rRect.Right()-rRect.Left();
+ nX=BigMulDiv(nX,nEscRel,10000);
+ nY=rRect.Bottom()-rRect.Top();
+ nY=BigMulDiv(nY,nEscRel,10000);
+ } else {
+ nX=nEscAbs;
+ nY=nEscAbs;
+ }
+ nX+=rRect.Left();
+ nY+=rRect.Top();
+ Point aBestPt;
+ EscDir eBestDir=LKS;
+ FASTBOOL bTryH=eEscDir==SDRCAPT_ESCBESTFIT;
+ if (!bTryH) {
+ if (eType!=SDRCAPT_TYPE1) {
+ bTryH=eEscDir==SDRCAPT_ESCHORIZONTAL;
+ } else {
+ bTryH=eEscDir==SDRCAPT_ESCVERTICAL;
+ }
+ }
+ FASTBOOL bTryV=eEscDir==SDRCAPT_ESCBESTFIT;
+ if (!bTryV) {
+ if (eType!=SDRCAPT_TYPE1) {
+ bTryV=eEscDir==SDRCAPT_ESCVERTICAL;
+ } else {
+ bTryV=eEscDir==SDRCAPT_ESCHORIZONTAL;
+ }
+ }
+
+ if (bTryH) {
+ Point aLft(rRect.Left()-nGap,nY);
+ Point aRgt(rRect.Right()+nGap,nY);
+ FASTBOOL bLft=(aTl.X()-aLft.X()<aRgt.X()-aTl.X());
+ if (bLft) {
+ eBestDir=LKS;
+ aBestPt=aLft;
+ } else {
+ eBestDir=RTS;
+ aBestPt=aRgt;
+ }
+ }
+ if (bTryV) {
+ Point aTop(nX,rRect.Top()-nGap);
+ Point aBtm(nX,rRect.Bottom()+nGap);
+ FASTBOOL bTop=(aTl.Y()-aTop.Y()<aBtm.Y()-aTl.Y());
+ Point aBest2;
+ EscDir eBest2;
+ if (bTop) {
+ eBest2=OBN;
+ aBest2=aTop;
+ } else {
+ eBest2=UNT;
+ aBest2=aBtm;
+ }
+ FASTBOOL bTakeIt=eEscDir!=SDRCAPT_ESCBESTFIT;
+ if (!bTakeIt) {
+ BigInt aHorX(aBestPt.X()-aTl.X()); aHorX*=aHorX;
+ BigInt aHorY(aBestPt.Y()-aTl.Y()); aHorY*=aHorY;
+ BigInt aVerX(aBest2.X()-aTl.X()); aVerX*=aVerX;
+ BigInt aVerY(aBest2.Y()-aTl.Y()); aVerY*=aVerY;
+ if (eType!=SDRCAPT_TYPE1) {
+ bTakeIt=aVerX+aVerY<aHorX+aHorY;
+ } else {
+ bTakeIt=aVerX+aVerY>=aHorX+aHorY;
+ }
+ }
+ if (bTakeIt) {
+ aBestPt=aBest2;
+ eBestDir=eBest2;
+ }
+ }
+ rPt=aBestPt;
+ rDir=eBestDir;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrCaptionObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::CaptionProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrCaptionObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrCaptionObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrCaptionObj,SdrRectObj);
+
+SdrCaptionObj::SdrCaptionObj():
+ SdrRectObj(OBJ_TEXT),
+ aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
+ mbSpecialTextBoxShadow(FALSE),
+ mbFixedTail(FALSE)
+{
+}
+
+SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect):
+ SdrRectObj(OBJ_TEXT,rRect),
+ aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
+ mbSpecialTextBoxShadow(FALSE),
+ mbFixedTail(FALSE)
+{
+}
+
+SdrCaptionObj::SdrCaptionObj(const Rectangle& rRect, const Point& rTail):
+ SdrRectObj(OBJ_TEXT,rRect),
+ aTailPoly(3), // Default Groesse: 3 Punkte = 2 Linien
+ mbSpecialTextBoxShadow(FALSE),
+ mbFixedTail(FALSE)
+{
+ aTailPoly[0]=maFixedTailPos=rTail;
+}
+
+SdrCaptionObj::~SdrCaptionObj()
+{
+}
+
+void SdrCaptionObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bRotate90Allowed =FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bMirror45Allowed =FALSE;
+ rInfo.bMirror90Allowed =FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bCanConvToPath =TRUE;
+ rInfo.bCanConvToPoly =TRUE;
+ rInfo.bCanConvToPathLineToArea=FALSE;
+ rInfo.bCanConvToPolyLineToArea=FALSE;
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrCaptionObj::GetObjIdentifier() const
+{
+ return UINT16(OBJ_CAPTION);
+}
+
+void SdrCaptionObj::operator=(const SdrObject& rObj)
+{
+ SdrRectObj::operator=(rObj);
+ aTailPoly=((SdrCaptionObj&)rObj).aTailPoly;
+}
+
+void SdrCaptionObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulCAPTION);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrCaptionObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralCAPTION);
+}
+
+basegfx::B2DPolyPolygon SdrCaptionObj::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aPolyPoly(SdrRectObj::TakeXorPoly());
+ aPolyPoly.append(aTailPoly.getB2DPolygon());
+
+ return aPolyPoly;
+}
+
+sal_uInt32 SdrCaptionObj::GetHdlCount() const
+{
+ sal_uInt32 nAnz1(SdrRectObj::GetHdlCount());
+ // sal_uInt32 nAnz2(aTailPoly.GetSize());
+ // Derzeit ist nur das Draggen des Schwanzendes implementiert
+ return nAnz1 + 1L;
+}
+
+SdrHdl* SdrCaptionObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ const sal_uInt32 nRectHdlAnz(SdrRectObj::GetHdlCount());
+
+ if(nHdlNum < nRectHdlAnz)
+ {
+ return SdrRectObj::GetHdl(nHdlNum);
+ }
+ else
+ {
+ sal_uInt32 nPntNum(nHdlNum);
+ nPntNum -= nRectHdlAnz;
+
+ if(nPntNum < aTailPoly.GetSize())
+ {
+ SdrHdl* pHdl = new SdrHdl(aTailPoly.GetPoint((sal_uInt16)nPntNum), HDL_POLY);
+ pHdl->SetPolyNum(1L);
+ pHdl->SetPointNum(nPntNum);
+ return pHdl;
+ }
+ else
+ {
+ return 0L;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrCaptionObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ rDrag.SetEndDragChangesAttributes(true);
+ rDrag.SetEndDragChangesGeoAndAttributes(true);
+
+ if(pHdl && 0 == pHdl->GetPolyNum())
+ {
+ return SdrRectObj::beginSpecialDrag(rDrag);
+ }
+ else
+ {
+ rDrag.SetOrtho8Possible(true);
+
+ if(!pHdl)
+ {
+ if (bMovProt)
+ return 0;
+
+ rDrag.SetNoSnap(true);
+ rDrag.SetActionRect(aRect);
+
+ Point aHit(rDrag.GetStart());
+
+ if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), 0, false))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if((1 == pHdl->GetPolyNum()) && (0 == pHdl->GetPointNum()))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SdrCaptionObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ if(pHdl && 0 == pHdl->GetPolyNum())
+ {
+ const bool bRet(SdrRectObj::applySpecialDrag(rDrag));
+ ImpRecalcTail();
+ ActionChanged();
+
+ return bRet;
+ }
+ else
+ {
+ Point aDelt(rDrag.GetNow()-rDrag.GetStart());
+
+ if(!pHdl)
+ {
+ aRect.Move(aDelt.X(),aDelt.Y());
+ }
+ else
+ {
+ aTailPoly[0] += aDelt;
+ }
+
+ ImpRecalcTail();
+ ActionChanged();
+
+ return true;
+ }
+}
+
+String SdrCaptionObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment)
+ {
+ return String();
+ }
+ else
+ {
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ if(pHdl && 0 == pHdl->GetPolyNum())
+ {
+ return SdrRectObj::getSpecialDragComment(rDrag);
+ }
+ else
+ {
+ XubString aStr;
+
+ if(!pHdl)
+ {
+ ImpTakeDescriptionStr(STR_DragCaptFram, aStr);
+ }
+ else
+ {
+ ImpTakeDescriptionStr(STR_DragCaptTail, aStr);
+ }
+
+ return aStr;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrCaptionObj::ImpGetCaptParams(ImpCaptParams& rPara) const
+{
+ const SfxItemSet& rSet = GetObjectItemSet();
+ rPara.eType =((SdrCaptionTypeItem&) (rSet.Get(SDRATTR_CAPTIONTYPE ))).GetValue();
+ rPara.bFixedAngle=((SdrCaptionFixedAngleItem&)(rSet.Get(SDRATTR_CAPTIONANGLE ))).GetValue();
+ rPara.nAngle =((SdrCaptionAngleItem&) (rSet.Get(SDRATTR_CAPTIONFIXEDANGLE))).GetValue();
+ rPara.nGap =((SdrCaptionGapItem&) (rSet.Get(SDRATTR_CAPTIONGAP ))).GetValue();
+ rPara.eEscDir =((SdrCaptionEscDirItem&) (rSet.Get(SDRATTR_CAPTIONESCDIR ))).GetValue();
+ rPara.bEscRel =((SdrCaptionEscIsRelItem&) (rSet.Get(SDRATTR_CAPTIONESCISREL ))).GetValue();
+ rPara.nEscRel =((SdrCaptionEscRelItem&) (rSet.Get(SDRATTR_CAPTIONESCREL ))).GetValue();
+ rPara.nEscAbs =((SdrCaptionEscAbsItem&) (rSet.Get(SDRATTR_CAPTIONESCABS ))).GetValue();
+ rPara.nLineLen =((SdrCaptionLineLenItem&) (rSet.Get(SDRATTR_CAPTIONLINELEN ))).GetValue();
+ rPara.bFitLineLen=((SdrCaptionFitLineLenItem&)(rSet.Get(SDRATTR_CAPTIONFITLINELEN))).GetValue();
+}
+
+void SdrCaptionObj::ImpRecalcTail()
+{
+ ImpCaptParams aPara;
+ ImpGetCaptParams(aPara);
+ ImpCalcTail(aPara,aTailPoly,aRect);
+ SetRectsDirty();
+ SetXPolyDirty();
+}
+
+// #i35971#
+// SdrCaptionObj::ImpCalcTail1 does move the object(!). What a hack.
+// I really wonder why this had not triggered problems before. I am
+// sure there are some places where SetTailPos() is called at least
+// twice or SetSnapRect after it again just to work around this.
+// Changed this method to not do that.
+// Also found why this has been done: For interactive dragging of the
+// tail end pos for SDRCAPT_TYPE1. This sure was the simplest method
+// to achieve this, for the cost to make a whole group of const methods
+// of this object implicitly chainging the object's position.
+void SdrCaptionObj::ImpCalcTail1(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
+{
+ Polygon aPol(2);
+ Point aTl(rPoly[0]);
+
+ aPol[0] = aTl;
+ aPol[1] = aTl;
+
+ EscDir eEscDir;
+ Point aEscPos;
+
+ rPara.CalcEscPos(aTl, rRect, aEscPos, eEscDir);
+ aPol[1] = aEscPos;
+
+ if(eEscDir==LKS || eEscDir==RTS)
+ {
+ aPol[0].X() = aEscPos.X();
+ }
+ else
+ {
+ aPol[0].Y() = aEscPos.Y();
+ }
+
+ rPoly = aPol;
+}
+
+void SdrCaptionObj::ImpCalcTail2(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
+{ // Gap/EscDir/EscPos/Angle
+ Polygon aPol(2);
+ Point aTl(rPoly[0]);
+ aPol[0]=aTl;
+
+ EscDir eEscDir;
+ Point aEscPos;
+ rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
+ aPol[1]=aEscPos;
+
+ if (!rPara.bFixedAngle) {
+ // fehlende Implementation
+ }
+ rPoly=aPol;
+}
+
+void SdrCaptionObj::ImpCalcTail3(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
+{ // Gap/EscDir/EscPos/Angle/LineLen
+ Polygon aPol(3);
+ Point aTl(rPoly[0]);
+ aPol[0]=aTl;
+
+ EscDir eEscDir;
+ Point aEscPos;
+ rPara.CalcEscPos(aTl,rRect,aEscPos,eEscDir);
+ aPol[1]=aEscPos;
+ aPol[2]=aEscPos;
+
+ if (eEscDir==LKS || eEscDir==RTS) {
+ if (rPara.bFitLineLen) {
+ aPol[1].X()=(aTl.X()+aEscPos.X())/2;
+ } else {
+ if (eEscDir==LKS) aPol[1].X()-=rPara.nLineLen;
+ else aPol[1].X()+=rPara.nLineLen;
+ }
+ } else {
+ if (rPara.bFitLineLen) {
+ aPol[1].Y()=(aTl.Y()+aEscPos.Y())/2;
+ } else {
+ if (eEscDir==OBN) aPol[1].Y()-=rPara.nLineLen;
+ else aPol[1].Y()+=rPara.nLineLen;
+ }
+ }
+ if (!rPara.bFixedAngle) {
+ // fehlende Implementation
+ }
+ rPoly=aPol;
+}
+
+void SdrCaptionObj::ImpCalcTail4(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
+{
+ ImpCalcTail3(rPara,rPoly,rRect);
+}
+
+void SdrCaptionObj::ImpCalcTail(const ImpCaptParams& rPara, Polygon& rPoly, Rectangle& rRect) const
+{
+ switch (rPara.eType) {
+ case SDRCAPT_TYPE1: ImpCalcTail1(rPara,rPoly,rRect); break;
+ case SDRCAPT_TYPE2: ImpCalcTail2(rPara,rPoly,rRect); break;
+ case SDRCAPT_TYPE3: ImpCalcTail3(rPara,rPoly,rRect); break;
+ case SDRCAPT_TYPE4: ImpCalcTail4(rPara,rPoly,rRect); break;
+ }
+}
+
+FASTBOOL SdrCaptionObj::BegCreate(SdrDragStat& rStat)
+{
+ if (aRect.IsEmpty()) return FALSE; // Create z.Zt. nur mit vorgegebenen Rect
+
+ ImpCaptParams aPara;
+ ImpGetCaptParams(aPara);
+ aRect.SetPos(rStat.GetNow());
+ aTailPoly[0]=rStat.GetStart();
+ ImpCalcTail(aPara,aTailPoly,aRect);
+ rStat.SetActionRect(aRect);
+ return TRUE;
+}
+
+FASTBOOL SdrCaptionObj::MovCreate(SdrDragStat& rStat)
+{
+ ImpCaptParams aPara;
+ ImpGetCaptParams(aPara);
+ aRect.SetPos(rStat.GetNow());
+ ImpCalcTail(aPara,aTailPoly,aRect);
+ rStat.SetActionRect(aRect);
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ return TRUE;
+}
+
+FASTBOOL SdrCaptionObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ ImpCaptParams aPara;
+ ImpGetCaptParams(aPara);
+ aRect.SetPos(rStat.GetNow());
+ ImpCalcTail(aPara,aTailPoly,aRect);
+ SetRectsDirty();
+ return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
+}
+
+FASTBOOL SdrCaptionObj::BckCreate(SdrDragStat& /*rStat*/)
+{
+ return FALSE;
+}
+
+void SdrCaptionObj::BrkCreate(SdrDragStat& /*rStat*/)
+{
+}
+
+basegfx::B2DPolyPolygon SdrCaptionObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ const basegfx::B2DRange aRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom());
+ aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
+ aRetval.append(aTailPoly.getB2DPolygon());
+ return aRetval;
+}
+
+Pointer SdrCaptionObj::GetCreatePointer() const
+{
+ return Pointer(POINTER_DRAW_CAPTION);
+}
+
+void SdrCaptionObj::NbcMove(const Size& rSiz)
+{
+ SdrRectObj::NbcMove(rSiz);
+ MovePoly(aTailPoly,rSiz);
+ if(mbFixedTail)
+ SetTailPos(GetFixedTailPos());
+}
+
+void SdrCaptionObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ SdrRectObj::NbcResize(rRef,xFact,yFact);
+ ResizePoly(aTailPoly,rRef,xFact,yFact);
+ ImpRecalcTail();
+ if(mbFixedTail)
+ SetTailPos(GetFixedTailPos());
+}
+
+void SdrCaptionObj::NbcSetRelativePos(const Point& rPnt)
+{
+ Point aRelPos0(aTailPoly.GetPoint(0)-aAnchor);
+ Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
+ NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
+}
+
+Point SdrCaptionObj::GetRelativePos() const
+{
+ return aTailPoly.GetPoint(0)-aAnchor;
+}
+
+void SdrCaptionObj::NbcSetAnchorPos(const Point& rPnt)
+{
+ SdrRectObj::NbcSetAnchorPos(rPnt);
+ // !!!!! fehlende Impl.
+}
+
+const Point& SdrCaptionObj::GetAnchorPos() const
+{
+ // !!!!! fehlende Impl.
+ return SdrRectObj::GetAnchorPos();
+}
+
+void SdrCaptionObj::RecalcSnapRect()
+{
+ SdrRectObj::RecalcSnapRect();
+ // #i32599#
+ // maSnapRect.Union(aTailPoly.GetBoundRect());
+ // !!!!! fehlende Impl.
+}
+
+const Rectangle& SdrCaptionObj::GetSnapRect() const
+{
+ return SdrRectObj::GetSnapRect();
+}
+
+void SdrCaptionObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ // #i32599#
+ // Move back to see the rectangle of the underlying SdrRectObj
+ // as the SnapRect, without the TailPos. That simplifies SnapRect
+ // handling again, if not allows it at all...
+ SdrRectObj::NbcSetSnapRect(rRect);
+}
+
+const Rectangle& SdrCaptionObj::GetLogicRect() const
+{
+ return aRect;
+}
+
+void SdrCaptionObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ SdrRectObj::NbcSetLogicRect(rRect);
+ ImpRecalcTail();
+}
+
+const Point& SdrCaptionObj::GetTailPos() const
+{
+ return aTailPoly[0];
+}
+
+void SdrCaptionObj::SetTailPos(const Point& rPos)
+{
+ if (aTailPoly.GetSize()==0 || aTailPoly[0]!=rPos) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetTailPos(rPos);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrCaptionObj::NbcSetTailPos(const Point& rPos)
+{
+ aTailPoly[0]=rPos;
+ ImpRecalcTail();
+}
+
+sal_uInt32 SdrCaptionObj::GetSnapPointCount() const
+{
+ // !!!!! fehlende Impl.
+ return 0L;
+}
+
+Point SdrCaptionObj::GetSnapPoint(sal_uInt32 /*i*/) const
+{
+ // !!!!! fehlende Impl.
+ return Point(0,0);
+}
+
+void SdrCaptionObj::SetModel(SdrModel* pNewModel)
+{
+ SdrRectObj::SetModel(pNewModel);
+ ImpRecalcTail();
+}
+
+void SdrCaptionObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SdrRectObj::Notify(rBC,rHint);
+ ImpRecalcTail();
+}
+
+SdrObjGeoData* SdrCaptionObj::NewGeoData() const
+{
+ return new SdrCaptObjGeoData;
+}
+
+void SdrCaptionObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrRectObj::SaveGeoData(rGeo);
+ SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
+ rCGeo.aTailPoly=aTailPoly;
+}
+
+void SdrCaptionObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrRectObj::RestGeoData(rGeo);
+ SdrCaptObjGeoData& rCGeo=(SdrCaptObjGeoData&)rGeo;
+ aTailPoly=rCGeo.aTailPoly;
+}
+
+SdrObject* SdrCaptionObj::DoConvertToPolyObj(BOOL bBezier) const
+{ // #42334# - Convert implementiert
+ SdrObject* pRect=SdrRectObj::DoConvertToPolyObj(bBezier);
+ SdrObject* pTail = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aTailPoly.getB2DPolygon()), sal_False, bBezier);
+ SdrObject* pRet=(pTail!=NULL) ? pTail : pRect;
+ if (pTail!=NULL && pRect!=NULL) {
+ FASTBOOL bInsRect=TRUE;
+ FASTBOOL bInsTail=TRUE;
+ SdrObjList* pOL=pTail->GetSubList();
+ if (pOL!=NULL) { pRet=pRect; bInsTail=FALSE; }
+ if (pOL==NULL) pOL=pRect->GetSubList();
+ if (pOL!=NULL) { pRet=pRect; bInsRect=FALSE; }
+ if (pOL==NULL) {
+ SdrObjGroup* pGrp=new SdrObjGroup;
+ pOL=pGrp->GetSubList();
+ pRet=pGrp;
+ }
+ if (bInsRect) pOL->NbcInsertObject(pRect);
+ if (bInsTail) pOL->NbcInsertObject(pTail,0);
+ }
+ return pRet;
+}
+
+// #i32599#
+// Add own implementation for TRSetBaseGeometry to handle TailPos over changes.
+void SdrCaptionObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+ // break up matrix
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate, fShearX;
+ rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
+ // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale.setX(fabs(aScale.getX()));
+ aScale.setY(fabs(aScale.getY()));
+ fRotate = fmod(fRotate + F_PI, F_2PI);
+ }
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
+ aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplMMToTwips(aScale.getX()));
+ aScale.setY(ImplMMToTwips(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ // if anchor is used, make position relative to it
+ if( pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // build BaseRect
+ Point aPoint(FRound(aTranslate.getX()), FRound(aTranslate.getY()));
+ Rectangle aBaseRect(aPoint, Size(FRound(aScale.getX()), FRound(aScale.getY())));
+
+ // set BaseRect, but rescue TailPos over this call
+ const Point aTailPoint = GetTailPos();
+ SetSnapRect(aBaseRect);
+ SetTailPos(aTailPoint);
+ ImpRecalcTail();
+}
+
+// geometry access
+basegfx::B2DPolygon SdrCaptionObj::getTailPolygon() const
+{
+ return aTailPoly.getB2DPolygon();
+}
+
+// eof
diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx
new file mode 100644
index 000000000000..4c600cba821f
--- /dev/null
+++ b/svx/source/svdraw/svdocirc.cxx
@@ -0,0 +1,1171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svl/style.hxx>
+#include <tools/bigint.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/svdocirc.hxx>
+#include <math.h>
+#include <svx/xpool.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdopath.hxx> // fuer die Objektkonvertierung
+#include <svx/svdview.hxx> // Zum Draggen (Ortho)
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <editeng/eeitem.hxx>
+#include "svdoimp.hxx"
+#include <svx/sdr/properties/circleproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdrcircobj.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+Point GetWinkPnt(const Rectangle& rR, long nWink)
+{
+ Point aCenter(rR.Center());
+ long nWdt=rR.Right()-rR.Left();
+ long nHgt=rR.Bottom()-rR.Top();
+ long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
+ double a;
+ a=nWink*nPi180;
+ Point aRetval(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
+ if (nWdt==0) aRetval.X()=0;
+ if (nHgt==0) aRetval.Y()=0;
+ if (nWdt!=nHgt) {
+ if (nWdt>nHgt) {
+ if (nWdt!=0) {
+ // eventuelle Ueberlaeufe bei sehr grossen Objekten abfangen (Bug 23384)
+ if (Abs(nHgt)>32767 || Abs(aRetval.Y())>32767) {
+ aRetval.Y()=BigMulDiv(aRetval.Y(),nHgt,nWdt);
+ } else {
+ aRetval.Y()=aRetval.Y()*nHgt/nWdt;
+ }
+ }
+ } else {
+ if (nHgt!=0) {
+ // eventuelle Ueberlaeufe bei sehr grossen Objekten abfangen (Bug 23384)
+ if (Abs(nWdt)>32767 || Abs(aRetval.X())>32767) {
+ aRetval.X()=BigMulDiv(aRetval.X(),nWdt,nHgt);
+ } else {
+ aRetval.X()=aRetval.X()*nWdt/nHgt;
+ }
+ }
+ }
+ }
+ aRetval+=aCenter;
+ return aRetval;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrCircObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::CircleProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrCircObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrCircObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrCircObj,SdrRectObj);
+
+SdrCircObj::SdrCircObj(SdrObjKind eNewKind)
+{
+ nStartWink=0;
+ nEndWink=36000;
+ meCircleKind=eNewKind;
+ bClosedObj=eNewKind!=OBJ_CARC;
+}
+
+SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect):
+ SdrRectObj(rRect)
+{
+ nStartWink=0;
+ nEndWink=36000;
+ meCircleKind=eNewKind;
+ bClosedObj=eNewKind!=OBJ_CARC;
+}
+
+SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect, long nNewStartWink, long nNewEndWink):
+ SdrRectObj(rRect)
+{
+ long nWinkDif=nNewEndWink-nNewStartWink;
+ nStartWink=NormAngle360(nNewStartWink);
+ nEndWink=NormAngle360(nNewEndWink);
+ if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
+ meCircleKind=eNewKind;
+ bClosedObj=eNewKind!=OBJ_CARC;
+}
+
+SdrCircObj::~SdrCircObj()
+{
+}
+
+void SdrCircObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ FASTBOOL bCanConv=!HasText() || ImpCanConvTextToCurve();
+ rInfo.bEdgeRadiusAllowed = FALSE;
+ rInfo.bCanConvToPath=bCanConv;
+ rInfo.bCanConvToPoly=bCanConv;
+ rInfo.bCanConvToContour = !IsFontwork() && (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrCircObj::GetObjIdentifier() const
+{
+ return UINT16(meCircleKind);
+}
+
+FASTBOOL SdrCircObj::PaintNeedsXPolyCirc() const
+{
+ // XPoly ist notwendig fuer alle gedrehten Ellipsenobjekte,
+ // fuer alle Kreis- und Ellipsenabschnitte
+ // und wenn nicht WIN dann (erstmal) auch fuer Kreis-/Ellipsenausschnitte
+ // und Kreis-/Ellipsenboegen (wg. Genauigkeit)
+ FASTBOOL bNeed=aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || meCircleKind==OBJ_CCUT;
+#ifndef WIN
+ // Wenn nicht Win, dann fuer alle ausser Vollkreis (erstmal!!!)
+ if (meCircleKind!=OBJ_CIRC) bNeed=TRUE;
+#endif
+
+ const SfxItemSet& rSet = GetObjectItemSet();
+ if(!bNeed)
+ {
+ // XPoly ist notwendig fuer alles was nicht LineSolid oder LineNone ist
+ XLineStyle eLine = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue();
+ bNeed = eLine != XLINE_NONE && eLine != XLINE_SOLID;
+
+ // XPoly ist notwendig fuer dicke Linien
+ if(!bNeed && eLine != XLINE_NONE)
+ bNeed = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue() != 0;
+
+ // XPoly ist notwendig fuer Kreisboegen mit Linienenden
+ if(!bNeed && meCircleKind == OBJ_CARC)
+ {
+ // Linienanfang ist da, wenn StartPolygon und StartWidth!=0
+ bNeed=((XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue().count() != 0L &&
+ ((XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue() != 0;
+
+ if(!bNeed)
+ {
+ // Linienende ist da, wenn EndPolygon und EndWidth!=0
+ bNeed = ((XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue().count() != 0L &&
+ ((XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue() != 0;
+ }
+ }
+ }
+
+ // XPoly ist notwendig, wenn Fill !=None und !=Solid
+ if(!bNeed && meCircleKind != OBJ_CARC)
+ {
+ XFillStyle eFill=((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue();
+ bNeed = eFill != XFILL_NONE && eFill != XFILL_SOLID;
+ }
+
+ if(!bNeed && meCircleKind != OBJ_CIRC && nStartWink == nEndWink)
+ bNeed=TRUE; // Weil sonst Vollkreis gemalt wird
+
+ return bNeed;
+}
+
+basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrObjKind eCicrleKind, const Rectangle& rRect1, long nStart, long nEnd) const
+{
+ const basegfx::B2DRange aRange(rRect1.Left(), rRect1.Top(), rRect1.Right(), rRect1.Bottom());
+ basegfx::B2DPolygon aCircPolygon;
+
+ if(OBJ_CIRC == eCicrleKind)
+ {
+ // create full circle. Do not use createPolygonFromEllipse; it's necessary
+ // to get the start point to the bottom of the circle to keep compatible to
+ // old geometry creation
+ aCircPolygon = basegfx::tools::createPolygonFromUnitCircle(1);
+
+ // needs own scaling and translation from unit circle to target size (same as
+ // would be in createPolygonFromEllipse)
+ const basegfx::B2DPoint aCenter(aRange.getCenter());
+ const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
+ aCenter.getX(), aCenter.getY()));
+ aCircPolygon.transform(aMatrix);
+ }
+ else
+ {
+ // mirror start, end for geometry creation since model coordinate system is mirrored in Y
+ // #i111715# increase numerical correctness by first dividing and not using F_PI1800
+ const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
+ const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
+
+ // create circle segment. This is not closed by default
+ aCircPolygon = basegfx::tools::createPolygonFromEllipseSegment(
+ aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
+ fStart, fEnd);
+
+ // check closing states
+ const bool bCloseSegment(OBJ_CARC != eCicrleKind);
+ const bool bCloseUsingCenter(OBJ_SECT == eCicrleKind);
+
+ if(bCloseSegment)
+ {
+ if(bCloseUsingCenter)
+ {
+ // add center point at start (for historical reasons)
+ basegfx::B2DPolygon aSector;
+ aSector.append(aRange.getCenter());
+ aSector.append(aCircPolygon);
+ aCircPolygon = aSector;
+ }
+
+ // close
+ aCircPolygon.setClosed(true);
+ }
+ }
+
+ // #i76950#
+ if(aGeo.nShearWink || aGeo.nDrehWink)
+ {
+ // translate top left to (0,0)
+ const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
+ basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
+ -aTopLeft.getX(), -aTopLeft.getY()));
+
+ // shear, rotate and back to top left (if needed)
+ aMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
+ aGeo.nShearWink ? tan((36000 - aGeo.nShearWink) * F_PI18000) : 0.0,
+ aGeo.nDrehWink ? (36000 - aGeo.nDrehWink) * F_PI18000 : 0.0,
+ aTopLeft) * aMatrix;
+
+ // apply transformation
+ aCircPolygon.transform(aMatrix);
+ }
+
+ return aCircPolygon;
+}
+
+void SdrCircObj::RecalcXPoly()
+{
+ const basegfx::B2DPolygon aPolyCirc(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
+ mpXPoly = new XPolygon(aPolyCirc);
+}
+
+void SdrCircObj::TakeObjNameSingul(XubString& rName) const
+{
+ USHORT nID=STR_ObjNameSingulCIRC;
+ if (aRect.GetWidth()==aRect.GetHeight() && aGeo.nShearWink==0) {
+ switch (meCircleKind) {
+ case OBJ_CIRC: nID=STR_ObjNameSingulCIRC; break;
+ case OBJ_SECT: nID=STR_ObjNameSingulSECT; break;
+ case OBJ_CARC: nID=STR_ObjNameSingulCARC; break;
+ case OBJ_CCUT: nID=STR_ObjNameSingulCCUT; break;
+ default: break;
+ }
+ } else {
+ switch (meCircleKind) {
+ case OBJ_CIRC: nID=STR_ObjNameSingulCIRCE; break;
+ case OBJ_SECT: nID=STR_ObjNameSingulSECTE; break;
+ case OBJ_CARC: nID=STR_ObjNameSingulCARCE; break;
+ case OBJ_CCUT: nID=STR_ObjNameSingulCCUTE; break;
+ default: break;
+ }
+ }
+ rName=ImpGetResStr(nID);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrCircObj::TakeObjNamePlural(XubString& rName) const
+{
+ USHORT nID=STR_ObjNamePluralCIRC;
+ if (aRect.GetWidth()==aRect.GetHeight() && aGeo.nShearWink==0) {
+ switch (meCircleKind) {
+ case OBJ_CIRC: nID=STR_ObjNamePluralCIRC; break;
+ case OBJ_SECT: nID=STR_ObjNamePluralSECT; break;
+ case OBJ_CARC: nID=STR_ObjNamePluralCARC; break;
+ case OBJ_CCUT: nID=STR_ObjNamePluralCCUT; break;
+ default: break;
+ }
+ } else {
+ switch (meCircleKind) {
+ case OBJ_CIRC: nID=STR_ObjNamePluralCIRCE; break;
+ case OBJ_SECT: nID=STR_ObjNamePluralSECTE; break;
+ case OBJ_CARC: nID=STR_ObjNamePluralCARCE; break;
+ case OBJ_CCUT: nID=STR_ObjNamePluralCCUTE; break;
+ default: break;
+ }
+ }
+ rName=ImpGetResStr(nID);
+}
+
+void SdrCircObj::operator=(const SdrObject& rObj)
+{
+ SdrRectObj::operator=(rObj);
+
+ nStartWink = ((SdrCircObj&)rObj).nStartWink;
+ nEndWink = ((SdrCircObj&)rObj).nEndWink;
+}
+
+basegfx::B2DPolyPolygon SdrCircObj::TakeXorPoly() const
+{
+ const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
+ return basegfx::B2DPolyPolygon(aCircPolygon);
+}
+
+struct ImpCircUser : public SdrDragStatUserData
+{
+ Rectangle aR;
+ Point aCenter;
+ Point aRadius;
+ Point aP1;
+ Point aP2;
+ long nMaxRad;
+ long nHgt;
+ long nWdt;
+ long nStart;
+ long nEnd;
+ long nWink;
+ FASTBOOL bRight; // noch nicht implementiert
+
+public:
+ ImpCircUser()
+ : nMaxRad(0),
+ nHgt(0),
+ nWdt(0),
+ nStart(0),
+ nEnd(0),
+ bRight(FALSE)
+ {}
+ void SetCreateParams(SdrDragStat& rStat);
+};
+
+sal_uInt32 SdrCircObj::GetHdlCount() const
+{
+ if(OBJ_CIRC != meCircleKind)
+ {
+ return 10L;
+ }
+ else
+ {
+ return 8L;
+ }
+}
+
+SdrHdl* SdrCircObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ if (meCircleKind==OBJ_CIRC)
+ {
+ nHdlNum += 2L;
+ }
+
+ SdrHdl* pH = NULL;
+ Point aPnt;
+ SdrHdlKind eLocalKind(HDL_MOVE);
+ sal_uInt32 nPNum(0);
+
+ switch (nHdlNum)
+ {
+ case 0:
+ aPnt = GetWinkPnt(aRect,nStartWink);
+ eLocalKind = HDL_CIRC;
+ nPNum = 1;
+ break;
+ case 1:
+ aPnt = GetWinkPnt(aRect,nEndWink);
+ eLocalKind = HDL_CIRC;
+ nPNum = 2L;
+ break;
+ case 2:
+ aPnt = aRect.TopLeft();
+ eLocalKind = HDL_UPLFT;
+ break;
+ case 3:
+ aPnt = aRect.TopCenter();
+ eLocalKind = HDL_UPPER;
+ break;
+ case 4:
+ aPnt = aRect.TopRight();
+ eLocalKind = HDL_UPRGT;
+ break;
+ case 5:
+ aPnt = aRect.LeftCenter();
+ eLocalKind = HDL_LEFT;
+ break;
+ case 6:
+ aPnt = aRect.RightCenter();
+ eLocalKind = HDL_RIGHT;
+ break;
+ case 7:
+ aPnt = aRect.BottomLeft();
+ eLocalKind = HDL_LWLFT;
+ break;
+ case 8:
+ aPnt = aRect.BottomCenter();
+ eLocalKind = HDL_LOWER;
+ break;
+ case 9:
+ aPnt = aRect.BottomRight();
+ eLocalKind = HDL_LWRGT;
+ break;
+ }
+
+ if (aGeo.nShearWink)
+ {
+ ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
+ }
+
+ if (aGeo.nDrehWink)
+ {
+ RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ }
+
+ if (eLocalKind != HDL_MOVE)
+ {
+ pH = new SdrHdl(aPnt,eLocalKind);
+ pH->SetPointNum(nPNum);
+ pH->SetObj((SdrObject*)this);
+ pH->SetDrehWink(aGeo.nDrehWink);
+ }
+
+ return pH;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrCircObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrCircObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if(bWink)
+ {
+ if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
+ {
+ rDrag.SetNoSnap(true);
+ }
+
+ return true;
+ }
+
+ return SdrTextObj::beginSpecialDrag(rDrag);
+}
+
+bool SdrCircObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if(bWink)
+ {
+ Point aPt(rDrag.GetNow());
+
+ if (aGeo.nDrehWink!=0)
+ RotatePoint(aPt,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
+
+ if (aGeo.nShearWink!=0)
+ ShearPoint(aPt,aRect.TopLeft(),-aGeo.nTan);
+
+ aPt-=aRect.Center();
+
+ long nWdt=aRect.Right()-aRect.Left();
+ long nHgt=aRect.Bottom()-aRect.Top();
+
+ if(nWdt>=nHgt)
+ {
+ aPt.Y()=BigMulDiv(aPt.Y(),nWdt,nHgt);
+ }
+ else
+ {
+ aPt.X()=BigMulDiv(aPt.X(),nHgt,nWdt);
+ }
+
+ long nWink=NormAngle360(GetAngle(aPt));
+
+ if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
+ {
+ long nSA=rDrag.GetView()->GetSnapAngle();
+
+ if (nSA!=0)
+ {
+ nWink+=nSA/2;
+ nWink/=nSA;
+ nWink*=nSA;
+ nWink=NormAngle360(nWink);
+ }
+ }
+
+ if(1 == rDrag.GetHdl()->GetPointNum())
+ {
+ nStartWink = nWink;
+ }
+ else if(2 == rDrag.GetHdl()->GetPointNum())
+ {
+ nEndWink = nWink;
+ }
+
+ SetRectsDirty();
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+ SetChanged();
+
+ return true;
+ }
+ else
+ {
+ return SdrTextObj::applySpecialDrag(rDrag);
+ }
+}
+
+String SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment)
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_ViewCreateObj, aStr);
+ const sal_uInt32 nPntAnz(rDrag.GetPointAnz());
+
+ if(OBJ_CIRC != meCircleKind && nPntAnz > 2)
+ {
+ ImpCircUser* pU = (ImpCircUser*)rDrag.GetUser();
+ sal_Int32 nWink;
+
+ aStr.AppendAscii(" (");
+
+ if(3 == nPntAnz)
+ {
+ nWink = pU->nStart;
+ }
+ else
+ {
+ nWink = pU->nEnd;
+ }
+
+ aStr += GetWinkStr(nWink,FALSE);
+ aStr += sal_Unicode(')');
+ }
+
+ return aStr;
+ }
+ else
+ {
+ const bool bWink(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if(bWink)
+ {
+ XubString aStr;
+ const sal_Int32 nWink(1 == rDrag.GetHdl()->GetPointNum() ? nStartWink : nEndWink);
+
+ ImpTakeDescriptionStr(STR_DragCircAngle, aStr);
+ aStr.AppendAscii(" (");
+ aStr += GetWinkStr(nWink,FALSE);
+ aStr += sal_Unicode(')');
+
+ return aStr;
+ }
+ else
+ {
+ return SdrTextObj::getSpecialDragComment(rDrag);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ImpCircUser::SetCreateParams(SdrDragStat& rStat)
+{
+ rStat.TakeCreateRect(aR);
+ aR.Justify();
+ aCenter=aR.Center();
+ nWdt=aR.Right()-aR.Left();
+ nHgt=aR.Bottom()-aR.Top();
+ nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
+ nStart=0;
+ nEnd=36000;
+ if (rStat.GetPointAnz()>2) {
+ Point aP(rStat.GetPoint(2)-aCenter);
+ if (nWdt==0) aP.X()=0;
+ if (nHgt==0) aP.Y()=0;
+ if (nWdt>=nHgt) {
+ if (nHgt!=0) aP.Y()=aP.Y()*nWdt/nHgt;
+ } else {
+ if (nWdt!=0) aP.X()=aP.X()*nHgt/nWdt;
+ }
+ nStart=NormAngle360(GetAngle(aP));
+ if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
+ long nSA=rStat.GetView()->GetSnapAngle();
+ if (nSA!=0) { // Winkelfang
+ nStart+=nSA/2;
+ nStart/=nSA;
+ nStart*=nSA;
+ nStart=NormAngle360(nStart);
+ }
+ }
+ aP1 = GetWinkPnt(aR,nStart);
+ nEnd=nStart;
+ aP2=aP1;
+ } else aP1=aCenter;
+ if (rStat.GetPointAnz()>3) {
+ Point aP(rStat.GetPoint(3)-aCenter);
+ if (nWdt>=nHgt) {
+ aP.Y()=BigMulDiv(aP.Y(),nWdt,nHgt);
+ } else {
+ aP.X()=BigMulDiv(aP.X(),nHgt,nWdt);
+ }
+ nEnd=NormAngle360(GetAngle(aP));
+ if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
+ long nSA=rStat.GetView()->GetSnapAngle();
+ if (nSA!=0) { // Winkelfang
+ nEnd+=nSA/2;
+ nEnd/=nSA;
+ nEnd*=nSA;
+ nEnd=NormAngle360(nEnd);
+ }
+ }
+ aP2 = GetWinkPnt(aR,nEnd);
+ } else aP2=aCenter;
+}
+
+void SdrCircObj::ImpSetCreateParams(SdrDragStat& rStat) const
+{
+ ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
+ if (pU==NULL) {
+ pU=new ImpCircUser;
+ rStat.SetUser(pU);
+ }
+ pU->SetCreateParams(rStat);
+}
+
+FASTBOOL SdrCircObj::BegCreate(SdrDragStat& rStat)
+{
+ rStat.SetOrtho4Possible();
+ Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
+ aRect1.Justify();
+ rStat.SetActionRect(aRect1);
+ aRect = aRect1;
+ ImpSetCreateParams(rStat);
+ return TRUE;
+}
+
+FASTBOOL SdrCircObj::MovCreate(SdrDragStat& rStat)
+{
+ ImpSetCreateParams(rStat);
+ ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
+ rStat.SetActionRect(pU->aR);
+ aRect=pU->aR; // fuer ObjName
+ ImpJustifyRect(aRect);
+ nStartWink=pU->nStart;
+ nEndWink=pU->nEnd;
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ SetXPolyDirty();
+
+ // #i103058# push current angle settings to ItemSet to
+ // allow FullDrag visualisation
+ if(rStat.GetPointAnz() >= 4)
+ {
+ ImpSetCircInfoToAttr();
+ }
+
+ return TRUE;
+}
+
+FASTBOOL SdrCircObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ ImpSetCreateParams(rStat);
+ ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
+ FASTBOOL bRet=FALSE;
+ if (eCmd==SDRCREATE_FORCEEND && rStat.GetPointAnz()<4) meCircleKind=OBJ_CIRC;
+ if (meCircleKind==OBJ_CIRC) {
+ bRet=rStat.GetPointAnz()>=2;
+ if (bRet) {
+ aRect=pU->aR;
+ ImpJustifyRect(aRect);
+ }
+ } else {
+ rStat.SetNoSnap(rStat.GetPointAnz()>=2);
+ rStat.SetOrtho4Possible(rStat.GetPointAnz()<2);
+ bRet=rStat.GetPointAnz()>=4;
+ if (bRet) {
+ aRect=pU->aR;
+ ImpJustifyRect(aRect);
+ nStartWink=pU->nStart;
+ nEndWink=pU->nEnd;
+ }
+ }
+ bClosedObj=meCircleKind!=OBJ_CARC;
+ SetRectsDirty();
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+ if (bRet) {
+ delete pU;
+ rStat.SetUser(NULL);
+ }
+ return bRet;
+}
+
+void SdrCircObj::BrkCreate(SdrDragStat& rStat)
+{
+ ImpCircUser* pU=(ImpCircUser*)rStat.GetUser();
+ delete pU;
+ rStat.SetUser(NULL);
+}
+
+FASTBOOL SdrCircObj::BckCreate(SdrDragStat& rStat)
+{
+ rStat.SetNoSnap(rStat.GetPointAnz()>=3);
+ rStat.SetOrtho4Possible(rStat.GetPointAnz()<3);
+ return meCircleKind!=OBJ_CIRC;
+}
+
+basegfx::B2DPolyPolygon SdrCircObj::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ ImpCircUser* pU = (ImpCircUser*)rDrag.GetUser();
+
+ if(rDrag.GetPointAnz() < 4L)
+ {
+ // force to OBJ_CIRC to get full visualisation
+ basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(OBJ_CIRC, pU->aR, pU->nStart, pU->nEnd));
+
+ if(3L == rDrag.GetPointAnz())
+ {
+ // add edge to first point on ellipse
+ basegfx::B2DPolygon aNew;
+
+ aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
+ aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
+ aRetval.append(aNew);
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
+ }
+}
+
+Pointer SdrCircObj::GetCreatePointer() const
+{
+ switch (meCircleKind) {
+ case OBJ_CIRC: return Pointer(POINTER_DRAW_ELLIPSE);
+ case OBJ_SECT: return Pointer(POINTER_DRAW_PIE);
+ case OBJ_CARC: return Pointer(POINTER_DRAW_ARC);
+ case OBJ_CCUT: return Pointer(POINTER_DRAW_CIRCLECUT);
+ default: break;
+ } // switch
+ return Pointer(POINTER_CROSS);
+}
+
+void SdrCircObj::NbcMove(const Size& aSiz)
+{
+ MoveRect(aRect,aSiz);
+ MoveRect(aOutRect,aSiz);
+ MoveRect(maSnapRect,aSiz);
+ SetXPolyDirty();
+ SetRectsDirty(sal_True);
+}
+
+void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ long nWink0=aGeo.nDrehWink;
+ FASTBOOL bNoShearRota=(aGeo.nDrehWink==0 && aGeo.nShearWink==0);
+ SdrTextObj::NbcResize(rRef,xFact,yFact);
+ bNoShearRota|=(aGeo.nDrehWink==0 && aGeo.nShearWink==0);
+ if (meCircleKind!=OBJ_CIRC) {
+ FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
+ FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
+ if (bXMirr || bYMirr) {
+ // bei bXMirr!=bYMirr muessten eigentlich noch die beiden
+ // Linienende vertauscht werden. Das ist jedoch mal wieder
+ // schlecht (wg. zwangslaeufiger harter Formatierung).
+ // Alternativ koennte ein bMirrored-Flag eingefuehrt werden
+ // (Vielleicht ja mal grundsaetzlich, auch fuer gepiegelten Text, ...).
+ long nS0=nStartWink;
+ long nE0=nEndWink;
+ if (bNoShearRota) {
+ // Das RectObj spiegelt bei VMirror bereits durch durch 180deg Drehung.
+ if (! (bXMirr && bYMirr)) {
+ long nTmp=nS0;
+ nS0=18000-nE0;
+ nE0=18000-nTmp;
+ }
+ } else { // Spiegeln fuer verzerrte Ellipsen
+ if (bXMirr!=bYMirr) {
+ nS0+=nWink0;
+ nE0+=nWink0;
+ if (bXMirr) {
+ long nTmp=nS0;
+ nS0=18000-nE0;
+ nE0=18000-nTmp;
+ }
+ if (bYMirr) {
+ long nTmp=nS0;
+ nS0=-nE0;
+ nE0=-nTmp;
+ }
+ nS0-=aGeo.nDrehWink;
+ nE0-=aGeo.nDrehWink;
+ }
+ }
+ long nWinkDif=nE0-nS0;
+ nStartWink=NormAngle360(nS0);
+ nEndWink =NormAngle360(nE0);
+ if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
+ }
+ }
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+}
+
+void SdrCircObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+}
+
+void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ //long nWink0=aGeo.nDrehWink;
+ FASTBOOL bFreeMirr=meCircleKind!=OBJ_CIRC;
+ Point aTmpPt1;
+ Point aTmpPt2;
+ if (bFreeMirr) { // bei freier Spiegelachse einige Vorbereitungen Treffen
+ Point aCenter(aRect.Center());
+ long nWdt=aRect.GetWidth()-1;
+ long nHgt=aRect.GetHeight()-1;
+ long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
+ double a;
+ // Startpunkt
+ a=nStartWink*nPi180;
+ aTmpPt1=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
+ if (nWdt==0) aTmpPt1.X()=0;
+ if (nHgt==0) aTmpPt1.Y()=0;
+ aTmpPt1+=aCenter;
+ // Endpunkt
+ a=nEndWink*nPi180;
+ aTmpPt2=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
+ if (nWdt==0) aTmpPt2.X()=0;
+ if (nHgt==0) aTmpPt2.Y()=0;
+ aTmpPt2+=aCenter;
+ if (aGeo.nDrehWink!=0) {
+ RotatePoint(aTmpPt1,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ RotatePoint(aTmpPt2,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ }
+ if (aGeo.nShearWink!=0) {
+ ShearPoint(aTmpPt1,aRect.TopLeft(),aGeo.nTan);
+ ShearPoint(aTmpPt2,aRect.TopLeft(),aGeo.nTan);
+ }
+ }
+ SdrTextObj::NbcMirror(rRef1,rRef2);
+ if (meCircleKind!=OBJ_CIRC) { // Anpassung von Start- und Endwinkel
+ MirrorPoint(aTmpPt1,rRef1,rRef2);
+ MirrorPoint(aTmpPt2,rRef1,rRef2);
+ // Unrotate:
+ if (aGeo.nDrehWink!=0) {
+ RotatePoint(aTmpPt1,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin fuer Umkehrung
+ RotatePoint(aTmpPt2,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin fuer Umkehrung
+ }
+ // Unshear:
+ if (aGeo.nShearWink!=0) {
+ ShearPoint(aTmpPt1,aRect.TopLeft(),-aGeo.nTan); // -tan fuer Umkehrung
+ ShearPoint(aTmpPt2,aRect.TopLeft(),-aGeo.nTan); // -tan fuer Umkehrung
+ }
+ Point aCenter(aRect.Center());
+ aTmpPt1-=aCenter;
+ aTmpPt2-=aCenter;
+ // Weil gespiegelt sind die Winkel nun auch noch vertauscht
+ nStartWink=GetAngle(aTmpPt2);
+ nEndWink =GetAngle(aTmpPt1);
+ long nWinkDif=nEndWink-nStartWink;
+ nStartWink=NormAngle360(nStartWink);
+ nEndWink =NormAngle360(nEndWink);
+ if (nWinkDif==36000) nEndWink+=nWinkDif; // Vollkreis
+ }
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+}
+
+SdrObjGeoData* SdrCircObj::NewGeoData() const
+{
+ return new SdrCircObjGeoData;
+}
+
+void SdrCircObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrRectObj::SaveGeoData(rGeo);
+ SdrCircObjGeoData& rCGeo=(SdrCircObjGeoData&)rGeo;
+ rCGeo.nStartWink=nStartWink;
+ rCGeo.nEndWink =nEndWink;
+}
+
+void SdrCircObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrRectObj::RestGeoData(rGeo);
+ SdrCircObjGeoData& rCGeo=(SdrCircObjGeoData&)rGeo;
+ nStartWink=rCGeo.nStartWink;
+ nEndWink =rCGeo.nEndWink;
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+}
+
+void Union(Rectangle& rR, const Point& rP)
+{
+ if (rP.X()<rR.Left ()) rR.Left ()=rP.X();
+ if (rP.X()>rR.Right ()) rR.Right ()=rP.X();
+ if (rP.Y()<rR.Top ()) rR.Top ()=rP.Y();
+ if (rP.Y()>rR.Bottom()) rR.Bottom()=rP.Y();
+}
+
+void SdrCircObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ rRect=aRect;
+ if (meCircleKind!=OBJ_CIRC) {
+ const Point aPntStart(GetWinkPnt(aRect,nStartWink));
+ const Point aPntEnd(GetWinkPnt(aRect,nEndWink));
+ long a=nStartWink;
+ long e=nEndWink;
+ rRect.Left ()=aRect.Right();
+ rRect.Right ()=aRect.Left();
+ rRect.Top ()=aRect.Bottom();
+ rRect.Bottom()=aRect.Top();
+ Union(rRect,aPntStart);
+ Union(rRect,aPntEnd);
+ if ((a<=18000 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
+ Union(rRect,aRect.LeftCenter());
+ }
+ if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
+ Union(rRect,aRect.BottomCenter());
+ }
+ if (a>e) {
+ Union(rRect,aRect.RightCenter());
+ }
+ if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
+ Union(rRect,aRect.TopCenter());
+ }
+ if (meCircleKind==OBJ_SECT) {
+ Union(rRect,aRect.Center());
+ }
+ if (aGeo.nDrehWink!=0) {
+ Point aDst(rRect.TopLeft());
+ aDst-=aRect.TopLeft();
+ Point aDst0(aDst);
+ RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
+ aDst-=aDst0;
+ rRect.Move(aDst.X(),aDst.Y());
+ }
+ }
+ if (aGeo.nShearWink!=0) {
+ long nDst=Round((rRect.Bottom()-rRect.Top())*aGeo.nTan);
+ if (aGeo.nShearWink>0) {
+ Point aRef(rRect.TopLeft());
+ rRect.Left()-=nDst;
+ Point aTmpPt(rRect.TopLeft());
+ RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
+ aTmpPt-=rRect.TopLeft();
+ rRect.Move(aTmpPt.X(),aTmpPt.Y());
+ } else {
+ rRect.Right()-=nDst;
+ }
+ }
+}
+
+void SdrCircObj::RecalcSnapRect()
+{
+ if (PaintNeedsXPolyCirc()) {
+ maSnapRect=GetXPoly().GetBoundRect();
+ } else {
+ TakeUnrotatedSnapRect(maSnapRect);
+ }
+}
+
+void SdrCircObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || meCircleKind!=OBJ_CIRC) {
+ Rectangle aSR0(GetSnapRect());
+ long nWdt0=aSR0.Right()-aSR0.Left();
+ long nHgt0=aSR0.Bottom()-aSR0.Top();
+ long nWdt1=rRect.Right()-rRect.Left();
+ long nHgt1=rRect.Bottom()-rRect.Top();
+ NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
+ NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
+ } else {
+ aRect=rRect;
+ ImpJustifyRect(aRect);
+ }
+ SetRectsDirty();
+ SetXPolyDirty();
+ ImpSetCircInfoToAttr();
+}
+
+sal_uInt32 SdrCircObj::GetSnapPointCount() const
+{
+ if (meCircleKind==OBJ_CIRC) {
+ return 1L;
+ } else {
+ return 3L;
+ }
+}
+
+Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
+{
+ switch (i) {
+ case 1 : return GetWinkPnt(aRect,nStartWink);
+ case 2 : return GetWinkPnt(aRect,nEndWink);
+ default: return aRect.Center();
+ }
+}
+
+void __EXPORT SdrCircObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SetXPolyDirty();
+ SdrRectObj::Notify(rBC,rHint);
+ ImpSetAttrToCircInfo();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrCircObj::ImpSetAttrToCircInfo()
+{
+ const SfxItemSet& rSet = GetObjectItemSet();
+ SdrCircKind eNewKindA = ((SdrCircKindItem&)rSet.Get(SDRATTR_CIRCKIND)).GetValue();
+ SdrObjKind eNewKind = meCircleKind;
+
+ if(eNewKindA == SDRCIRC_FULL)
+ eNewKind = OBJ_CIRC;
+ else if(eNewKindA == SDRCIRC_SECT)
+ eNewKind = OBJ_SECT;
+ else if(eNewKindA == SDRCIRC_ARC)
+ eNewKind = OBJ_CARC;
+ else if(eNewKindA == SDRCIRC_CUT)
+ eNewKind = OBJ_CCUT;
+
+ sal_Int32 nNewStart = ((SdrCircStartAngleItem&)rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
+ sal_Int32 nNewEnd = ((SdrCircEndAngleItem&)rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
+
+ BOOL bKindChg = meCircleKind != eNewKind;
+ BOOL bWinkChg = nNewStart != nStartWink || nNewEnd != nEndWink;
+
+ if(bKindChg || bWinkChg)
+ {
+ meCircleKind = eNewKind;
+ nStartWink = nNewStart;
+ nEndWink = nNewEnd;
+
+ if(bKindChg || (meCircleKind != OBJ_CIRC && bWinkChg))
+ {
+ SetXPolyDirty();
+ SetRectsDirty();
+ }
+ }
+}
+
+void SdrCircObj::ImpSetCircInfoToAttr()
+{
+ SdrCircKind eNewKindA = SDRCIRC_FULL;
+ const SfxItemSet& rSet = GetObjectItemSet();
+
+ if(meCircleKind == OBJ_SECT)
+ eNewKindA = SDRCIRC_SECT;
+ else if(meCircleKind == OBJ_CARC)
+ eNewKindA = SDRCIRC_ARC;
+ else if(meCircleKind == OBJ_CCUT)
+ eNewKindA = SDRCIRC_CUT;
+
+ SdrCircKind eOldKindA = ((SdrCircKindItem&)rSet.Get(SDRATTR_CIRCKIND)).GetValue();
+ sal_Int32 nOldStartWink = ((SdrCircStartAngleItem&)rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
+ sal_Int32 nOldEndWink = ((SdrCircEndAngleItem&)rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
+
+ if(eNewKindA != eOldKindA || nStartWink != nOldStartWink || nEndWink != nOldEndWink)
+ {
+ // #81921# since SetItem() implicitly calls ImpSetAttrToCircInfo()
+ // setting the item directly is necessary here.
+ if(eNewKindA != eOldKindA)
+ {
+ GetProperties().SetObjectItemDirect(SdrCircKindItem(eNewKindA));
+ }
+
+ if(nStartWink != nOldStartWink)
+ {
+ GetProperties().SetObjectItemDirect(SdrCircStartAngleItem(nStartWink));
+ }
+
+ if(nEndWink != nOldEndWink)
+ {
+ GetProperties().SetObjectItemDirect(SdrCircEndAngleItem(nEndWink));
+ }
+
+ SetXPolyDirty();
+ ImpSetAttrToCircInfo();
+ }
+}
+
+SdrObject* SdrCircObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ const sal_Bool bFill(OBJ_CARC == meCircleKind ? sal_False : sal_True);
+ const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, aRect, nStartWink, nEndWink));
+ SdrObject* pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
+ pRet = ImpConvertAddText(pRet, bBezier);
+
+ return pRet;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
new file mode 100644
index 000000000000..3d254aeb39c4
--- /dev/null
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -0,0 +1,2497 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdoedge.hxx>
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svddrgv.hxx>
+#include "svddrgm1.hxx"
+#include <svx/svdhdl.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <svl/style.hxx>
+#include <svl/smplhint.hxx>
+#include <editeng/eeitem.hxx>
+#include "svdoimp.hxx"
+#include <svx/sdr/properties/connectorproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdredgeobj.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObjConnection::~SdrObjConnection()
+{
+}
+
+void SdrObjConnection::ResetVars()
+{
+ pObj=NULL;
+ nConId=0;
+ nXDist=0;
+ nYDist=0;
+ bBestConn=TRUE;
+ bBestVertex=TRUE;
+ bXDistOvr=FALSE;
+ bYDistOvr=FALSE;
+ bAutoVertex=FALSE;
+ bAutoCorner=FALSE;
+}
+
+FASTBOOL SdrObjConnection::TakeGluePoint(SdrGluePoint& rGP, FASTBOOL bSetAbsPos) const
+{
+ FASTBOOL bRet=FALSE;
+ if (pObj!=NULL) { // Ein Obj muss schon angedockt sein!
+ if (bAutoVertex) {
+ rGP=pObj->GetVertexGluePoint(nConId);
+ bRet=TRUE;
+ } else if (bAutoCorner) {
+ rGP=pObj->GetCornerGluePoint(nConId);
+ bRet=TRUE;
+ } else {
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=NULL) {
+ USHORT nNum=pGPL->FindGluePoint(nConId);
+ if (nNum!=SDRGLUEPOINT_NOTFOUND) {
+ rGP=(*pGPL)[nNum];
+ bRet=TRUE;
+ }
+ }
+ }
+ }
+ if (bRet && bSetAbsPos) {
+ Point aPt(rGP.GetAbsolutePos(*pObj));
+ aPt+=aObjOfs;
+ rGP.SetPos(aPt);
+ }
+ return bRet;
+}
+
+Point& SdrEdgeInfoRec::ImpGetLineVersatzPoint(SdrEdgeLineCode eLineCode)
+{
+ switch (eLineCode) {
+ case OBJ1LINE2 : return aObj1Line2;
+ case OBJ1LINE3 : return aObj1Line3;
+ case OBJ2LINE2 : return aObj2Line2;
+ case OBJ2LINE3 : return aObj2Line3;
+ case MIDDLELINE: return aMiddleLine;
+ } // switch
+ return aMiddleLine;
+}
+
+USHORT SdrEdgeInfoRec::ImpGetPolyIdx(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const
+{
+ switch (eLineCode) {
+ case OBJ1LINE2 : return 1;
+ case OBJ1LINE3 : return 2;
+ case OBJ2LINE2 : return rXP.GetPointCount()-3;
+ case OBJ2LINE3 : return rXP.GetPointCount()-4;
+ case MIDDLELINE: return nMiddleLine;
+ } // switch
+ return 0;
+}
+
+FASTBOOL SdrEdgeInfoRec::ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const
+{
+ USHORT nIdx=ImpGetPolyIdx(eLineCode,rXP);
+ FASTBOOL bHorz=nAngle1==0 || nAngle1==18000;
+ if (eLineCode==OBJ2LINE2 || eLineCode==OBJ2LINE3) {
+ nIdx=rXP.GetPointCount()-nIdx; // #36314#
+ bHorz=nAngle2==0 || nAngle2==18000; // #52000#
+ }
+ if ((nIdx & 1)==1) bHorz=!bHorz;
+ return bHorz;
+}
+
+void SdrEdgeInfoRec::ImpSetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP, long nVal)
+{
+ Point& rPt=ImpGetLineVersatzPoint(eLineCode);
+ if (ImpIsHorzLine(eLineCode,rXP)) rPt.Y()=nVal;
+ else rPt.X()=nVal;
+}
+
+long SdrEdgeInfoRec::ImpGetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const
+{
+ const Point& rPt=ImpGetLineVersatzPoint(eLineCode);
+ if (ImpIsHorzLine(eLineCode,rXP)) return rPt.Y();
+ else return rPt.X();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrEdgeObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::ConnectorProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrEdgeObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrEdgeObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrEdgeObj,SdrTextObj);
+
+SdrEdgeObj::SdrEdgeObj()
+: SdrTextObj(),
+ nNotifyingCount(0),
+ bEdgeTrackDirty(sal_False),
+ bEdgeTrackUserDefined(sal_False),
+ // #109007# Default is to allow default connects
+ mbSuppressDefaultConnect(sal_False),
+ // #110649#
+ mbBoundRectCalculationRunning(sal_False)
+{
+ bClosedObj=FALSE;
+ bIsEdge=TRUE;
+ pEdgeTrack=new XPolygon;
+
+}
+
+SdrEdgeObj::~SdrEdgeObj()
+{
+ DisconnectFromNode(TRUE);
+ DisconnectFromNode(FALSE);
+ delete pEdgeTrack;
+}
+
+void SdrEdgeObj::ImpSetAttrToEdgeInfo()
+{
+ const SfxItemSet& rSet = GetObjectItemSet();
+ SdrEdgeKind eKind = ((SdrEdgeKindItem&)(rSet.Get(SDRATTR_EDGEKIND))).GetValue();
+ sal_Int32 nVal1 = ((SdrEdgeLine1DeltaItem&)rSet.Get(SDRATTR_EDGELINE1DELTA)).GetValue();
+ sal_Int32 nVal2 = ((SdrEdgeLine2DeltaItem&)rSet.Get(SDRATTR_EDGELINE2DELTA)).GetValue();
+ sal_Int32 nVal3 = ((SdrEdgeLine3DeltaItem&)rSet.Get(SDRATTR_EDGELINE3DELTA)).GetValue();
+
+ if(eKind == SDREDGE_ORTHOLINES || eKind == SDREDGE_BEZIER)
+ {
+ sal_Int32 nVals[3] = { nVal1, nVal2, nVal3 };
+ sal_uInt16 n = 0;
+
+ if(aEdgeInfo.nObj1Lines >= 2 && n < 3)
+ {
+ aEdgeInfo.ImpSetLineVersatz(OBJ1LINE2, *pEdgeTrack, nVals[n]);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj1Lines >= 3 && n < 3)
+ {
+ aEdgeInfo.ImpSetLineVersatz(OBJ1LINE3, *pEdgeTrack, nVals[n]);
+ n++;
+ }
+
+ if(aEdgeInfo.nMiddleLine != 0xFFFF && n < 3)
+ {
+ aEdgeInfo.ImpSetLineVersatz(MIDDLELINE, *pEdgeTrack, nVals[n]);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj2Lines >= 3 && n < 3)
+ {
+ aEdgeInfo.ImpSetLineVersatz(OBJ2LINE3, *pEdgeTrack, nVals[n]);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj2Lines >= 2 && n < 3)
+ {
+ aEdgeInfo.ImpSetLineVersatz(OBJ2LINE2, *pEdgeTrack, nVals[n]);
+ n++;
+ }
+ }
+ else if(eKind == SDREDGE_THREELINES)
+ {
+ BOOL bHor1 = aEdgeInfo.nAngle1 == 0 || aEdgeInfo.nAngle1 == 18000;
+ BOOL bHor2 = aEdgeInfo.nAngle2 == 0 || aEdgeInfo.nAngle2 == 18000;
+
+ if(bHor1)
+ {
+ aEdgeInfo.aObj1Line2.X() = nVal1;
+ }
+ else
+ {
+ aEdgeInfo.aObj1Line2.Y() = nVal1;
+ }
+
+ if(bHor2)
+ {
+ aEdgeInfo.aObj2Line2.X() = nVal2;
+ }
+ else
+ {
+ aEdgeInfo.aObj2Line2.Y() = nVal2;
+ }
+ }
+
+ // #84649#
+ ImpDirtyEdgeTrack();
+}
+
+void SdrEdgeObj::ImpSetEdgeInfoToAttr()
+{
+ const SfxItemSet& rSet = GetObjectItemSet();
+ SdrEdgeKind eKind = ((SdrEdgeKindItem&)(rSet.Get(SDRATTR_EDGEKIND))).GetValue();
+ sal_Int32 nValAnz = ((SdrEdgeLineDeltaAnzItem&)rSet.Get(SDRATTR_EDGELINEDELTAANZ)).GetValue();
+ sal_Int32 nVal1 = ((SdrEdgeLine1DeltaItem&)rSet.Get(SDRATTR_EDGELINE1DELTA)).GetValue();
+ sal_Int32 nVal2 = ((SdrEdgeLine2DeltaItem&)rSet.Get(SDRATTR_EDGELINE2DELTA)).GetValue();
+ sal_Int32 nVal3 = ((SdrEdgeLine3DeltaItem&)rSet.Get(SDRATTR_EDGELINE3DELTA)).GetValue();
+ sal_Int32 nVals[3] = { nVal1, nVal2, nVal3 };
+ sal_uInt16 n = 0;
+
+ if(eKind == SDREDGE_ORTHOLINES || eKind == SDREDGE_BEZIER)
+ {
+ if(aEdgeInfo.nObj1Lines >= 2 && n < 3)
+ {
+ nVals[n] = aEdgeInfo.ImpGetLineVersatz(OBJ1LINE2, *pEdgeTrack);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj1Lines >= 3 && n < 3)
+ {
+ nVals[n] = aEdgeInfo.ImpGetLineVersatz(OBJ1LINE3, *pEdgeTrack);
+ n++;
+ }
+
+ if(aEdgeInfo.nMiddleLine != 0xFFFF && n < 3)
+ {
+ nVals[n] = aEdgeInfo.ImpGetLineVersatz(MIDDLELINE, *pEdgeTrack);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj2Lines >= 3 && n < 3)
+ {
+ nVals[n] = aEdgeInfo.ImpGetLineVersatz(OBJ2LINE3, *pEdgeTrack);
+ n++;
+ }
+
+ if(aEdgeInfo.nObj2Lines >= 2 && n < 3)
+ {
+ nVals[n] = aEdgeInfo.ImpGetLineVersatz(OBJ2LINE2, *pEdgeTrack);
+ n++;
+ }
+ }
+ else if(eKind == SDREDGE_THREELINES)
+ {
+ BOOL bHor1 = aEdgeInfo.nAngle1 == 0 || aEdgeInfo.nAngle1 == 18000;
+ BOOL bHor2 = aEdgeInfo.nAngle2 == 0 || aEdgeInfo.nAngle2 == 18000;
+
+ n = 2;
+ nVals[0] = bHor1 ? aEdgeInfo.aObj1Line2.X() : aEdgeInfo.aObj1Line2.Y();
+ nVals[1] = bHor2 ? aEdgeInfo.aObj2Line2.X() : aEdgeInfo.aObj2Line2.Y();
+ }
+
+ if(n != nValAnz || nVals[0] != nVal1 || nVals[1] != nVal2 || nVals[2] != nVal3)
+ {
+ // #75371# Here no more notifying is necessary, just local changes are OK.
+ if(n != nValAnz)
+ {
+ GetProperties().SetObjectItemDirect(SdrEdgeLineDeltaAnzItem(n));
+ }
+
+ if(nVals[0] != nVal1)
+ {
+ GetProperties().SetObjectItemDirect(SdrEdgeLine1DeltaItem(nVals[0]));
+ }
+
+ if(nVals[1] != nVal2)
+ {
+ GetProperties().SetObjectItemDirect(SdrEdgeLine2DeltaItem(nVals[1]));
+ }
+
+ if(nVals[2] != nVal3)
+ {
+ GetProperties().SetObjectItemDirect(SdrEdgeLine3DeltaItem(nVals[2]));
+ }
+
+ if(n < 3)
+ {
+ GetProperties().ClearObjectItemDirect(SDRATTR_EDGELINE3DELTA);
+ }
+
+ if(n < 2)
+ {
+ GetProperties().ClearObjectItemDirect(SDRATTR_EDGELINE2DELTA);
+ }
+
+ if(n < 1)
+ {
+ GetProperties().ClearObjectItemDirect(SDRATTR_EDGELINE1DELTA);
+ }
+ }
+}
+
+void SdrEdgeObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bRotate90Allowed =FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bMirror45Allowed =FALSE;
+ rInfo.bMirror90Allowed =FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ FASTBOOL bCanConv=!HasText() || ImpCanConvTextToCurve();
+ rInfo.bCanConvToPath=bCanConv;
+ rInfo.bCanConvToPoly=bCanConv;
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrEdgeObj::GetObjIdentifier() const
+{
+ return UINT16(OBJ_EDGE);
+}
+
+const Rectangle& SdrEdgeObj::GetCurrentBoundRect() const
+{
+ if(bEdgeTrackDirty)
+ {
+ ((SdrEdgeObj*)this)->ImpRecalcEdgeTrack();
+ }
+
+ return SdrTextObj::GetCurrentBoundRect();
+}
+
+const Rectangle& SdrEdgeObj::GetSnapRect() const
+{
+ if(bEdgeTrackDirty)
+ {
+ ((SdrEdgeObj*)this)->ImpRecalcEdgeTrack();
+ }
+
+ return SdrTextObj::GetSnapRect();
+}
+
+void SdrEdgeObj::RecalcSnapRect()
+{
+ maSnapRect=pEdgeTrack->GetBoundRect();
+}
+
+void SdrEdgeObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ rRect=GetSnapRect();
+}
+
+FASTBOOL SdrEdgeObj::IsNode() const
+{
+ return TRUE;
+}
+
+SdrGluePoint SdrEdgeObj::GetVertexGluePoint(USHORT nNum) const
+{
+ Point aPt;
+ USHORT nPntAnz=pEdgeTrack->GetPointCount();
+ if (nPntAnz>0)
+ {
+ Point aOfs = GetSnapRect().Center();
+ if (nNum==2 && GetConnectedNode(TRUE)==NULL) aPt=(*pEdgeTrack)[0];
+ else if (nNum==3 && GetConnectedNode(FALSE)==NULL) aPt=(*pEdgeTrack)[nPntAnz-1];
+ else {
+ if ((nPntAnz & 1) ==1) {
+ aPt=(*pEdgeTrack)[nPntAnz/2];
+ } else {
+ Point aPt1((*pEdgeTrack)[nPntAnz/2-1]);
+ Point aPt2((*pEdgeTrack)[nPntAnz/2]);
+ aPt1+=aPt2;
+ aPt1.X()/=2;
+ aPt1.Y()/=2;
+ aPt=aPt1;
+ }
+ }
+ aPt-=aOfs;
+ }
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+ return aGP;
+}
+
+SdrGluePoint SdrEdgeObj::GetCornerGluePoint(USHORT nNum) const
+{
+ return GetVertexGluePoint(nNum);
+}
+
+const SdrGluePointList* SdrEdgeObj::GetGluePointList() const
+{
+ return NULL; // Keine benutzerdefinierten Klebepunkte fuer Verbinder #31671#
+}
+
+SdrGluePointList* SdrEdgeObj::ForceGluePointList()
+{
+ return NULL; // Keine benutzerdefinierten Klebepunkte fuer Verbinder #31671#
+}
+
+FASTBOOL SdrEdgeObj::IsEdge() const
+{
+ return TRUE;
+}
+
+void SdrEdgeObj::ConnectToNode(FASTBOOL bTail1, SdrObject* pObj)
+{
+ SdrObjConnection& rCon=GetConnection(bTail1);
+ DisconnectFromNode(bTail1);
+ if (pObj!=NULL) {
+ pObj->AddListener(*this);
+ rCon.pObj=pObj;
+ ImpDirtyEdgeTrack();
+ }
+}
+
+void SdrEdgeObj::DisconnectFromNode(FASTBOOL bTail1)
+{
+ SdrObjConnection& rCon=GetConnection(bTail1);
+ if (rCon.pObj!=NULL) {
+ rCon.pObj->RemoveListener(*this);
+ rCon.pObj=NULL;
+ }
+}
+
+SdrObject* SdrEdgeObj::GetConnectedNode(FASTBOOL bTail1) const
+{
+ SdrObject* pObj=GetConnection(bTail1).pObj;
+ if (pObj!=NULL && (pObj->GetPage()!=pPage || !pObj->IsInserted())) pObj=NULL;
+ return pObj;
+}
+
+FASTBOOL SdrEdgeObj::CheckNodeConnection(FASTBOOL bTail1) const
+{
+ FASTBOOL bRet=FALSE;
+ const SdrObjConnection& rCon=GetConnection(bTail1);
+ USHORT nPtAnz=pEdgeTrack->GetPointCount();
+ if (rCon.pObj!=NULL && rCon.pObj->GetPage()==pPage && nPtAnz!=0) {
+ const SdrGluePointList* pGPL=rCon.pObj->GetGluePointList();
+ USHORT nConAnz=pGPL==NULL ? 0 : pGPL->GetCount();
+ USHORT nGesAnz=nConAnz+8;
+ Point aTail(bTail1 ? (*pEdgeTrack)[0] : (*pEdgeTrack)[USHORT(nPtAnz-1)]);
+ for (USHORT i=0; i<nGesAnz && !bRet; i++) {
+ if (i<nConAnz) { // UserDefined
+ bRet=aTail==(*pGPL)[i].GetAbsolutePos(*rCon.pObj);
+ } else if (i<nConAnz+4) { // Vertex
+ SdrGluePoint aPt(rCon.pObj->GetVertexGluePoint(i-nConAnz));
+ bRet=aTail==aPt.GetAbsolutePos(*rCon.pObj);
+ } else { // Corner
+ SdrGluePoint aPt(rCon.pObj->GetCornerGluePoint(i-nConAnz-4));
+ bRet=aTail==aPt.GetAbsolutePos(*rCon.pObj);
+ }
+ }
+ }
+ return bRet;
+}
+
+void SdrEdgeObj::ImpSetTailPoint(FASTBOOL bTail1, const Point& rPt)
+{
+ USHORT nPtAnz=pEdgeTrack->GetPointCount();
+ if (nPtAnz==0) {
+ (*pEdgeTrack)[0]=rPt;
+ (*pEdgeTrack)[1]=rPt;
+ } else if (nPtAnz==1) {
+ if (!bTail1) (*pEdgeTrack)[1]=rPt;
+ else { (*pEdgeTrack)[1]=(*pEdgeTrack)[0]; (*pEdgeTrack)[0]=rPt; }
+ } else {
+ if (!bTail1) (*pEdgeTrack)[USHORT(nPtAnz-1)]=rPt;
+ else (*pEdgeTrack)[0]=rPt;
+ }
+ ImpRecalcEdgeTrack();
+ SetRectsDirty();
+}
+
+void SdrEdgeObj::ImpDirtyEdgeTrack()
+{
+ if ( !bEdgeTrackUserDefined || !(GetModel() && GetModel()->isLocked()) )
+ bEdgeTrackDirty = sal_True;
+}
+
+void SdrEdgeObj::ImpUndirtyEdgeTrack()
+{
+ if (bEdgeTrackDirty && (GetModel() && GetModel()->isLocked()) ) {
+ ImpRecalcEdgeTrack();
+ }
+}
+
+void SdrEdgeObj::ImpRecalcEdgeTrack()
+{
+ if ( bEdgeTrackUserDefined && (GetModel() && GetModel()->isLocked()) )
+ return;
+
+ // #110649#
+ if(IsBoundRectCalculationRunning())
+ {
+ // this object is involved into another ImpRecalcEdgeTrack() call
+ // from another SdrEdgeObj. Do not calculate again to avoid loop.
+ // Also, do not change bEdgeTrackDirty so that it gets recalculated
+ // later at the first non-looping call.
+ }
+ // #i43068#
+ else if(GetModel() && GetModel()->isLocked())
+ {
+ // avoid re-layout during imports/API call sequences
+ // #i45294# but calc EdgeTrack and secure properties there
+ ((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_True;
+ *pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
+ ImpSetAttrToEdgeInfo();
+ bEdgeTrackDirty=sal_False;
+ ((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_False;
+ }
+ else
+ {
+ // To not run in a depth loop, use a coloring algorythm on
+ // SdrEdgeObj BoundRect calculations
+ ((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_True;
+
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ SetRectsDirty();
+ // #110094#-14 if (!bEdgeTrackDirty) SendRepaintBroadcast();
+ *pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
+ ImpSetEdgeInfoToAttr(); // Die Werte aus aEdgeInfo in den Pool kopieren
+ bEdgeTrackDirty=sal_False;
+
+ // Only redraw here, no object change
+ ActionChanged();
+ // BroadcastObjectChange();
+
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+
+ // #110649#
+ ((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_False;
+ }
+}
+
+USHORT SdrEdgeObj::ImpCalcEscAngle(SdrObject* pObj, const Point& rPt) const
+{
+ if (pObj==NULL) return SDRESC_ALL;
+ Rectangle aR(pObj->GetSnapRect());
+ long dxl=rPt.X()-aR.Left();
+ long dyo=rPt.Y()-aR.Top();
+ long dxr=aR.Right()-rPt.X();
+ long dyu=aR.Bottom()-rPt.Y();
+ FASTBOOL bxMitt=Abs(dxl-dxr)<2;
+ FASTBOOL byMitt=Abs(dyo-dyu)<2;
+ long dx=Min(dxl,dxr);
+ long dy=Min(dyo,dyu);
+ FASTBOOL bDiag=Abs(dx-dy)<2;
+ if (bxMitt && byMitt) return SDRESC_ALL; // In der Mitte
+ if (bDiag) { // diagonal
+ USHORT nRet=0;
+ if (byMitt) nRet|=SDRESC_VERT;
+ if (bxMitt) nRet|=SDRESC_HORZ;
+ if (dxl<dxr) { // Links
+ if (dyo<dyu) nRet|=SDRESC_LEFT | SDRESC_TOP;
+ else nRet|=SDRESC_LEFT | SDRESC_BOTTOM;
+ } else { // Rechts
+ if (dyo<dyu) nRet|=SDRESC_RIGHT | SDRESC_TOP;
+ else nRet|=SDRESC_RIGHT | SDRESC_BOTTOM;
+ }
+ return nRet;
+ }
+ if (dx<dy) { // waagerecht
+ if (bxMitt) return SDRESC_HORZ;
+ if (dxl<dxr) return SDRESC_LEFT;
+ else return SDRESC_RIGHT;
+ } else { // senkrecht
+ if (byMitt) return SDRESC_VERT;
+ if (dyo<dyu) return SDRESC_TOP;
+ else return SDRESC_BOTTOM;
+ }
+}
+
+FASTBOOL SdrEdgeObj::ImpStripPolyPoints(XPolygon& /*rXP*/) const
+{
+ // fehlende Implementation !!!
+ return FALSE;
+}
+
+XPolygon SdrEdgeObj::ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, const Rectangle& rRect, const Point& rMeeting) const
+{
+ XPolygon aXP;
+ aXP.Insert(XPOLY_APPEND,rStPt,XPOLY_NORMAL);
+ FASTBOOL bRts=nEscAngle==0;
+ FASTBOOL bObn=nEscAngle==9000;
+ FASTBOOL bLks=nEscAngle==18000;
+ FASTBOOL bUnt=nEscAngle==27000;
+
+ Point aP1(rStPt); // erstmal den Pflichtabstand
+ if (bLks) aP1.X()=rRect.Left();
+ if (bRts) aP1.X()=rRect.Right();
+ if (bObn) aP1.Y()=rRect.Top();
+ if (bUnt) aP1.Y()=rRect.Bottom();
+
+ FASTBOOL bFinish=FALSE;
+ if (!bFinish) {
+ Point aP2(aP1); // Und nun den Pflichtabstand ggf. bis auf Meetinghoehe erweitern
+ if (bLks && rMeeting.X()<=aP2.X()) aP2.X()=rMeeting.X();
+ if (bRts && rMeeting.X()>=aP2.X()) aP2.X()=rMeeting.X();
+ if (bObn && rMeeting.Y()<=aP2.Y()) aP2.Y()=rMeeting.Y();
+ if (bUnt && rMeeting.Y()>=aP2.Y()) aP2.Y()=rMeeting.Y();
+ aXP.Insert(XPOLY_APPEND,aP2,XPOLY_NORMAL);
+
+ Point aP3(aP2);
+ if ((bLks && rMeeting.X()>aP2.X()) || (bRts && rMeeting.X()<aP2.X())) { // Aussenrum
+ if (rMeeting.Y()<aP2.Y()) {
+ aP3.Y()=rRect.Top();
+ if (rMeeting.Y()<aP3.Y()) aP3.Y()=rMeeting.Y();
+ } else {
+ aP3.Y()=rRect.Bottom();
+ if (rMeeting.Y()>aP3.Y()) aP3.Y()=rMeeting.Y();
+ }
+ aXP.Insert(XPOLY_APPEND,aP3,XPOLY_NORMAL);
+ if (aP3.Y()!=rMeeting.Y()) {
+ aP3.X()=rMeeting.X();
+ aXP.Insert(XPOLY_APPEND,aP3,XPOLY_NORMAL);
+ }
+ }
+ if ((bObn && rMeeting.Y()>aP2.Y()) || (bUnt && rMeeting.Y()<aP2.Y())) { // Aussenrum
+ if (rMeeting.X()<aP2.X()) {
+ aP3.X()=rRect.Left();
+ if (rMeeting.X()<aP3.X()) aP3.X()=rMeeting.X();
+ } else {
+ aP3.X()=rRect.Right();
+ if (rMeeting.X()>aP3.X()) aP3.X()=rMeeting.X();
+ }
+ aXP.Insert(XPOLY_APPEND,aP3,XPOLY_NORMAL);
+ if (aP3.X()!=rMeeting.X()) {
+ aP3.Y()=rMeeting.Y();
+ aXP.Insert(XPOLY_APPEND,aP3,XPOLY_NORMAL);
+ }
+ }
+ }
+#ifdef DBG_UTIL
+ if (aXP.GetPointCount()>4) {
+ DBG_ERROR("SdrEdgeObj::ImpCalcObjToCenter(): Polygon hat mehr als 4 Punkte!");
+ }
+#endif
+ return aXP;
+}
+
+XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& rCon1, SdrObjConnection& rCon2, SdrEdgeInfoRec* pInfo) const
+{
+ Point aPt1,aPt2;
+ SdrGluePoint aGP1,aGP2;
+ USHORT nEsc1=SDRESC_ALL,nEsc2=SDRESC_ALL;
+ Rectangle aBoundRect1;
+ Rectangle aBoundRect2;
+ Rectangle aBewareRect1;
+ Rectangle aBewareRect2;
+ // Erstmal die alten Endpunkte wiederholen
+ if (rTrack0.GetPointCount()!=0) {
+ aPt1=rTrack0[0];
+ USHORT nSiz=rTrack0.GetPointCount();
+ nSiz--;
+ aPt2=rTrack0[nSiz];
+ } else {
+ if (!aOutRect.IsEmpty()) {
+ aPt1=aOutRect.TopLeft();
+ aPt2=aOutRect.BottomRight();
+ }
+ }
+ FASTBOOL bCon1=rCon1.pObj!=NULL && rCon1.pObj->GetPage()==pPage && rCon1.pObj->IsInserted();
+ FASTBOOL bCon2=rCon2.pObj!=NULL && rCon2.pObj->GetPage()==pPage && rCon2.pObj->IsInserted();
+ const SfxItemSet& rSet = GetObjectItemSet();
+
+ if (bCon1) {
+ if (rCon1.pObj==(SdrObject*)this)
+ {
+ // sicherheitshalber Abfragen #44515#
+ aBoundRect1=aOutRect;
+ }
+ else
+ {
+ aBoundRect1 = rCon1.pObj->GetCurrentBoundRect();
+ }
+ aBoundRect1.Move(rCon1.aObjOfs.X(),rCon1.aObjOfs.Y());
+ aBewareRect1=aBoundRect1;
+
+ sal_Int32 nH = ((SdrEdgeNode1HorzDistItem&)rSet.Get(SDRATTR_EDGENODE1HORZDIST)).GetValue();
+ sal_Int32 nV = ((SdrEdgeNode1VertDistItem&)rSet.Get(SDRATTR_EDGENODE1VERTDIST)).GetValue();
+
+ aBewareRect1.Left()-=nH;
+ aBewareRect1.Right()+=nH;
+ aBewareRect1.Top()-=nV;
+ aBewareRect1.Bottom()+=nV;
+ } else {
+ aBoundRect1=Rectangle(aPt1,aPt1);
+ aBoundRect1.Move(rCon1.aObjOfs.X(),rCon1.aObjOfs.Y());
+ aBewareRect1=aBoundRect1;
+ }
+ if (bCon2) {
+ if (rCon2.pObj==(SdrObject*)this) { // sicherheitshalber Abfragen #44515#
+ aBoundRect2=aOutRect;
+ }
+ else
+ {
+ aBoundRect2 = rCon2.pObj->GetCurrentBoundRect();
+ }
+ aBoundRect2.Move(rCon2.aObjOfs.X(),rCon2.aObjOfs.Y());
+ aBewareRect2=aBoundRect2;
+
+ sal_Int32 nH = ((SdrEdgeNode2HorzDistItem&)rSet.Get(SDRATTR_EDGENODE2HORZDIST)).GetValue();
+ sal_Int32 nV = ((SdrEdgeNode2VertDistItem&)rSet.Get(SDRATTR_EDGENODE2VERTDIST)).GetValue();
+
+ aBewareRect2.Left()-=nH;
+ aBewareRect2.Right()+=nH;
+ aBewareRect2.Top()-=nV;
+ aBewareRect2.Bottom()+=nV;
+ } else {
+ aBoundRect2=Rectangle(aPt2,aPt2);
+ aBoundRect2.Move(rCon2.aObjOfs.X(),rCon2.aObjOfs.Y());
+ aBewareRect2=aBoundRect2;
+ }
+ XPolygon aBestXP;
+ ULONG nBestQual=0xFFFFFFFF;
+ SdrEdgeInfoRec aBestInfo;
+ FASTBOOL bAuto1=bCon1 && rCon1.bBestVertex;
+ FASTBOOL bAuto2=bCon2 && rCon2.bBestVertex;
+ if (bAuto1) rCon1.bAutoVertex=TRUE;
+ if (bAuto2) rCon2.bAutoVertex=TRUE;
+ USHORT nBestAuto1=0;
+ USHORT nBestAuto2=0;
+ USHORT nAnz1=bAuto1 ? 4 : 1;
+ USHORT nAnz2=bAuto2 ? 4 : 1;
+ for (USHORT nNum1=0; nNum1<nAnz1; nNum1++) {
+ if (bAuto1) rCon1.nConId=nNum1;
+ if (bCon1 && rCon1.TakeGluePoint(aGP1,TRUE)) {
+ aPt1=aGP1.GetPos();
+ nEsc1=aGP1.GetEscDir();
+ if (nEsc1==SDRESC_SMART) nEsc1=ImpCalcEscAngle(rCon1.pObj,aPt1-rCon1.aObjOfs);
+ }
+ for (USHORT nNum2=0; nNum2<nAnz2; nNum2++) {
+ if (bAuto2) rCon2.nConId=nNum2;
+ if (bCon2 && rCon2.TakeGluePoint(aGP2,TRUE)) {
+ aPt2=aGP2.GetPos();
+ nEsc2=aGP2.GetEscDir();
+ if (nEsc2==SDRESC_SMART) nEsc2=ImpCalcEscAngle(rCon2.pObj,aPt2-rCon2.aObjOfs);
+ }
+ for (long nA1=0; nA1<36000; nA1+=9000) {
+ USHORT nE1=nA1==0 ? SDRESC_RIGHT : nA1==9000 ? SDRESC_TOP : nA1==18000 ? SDRESC_LEFT : nA1==27000 ? SDRESC_BOTTOM : 0;
+ for (long nA2=0; nA2<36000; nA2+=9000) {
+ USHORT nE2=nA2==0 ? SDRESC_RIGHT : nA2==9000 ? SDRESC_TOP : nA2==18000 ? SDRESC_LEFT : nA2==27000 ? SDRESC_BOTTOM : 0;
+ if ((nEsc1&nE1)!=0 && (nEsc2&nE2)!=0) {
+ ULONG nQual=0;
+ SdrEdgeInfoRec aInfo;
+ if (pInfo!=NULL) aInfo=*pInfo;
+ XPolygon aXP(ImpCalcEdgeTrack(aPt1,nA1,aBoundRect1,aBewareRect1,aPt2,nA2,aBoundRect2,aBewareRect2,&nQual,&aInfo));
+ if (nQual<nBestQual) {
+ aBestXP=aXP;
+ nBestQual=nQual;
+ aBestInfo=aInfo;
+ nBestAuto1=nNum1;
+ nBestAuto2=nNum2;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (bAuto1) rCon1.nConId=nBestAuto1;
+ if (bAuto2) rCon2.nConId=nBestAuto2;
+ if (pInfo!=NULL) *pInfo=aBestInfo;
+ return aBestXP;
+}
+
+XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rectangle& rBoundRect1, const Rectangle& rBewareRect1,
+ const Point& rPt2, long nAngle2, const Rectangle& rBoundRect2, const Rectangle& rBewareRect2,
+ ULONG* pnQuality, SdrEdgeInfoRec* pInfo) const
+{
+ SdrEdgeKind eKind=((SdrEdgeKindItem&)(GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
+ FASTBOOL bRts1=nAngle1==0;
+ FASTBOOL bObn1=nAngle1==9000;
+ FASTBOOL bLks1=nAngle1==18000;
+ FASTBOOL bUnt1=nAngle1==27000;
+ FASTBOOL bHor1=bLks1 || bRts1;
+ FASTBOOL bVer1=bObn1 || bUnt1;
+ FASTBOOL bRts2=nAngle2==0;
+ FASTBOOL bObn2=nAngle2==9000;
+ FASTBOOL bLks2=nAngle2==18000;
+ FASTBOOL bUnt2=nAngle2==27000;
+ FASTBOOL bHor2=bLks2 || bRts2;
+ FASTBOOL bVer2=bObn2 || bUnt2;
+ FASTBOOL bInfo=pInfo!=NULL;
+ if (bInfo) {
+ pInfo->cOrthoForm=0;
+ pInfo->nAngle1=nAngle1;
+ pInfo->nAngle2=nAngle2;
+ pInfo->nObj1Lines=1;
+ pInfo->nObj2Lines=1;
+ pInfo->nMiddleLine=0xFFFF;
+ }
+ Point aPt1(rPt1);
+ Point aPt2(rPt2);
+ Rectangle aBoundRect1 (rBoundRect1 );
+ Rectangle aBoundRect2 (rBoundRect2 );
+ Rectangle aBewareRect1(rBewareRect1);
+ Rectangle aBewareRect2(rBewareRect2);
+ Point aMeeting((aPt1.X()+aPt2.X()+1)/2,(aPt1.Y()+aPt2.Y()+1)/2);
+ FASTBOOL bMeetingXMid=TRUE;
+ FASTBOOL bMeetingYMid=TRUE;
+ if (eKind==SDREDGE_ONELINE) {
+ XPolygon aXP(2);
+ aXP[0]=rPt1;
+ aXP[1]=rPt2;
+ if (pnQuality!=NULL) {
+ *pnQuality=Abs(rPt1.X()-rPt2.X())+Abs(rPt1.Y()-rPt2.Y());
+ }
+ return aXP;
+ } else if (eKind==SDREDGE_THREELINES) {
+ XPolygon aXP(4);
+ aXP[0]=rPt1;
+ aXP[1]=rPt1;
+ aXP[2]=rPt2;
+ aXP[3]=rPt2;
+ if (bRts1) aXP[1].X()=aBewareRect1.Right(); //+=500;
+ if (bObn1) aXP[1].Y()=aBewareRect1.Top(); //-=500;
+ if (bLks1) aXP[1].X()=aBewareRect1.Left(); //-=500;
+ if (bUnt1) aXP[1].Y()=aBewareRect1.Bottom(); //+=500;
+ if (bRts2) aXP[2].X()=aBewareRect2.Right(); //+=500;
+ if (bObn2) aXP[2].Y()=aBewareRect2.Top(); //-=500;
+ if (bLks2) aXP[2].X()=aBewareRect2.Left(); //-=500;
+ if (bUnt2) aXP[2].Y()=aBewareRect2.Bottom(); //+=500;
+ if (pnQuality!=NULL) {
+ long nQ=Abs(aXP[1].X()-aXP[0].X())+Abs(aXP[1].Y()-aXP[0].Y());
+ nQ+=Abs(aXP[2].X()-aXP[1].X())+Abs(aXP[2].Y()-aXP[1].Y());
+ nQ+=Abs(aXP[3].X()-aXP[2].X())+Abs(aXP[3].Y()-aXP[2].Y());
+ *pnQuality=nQ;
+ }
+ if (bInfo) {
+ pInfo->nObj1Lines=2;
+ pInfo->nObj2Lines=2;
+ if (bHor1) {
+ aXP[1].X()+=pInfo->aObj1Line2.X();
+ } else {
+ aXP[1].Y()+=pInfo->aObj1Line2.Y();
+ }
+ if (bHor2) {
+ aXP[2].X()+=pInfo->aObj2Line2.X();
+ } else {
+ aXP[2].Y()+=pInfo->aObj2Line2.Y();
+ }
+ }
+ return aXP;
+ }
+ USHORT nIntersections=0;
+ FASTBOOL bForceMeeting=FALSE; // Muss die Linie durch den MeetingPoint laufen?
+ {
+ Point aC1(aBewareRect1.Center());
+ Point aC2(aBewareRect2.Center());
+ if (aBewareRect1.Left()<=aBewareRect2.Right() && aBewareRect1.Right()>=aBewareRect2.Left()) {
+ // Ueberschneidung auf der X-Achse
+ long n1=Max(aBewareRect1.Left(),aBewareRect2.Left());
+ long n2=Min(aBewareRect1.Right(),aBewareRect2.Right());
+ aMeeting.X()=(n1+n2+1)/2;
+ } else {
+ // Ansonsten den Mittelpunkt des Freiraums
+ if (aC1.X()<aC2.X()) {
+ aMeeting.X()=(aBewareRect1.Right()+aBewareRect2.Left()+1)/2;
+ } else {
+ aMeeting.X()=(aBewareRect1.Left()+aBewareRect2.Right()+1)/2;
+ }
+ }
+ if (aBewareRect1.Top()<=aBewareRect2.Bottom() && aBewareRect1.Bottom()>=aBewareRect2.Top()) {
+ // Ueberschneidung auf der Y-Achse
+ long n1=Max(aBewareRect1.Top(),aBewareRect2.Top());
+ long n2=Min(aBewareRect1.Bottom(),aBewareRect2.Bottom());
+ aMeeting.Y()=(n1+n2+1)/2;
+ } else {
+ // Ansonsten den Mittelpunkt des Freiraums
+ if (aC1.Y()<aC2.Y()) {
+ aMeeting.Y()=(aBewareRect1.Bottom()+aBewareRect2.Top()+1)/2;
+ } else {
+ aMeeting.Y()=(aBewareRect1.Top()+aBewareRect2.Bottom()+1)/2;
+ }
+ }
+ // Im Prinzip gibt es 3 zu unterscheidene Faelle:
+ // 1. Beide in die selbe Richtung
+ // 2. Beide in genau entgegengesetzte Richtungen
+ // 3. Einer waagerecht und der andere senkrecht
+ long nXMin=Min(aBewareRect1.Left(),aBewareRect2.Left());
+ long nXMax=Max(aBewareRect1.Right(),aBewareRect2.Right());
+ long nYMin=Min(aBewareRect1.Top(),aBewareRect2.Top());
+ long nYMax=Max(aBewareRect1.Bottom(),aBewareRect2.Bottom());
+ //FASTBOOL bBoundOverlap=aBoundRect1.Right()>aBoundRect2.Left() && aBoundRect1.Left()<aBoundRect2.Right() &&
+ aBoundRect1.Bottom()>aBoundRect2.Top() && aBoundRect1.Top()<aBoundRect2.Bottom();
+ FASTBOOL bBewareOverlap=aBewareRect1.Right()>aBewareRect2.Left() && aBewareRect1.Left()<aBewareRect2.Right() &&
+ aBewareRect1.Bottom()>aBewareRect2.Top() && aBewareRect1.Top()<aBewareRect2.Bottom();
+ unsigned nMainCase=3;
+ if (nAngle1==nAngle2) nMainCase=1;
+ else if ((bHor1 && bHor2) || (bVer1 && bVer2)) nMainCase=2;
+ if (nMainCase==1) { // Fall 1: Beide in eine Richtung moeglich.
+ if (bVer1) aMeeting.X()=(aPt1.X()+aPt2.X()+1)/2; // ist hier besser, als der
+ if (bHor1) aMeeting.Y()=(aPt1.Y()+aPt2.Y()+1)/2; // Mittelpunkt des Freiraums
+ // bX1Ok bedeutet, dass die Vertikale, die aus Obj1 austritt, keinen Konflikt mit Obj2 bildet, ...
+ FASTBOOL bX1Ok=aPt1.X()<=aBewareRect2.Left() || aPt1.X()>=aBewareRect2.Right();
+ FASTBOOL bX2Ok=aPt2.X()<=aBewareRect1.Left() || aPt2.X()>=aBewareRect1.Right();
+ FASTBOOL bY1Ok=aPt1.Y()<=aBewareRect2.Top() || aPt1.Y()>=aBewareRect2.Bottom();
+ FASTBOOL bY2Ok=aPt2.Y()<=aBewareRect1.Top() || aPt2.Y()>=aBewareRect1.Bottom();
+ if (bLks1 && (bY1Ok || aBewareRect1.Left()<aBewareRect2.Right()) && (bY2Ok || aBewareRect2.Left()<aBewareRect1.Right())) {
+ aMeeting.X()=nXMin;
+ bMeetingXMid=FALSE;
+ }
+ if (bRts1 && (bY1Ok || aBewareRect1.Right()>aBewareRect2.Left()) && (bY2Ok || aBewareRect2.Right()>aBewareRect1.Left())) {
+ aMeeting.X()=nXMax;
+ bMeetingXMid=FALSE;
+ }
+ if (bObn1 && (bX1Ok || aBewareRect1.Top()<aBewareRect2.Bottom()) && (bX2Ok || aBewareRect2.Top()<aBewareRect1.Bottom())) {
+ aMeeting.Y()=nYMin;
+ bMeetingYMid=FALSE;
+ }
+ if (bUnt1 && (bX1Ok || aBewareRect1.Bottom()>aBewareRect2.Top()) && (bX2Ok || aBewareRect2.Bottom()>aBewareRect1.Top())) {
+ aMeeting.Y()=nYMax;
+ bMeetingYMid=FALSE;
+ }
+ } else if (nMainCase==2) {
+ // Fall 2:
+ bForceMeeting=TRUE;
+ if (bHor1) { // beide waagerecht
+ /* 9 Moeglichkeiten: ù ù ù */
+ /* 2.1 Gegenueber, Ueberschneidung à ´ ù */
+ /* nur auf der Y-Achse ù ù ù */
+ /* 2.2, 2.3 Gegenueber, vertikal versetzt. Ã ù ù ù ù ù */
+ /* Ueberschneidung weder auf der ù ´ ù ù ´ ù */
+ /* X- noch auf der Y-Achse ù ù ù Ã ù ù */
+ /* 2.4, 2.5 Untereinander, ù Ã ù ù ù ù */
+ /* Ueberschneidung ù ´ ù ù ´ ù */
+ /* nur auf X-Achse ù ù ù ù Ã ù */
+ /* 2.6, 2.7 Gegeneinander, vertikal versetzt. ù ù Ã ù ù ù */
+ /* Ueberschneidung weder auf der ù ´ ù ù ´ ù */
+ /* X- noch auf der Y-Achse. ù ù ù ù ù Ã */
+ /* 2.8 Gegeneinander. ù ù ù */
+ /* Ueberschneidung nur ù ´ Ã */
+ /* auf der Y-Achse. ù ù ù */
+ /* 2.9 Die BewareRects der Objekte ueberschneiden */
+ /* sich auf X- und Y-Achse. */
+ /* Die Faelle gelten entsprechend umgesetzt auch fuer */
+ /* senkrechte Linienaustritte. */
+ /* Die Faelle 2.1-2.7 werden mit dem Default-Meeting ausreichend*/
+ /* gut behandelt. Spezielle MeetingPoints werden hier also nur */
+ /* fuer 2.8 und 2.9 bestimmt. */
+
+ // Normalisierung. aR1 soll der nach rechts und
+ // aR2 der nach links austretende sein.
+ Rectangle aBewR1(bRts1 ? aBewareRect1 : aBewareRect2);
+ Rectangle aBewR2(bRts1 ? aBewareRect2 : aBewareRect1);
+ Rectangle aBndR1(bRts1 ? aBoundRect1 : aBoundRect2);
+ Rectangle aBndR2(bRts1 ? aBoundRect2 : aBoundRect1);
+ if (aBewR1.Bottom()>aBewR2.Top() && aBewR1.Top()<aBewR2.Bottom()) {
+ // Ueberschneidung auf der Y-Achse. Faelle 2.1, 2.8, 2.9
+ if (aBewR1.Right()>aBewR2.Left()) {
+ // Faelle 2.8, 2.9
+ // Fall 2.8 ist immer Aussenrumlauf (bDirect=FALSE).
+ // Fall 2.9 kann auch Direktverbindung sein (bei geringer
+ // Ueberschneidung der BewareRects ohne Ueberschneidung der
+ // Boundrects wenn die Linienaustritte sonst das BewareRect
+ // des jeweils anderen Objekts verletzen wuerden.
+ FASTBOOL bCase29Direct=FALSE;
+ FASTBOOL bCase29=aBewR1.Right()>aBewR2.Left();
+ if (aBndR1.Right()<=aBndR2.Left()) { // Fall 2.9 und keine Boundrectueberschneidung
+ if ((aPt1.Y()>aBewareRect2.Top() && aPt1.Y()<aBewareRect2.Bottom()) ||
+ (aPt2.Y()>aBewareRect1.Top() && aPt2.Y()<aBewareRect1.Bottom())) {
+ bCase29Direct=TRUE;
+ }
+ }
+ if (!bCase29Direct) {
+ FASTBOOL bObenLang=Abs(nYMin-aMeeting.Y())<=Abs(nYMax-aMeeting.Y());
+ if (bObenLang) {
+ aMeeting.Y()=nYMin;
+ } else {
+ aMeeting.Y()=nYMax;
+ }
+ bMeetingYMid=FALSE;
+ if (bCase29) {
+ // und nun noch dafuer sorgen, dass das
+ // umzingelte Obj nicht durchquert wird
+ if ((aBewR1.Center().Y()<aBewR2.Center().Y()) != bObenLang) {
+ aMeeting.X()=aBewR2.Right();
+ } else {
+ aMeeting.X()=aBewR1.Left();
+ }
+ bMeetingXMid=FALSE;
+ }
+ } else {
+ // Direkte Verbindung (3-Linien Z-Verbindung), da
+ // Verletzung der BewareRects unvermeidlich ist.
+ // Via Dreisatz werden die BewareRects nun verkleinert.
+ long nWant1=aBewR1.Right()-aBndR1.Right(); // Abstand bei Obj1
+ long nWant2=aBndR2.Left()-aBewR2.Left(); // Abstand bei Obj2
+ long nSpace=aBndR2.Left()-aBndR1.Right(); // verfuegbarer Platz
+ long nGet1=BigMulDiv(nWant1,nSpace,nWant1+nWant2);
+ long nGet2=nSpace-nGet1;
+ if (bRts1) { // Normalisierung zurueckwandeln
+ aBewareRect1.Right()+=nGet1-nWant1;
+ aBewareRect2.Left()-=nGet2-nWant2;
+ } else {
+ aBewareRect2.Right()+=nGet1-nWant1;
+ aBewareRect1.Left()-=nGet2-nWant2;
+ }
+ nIntersections++; // Qualitaet herabsetzen
+ }
+ }
+ }
+ } else if (bVer1) { // beide senkrecht
+ Rectangle aBewR1(bUnt1 ? aBewareRect1 : aBewareRect2);
+ Rectangle aBewR2(bUnt1 ? aBewareRect2 : aBewareRect1);
+ Rectangle aBndR1(bUnt1 ? aBoundRect1 : aBoundRect2);
+ Rectangle aBndR2(bUnt1 ? aBoundRect2 : aBoundRect1);
+ if (aBewR1.Right()>aBewR2.Left() && aBewR1.Left()<aBewR2.Right()) {
+ // Ueberschneidung auf der Y-Achse. Faelle 2.1, 2.8, 2.9
+ if (aBewR1.Bottom()>aBewR2.Top()) {
+ // Faelle 2.8, 2.9
+ // Fall 2.8 ist immer Aussenrumlauf (bDirect=FALSE).
+ // Fall 2.9 kann auch Direktverbindung sein (bei geringer
+ // Ueberschneidung der BewareRects ohne Ueberschneidung der
+ // Boundrects wenn die Linienaustritte sonst das BewareRect
+ // des jeweils anderen Objekts verletzen wuerden.
+ FASTBOOL bCase29Direct=FALSE;
+ FASTBOOL bCase29=aBewR1.Bottom()>aBewR2.Top();
+ if (aBndR1.Bottom()<=aBndR2.Top()) { // Fall 2.9 und keine Boundrectueberschneidung
+ if ((aPt1.X()>aBewareRect2.Left() && aPt1.X()<aBewareRect2.Right()) ||
+ (aPt2.X()>aBewareRect1.Left() && aPt2.X()<aBewareRect1.Right())) {
+ bCase29Direct=TRUE;
+ }
+ }
+ if (!bCase29Direct) {
+ FASTBOOL bLinksLang=Abs(nXMin-aMeeting.X())<=Abs(nXMax-aMeeting.X());
+ if (bLinksLang) {
+ aMeeting.X()=nXMin;
+ } else {
+ aMeeting.X()=nXMax;
+ }
+ bMeetingXMid=FALSE;
+ if (bCase29) {
+ // und nun noch dafuer sorgen, dass das
+ // umzingelte Obj nicht durchquert wird
+ if ((aBewR1.Center().X()<aBewR2.Center().X()) != bLinksLang) {
+ aMeeting.Y()=aBewR2.Bottom();
+ } else {
+ aMeeting.Y()=aBewR1.Top();
+ }
+ bMeetingYMid=FALSE;
+ }
+ } else {
+ // Direkte Verbindung (3-Linien Z-Verbindung), da
+ // Verletzung der BewareRects unvermeidlich ist.
+ // Via Dreisatz werden die BewareRects nun verkleinert.
+ long nWant1=aBewR1.Bottom()-aBndR1.Bottom(); // Abstand bei Obj1
+ long nWant2=aBndR2.Top()-aBewR2.Top(); // Abstand bei Obj2
+ long nSpace=aBndR2.Top()-aBndR1.Bottom(); // verfuegbarer Platz
+ long nGet1=BigMulDiv(nWant1,nSpace,nWant1+nWant2);
+ long nGet2=nSpace-nGet1;
+ if (bUnt1) { // Normalisierung zurueckwandeln
+ aBewareRect1.Bottom()+=nGet1-nWant1;
+ aBewareRect2.Top()-=nGet2-nWant2;
+ } else {
+ aBewareRect2.Bottom()+=nGet1-nWant1;
+ aBewareRect1.Top()-=nGet2-nWant2;
+ }
+ nIntersections++; // Qualitaet herabsetzen
+ }
+ }
+ }
+ }
+ } else if (nMainCase==3) { // Fall 3: Einer waagerecht und der andere senkrecht. Sehr viele Fallunterscheidungen
+ /* Kleine Legende: ù ú ù ú ù -> Ohne Ueberschneidung, maximal Beruehrung. */
+ /* ú ú ú ú ú -> Ueberschneidung */
+ /* ù ú Ã ú ù -> Selbe Hoehe */
+ /* ú ú ú ú ú -> Ueberschneidung */
+ /* ù ú ù ú ù -> Ohne Ueberschneidung, maximal Beruehrung. */
+ /* Linienaustritte links ´, rechts Ã, oben Á und unten Â. */
+ /* Insgesamt sind 96 Konstellationen moeglich, wobei einige nicht einmal */
+ /* eindeutig einem Fall und damit einer Behandlungsmethode zugeordnet werden */
+ /* koennen. */
+ /* 3.1: Hierzu moegen alle Konstellationen zaehlen, die durch den */
+ /* Default-MeetingPoint zufriedenstellend abgedeckt sind (20+12). */
+ /* Â Â Â ú Á Á ú Â Â Â Diese 12 ù ú ù Â ù ù ú ù ú ù ù Â ù ú ù ù ú ù ú ù */
+ /* ú ú ú ú Á Á ú ú ú ú Konstel. ú ú ú ú ú ú ú ú ú Â ú ú ú ú ú Â ú ú ú ú */
+ /* ù ú Ã ú ù ù ú ´ ú ù jedoch ù ú Ã ú Á ù ú Ã ú Â Á ú ´ ú ù Â ú ´ ú ù */
+ /* ú ú ú ú Â Â ú ú ú ú nur zum ú ú ú ú Á ú ú ú ú ú Á ú ú ú ú ú ú ú ú ú */
+ /* Á Á Á ú Â Â ú Á Á Á Teil: ù ú ù Á ù ù ú ù ú ù ù Á ù ú ù ù ú ù ú ù */
+ /* Letztere 16 Faelle scheiden aus, sobald sich die Objekte offen */
+ /* gegenueberstehen (siehe Fall 3.2). */
+ /* 3.2: Die Objekte stehen sich offen gegenueber und somit ist eine */
+ /* Verbindung mit lediglich 2 Linien moeglich (4+20). */
+ /* Dieser Fall hat 1. Prioritaet. */
+ /* ù ú ù ú Â Â ú ù ú ù Diese 20 ù ú ù Â ù ù Â ù ú ù ù ú ù ú ù ù ú ù ú ù */
+ /* ú ú ú ú ú ú ú ú ú ú Konstel. ú ú ú Â Â Â Â ú ú ú ú ú ú ú ú ú ú ú ú ú */
+ /* ù ú Ã ú ù ù ú ´ ú ù jedoch ù ú Ã Á Á Á Á ´ ú ù ù ú Ã Â Â Â Â ´ ú ù */
+ /* ú ú ú ú ú ú ú ú ú ú nur zum ú ú ú Á Á Á Á ú ú ú ú ú ú ú ú ú ú ú ú ú */
+ /* ù ú ù ú Á Á ú ù ú ù Teil: ù ú ù Á ù ù Á ù ú ù ù ú ù ú ù ù ú ù ú ù */
+ /* 3.3: Die Linienaustritte zeigen vom anderen Objekt weg bzw. hinter */
+ /* dessen Ruecken vorbei (52+4). */
+ /* Á Á Á Á ù ù Á Á Á Á ù ú ú ú ù ù ú ù ú ù Diese 4 ù ú ù ú ù ù ú ù ú ù */
+ /* Á Á Á Á ú ú Á Á Á Á Â Â Â ú ú ú ú Â Â Â Konstel. ú ú ú Â ú ú Â ú ú ú */
+ /* Á Á Ã ú ù ù ú ´ Á Á Â Â Ã ú ù ù ú ´ Â Â jedoch ù ú Ã ú ù ù ú ´ ú ù */
+ /* Á Á Á ú ú ú ú Á Á Á Â Â Â Â ú ú Â Â Â Â nur zum ú ú ú Á ú ú Á ú ú ú */
+ /* ù ú ù ú ù ù ú ù ú ù Â Â Â Â ù ù Â Â Â Â Teil: ù ú ù ú ù ù ú ù ú ù */
+
+ // Fall 3.2
+ Rectangle aTmpR1(aBewareRect1);
+ Rectangle aTmpR2(aBewareRect2);
+ if (bBewareOverlap) {
+ // Ueberschneidung der BewareRects: BoundRects fuer Check auf Fall 3.2 verwenden.
+ aTmpR1=aBoundRect1;
+ aTmpR2=aBoundRect2;
+ }
+ if ((((bRts1 && aTmpR1.Right ()<=aPt2.X()) || (bLks1 && aTmpR1.Left()>=aPt2.X())) &&
+ ((bUnt2 && aTmpR2.Bottom()<=aPt1.Y()) || (bObn2 && aTmpR2.Top ()>=aPt1.Y()))) ||
+ (((bRts2 && aTmpR2.Right ()<=aPt1.X()) || (bLks2 && aTmpR2.Left()>=aPt1.X())) &&
+ ((bUnt1 && aTmpR1.Bottom()<=aPt2.Y()) || (bObn1 && aTmpR1.Top ()>=aPt2.Y())))) {
+ // Fall 3.2 trifft zu: Verbindung mit lediglich 2 Linien
+ bForceMeeting=TRUE;
+ bMeetingXMid=FALSE;
+ bMeetingYMid=FALSE;
+ if (bHor1) {
+ aMeeting.X()=aPt2.X();
+ aMeeting.Y()=aPt1.Y();
+ } else {
+ aMeeting.X()=aPt1.X();
+ aMeeting.Y()=aPt2.Y();
+ }
+ // Falls Ueberschneidung der BewareRects:
+ aBewareRect1=aTmpR1;
+ aBewareRect2=aTmpR2;
+ } else if ((((bRts1 && aBewareRect1.Right ()>aBewareRect2.Left ()) ||
+ (bLks1 && aBewareRect1.Left ()<aBewareRect2.Right ())) &&
+ ((bUnt2 && aBewareRect2.Bottom()>aBewareRect1.Top ()) ||
+ (bObn2 && aBewareRect2.Top ()<aBewareRect1.Bottom()))) ||
+ (((bRts2 && aBewareRect2.Right ()>aBewareRect1.Left ()) ||
+ (bLks2 && aBewareRect2.Left ()<aBewareRect1.Right ())) &&
+ ((bUnt1 && aBewareRect1.Bottom()>aBewareRect2.Top ()) ||
+ (bObn1 && aBewareRect1.Top ()<aBewareRect2.Bottom())))) {
+ // Fall 3.3
+ bForceMeeting=TRUE;
+ if (bRts1 || bRts2) { aMeeting.X()=nXMax; bMeetingXMid=FALSE; }
+ if (bLks1 || bLks2) { aMeeting.X()=nXMin; bMeetingXMid=FALSE; }
+ if (bUnt1 || bUnt2) { aMeeting.Y()=nYMax; bMeetingYMid=FALSE; }
+ if (bObn1 || bObn2) { aMeeting.Y()=nYMin; bMeetingYMid=FALSE; }
+ }
+ }
+ }
+
+ XPolygon aXP1(ImpCalcObjToCenter(aPt1,nAngle1,aBewareRect1,aMeeting));
+ XPolygon aXP2(ImpCalcObjToCenter(aPt2,nAngle2,aBewareRect2,aMeeting));
+ USHORT nXP1Anz=aXP1.GetPointCount();
+ USHORT nXP2Anz=aXP2.GetPointCount();
+ if (bInfo) {
+ pInfo->nObj1Lines=nXP1Anz; if (nXP1Anz>1) pInfo->nObj1Lines--;
+ pInfo->nObj2Lines=nXP2Anz; if (nXP2Anz>1) pInfo->nObj2Lines--;
+ }
+ Point aEP1(aXP1[nXP1Anz-1]);
+ Point aEP2(aXP2[nXP2Anz-1]);
+ FASTBOOL bInsMeetingPoint=aEP1.X()!=aEP2.X() && aEP1.Y()!=aEP2.Y();
+ FASTBOOL bHorzE1=aEP1.Y()==aXP1[nXP1Anz-2].Y(); // letzte Linie von XP1 horizontal?
+ FASTBOOL bHorzE2=aEP2.Y()==aXP2[nXP2Anz-2].Y(); // letzte Linie von XP2 horizontal?
+ if (aEP1==aEP2 && (bHorzE1 && bHorzE2 && aEP1.Y()==aEP2.Y()) || (!bHorzE1 && !bHorzE2 && aEP1.X()==aEP2.X())) {
+ // Sonderbehandlung fuer 'I'-Verbinder
+ nXP1Anz--; aXP1.Remove(nXP1Anz,1);
+ nXP2Anz--; aXP2.Remove(nXP2Anz,1);
+ bMeetingXMid=FALSE;
+ bMeetingYMid=FALSE;
+ }
+ if (bInsMeetingPoint) {
+ aXP1.Insert(XPOLY_APPEND,aMeeting,XPOLY_NORMAL);
+ if (bInfo) {
+ // Durch einfuegen des MeetingPoints kommen 2 weitere Linie hinzu.
+ // Evtl. wird eine von diesen die Mittellinie.
+ if (pInfo->nObj1Lines==pInfo->nObj2Lines) {
+ pInfo->nObj1Lines++;
+ pInfo->nObj2Lines++;
+ } else {
+ if (pInfo->nObj1Lines>pInfo->nObj2Lines) {
+ pInfo->nObj2Lines++;
+ pInfo->nMiddleLine=nXP1Anz-1;
+ } else {
+ pInfo->nObj1Lines++;
+ pInfo->nMiddleLine=nXP1Anz;
+ }
+ }
+ }
+ } else if (bInfo && aEP1!=aEP2 && nXP1Anz+nXP2Anz>=4) {
+ // Durch Verbinden der beiden Enden kommt eine weitere Linie hinzu.
+ // Dies wird die Mittellinie.
+ pInfo->nMiddleLine=nXP1Anz-1;
+ }
+ USHORT nNum=aXP2.GetPointCount();
+ if (aXP1[nXP1Anz-1]==aXP2[nXP2Anz-1] && nXP1Anz>1 && nXP2Anz>1) nNum--;
+ while (nNum>0) {
+ nNum--;
+ aXP1.Insert(XPOLY_APPEND,aXP2[nNum],XPOLY_NORMAL);
+ }
+ USHORT nPntAnz=aXP1.GetPointCount();
+ char cForm=0;
+ if (bInfo || pnQuality!=NULL) {
+ cForm='?';
+ if (nPntAnz==2) cForm='I';
+ else if (nPntAnz==3) cForm='L';
+ else if (nPntAnz==4) { // Z oder U
+ if (nAngle1==nAngle2) cForm='U';
+ else cForm='Z';
+ } else if (nPntAnz==4) { /* Ú-¿ Ú-¿ */
+ /* ... -Ù -Ù */
+ } else if (nPntAnz==6) { // S oder C oder ...
+ if (nAngle1!=nAngle2) {
+ // Fuer Typ S hat Linie2 dieselbe Richtung wie Linie4.
+ // Bei Typ C sind die beiden genau entgegengesetzt.
+ Point aP1(aXP1[1]);
+ Point aP2(aXP1[2]);
+ Point aP3(aXP1[3]);
+ Point aP4(aXP1[4]);
+ if (aP1.Y()==aP2.Y()) { // beide Linien Horz
+ if ((aP1.X()<aP2.X())==(aP3.X()<aP4.X())) cForm='S';
+ else cForm='C';
+ } else { // sonst beide Linien Vert
+ if ((aP1.Y()<aP2.Y())==(aP3.Y()<aP4.Y())) cForm='S';
+ else cForm='C';
+ }
+ } else cForm='4'; // sonst der 3. Fall mit 5 Linien
+ } else cForm='?'; //
+ // Weitere Formen:
+ if (bInfo) {
+ pInfo->cOrthoForm=cForm;
+ if (cForm=='I' || cForm=='L' || cForm=='Z' || cForm=='U') {
+ pInfo->nObj1Lines=1;
+ pInfo->nObj2Lines=1;
+ if (cForm=='Z' || cForm=='U') {
+ pInfo->nMiddleLine=1;
+ } else {
+ pInfo->nMiddleLine=0xFFFF;
+ }
+ } else if (cForm=='S' || cForm=='C') {
+ pInfo->nObj1Lines=2;
+ pInfo->nObj2Lines=2;
+ pInfo->nMiddleLine=2;
+ }
+ }
+ }
+ if (pnQuality!=NULL) {
+ ULONG nQual=0;
+ ULONG nQual0=nQual; // Ueberlaeufe vorbeugen
+ FASTBOOL bOverflow=FALSE;
+ Point aPt0(aXP1[0]);
+ for (USHORT nPntNum=1; nPntNum<nPntAnz; nPntNum++) {
+ Point aPt1b(aXP1[nPntNum]);
+ nQual+=Abs(aPt1b.X()-aPt0.X())+Abs(aPt1b.Y()-aPt0.Y());
+ if (nQual<nQual0) bOverflow=TRUE;
+ nQual0=nQual;
+ aPt0=aPt1b;
+ }
+
+ USHORT nTmp=nPntAnz;
+ if (cForm=='Z') {
+ nTmp=2; // Z-Form hat gute Qualitaet (nTmp=2 statt 4)
+ ULONG n1=Abs(aXP1[1].X()-aXP1[0].X())+Abs(aXP1[1].Y()-aXP1[0].Y());
+ ULONG n2=Abs(aXP1[2].X()-aXP1[1].X())+Abs(aXP1[2].Y()-aXP1[1].Y());
+ ULONG n3=Abs(aXP1[3].X()-aXP1[2].X())+Abs(aXP1[3].Y()-aXP1[2].Y());
+ // fuer moeglichst gleichlange Linien sorgen
+ ULONG nBesser=0;
+ n1+=n3;
+ n3=n2/4;
+ if (n1>=n2) nBesser=6;
+ else if (n1>=3*n3) nBesser=4;
+ else if (n1>=2*n3) nBesser=2;
+ if (aXP1[0].Y()!=aXP1[1].Y()) nBesser++; // Senkrechte Startlinie kriegt auch noch einen Pluspunkt (fuer H/V-Prio)
+ if (nQual>nBesser) nQual-=nBesser; else nQual=0;
+ }
+ if (nTmp>=3) {
+ nQual0=nQual;
+ nQual+=(ULONG)nTmp*0x01000000;
+ if (nQual<nQual0 || nTmp>15) bOverflow=TRUE;
+ }
+ if (nPntAnz>=2) { // Austrittswinkel nochmal pruefen
+ Point aP1(aXP1[1]); aP1-=aXP1[0];
+ Point aP2(aXP1[nPntAnz-2]); aP2-=aXP1[nPntAnz-1];
+ long nAng1=0; if (aP1.X()<0) nAng1=18000; if (aP1.Y()>0) nAng1=27000;
+ if (aP1.Y()<0) nAng1=9000; if (aP1.X()!=0 && aP1.Y()!=0) nAng1=1; // Schraeg!?!
+ long nAng2=0; if (aP2.X()<0) nAng2=18000; if (aP2.Y()>0) nAng2=27000;
+ if (aP2.Y()<0) nAng2=9000; if (aP2.X()!=0 && aP2.Y()!=0) nAng2=1; // Schraeg!?!
+ if (nAng1!=nAngle1) nIntersections++;
+ if (nAng2!=nAngle2) nIntersections++;
+ }
+
+ // Fuer den Qualitaetscheck wieder die Original-Rects verwenden und
+ // gleichzeitig checken, ob eins fuer die Edge-Berechnung verkleinert
+ // wurde (z.B. Fall 2.9)
+ aBewareRect1=rBewareRect1;
+ aBewareRect2=rBewareRect2;
+
+ for (USHORT i=0; i<nPntAnz; i++) {
+ Point aPt1b(aXP1[i]);
+ FASTBOOL b1=aPt1b.X()>aBewareRect1.Left() && aPt1b.X()<aBewareRect1.Right() &&
+ aPt1b.Y()>aBewareRect1.Top() && aPt1b.Y()<aBewareRect1.Bottom();
+ FASTBOOL b2=aPt1b.X()>aBewareRect2.Left() && aPt1b.X()<aBewareRect2.Right() &&
+ aPt1b.Y()>aBewareRect2.Top() && aPt1b.Y()<aBewareRect2.Bottom();
+ USHORT nInt0=nIntersections;
+ if (i==0 || i==nPntAnz-1) {
+ if (b1 && b2) nIntersections++;
+ } else {
+ if (b1) nIntersections++;
+ if (b2) nIntersections++;
+ }
+ // und nun noch auf Ueberschneidungen checken
+ if (i>0 && nInt0==nIntersections) {
+ if (aPt0.Y()==aPt1b.Y()) { // Horizontale Linie
+ if (aPt0.Y()>aBewareRect1.Top() && aPt0.Y()<aBewareRect1.Bottom() &&
+ ((aPt0.X()<=aBewareRect1.Left() && aPt1b.X()>=aBewareRect1.Right()) ||
+ (aPt1b.X()<=aBewareRect1.Left() && aPt0.X()>=aBewareRect1.Right()))) nIntersections++;
+ if (aPt0.Y()>aBewareRect2.Top() && aPt0.Y()<aBewareRect2.Bottom() &&
+ ((aPt0.X()<=aBewareRect2.Left() && aPt1b.X()>=aBewareRect2.Right()) ||
+ (aPt1b.X()<=aBewareRect2.Left() && aPt0.X()>=aBewareRect2.Right()))) nIntersections++;
+ } else { // Vertikale Linie
+ if (aPt0.X()>aBewareRect1.Left() && aPt0.X()<aBewareRect1.Right() &&
+ ((aPt0.Y()<=aBewareRect1.Top() && aPt1b.Y()>=aBewareRect1.Bottom()) ||
+ (aPt1b.Y()<=aBewareRect1.Top() && aPt0.Y()>=aBewareRect1.Bottom()))) nIntersections++;
+ if (aPt0.X()>aBewareRect2.Left() && aPt0.X()<aBewareRect2.Right() &&
+ ((aPt0.Y()<=aBewareRect2.Top() && aPt1b.Y()>=aBewareRect2.Bottom()) ||
+ (aPt1b.Y()<=aBewareRect2.Top() && aPt0.Y()>=aBewareRect2.Bottom()))) nIntersections++;
+ }
+ }
+ aPt0=aPt1b;
+ }
+ if (nPntAnz<=1) nIntersections++;
+ nQual0=nQual;
+ nQual+=(ULONG)nIntersections*0x10000000;
+ if (nQual<nQual0 || nIntersections>15) bOverflow=TRUE;
+
+ if (bOverflow || nQual==0xFFFFFFFF) nQual=0xFFFFFFFE;
+ *pnQuality=nQual;
+ }
+ if (bInfo) { // nun die Linienversaetze auf aXP1 anwenden
+ if (pInfo->nMiddleLine!=0xFFFF) {
+ USHORT nIdx=pInfo->ImpGetPolyIdx(MIDDLELINE,aXP1);
+ if (pInfo->ImpIsHorzLine(MIDDLELINE,aXP1)) {
+ aXP1[nIdx].Y()+=pInfo->aMiddleLine.Y();
+ aXP1[nIdx+1].Y()+=pInfo->aMiddleLine.Y();
+ } else {
+ aXP1[nIdx].X()+=pInfo->aMiddleLine.X();
+ aXP1[nIdx+1].X()+=pInfo->aMiddleLine.X();
+ }
+ }
+ if (pInfo->nObj1Lines>=2) {
+ USHORT nIdx=pInfo->ImpGetPolyIdx(OBJ1LINE2,aXP1);
+ if (pInfo->ImpIsHorzLine(OBJ1LINE2,aXP1)) {
+ aXP1[nIdx].Y()+=pInfo->aObj1Line2.Y();
+ aXP1[nIdx+1].Y()+=pInfo->aObj1Line2.Y();
+ } else {
+ aXP1[nIdx].X()+=pInfo->aObj1Line2.X();
+ aXP1[nIdx+1].X()+=pInfo->aObj1Line2.X();
+ }
+ }
+ if (pInfo->nObj1Lines>=3) {
+ USHORT nIdx=pInfo->ImpGetPolyIdx(OBJ1LINE3,aXP1);
+ if (pInfo->ImpIsHorzLine(OBJ1LINE3,aXP1)) {
+ aXP1[nIdx].Y()+=pInfo->aObj1Line3.Y();
+ aXP1[nIdx+1].Y()+=pInfo->aObj1Line3.Y();
+ } else {
+ aXP1[nIdx].X()+=pInfo->aObj1Line3.X();
+ aXP1[nIdx+1].X()+=pInfo->aObj1Line3.X();
+ }
+ }
+ if (pInfo->nObj2Lines>=2) {
+ USHORT nIdx=pInfo->ImpGetPolyIdx(OBJ2LINE2,aXP1);
+ if (pInfo->ImpIsHorzLine(OBJ2LINE2,aXP1)) {
+ aXP1[nIdx].Y()+=pInfo->aObj2Line2.Y();
+ aXP1[nIdx+1].Y()+=pInfo->aObj2Line2.Y();
+ } else {
+ aXP1[nIdx].X()+=pInfo->aObj2Line2.X();
+ aXP1[nIdx+1].X()+=pInfo->aObj2Line2.X();
+ }
+ }
+ if (pInfo->nObj2Lines>=3) {
+ USHORT nIdx=pInfo->ImpGetPolyIdx(OBJ2LINE3,aXP1);
+ if (pInfo->ImpIsHorzLine(OBJ2LINE3,aXP1)) {
+ aXP1[nIdx].Y()+=pInfo->aObj2Line3.Y();
+ aXP1[nIdx+1].Y()+=pInfo->aObj2Line3.Y();
+ } else {
+ aXP1[nIdx].X()+=pInfo->aObj2Line3.X();
+ aXP1[nIdx+1].X()+=pInfo->aObj2Line3.X();
+ }
+ }
+ }
+ // Nun mache ich ggf. aus dem Verbinder eine Bezierkurve
+ if (eKind==SDREDGE_BEZIER && nPntAnz>2) {
+ Point* pPt1=&aXP1[0];
+ Point* pPt2=&aXP1[1];
+ Point* pPt3=&aXP1[nPntAnz-2];
+ Point* pPt4=&aXP1[nPntAnz-1];
+ long dx1=pPt2->X()-pPt1->X();
+ long dy1=pPt2->Y()-pPt1->Y();
+ long dx2=pPt3->X()-pPt4->X();
+ long dy2=pPt3->Y()-pPt4->Y();
+ if (cForm=='L') { // nPntAnz==3
+ aXP1.SetFlags(1,XPOLY_CONTROL);
+ Point aPt3(*pPt2);
+ aXP1.Insert(2,aPt3,XPOLY_CONTROL);
+ nPntAnz=aXP1.GetPointCount();
+ pPt1=&aXP1[0];
+ pPt2=&aXP1[1];
+ pPt3=&aXP1[nPntAnz-2];
+ pPt4=&aXP1[nPntAnz-1];
+ pPt2->X()-=dx1/3;
+ pPt2->Y()-=dy1/3;
+ pPt3->X()-=dx2/3;
+ pPt3->Y()-=dy2/3;
+ } else if (nPntAnz>=4 && nPntAnz<=6) { // Z oder U oder ...
+ // fuer Alle Anderen werden die Endpunkte der Ausgangslinien
+ // erstmal zu Kontrollpunkten. Bei nPntAnz>4 ist also noch
+ // Nacharbeit erforderlich!
+ aXP1.SetFlags(1,XPOLY_CONTROL);
+ aXP1.SetFlags(nPntAnz-2,XPOLY_CONTROL);
+ // Distanz x1.5
+ pPt2->X()+=dx1/2;
+ pPt2->Y()+=dy1/2;
+ pPt3->X()+=dx2/2;
+ pPt3->Y()+=dy2/2;
+ if (nPntAnz==5) {
+ // Vor und hinter dem Mittelpunkt jeweils
+ // noch einen Kontrollpunkt einfuegen
+ Point aCenter(aXP1[2]);
+ long dx1b=aCenter.X()-aXP1[1].X();
+ long dy1b=aCenter.Y()-aXP1[1].Y();
+ long dx2b=aCenter.X()-aXP1[3].X();
+ long dy2b=aCenter.Y()-aXP1[3].Y();
+ aXP1.Insert(2,aCenter,XPOLY_CONTROL);
+ aXP1.SetFlags(3,XPOLY_SYMMTR);
+ aXP1.Insert(4,aCenter,XPOLY_CONTROL);
+ aXP1[2].X()-=dx1b/2;
+ aXP1[2].Y()-=dy1b/2;
+ aXP1[3].X()-=(dx1b+dx2b)/4;
+ aXP1[3].Y()-=(dy1b+dy2b)/4;
+ aXP1[4].X()-=dx2b/2;
+ aXP1[4].Y()-=dy2b/2;
+ }
+ if (nPntAnz==6) {
+ Point aPt1b(aXP1[2]);
+ Point aPt2b(aXP1[3]);
+ aXP1.Insert(2,aPt1b,XPOLY_CONTROL);
+ aXP1.Insert(5,aPt2b,XPOLY_CONTROL);
+ long dx=aPt1b.X()-aPt2b.X();
+ long dy=aPt1b.Y()-aPt2b.Y();
+ aXP1[3].X()-=dx/2;
+ aXP1[3].Y()-=dy/2;
+ aXP1.SetFlags(3,XPOLY_SYMMTR);
+ //aXP1[4].X()+=dx/2;
+ //aXP1[4].Y()+=dy/2;
+ aXP1.Remove(4,1); // weil identisch mit aXP1[3]
+ }
+ }
+ }
+ return aXP1;
+}
+
+/*
+Nach einer einfachen Rechnung koennte es max. 64 unterschiedliche Verlaeufe mit
+5 Linien, 32 mit 4 Linien, 16 mit 3, 8 mit 2 Linien und 4 mit 1 Linie geben=124.
+Normalisiert auf 1. Austrittswinkel nach rechts bleiben dann noch 31.
+Dann noch eine vertikale Spiegelung wegnormalisiert bleiben noch 16
+characteristische Verlaufszuege mit 1-5 Linien:
+Mit 1 Linie (Typ 'I'): --
+Mit 2 Linien (Typ 'L'): -Ù
+Mit 3 Linien (Typ 'U'): -¿ (Typ 'Z'): Ú-
+ -Ù -Ù
+Mit 4 Linien: 1 ist nicht plausibel, 3 ist=2 (90deg Drehung). Verbleibt 2,4
+ Ú-Ù Ú¿ À¿ Ú¿ Ú¿ Ú-¿
+ -Ù -Ù -Ù -Ù -Ù -Ù
+Mit 5 Linien: nicht plausibel sind 1,2,4,5. 7 ist identisch mit 3 (Richtungsumkehr)
+ Bleibt also 3,6 und 8. '4' 'S' 'C'
+ ¿ Ú -¿ Ú- Ú-¿ Ú-
+ Ú-Ù Ú-Ù Ú-¿ Ú-¿ À¿ À¿ -Ù ³ Ú-¿ Ú-¿ À¿ Ú-¿
+ -Ù -Ù -Ù Ù -Ù À- -Ù -Ù --Ù À Ù -Ù Ù -Ù À Ù
+Insgesamt sind also 9 Grundtypen zu unterscheiden die den 400 Konstellationen
+aus Objektposition und Austrittswinkeln zuzuordnen sind.
+4 der 9 Grundtypen haben eine 'Mittellinie'. Die Anzahl der zu Objektabstaende
+je Objekt variiert von 0-3:
+ Mi O1 O2 Anmerkung
+'I': n 0 0
+'L': n 0 0
+'U': n 0-1 0-1
+'Z': j 0 0
+4.1: j 0 1 = U+1 bzw. 1+U
+4.2: n 0-2 0-2 = Z+1
+'4': j 0 2 = Z+2
+'S': j 1 1 = 1+Z+1
+'C': n 0-3 0-3 = 1+U+1
+*/
+
+void __EXPORT SdrEdgeObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SfxSimpleHint* pSimple=PTR_CAST(SfxSimpleHint,&rHint);
+ ULONG nId=pSimple==0 ? 0 : pSimple->GetId();
+ FASTBOOL bDataChg=nId==SFX_HINT_DATACHANGED;
+ FASTBOOL bDying=nId==SFX_HINT_DYING;
+ FASTBOOL bObj1=aCon1.pObj!=NULL && aCon1.pObj->GetBroadcaster()==&rBC;
+ FASTBOOL bObj2=aCon2.pObj!=NULL && aCon2.pObj->GetBroadcaster()==&rBC;
+ if (bDying && (bObj1 || bObj2)) {
+ // #35605# Dying vorher abfangen, damit AttrObj nicht
+ // wg. vermeintlicher Vorlagenaenderung rumbroadcastet
+ if (bObj1) aCon1.pObj=NULL;
+ if (bObj2) aCon2.pObj=NULL;
+ return; // Und mehr braucht hier nicht getan werden.
+ }
+ if ( bObj1 || bObj2 )
+ {
+ bEdgeTrackUserDefined = sal_False;
+ }
+ SdrTextObj::Notify(rBC,rHint);
+ if (nNotifyingCount==0) { // Hier nun auch ein VerriegelungsFlag
+ ((SdrEdgeObj*)this)->nNotifyingCount++;
+ SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
+ if (bDataChg) { // StyleSheet geaendert
+ ImpSetAttrToEdgeInfo(); // Werte bei Vorlagenaenderung vom Pool nach aEdgeInfo kopieren
+ }
+ if (bDataChg ||
+ (bObj1 && aCon1.pObj->GetPage()==pPage) ||
+ (bObj2 && aCon2.pObj->GetPage()==pPage) ||
+ (pSdrHint && pSdrHint->GetKind()==HINT_OBJREMOVED))
+ {
+ // Broadcasting nur, wenn auf der selben Page
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 if (!bEdgeTrackDirty) SendRepaintBroadcast();
+ ImpDirtyEdgeTrack();
+
+ // only redraw here, no objectchange
+ ActionChanged();
+ // BroadcastObjectChange();
+
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+ ((SdrEdgeObj*)this)->nNotifyingCount--;
+ }
+}
+
+/** updates edges that are connected to the edges of this object
+ as if the connected objects send a repaint broadcast
+ #103122#
+*/
+void SdrEdgeObj::Reformat()
+{
+ if( NULL != aCon1.pObj )
+ {
+ SfxSimpleHint aHint( SFX_HINT_DATACHANGED );
+ Notify( *const_cast<SfxBroadcaster*>(aCon1.pObj->GetBroadcaster()), aHint );
+ }
+
+ if( NULL != aCon2.pObj )
+ {
+ SfxSimpleHint aHint( SFX_HINT_DATACHANGED );
+ Notify( *const_cast<SfxBroadcaster*>(aCon2.pObj->GetBroadcaster()), aHint );
+ }
+}
+
+void SdrEdgeObj::operator=(const SdrObject& rObj)
+{
+ SdrTextObj::operator=(rObj);
+ *pEdgeTrack =*((SdrEdgeObj&)rObj).pEdgeTrack;
+ bEdgeTrackDirty=((SdrEdgeObj&)rObj).bEdgeTrackDirty;
+ aCon1 =((SdrEdgeObj&)rObj).aCon1;
+ aCon2 =((SdrEdgeObj&)rObj).aCon2;
+ aCon1.pObj=NULL;
+ aCon2.pObj=NULL;
+ aEdgeInfo=((SdrEdgeObj&)rObj).aEdgeInfo;
+}
+
+void SdrEdgeObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulEDGE);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrEdgeObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralEDGE);
+}
+
+basegfx::B2DPolyPolygon SdrEdgeObj::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if (bEdgeTrackDirty)
+ {
+ ((SdrEdgeObj*)this)->ImpRecalcEdgeTrack();
+ }
+
+ if(pEdgeTrack)
+ {
+ aPolyPolygon.append(pEdgeTrack->getB2DPolygon());
+ }
+
+ return aPolyPolygon;
+}
+
+void SdrEdgeObj::SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly )
+{
+ if ( !rPoly.count() )
+ {
+ bEdgeTrackDirty = sal_True;
+ bEdgeTrackUserDefined = sal_False;
+ }
+ else
+ {
+ *pEdgeTrack = XPolygon( rPoly.getB2DPolygon( 0 ) );
+ bEdgeTrackDirty = sal_False;
+ bEdgeTrackUserDefined = sal_True;
+
+ // #i110629# also set aRect and maSnapeRect dependent from pEdgeTrack
+ const Rectangle aPolygonBounds(pEdgeTrack->GetBoundRect());
+ aRect = aPolygonBounds;
+ maSnapRect = aPolygonBounds;
+ }
+}
+
+basegfx::B2DPolyPolygon SdrEdgeObj::GetEdgeTrackPath() const
+{
+ basegfx::B2DPolyPolygon aPolyPolygon;
+
+ if (bEdgeTrackDirty)
+ ((SdrEdgeObj*)this)->ImpRecalcEdgeTrack();
+
+ aPolyPolygon.append( pEdgeTrack->getB2DPolygon() );
+
+ return aPolyPolygon;
+}
+
+sal_uInt32 SdrEdgeObj::GetHdlCount() const
+{
+ SdrEdgeKind eKind=((SdrEdgeKindItem&)(GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
+ sal_uInt32 nHdlAnz(0L);
+ sal_uInt32 nPntAnz(pEdgeTrack->GetPointCount());
+
+ if(nPntAnz)
+ {
+ nHdlAnz = 2L;
+
+ if ((eKind==SDREDGE_ORTHOLINES || eKind==SDREDGE_BEZIER) && nPntAnz >= 4L)
+ {
+ sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0L ? aEdgeInfo.nObj1Lines - 1L : 0L);
+ sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0L ? aEdgeInfo.nObj2Lines - 1L : 0L);
+ sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1L : 0L);
+ nHdlAnz += nO1 + nO2 + nM;
+ }
+ else if (eKind==SDREDGE_THREELINES && nPntAnz == 4L)
+ {
+ if(GetConnectedNode(TRUE))
+ nHdlAnz++;
+
+ if(GetConnectedNode(FALSE))
+ nHdlAnz++;
+ }
+ }
+
+ return nHdlAnz;
+}
+
+SdrHdl* SdrEdgeObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pHdl=NULL;
+ sal_uInt32 nPntAnz(pEdgeTrack->GetPointCount());
+ if (nPntAnz!=0) {
+ if (nHdlNum==0) {
+ pHdl=new ImpEdgeHdl((*pEdgeTrack)[0],HDL_POLY);
+ if (aCon1.pObj!=NULL && aCon1.bBestVertex) pHdl->Set1PixMore(TRUE);
+ } else if (nHdlNum==1) {
+ pHdl=new ImpEdgeHdl((*pEdgeTrack)[USHORT(nPntAnz-1)],HDL_POLY);
+ if (aCon2.pObj!=NULL && aCon2.bBestVertex) pHdl->Set1PixMore(TRUE);
+ } else {
+ SdrEdgeKind eKind=((SdrEdgeKindItem&)(GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
+ if (eKind==SDREDGE_ORTHOLINES || eKind==SDREDGE_BEZIER) {
+ sal_uInt32 nO1(aEdgeInfo.nObj1Lines > 0L ? aEdgeInfo.nObj1Lines - 1L : 0L);
+ sal_uInt32 nO2(aEdgeInfo.nObj2Lines > 0L ? aEdgeInfo.nObj2Lines - 1L : 0L);
+ sal_uInt32 nM(aEdgeInfo.nMiddleLine != 0xFFFF ? 1L : 0L);
+ sal_uInt32 nNum(nHdlNum - 2L);
+ sal_Int32 nPt(0L);
+ pHdl=new ImpEdgeHdl(Point(),HDL_POLY);
+ if (nNum<nO1) {
+ nPt=nNum+1L;
+ if (nNum==0) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ1LINE2);
+ if (nNum==1) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ1LINE3);
+ } else {
+ nNum=nNum-nO1;
+ if (nNum<nO2) {
+ nPt=nPntAnz-3-nNum;
+ if (nNum==0) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ2LINE2);
+ if (nNum==1) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ2LINE3);
+ } else {
+ nNum=nNum-nO2;
+ if (nNum<nM) {
+ nPt=aEdgeInfo.nMiddleLine;
+ ((ImpEdgeHdl*)pHdl)->SetLineCode(MIDDLELINE);
+ }
+ }
+ }
+ if (nPt>0) {
+ Point aPos((*pEdgeTrack)[(sal_uInt16)nPt]);
+ aPos+=(*pEdgeTrack)[(sal_uInt16)nPt+1];
+ aPos.X()/=2;
+ aPos.Y()/=2;
+ pHdl->SetPos(aPos);
+ } else {
+ delete pHdl;
+ pHdl=NULL;
+ }
+ } else if (eKind==SDREDGE_THREELINES) {
+ sal_uInt32 nNum(nHdlNum);
+ if (GetConnectedNode(TRUE)==NULL) nNum++;
+ Point aPos((*pEdgeTrack)[(sal_uInt16)nNum-1]);
+ pHdl=new ImpEdgeHdl(aPos,HDL_POLY);
+ if (nNum==2) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ1LINE2);
+ if (nNum==3) ((ImpEdgeHdl*)pHdl)->SetLineCode(OBJ2LINE2);
+ }
+ }
+ if (pHdl!=NULL) {
+ pHdl->SetPointNum(nHdlNum);
+ }
+ }
+ return pHdl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrEdgeObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+SdrObject* SdrEdgeObj::getFullDragClone() const
+{
+ // use Clone operator
+ SdrEdgeObj* pRetval = (SdrEdgeObj*)Clone();
+
+ // copy connections for clone, SdrEdgeObj::operator= does not do this
+ pRetval->ConnectToNode(true, GetConnectedNode(true));
+ pRetval->ConnectToNode(false, GetConnectedNode(false));
+
+ return pRetval;
+}
+
+bool SdrEdgeObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ if(!rDrag.GetHdl())
+ return false;
+
+ rDrag.SetEndDragChangesAttributes(true);
+
+ if(rDrag.GetHdl()->GetPointNum() < 2)
+ {
+ rDrag.SetNoSnap(true);
+ }
+
+ return true;
+}
+
+bool SdrEdgeObj::applySpecialDrag(SdrDragStat& rDragStat)
+{
+ SdrEdgeObj* pOriginalEdge = dynamic_cast< SdrEdgeObj* >(rDragStat.GetHdl()->GetObj());
+ const bool bOriginalEdgeModified(pOriginalEdge == this);
+
+ if(!bOriginalEdgeModified && pOriginalEdge)
+ {
+ // copy connections when clone is modified. This is needed because
+ // as preparation to this modification the data from the original object
+ // was copied to the clone using the operator=. As can be seen there,
+ // that operator does not copy the connections (for good reason)
+ ConnectToNode(true, pOriginalEdge->GetConnection(true).GetObject());
+ ConnectToNode(false, pOriginalEdge->GetConnection(false).GetObject());
+ }
+
+ if(rDragStat.GetHdl()->GetPointNum() < 2)
+ {
+ // start or end point connector drag
+ const bool bDragA(0 == rDragStat.GetHdl()->GetPointNum());
+ const Point aPointNow(rDragStat.GetNow());
+
+ if(rDragStat.GetPageView())
+ {
+ SdrObjConnection* pDraggedOne(bDragA ? &aCon1 : &aCon2);
+
+ // clear connection
+ DisconnectFromNode(bDragA);
+
+ // look for new connection
+ ImpFindConnector(aPointNow, *rDragStat.GetPageView(), *pDraggedOne, pOriginalEdge);
+
+ if(pDraggedOne->pObj)
+ {
+ // if found, officially connect to it; ImpFindConnector only
+ // sets pObj hard
+ SdrObject* pNewConnection = pDraggedOne->pObj;
+ pDraggedOne->pObj = 0;
+ ConnectToNode(bDragA, pNewConnection);
+ }
+
+ if(rDragStat.GetView() && !bOriginalEdgeModified)
+ {
+ // show IA helper, but only do this during IA, so not when the original
+ // Edge gets modified in the last call
+ rDragStat.GetView()->SetConnectMarker(*pDraggedOne, *rDragStat.GetPageView());
+ }
+ }
+
+ if(pEdgeTrack)
+ {
+ // change pEdgeTrack to modified position
+ if(bDragA)
+ {
+ (*pEdgeTrack)[0] = aPointNow;
+ }
+ else
+ {
+ (*pEdgeTrack)[sal_uInt16(pEdgeTrack->GetPointCount()-1)] = aPointNow;
+ }
+ }
+
+ // reset edge info's offsets, this is a end point drag
+ aEdgeInfo.aObj1Line2 = Point();
+ aEdgeInfo.aObj1Line3 = Point();
+ aEdgeInfo.aObj2Line2 = Point();
+ aEdgeInfo.aObj2Line3 = Point();
+ aEdgeInfo.aMiddleLine = Point();
+ }
+ else
+ {
+ // control point connector drag
+ const ImpEdgeHdl* pEdgeHdl = (ImpEdgeHdl*)rDragStat.GetHdl();
+ const SdrEdgeLineCode eLineCode = pEdgeHdl->GetLineCode();
+ const Point aDist(rDragStat.GetNow() - rDragStat.GetStart());
+ sal_Int32 nDist(pEdgeHdl->IsHorzDrag() ? aDist.X() : aDist.Y());
+
+ nDist += aEdgeInfo.ImpGetLineVersatz(eLineCode, *pEdgeTrack);
+ aEdgeInfo.ImpSetLineVersatz(eLineCode, *pEdgeTrack, nDist);
+ }
+
+ // force recalc EdgeTrack
+ *pEdgeTrack = ImpCalcEdgeTrack(*pEdgeTrack, aCon1, aCon2, &aEdgeInfo);
+ bEdgeTrackDirty=FALSE;
+
+ // save EdgeInfos and mark object as user modified
+ ImpSetEdgeInfoToAttr();
+ bEdgeTrackUserDefined = false;
+ //SetRectsDirty();
+ //SetChanged();
+
+ if(bOriginalEdgeModified && rDragStat.GetView())
+ {
+ // hide connect marker helper again when original gets changed.
+ // This happens at the end of the interaction
+ rDragStat.GetView()->HideConnectMarker();
+ }
+
+ return true;
+}
+
+String SdrEdgeObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment)
+ {
+ return String();
+ }
+ else
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_DragEdgeTail, aStr);
+
+ return aStr;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+basegfx::B2DPolygon SdrEdgeObj::ImplAddConnectorOverlay(SdrDragMethod& rDragMethod, bool bTail1, bool bTail2, bool bDetail) const
+{
+ basegfx::B2DPolygon aResult;
+
+ if(bDetail)
+ {
+ SdrObjConnection aMyCon1(aCon1);
+ SdrObjConnection aMyCon2(aCon2);
+
+ if (bTail1)
+ {
+ const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aMyCon1.aObjOfs.X(), aMyCon1.aObjOfs.Y()));
+ aMyCon1.aObjOfs.X() = basegfx::fround(aTemp.getX());
+ aMyCon1.aObjOfs.Y() = basegfx::fround(aTemp.getY());
+ }
+
+ if (bTail2)
+ {
+ const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aMyCon2.aObjOfs.X(), aMyCon2.aObjOfs.Y()));
+ aMyCon2.aObjOfs.X() = basegfx::fround(aTemp.getX());
+ aMyCon2.aObjOfs.Y() = basegfx::fround(aTemp.getY());
+ }
+
+ SdrEdgeInfoRec aInfo(aEdgeInfo);
+ XPolygon aXP(ImpCalcEdgeTrack(*pEdgeTrack, aMyCon1, aMyCon2, &aInfo));
+
+ if(aXP.GetPointCount())
+ {
+ aResult = aXP.getB2DPolygon();
+ }
+ }
+ else
+ {
+ Point aPt1((*pEdgeTrack)[0]);
+ Point aPt2((*pEdgeTrack)[sal_uInt16(pEdgeTrack->GetPointCount() - 1)]);
+
+ if (aCon1.pObj && (aCon1.bBestConn || aCon1.bBestVertex))
+ aPt1 = aCon1.pObj->GetSnapRect().Center();
+
+ if (aCon2.pObj && (aCon2.bBestConn || aCon2.bBestVertex))
+ aPt2 = aCon2.pObj->GetSnapRect().Center();
+
+ if (bTail1)
+ {
+ const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aPt1.X(), aPt1.Y()));
+ aPt1.X() = basegfx::fround(aTemp.getX());
+ aPt1.Y() = basegfx::fround(aTemp.getY());
+ }
+
+ if (bTail2)
+ {
+ const basegfx::B2DPoint aTemp(rDragMethod.getCurrentTransformation() * basegfx::B2DPoint(aPt2.X(), aPt2.Y()));
+ aPt2.X() = basegfx::fround(aTemp.getX());
+ aPt2.Y() = basegfx::fround(aTemp.getY());
+ }
+
+ aResult.append(basegfx::B2DPoint(aPt1.X(), aPt1.Y()));
+ aResult.append(basegfx::B2DPoint(aPt2.X(), aPt2.Y()));
+ }
+
+ return aResult;
+}
+
+FASTBOOL SdrEdgeObj::BegCreate(SdrDragStat& rDragStat)
+{
+ rDragStat.SetNoSnap(TRUE);
+ pEdgeTrack->SetPointCount(2);
+ (*pEdgeTrack)[0]=rDragStat.GetStart();
+ (*pEdgeTrack)[1]=rDragStat.GetNow();
+ if (rDragStat.GetPageView()!=NULL) {
+ ImpFindConnector(rDragStat.GetStart(),*rDragStat.GetPageView(),aCon1,this);
+ ConnectToNode(TRUE,aCon1.pObj);
+ }
+ *pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
+ return TRUE;
+}
+
+FASTBOOL SdrEdgeObj::MovCreate(SdrDragStat& rDragStat)
+{
+ USHORT nMax=pEdgeTrack->GetPointCount();
+ (*pEdgeTrack)[nMax-1]=rDragStat.GetNow();
+ if (rDragStat.GetPageView()!=NULL) {
+ ImpFindConnector(rDragStat.GetNow(),*rDragStat.GetPageView(),aCon2,this);
+ rDragStat.GetView()->SetConnectMarker(aCon2,*rDragStat.GetPageView());
+ }
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ ConnectToNode(FALSE,aCon2.pObj);
+ *pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
+ bEdgeTrackDirty=FALSE;
+ return TRUE;
+}
+
+FASTBOOL SdrEdgeObj::EndCreate(SdrDragStat& rDragStat, SdrCreateCmd eCmd)
+{
+ FASTBOOL bOk=(eCmd==SDRCREATE_FORCEEND || rDragStat.GetPointAnz()>=2);
+ if (bOk) {
+ ConnectToNode(TRUE,aCon1.pObj);
+ ConnectToNode(FALSE,aCon2.pObj);
+ if (rDragStat.GetView()!=NULL) {
+ rDragStat.GetView()->HideConnectMarker();
+ }
+ ImpSetEdgeInfoToAttr(); // Die Werte aus aEdgeInfo in den Pool kopieren
+ }
+ SetRectsDirty();
+ return bOk;
+}
+
+FASTBOOL SdrEdgeObj::BckCreate(SdrDragStat& rDragStat)
+{
+ if (rDragStat.GetView()!=NULL) {
+ rDragStat.GetView()->HideConnectMarker();
+ }
+ return FALSE;
+}
+
+void SdrEdgeObj::BrkCreate(SdrDragStat& rDragStat)
+{
+ if (rDragStat.GetView()!=NULL) {
+ rDragStat.GetView()->HideConnectMarker();
+ }
+}
+
+basegfx::B2DPolyPolygon SdrEdgeObj::TakeCreatePoly(const SdrDragStat& /*rStatDrag*/) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ aRetval.append(pEdgeTrack->getB2DPolygon());
+ return aRetval;
+}
+
+Pointer SdrEdgeObj::GetCreatePointer() const
+{
+ return Pointer(POINTER_DRAW_CONNECT);
+}
+
+FASTBOOL SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrObjConnection& rCon, const SdrEdgeObj* pThis, OutputDevice* pOut)
+{
+ rCon.ResetVars();
+ if (pOut==NULL) pOut=rPV.GetView().GetFirstOutputDevice(); // GetWin(0);
+ if (pOut==NULL) return FALSE;
+ SdrObjList* pOL=rPV.GetObjList();
+ const SetOfByte& rVisLayer=rPV.GetVisibleLayers();
+ // Sensitiver Bereich der Konnektoren ist doppelt so gross wie die Handles:
+ USHORT nMarkHdSiz=rPV.GetView().GetMarkHdlSizePixel();
+ Size aHalfConSiz(nMarkHdSiz,nMarkHdSiz);
+ aHalfConSiz=pOut->PixelToLogic(aHalfConSiz);
+ Size aHalfCenterSiz(2*aHalfConSiz.Width(),2*aHalfConSiz.Height());
+ Rectangle aMouseRect(rPt,rPt);
+ aMouseRect.Left() -=aHalfConSiz.Width();
+ aMouseRect.Top() -=aHalfConSiz.Height();
+ aMouseRect.Right() +=aHalfConSiz.Width();
+ aMouseRect.Bottom()+=aHalfConSiz.Height();
+ USHORT nBoundHitTol=(USHORT)aHalfConSiz.Width()/2; if (nBoundHitTol==0) nBoundHitTol=1;
+ ULONG no=pOL->GetObjCount();
+ FASTBOOL bFnd=FALSE;
+ SdrObjConnection aTestCon;
+ SdrObjConnection aBestCon;
+ FASTBOOL bTestBoundHit=FALSE;
+ //FASTBOOL bBestBoundHit=FALSE;
+
+ while (no>0 && !bFnd) {
+ // Problem: Gruppenobjekt mit verschiedenen Layern liefert LayerID 0 !!!!
+ no--;
+ SdrObject* pObj=pOL->GetObj(no);
+ if (rVisLayer.IsSet(pObj->GetLayer()) && pObj->IsVisible() && // only visible objects
+ (pThis==NULL || pObj!=(SdrObject*)pThis) && // nicht an mich selbst connecten
+ pObj->IsNode())
+ {
+ Rectangle aObjBound(pObj->GetCurrentBoundRect());
+ if (aObjBound.IsOver(aMouseRect)) {
+ aTestCon.ResetVars();
+ bTestBoundHit=FALSE;
+ FASTBOOL bEdge=HAS_BASE(SdrEdgeObj,pObj); // kein BestCon fuer Edge
+ // Die Userdefined Konnektoren haben absolute Prioritaet.
+ // Danach kommt Vertex, Corner und Mitte(Best) gleich priorisiert.
+ // Zum Schluss kommt noch ein HitTest aufs Obj.
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ USHORT nConAnz=pGPL==NULL ? 0 : pGPL->GetCount();
+ USHORT nGesAnz=nConAnz+9;
+ FASTBOOL bUserFnd=FALSE;
+ ULONG nBestDist=0xFFFFFFFF;
+ for (USHORT i=0; i<nGesAnz; i++)
+ {
+ FASTBOOL bUser=i<nConAnz;
+ FASTBOOL bVertex=i>=nConAnz+0 && i<nConAnz+4;
+ FASTBOOL bCorner=i>=nConAnz+4 && i<nConAnz+8;
+ FASTBOOL bCenter=i==nConAnz+8;
+ FASTBOOL bOk=FALSE;
+ Point aConPos;
+ USHORT nConNum=i;
+ if (bUser) {
+ const SdrGluePoint& rGP=(*pGPL)[nConNum];
+ aConPos=rGP.GetAbsolutePos(*pObj);
+ nConNum=rGP.GetId();
+ bOk=TRUE;
+ } else if (bVertex && !bUserFnd) {
+ nConNum=nConNum-nConAnz;
+ if (rPV.GetView().IsAutoVertexConnectors()) {
+ SdrGluePoint aPt(pObj->GetVertexGluePoint(nConNum));
+ aConPos=aPt.GetAbsolutePos(*pObj);
+ bOk=TRUE;
+ } else i+=3;
+ } else if (bCorner && !bUserFnd) {
+ nConNum-=nConAnz+4;
+ if (rPV.GetView().IsAutoCornerConnectors()) {
+ SdrGluePoint aPt(pObj->GetCornerGluePoint(nConNum));
+ aConPos=aPt.GetAbsolutePos(*pObj);
+ bOk=TRUE;
+ } else i+=3;
+ }
+ else if (bCenter && !bUserFnd && !bEdge)
+ {
+ // #109007#
+ // Suppress default connect at object center
+ if(!pThis || !pThis->GetSuppressDefaultConnect())
+ {
+ // Edges nicht!
+ nConNum=0;
+ aConPos=aObjBound.Center();
+ bOk=TRUE;
+ }
+ }
+ if (bOk && aMouseRect.IsInside(aConPos)) {
+ if (bUser) bUserFnd=TRUE;
+ bFnd=TRUE;
+ ULONG nDist=(ULONG)Abs(aConPos.X()-rPt.X())+(ULONG)Abs(aConPos.Y()-rPt.Y());
+ if (nDist<nBestDist) {
+ nBestDist=nDist;
+ aTestCon.pObj=pObj;
+ aTestCon.nConId=nConNum;
+ aTestCon.bAutoCorner=bCorner;
+ aTestCon.bAutoVertex=bVertex;
+ aTestCon.bBestConn=FALSE; // bCenter;
+ aTestCon.bBestVertex=bCenter;
+ }
+ }
+ }
+ // Falls kein Konnektor getroffen wird nochmal
+ // HitTest versucht fuer BestConnector (=bCenter)
+ if(!bFnd &&
+ !bEdge &&
+ SdrObjectPrimitiveHit(*pObj, rPt, nBoundHitTol, rPV, &rVisLayer, false))
+ {
+ // #109007#
+ // Suppress default connect at object inside bound
+ if(!pThis || !pThis->GetSuppressDefaultConnect())
+ {
+ bFnd=TRUE;
+ aTestCon.pObj=pObj;
+ aTestCon.bBestConn=TRUE;
+ }
+ }
+ if (bFnd) {
+ Rectangle aMouseRect2(rPt,rPt);
+ aMouseRect.Left() -=nBoundHitTol;
+ aMouseRect.Top() -=nBoundHitTol;
+ aMouseRect.Right() +=nBoundHitTol;
+ aMouseRect.Bottom()+=nBoundHitTol;
+ bTestBoundHit=aObjBound.IsOver(aMouseRect2);
+ }
+
+ }
+ }
+ }
+ rCon=aTestCon;
+ return bFnd;
+}
+
+void SdrEdgeObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ const Rectangle aOld(GetSnapRect());
+
+ if(aOld != rRect)
+ {
+ if(aRect.IsEmpty() && 0 == pEdgeTrack->GetPointCount())
+ {
+ // #i110629# When initializing, do not scale on empty Rectangle; this
+ // will mirror the underlying text object (!)
+ aRect = rRect;
+ maSnapRect = rRect;
+ }
+ else
+ {
+ long nMulX = rRect.Right() - rRect.Left();
+ long nDivX = aOld.Right() - aOld.Left();
+ long nMulY = rRect.Bottom() - rRect.Top();
+ long nDivY = aOld.Bottom() - aOld.Top();
+ if ( nDivX == 0 ) { nMulX = 1; nDivX = 1; }
+ if ( nDivY == 0 ) { nMulY = 1; nDivY = 1; }
+ Fraction aX(nMulX, nDivX);
+ Fraction aY(nMulY, nDivY);
+ NbcResize(aOld.TopLeft(), aX, aY);
+ NbcMove(Size(rRect.Left() - aOld.Left(), rRect.Top() - aOld.Top()));
+ }
+ }
+}
+
+void SdrEdgeObj::NbcMove(const Size& rSiz)
+{
+ SdrTextObj::NbcMove(rSiz);
+ MoveXPoly(*pEdgeTrack,rSiz);
+}
+
+void SdrEdgeObj::NbcResize(const Point& rRefPnt, const Fraction& aXFact, const Fraction& aYFact)
+{
+ SdrTextObj::NbcResize(rRefPnt,aXFact,aXFact);
+ ResizeXPoly(*pEdgeTrack,rRefPnt,aXFact,aYFact);
+
+ // #75371# if resize is not from paste, forget user distances
+ if(!GetModel()->IsPasteResize())
+ {
+ // #75735#
+ aEdgeInfo.aObj1Line2 = Point();
+ aEdgeInfo.aObj1Line3 = Point();
+ aEdgeInfo.aObj2Line2 = Point();
+ aEdgeInfo.aObj2Line3 = Point();
+ aEdgeInfo.aMiddleLine = Point();
+ }
+}
+
+SdrObject* SdrEdgeObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ basegfx::B2DPolyPolygon aPolyPolygon;
+ aPolyPolygon.append(pEdgeTrack->getB2DPolygon());
+ SdrObject* pRet = ImpConvertMakeObj(aPolyPolygon, sal_False, bBezier);
+ pRet = ImpConvertAddText(pRet, bBezier);
+
+ return pRet;
+}
+
+sal_uInt32 SdrEdgeObj::GetSnapPointCount() const
+{
+ return 2L;
+}
+
+Point SdrEdgeObj::GetSnapPoint(sal_uInt32 i) const
+{
+ ((SdrEdgeObj*)this)->ImpUndirtyEdgeTrack();
+ USHORT nAnz=pEdgeTrack->GetPointCount();
+ if (i==0) return (*pEdgeTrack)[0];
+ else return (*pEdgeTrack)[nAnz-1];
+}
+
+sal_Bool SdrEdgeObj::IsPolyObj() const
+{
+ return sal_False;
+}
+
+sal_uInt32 SdrEdgeObj::GetPointCount() const
+{
+ return 0L;
+}
+
+Point SdrEdgeObj::GetPoint(sal_uInt32 i) const
+{
+ ((SdrEdgeObj*)this)->ImpUndirtyEdgeTrack();
+ USHORT nAnz=pEdgeTrack->GetPointCount();
+ if (0L == i)
+ return (*pEdgeTrack)[0];
+ else
+ return (*pEdgeTrack)[nAnz-1];
+}
+
+void SdrEdgeObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
+{
+ // ToDo: Umconnekten fehlt noch
+ ImpUndirtyEdgeTrack();
+ USHORT nAnz=pEdgeTrack->GetPointCount();
+ if (0L == i)
+ (*pEdgeTrack)[0]=rPnt;
+ if (1L == i)
+ (*pEdgeTrack)[nAnz-1]=rPnt;
+ SetEdgeTrackDirty();
+ SetRectsDirty();
+}
+
+SdrEdgeObjGeoData::SdrEdgeObjGeoData()
+{
+ pEdgeTrack=new XPolygon;
+}
+
+SdrEdgeObjGeoData::~SdrEdgeObjGeoData()
+{
+ delete pEdgeTrack;
+}
+
+SdrObjGeoData* SdrEdgeObj::NewGeoData() const
+{
+ return new SdrEdgeObjGeoData;
+}
+
+void SdrEdgeObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrTextObj::SaveGeoData(rGeo);
+ SdrEdgeObjGeoData& rEGeo=(SdrEdgeObjGeoData&)rGeo;
+ rEGeo.aCon1 =aCon1;
+ rEGeo.aCon2 =aCon2;
+ *rEGeo.pEdgeTrack =*pEdgeTrack;
+ rEGeo.bEdgeTrackDirty=bEdgeTrackDirty;
+ rEGeo.bEdgeTrackUserDefined=bEdgeTrackUserDefined;
+ rEGeo.aEdgeInfo =aEdgeInfo;
+}
+
+void SdrEdgeObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrTextObj::RestGeoData(rGeo);
+ SdrEdgeObjGeoData& rEGeo=(SdrEdgeObjGeoData&)rGeo;
+ if (aCon1.pObj!=rEGeo.aCon1.pObj) {
+ if (aCon1.pObj!=NULL) aCon1.pObj->RemoveListener(*this);
+ aCon1=rEGeo.aCon1;
+ if (aCon1.pObj!=NULL) aCon1.pObj->AddListener(*this);
+ }
+ if (aCon2.pObj!=rEGeo.aCon2.pObj) {
+ if (aCon2.pObj!=NULL) aCon2.pObj->RemoveListener(*this);
+ aCon2=rEGeo.aCon2;
+ if (aCon2.pObj!=NULL) aCon2.pObj->AddListener(*this);
+ }
+ *pEdgeTrack =*rEGeo.pEdgeTrack;
+ bEdgeTrackDirty=rEGeo.bEdgeTrackDirty;
+ bEdgeTrackUserDefined=rEGeo.bEdgeTrackUserDefined;
+ aEdgeInfo =rEGeo.aEdgeInfo;
+}
+
+Point SdrEdgeObj::GetTailPoint( BOOL bTail ) const
+{
+ if( pEdgeTrack && pEdgeTrack->GetPointCount()!=0)
+ {
+ const XPolygon& rTrack0 = *pEdgeTrack;
+ if(bTail)
+ {
+ return rTrack0[0];
+ }
+ else
+ {
+ const USHORT nSiz = rTrack0.GetPointCount() - 1;
+ return rTrack0[nSiz];
+ }
+ }
+ else
+ {
+ if(bTail)
+ return aOutRect.TopLeft();
+ else
+ return aOutRect.BottomRight();
+ }
+
+}
+
+void SdrEdgeObj::SetTailPoint( BOOL bTail, const Point& rPt )
+{
+ ImpSetTailPoint( bTail, rPt );
+ SetChanged();
+}
+
+/** this method is used by the api to set a glue point for a connection
+ nId == -1 : The best default point is automaticly choosen
+ 0 <= nId <= 3 : One of the default points is choosen
+ nId >= 4 : A user defined glue point is choosen
+*/
+void SdrEdgeObj::setGluePointIndex( sal_Bool bTail, sal_Int32 nIndex /* = -1 */ )
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetCurrentBoundRect();
+ // #110094#-14 BroadcastObjectChange();
+
+ SdrObjConnection& rConn1 = GetConnection( bTail );
+
+ rConn1.SetAutoVertex( nIndex >= 0 && nIndex <= 3 );
+ rConn1.SetBestConnection( nIndex < 0 );
+ rConn1.SetBestVertex( nIndex < 0 );
+
+ if( nIndex > 3 )
+ {
+// nIndex -= 4;
+ nIndex -= 3; // SJ: the start api index is 0, whereas the implementation in svx starts from 1
+
+ // for user defined glue points we have
+ // to get the id for this index first
+ const SdrGluePointList* pList = rConn1.GetObject() ? rConn1.GetObject()->GetGluePointList() : NULL;
+ if( pList == NULL || SDRGLUEPOINT_NOTFOUND == pList->FindGluePoint((sal_uInt16)nIndex) )
+ return;
+ }
+ else if( nIndex < 0 )
+ {
+ nIndex = 0;
+ }
+
+ rConn1.SetConnectorId( (USHORT)nIndex );
+
+ SetChanged();
+ SetRectsDirty();
+ ImpRecalcEdgeTrack();
+ // bEdgeTrackDirty=TRUE;
+}
+
+/** this method is used by the api to return a glue point id for a connection.
+ See setGluePointId for possible return values */
+sal_Int32 SdrEdgeObj::getGluePointIndex( sal_Bool bTail )
+{
+ SdrObjConnection& rConn1 = GetConnection( bTail );
+ sal_Int32 nId = -1;
+ if( !rConn1.IsBestConnection() )
+ {
+ nId = rConn1.GetConnectorId();
+ if( !rConn1.IsAutoVertex() )
+// nId += 4;
+ nId += 3; // SJ: the start api index is 0, whereas the implementation in svx starts from 1
+ }
+ return nId;
+}
+
+// #102344# Implementation was missing; edge track needs to be invalidated additionally.
+void SdrEdgeObj::NbcSetAnchorPos(const Point& rPnt)
+{
+ // call parent functionality
+ SdrTextObj::NbcSetAnchorPos(rPnt);
+
+ // Additionally, invalidate edge track
+ ImpDirtyEdgeTrack();
+}
+
+sal_Bool SdrEdgeObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const
+{
+ // use base method from SdrObject, it's not rotatable and
+ // a call to GetSnapRect() is used. That's what we need for Connector.
+ return SdrObject::TRGetBaseGeometry(rMatrix, rPolyPolygon);
+}
+
+void SdrEdgeObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ // evtl. take care for existing connections. For now, just use the
+ // implementation from SdrObject.
+ SdrObject::TRSetBaseGeometry(rMatrix, rPolyPolygon);
+}
+
+// for geometry access
+::basegfx::B2DPolygon SdrEdgeObj::getEdgeTrack() const
+{
+ if(bEdgeTrackDirty)
+ {
+ const_cast< SdrEdgeObj* >(this)->ImpRecalcEdgeTrack();
+ }
+
+ if(pEdgeTrack)
+ {
+ return pEdgeTrack->getB2DPolygon();
+ }
+ else
+ {
+ return ::basegfx::B2DPolygon();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
new file mode 100644
index 000000000000..d1f65c30050d
--- /dev/null
+++ b/svx/source/svdraw/svdograf.cxx
@@ -0,0 +1,1282 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#define _ANIMATION
+#include <unotools/streamwrap.hxx>
+
+#include <sfx2/lnkbase.hxx>
+#include <math.h>
+#include <vcl/salbtype.hxx>
+#include <sot/formats.hxx>
+#include <sot/storage.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <svl/style.hxx>
+#include <svtools/filter.hxx>
+#include <svl/urihelper.hxx>
+#include <svtools/grfmgr.hxx>
+#include <vcl/svapp.hxx>
+
+#include <sfx2/linkmgr.hxx>
+#include <svx/svdetc.hxx>
+#include "svdglob.hxx"
+#include "svdstr.hrc"
+#include <svx/svdpool.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdpagv.hxx>
+#include "svdviter.hxx"
+#include <svx/svdview.hxx>
+#include "svtools/filter.hxx"
+#include <svx/svdograf.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/xbitmap.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/svdundo.hxx>
+#include "svdfmtf.hxx"
+#include <svx/sdgcpitm.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/sdr/properties/graphicproperties.hxx>
+#include <svx/sdr/contact/viewcontactofgraphic.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+
+// -----------
+// - Defines -
+// -----------
+
+#define GRAFSTREAMPOS_INVALID 0xffffffff
+#define SWAPGRAPHIC_TIMEOUT 5000
+
+// ------------------
+// - SdrGraphicLink -
+// ------------------
+
+class SdrGraphicLink : public sfx2::SvBaseLink
+{
+ SdrGrafObj* pGrafObj;
+
+public:
+ SdrGraphicLink(SdrGrafObj* pObj);
+ virtual ~SdrGraphicLink();
+
+ virtual void Closed();
+ virtual void DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+
+ BOOL Connect() { return 0 != GetRealObject(); }
+ void UpdateSynchron();
+};
+
+// -----------------------------------------------------------------------------
+
+SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj):
+ ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ),
+ pGrafObj(pObj)
+{
+ SetSynchron( FALSE );
+}
+
+// -----------------------------------------------------------------------------
+
+SdrGraphicLink::~SdrGraphicLink()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGraphicLink::DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue )
+{
+ SdrModel* pModel = pGrafObj ? pGrafObj->GetModel() : 0;
+ sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
+
+ if( pLinkManager && rValue.hasValue() )
+ {
+ pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );
+
+ Graphic aGraphic;
+ if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
+ {
+ pGrafObj->NbcSetGraphic( aGraphic );
+ pGrafObj->ActionChanged();
+ }
+ else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
+ {
+ // only repaint, no objectchange
+ pGrafObj->ActionChanged();
+ // pGrafObj->BroadcastObjectChange();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGraphicLink::Closed()
+{
+ // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
+ pGrafObj->ForceSwapIn();
+ pGrafObj->pGraphicLink=NULL;
+ pGrafObj->ReleaseGraphicLink();
+ SvBaseLink::Closed();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGraphicLink::UpdateSynchron()
+{
+ if( GetObj() )
+ {
+ String aMimeType( SotExchange::GetFormatMimeType( GetContentType() ));
+ ::com::sun::star::uno::Any aValue;
+ GetObj()->GetData( aValue, aMimeType, TRUE );
+ DataChanged( aMimeType, aValue );
+ }
+}
+
+// --------------
+// - SdrGrafObj -
+// --------------
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::GraphicProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfGraphic(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrGrafObj,SdrRectObj);
+
+// -----------------------------------------------------------------------------
+
+SdrGrafObj::SdrGrafObj()
+: SdrRectObj(),
+ pGraphicLink ( NULL ),
+ bMirrored ( FALSE )
+{
+ pGraphic = new GraphicObject;
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
+ bNoShear = TRUE;
+
+ // #111096#
+ mbGrafAnimationAllowed = sal_True;
+
+ // #i25616#
+ mbLineIsOutsideGeometry = sal_True;
+ mbInsidePaint = sal_False;
+ mbIsPreview = sal_False;
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
+: SdrRectObj ( rRect ),
+ pGraphicLink ( NULL ),
+ bMirrored ( FALSE )
+{
+ pGraphic = new GraphicObject( rGrf );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
+ bNoShear = TRUE;
+
+ // #111096#
+ mbGrafAnimationAllowed = sal_True;
+
+ // #i25616#
+ mbLineIsOutsideGeometry = sal_True;
+ mbInsidePaint = sal_False;
+ mbIsPreview = sal_False;
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
+: SdrRectObj(),
+ pGraphicLink ( NULL ),
+ bMirrored ( FALSE )
+{
+ pGraphic = new GraphicObject( rGrf );
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
+ bNoShear = TRUE;
+
+ // #111096#
+ mbGrafAnimationAllowed = sal_True;
+
+ // #i25616#
+ mbLineIsOutsideGeometry = sal_True;
+ mbInsidePaint = sal_False;
+ mbIsPreview = sal_False;
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+}
+
+// -----------------------------------------------------------------------------
+
+SdrGrafObj::~SdrGrafObj()
+{
+ delete pGraphic;
+ ImpLinkAbmeldung();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
+{
+ *pGraphic = rGrfObj;
+ pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
+ pGraphic->SetUserData();
+ mbIsPreview = sal_False;
+ SetChanged();
+ BroadcastObjectChange();
+}
+
+// -----------------------------------------------------------------------------
+
+const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
+{
+ if(bForceSwapIn)
+ {
+ ForceSwapIn();
+ }
+
+ return *pGraphic;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
+{
+ pGraphic->SetGraphic( rGrf );
+ pGraphic->SetUserData();
+ mbIsPreview = sal_False;
+}
+
+void SdrGrafObj::SetGraphic( const Graphic& rGrf )
+{
+ NbcSetGraphic(rGrf);
+ SetChanged();
+ BroadcastObjectChange();
+}
+
+// -----------------------------------------------------------------------------
+
+const Graphic& SdrGrafObj::GetGraphic() const
+{
+ ForceSwapIn();
+ return pGraphic->GetGraphic();
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic SdrGrafObj::GetTransformedGraphic( ULONG nTransformFlags ) const
+{
+ // #107947# Refactored most of the code to GraphicObject, where
+ // everybody can use e.g. the cropping functionality
+
+ GraphicType eType = GetGraphicType();
+ MapMode aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
+ const Size aDestSize( GetLogicRect().GetSize() );
+ const BOOL bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0;
+ const BOOL bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) &&
+ ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType );
+
+ // #104115# Need cropping info earlier
+ ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();
+ GraphicAttr aActAttr;
+
+ if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags &&
+ GRAPHIC_NONE != eType )
+ {
+ // actually transform the graphic only in this case. On the
+ // other hand, cropping will always happen
+ aActAttr = aGrafInfo;
+
+ if( bMirror )
+ {
+ USHORT nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
+ FASTBOOL bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
+ FASTBOOL bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
+
+ aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
+ }
+
+ if( bRotate )
+ aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) );
+ }
+
+ // #107947# Delegate to moved code in GraphicObject
+ return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicType SdrGrafObj::GetGraphicType() const
+{
+ return pGraphic->GetType();
+}
+
+sal_Bool SdrGrafObj::IsAnimated() const
+{
+ return pGraphic->IsAnimated();
+}
+
+sal_Bool SdrGrafObj::IsEPS() const
+{
+ return pGraphic->IsEPS();
+}
+
+sal_Bool SdrGrafObj::IsSwappedOut() const
+{
+ return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
+}
+
+const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
+{
+ return pGraphic->GetPrefMapMode();
+}
+
+const Size& SdrGrafObj::GetGrafPrefSize() const
+{
+ return pGraphic->GetPrefSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
+{
+ mbIsPreview = sal_False;
+ if( !rGraphicStreamURL.Len() )
+ {
+ pGraphic->SetUserData();
+ }
+ else if( pModel->IsSwapGraphics() )
+ {
+ pGraphic->SetUserData( rGraphicStreamURL );
+
+ // set state of graphic object to 'swapped out'
+ if( pGraphic->GetType() == GRAPHIC_NONE )
+ pGraphic->SetSwapState();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+String SdrGrafObj::GetGrafStreamURL() const
+{
+ return pGraphic->GetUserData();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetFileName(const String& rFileName)
+{
+ aFileName = rFileName;
+ SetChanged();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetFilterName(const String& rFilterName)
+{
+ aFilterName = rFilterName;
+ SetChanged();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ForceSwapIn() const
+{
+ if( mbIsPreview )
+ {
+ // removing preview graphic
+ const String aUserData( pGraphic->GetUserData() );
+
+ Graphic aEmpty;
+ pGraphic->SetGraphic( aEmpty );
+ pGraphic->SetUserData( aUserData );
+ pGraphic->SetSwapState();
+
+ const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False;
+ }
+
+ pGraphic->FireSwapInRequest();
+
+ if( pGraphic->IsSwappedOut() ||
+ ( pGraphic->GetType() == GRAPHIC_NONE ) ||
+ ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
+ {
+ Graphic aDefaultGraphic;
+ aDefaultGraphic.SetDefaultType();
+ pGraphic->SetGraphic( aDefaultGraphic );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ForceSwapOut() const
+{
+ pGraphic->FireSwapOutRequest();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ImpLinkAnmeldung()
+{
+ sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
+
+ if( pLinkManager != NULL && pGraphicLink == NULL )
+ {
+ if( aFileName.Len() )
+ {
+ pGraphicLink = new SdrGraphicLink( this );
+ pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
+ pGraphicLink->Connect();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ImpLinkAbmeldung()
+{
+ sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
+
+ if( pLinkManager != NULL && pGraphicLink!=NULL)
+ {
+ // Bei Remove wird *pGraphicLink implizit deleted
+ pLinkManager->Remove( pGraphicLink );
+ pGraphicLink=NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
+{
+ ImpLinkAbmeldung();
+ aFileName = rFileName;
+ aFilterName = rFilterName;
+ ImpLinkAnmeldung();
+ pGraphic->SetUserData();
+
+ // #92205# A linked graphic is per definition swapped out (has to be loaded)
+ pGraphic->SetSwapState();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ReleaseGraphicLink()
+{
+ ImpLinkAbmeldung();
+ aFileName = String();
+ aFilterName = String();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ FASTBOOL bAnim = pGraphic->IsAnimated();
+ FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
+
+ rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
+ aGeo.nDrehWink % 18000 == 0 ||
+ aGeo.nDrehWink % 27000 == 0;
+
+ rInfo.bResizePropAllowed = TRUE;
+ rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim;
+ rInfo.bRotate90Allowed = bNoPresGrf && !bAnim;
+ rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim;
+ rInfo.bMirror45Allowed = bNoPresGrf && !bAnim;
+ rInfo.bMirror90Allowed = !bEmptyPresObj;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed = FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bCanConvToPath = FALSE;
+ rInfo.bCanConvToPathLineToArea = FALSE;
+ rInfo.bCanConvToPolyLineToArea = FALSE;
+ rInfo.bCanConvToPoly = !IsEPS();
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+// -----------------------------------------------------------------------------
+
+UINT16 SdrGrafObj::GetObjIdentifier() const
+{
+ return UINT16( OBJ_GRAF );
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SdrGrafObj::ImpUpdateGraphicLink() const
+{
+ sal_Bool bRet = sal_False;
+
+ if( pGraphicLink )
+ {
+ const sal_Bool bIsChanged = pModel->IsChanged();
+ pGraphicLink->UpdateSynchron();
+ pModel->SetChanged( bIsChanged );
+
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
+{
+ switch( pGraphic->GetType() )
+ {
+ case GRAPHIC_BITMAP:
+ {
+ const USHORT nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
+ ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
+ ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
+
+ rName=ImpGetResStr( nId );
+ }
+ break;
+
+ case GRAPHIC_GDIMETAFILE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
+ break;
+
+ case GRAPHIC_NONE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
+ break;
+
+ default:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
+ break;
+ }
+
+ const String aName(GetName());
+
+ if( aName.Len() )
+ {
+ rName.AppendAscii( " '" );
+ rName += aName;
+ rName += sal_Unicode( '\'' );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
+{
+ switch( pGraphic->GetType() )
+ {
+ case GRAPHIC_BITMAP:
+ {
+ const USHORT nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
+ ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
+ ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
+
+ rName=ImpGetResStr( nId );
+ }
+ break;
+
+ case GRAPHIC_GDIMETAFILE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
+ break;
+
+ case GRAPHIC_NONE:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
+ break;
+
+ default:
+ rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
+ break;
+ }
+
+ const String aName(GetName());
+
+ if( aName.Len() )
+ {
+ rName.AppendAscii( " '" );
+ rName += aName;
+ rName += sal_Unicode( '\'' );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+SdrObject* SdrGrafObj::getFullDragClone() const
+{
+ // call parent
+ SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
+
+ // #i103116# the full drag clone leads to problems
+ // with linked graphics, so reset the link in this
+ // temporary interaction object and load graphic
+ if(pRetval && IsLinkedGraphic())
+ {
+ pRetval->ForceSwapIn();
+ pRetval->ReleaseGraphicLink();
+ }
+
+ return pRetval;
+}
+
+void SdrGrafObj::operator=( const SdrObject& rObj )
+{
+ SdrRectObj::operator=( rObj );
+
+ const SdrGrafObj& rGraf = (SdrGrafObj&) rObj;
+
+ pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() );
+ aCropRect = rGraf.aCropRect;
+ aFileName = rGraf.aFileName;
+ aFilterName = rGraf.aFilterName;
+ bMirrored = rGraf.bMirrored;
+
+ if( rGraf.pGraphicLink != NULL)
+ {
+ SetGraphicLink( aFileName, aFilterName );
+ }
+
+ ImpSetAttrToGrafInfo();
+}
+
+// -----------------------------------------------------------------------------
+// #i25616#
+
+basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
+{
+ if(mbInsidePaint)
+ {
+ basegfx::B2DPolyPolygon aRetval;
+
+ // take grown rectangle
+ const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
+ const Rectangle aGrownRect(
+ aRect.Left() - nHalfLineWidth,
+ aRect.Top() - nHalfLineWidth,
+ aRect.Right() + nHalfLineWidth,
+ aRect.Bottom() + nHalfLineWidth);
+
+ XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
+ aRetval.append(aXPoly.getB2DPolygon());
+
+ return aRetval;
+ }
+ else
+ {
+ // call parent
+ return SdrRectObj::TakeXorPoly();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+sal_uInt32 SdrGrafObj::GetHdlCount() const
+{
+ return 8L;
+}
+
+// -----------------------------------------------------------------------------
+
+SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ return SdrRectObj::GetHdl( nHdlNum + 1L );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ SdrRectObj::NbcResize( rRef, xFact, yFact );
+
+ FASTBOOL bMirrX = xFact.GetNumerator() < 0;
+ FASTBOOL bMirrY = yFact.GetNumerator() < 0;
+
+ if( bMirrX != bMirrY )
+ bMirrored = !bMirrored;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SdrRectObj::NbcRotate(rRef,nWink,sn,cs);
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SdrRectObj::NbcMirror(rRef1,rRef2);
+ bMirrored = !bMirrored;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SdrRectObj::NbcRotate( rRef, nWink, tn, bVShear );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ SdrRectObj::NbcSetSnapRect(rRect);
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
+{
+ //FASTBOOL bChg=rRect.GetSize()!=aRect.GetSize();
+ SdrRectObj::NbcSetLogicRect(rRect);
+}
+
+// -----------------------------------------------------------------------------
+
+SdrObjGeoData* SdrGrafObj::NewGeoData() const
+{
+ return new SdrGrafObjGeoData;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrRectObj::SaveGeoData(rGeo);
+ SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
+ rGGeo.bMirrored=bMirrored;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ //long nDrehMerk = aGeo.nDrehWink;
+ //long nShearMerk = aGeo.nShearWink;
+ //FASTBOOL bMirrMerk = bMirrored;
+ Size aSizMerk( aRect.GetSize() );
+
+ SdrRectObj::RestGeoData(rGeo);
+ SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
+ bMirrored=rGGeo.bMirrored;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetPage( SdrPage* pNewPage )
+{
+ FASTBOOL bRemove = pNewPage == NULL && pPage != NULL;
+ FASTBOOL bInsert = pNewPage != NULL && pPage == NULL;
+
+ if( bRemove )
+ {
+ // hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert.
+ if( pGraphic->IsAnimated())
+ pGraphic->StopAnimation();
+
+ if( pGraphicLink != NULL )
+ ImpLinkAbmeldung();
+ }
+
+ SdrRectObj::SetPage( pNewPage );
+
+ if(aFileName.Len() && bInsert)
+ ImpLinkAnmeldung();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::SetModel( SdrModel* pNewModel )
+{
+ FASTBOOL bChg = pNewModel != pModel;
+
+ if( bChg )
+ {
+ if( pGraphic->HasUserData() )
+ {
+ ForceSwapIn();
+ pGraphic->SetUserData();
+ }
+
+ if( pGraphicLink != NULL )
+ ImpLinkAbmeldung();
+ }
+
+ // Model umsetzen
+ SdrRectObj::SetModel(pNewModel);
+
+ if( bChg && aFileName.Len() )
+ ImpLinkAnmeldung();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
+{
+ // #111096#
+ // use new graf animation
+ SetGrafAnimationAllowed(sal_True);
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
+{
+ // #111096#
+ // use new graf animation
+ SetGrafAnimationAllowed(sal_False);
+}
+
+// -----------------------------------------------------------------------------
+
+FASTBOOL SdrGrafObj::HasGDIMetaFile() const
+{
+ return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
+}
+
+// -----------------------------------------------------------------------------
+
+const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
+{
+ DBG_ERROR( "Invalid return value! Don't use it! (KA)" );
+ return &GetGraphic().GetGDIMetaFile();
+}
+
+// -----------------------------------------------------------------------------
+
+SdrObject* SdrGrafObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ SdrObject* pRetval = NULL;
+
+ switch( GetGraphicType() )
+ {
+ case GRAPHIC_GDIMETAFILE:
+ {
+ // NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern
+ SdrObjGroup* pGrp = new SdrObjGroup();
+ ImpSdrGDIMetaFileImport aFilter(*GetModel());
+ Point aOutPos( aRect.TopLeft() );
+ const Size aOutSiz( aRect.GetSize() );
+
+ aFilter.SetScaleRect(GetSnapRect());
+ aFilter.SetLayer(GetLayer());
+
+ UINT32 nInsAnz = aFilter.DoImport(GetTransformedGraphic().GetGDIMetaFile(), *pGrp->GetSubList(), 0);
+ if(nInsAnz)
+ {
+ pRetval = pGrp;
+ pGrp->NbcSetLayer(GetLayer());
+ pGrp->SetModel(GetModel());
+ pRetval = ImpConvertAddText(pRetval, bBezier);
+
+ // convert all children
+ if( pRetval )
+ {
+ SdrObject* pHalfDone = pRetval;
+ pRetval = pHalfDone->DoConvertToPolyObj(bBezier);
+ SdrObject::Free( pHalfDone ); // resulting object is newly created
+
+ if( pRetval )
+ {
+ // flatten subgroups. As we call
+ // DoConvertToPolyObj() on the resulting group
+ // objects, subgroups can exist (e.g. text is
+ // a group object for every line).
+ SdrObjList* pList = pRetval->GetSubList();
+ if( pList )
+ pList->FlattenGroups();
+ }
+ }
+ }
+ else
+ delete pGrp;
+ break;
+ }
+ case GRAPHIC_BITMAP:
+ {
+ // Grundobjekt kreieren und Fuellung ergaenzen
+ pRetval = SdrRectObj::DoConvertToPolyObj(bBezier);
+
+ // Bitmap als Attribut retten
+ if(pRetval)
+ {
+ // Bitmap als Fuellung holen
+ SfxItemSet aSet(GetObjectItemSet());
+
+ aSet.Put(XFillStyleItem(XFILL_BITMAP));
+ Bitmap aBitmap( GetTransformedGraphic().GetBitmap() );
+ XOBitmap aXBmp(aBitmap, XBITMAP_STRETCH);
+ aSet.Put(XFillBitmapItem(String(), aXBmp));
+ aSet.Put(XFillBmpTileItem(FALSE));
+
+ pRetval->SetMergedItemSet(aSet);
+ }
+ break;
+ }
+ case GRAPHIC_NONE:
+ case GRAPHIC_DEFAULT:
+ {
+ pRetval = SdrRectObj::DoConvertToPolyObj(bBezier);
+ break;
+ }
+ }
+
+ return pRetval;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ SetXPolyDirty();
+ SdrRectObj::Notify( rBC, rHint );
+ ImpSetAttrToGrafInfo();
+}
+
+void SdrGrafObj::ImpSetAttrToGrafInfo()
+{
+ const SfxItemSet& rSet = GetObjectItemSet();
+ const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
+ const SdrGrafCropItem& rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP );
+
+ aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
+ aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
+ aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
+ aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
+ aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
+ aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
+ aGrafInfo.SetTransparency( (BYTE) FRound( Min( nTrans, (USHORT) 100 ) * 2.55 ) );
+ aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
+ aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
+ aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
+
+ SetXPolyDirty();
+ SetRectsDirty();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::ImpSetGrafInfoToAttr()
+{
+ SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) );
+ SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) );
+ SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) );
+ SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) );
+ SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) );
+ SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) );
+ SetObjectItem( SdrGrafTransparenceItem( (USHORT) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) );
+ SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) );
+ SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) );
+ SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
+{
+ Size aSize;
+ Size aMaxSize( rMaxRect.GetSize() );
+ if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
+ aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
+ else
+ aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(),
+ MapMode( MAP_100TH_MM ) );
+
+ if( aSize.Height() != 0 && aSize.Width() != 0 )
+ {
+ Point aPos( rMaxRect.TopLeft() );
+
+ // Falls Grafik zu gross, wird die Grafik
+ // in die Seite eingepasst
+ if ( (!bShrinkOnly ||
+ ( aSize.Height() > aMaxSize.Height() ) ||
+ ( aSize.Width() > aMaxSize.Width() ) )&&
+ aSize.Height() && aMaxSize.Height() )
+ {
+ float fGrfWH = (float)aSize.Width() /
+ (float)aSize.Height();
+ float fWinWH = (float)aMaxSize.Width() /
+ (float)aMaxSize.Height();
+
+ // Grafik an Pagesize anpassen (skaliert)
+ if ( fGrfWH < fWinWH )
+ {
+ aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
+ aSize.Height()= aMaxSize.Height();
+ }
+ else if ( fGrfWH > 0.F )
+ {
+ aSize.Width() = aMaxSize.Width();
+ aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
+ }
+
+ aPos = rMaxRect.Center();
+ }
+
+ if( bShrinkOnly )
+ aPos = aRect.TopLeft();
+
+ aPos.X() -= aSize.Width() / 2;
+ aPos.Y() -= aSize.Height() / 2;
+ SetLogicRect( Rectangle( aPos, aSize ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
+{
+ SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
+
+ if( pO->IsInSwapOut() )
+ {
+ if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
+ {
+ // test if this object is visualized from someone
+ // ## test only if there are VOCs other than the preview renderer
+ if(!GetViewContact().HasViewObjectContacts(true))
+ {
+ const ULONG nSwapMode = pModel->GetSwapGraphicsMode();
+
+ if( ( pGraphic->HasUserData() || pGraphicLink ) &&
+ ( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) )
+ {
+ pRet = NULL;
+ }
+ else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP )
+ {
+ pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
+ pGraphic->SetUserData();
+ }
+
+ // #i102380#
+ sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
+
+ if(pVC)
+ {
+ pVC->flushGraphicObjects();
+ }
+ }
+ }
+ }
+ else if( pO->IsInSwapIn() )
+ {
+ // kann aus dem original Doc-Stream nachgeladen werden...
+ if( pModel != NULL )
+ {
+ if( pGraphic->HasUserData() )
+ {
+ SdrDocumentStreamInfo aStreamInfo;
+
+ aStreamInfo.mbDeleteAfterUse = FALSE;
+ aStreamInfo.maUserData = pGraphic->GetUserData();
+
+ SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
+
+ if( pStream != NULL )
+ {
+ Graphic aGraphic;
+
+ com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL;
+
+ if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
+ {
+// Rectangle aSnapRect(GetSnapRect());
+// const Rectangle aSnapRectPixel(pOutDev->LogicToPixel(aSnapRect));
+
+ pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
+
+ com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
+ sal_Bool bAllowPartialStreamRead = sal_True;
+ sal_Bool bCreateNativeLink = sal_False;
+ (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) );
+ (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
+ (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) );
+ (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
+ (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
+ (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
+
+ mbIsPreview = sal_True;
+ }
+
+ if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream,
+ GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData ) )
+ {
+ const String aUserData( pGraphic->GetUserData() );
+
+ pGraphic->SetGraphic( aGraphic );
+ pGraphic->SetUserData( aUserData );
+
+ // #142146# Graphic successfully swapped in.
+ pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
+ }
+ delete pFilterData;
+
+ pStream->ResetError();
+
+ if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() )
+ {
+ if ( aStreamInfo.mxStorageRef.is() )
+ {
+ aStreamInfo.mxStorageRef->dispose();
+ aStreamInfo.mxStorageRef = 0;
+ }
+
+ delete pStream;
+ }
+ }
+ }
+ else if( !ImpUpdateGraphicLink() )
+ {
+ pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
+ }
+ else
+ {
+ pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
+ }
+ }
+ else
+ pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
+ }
+
+ return (long)(void*) pRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// #111096#
+// Access to GrafAnimationAllowed flag
+sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const
+{
+ return mbGrafAnimationAllowed;
+}
+
+void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew)
+{
+ if(mbGrafAnimationAllowed != bNew)
+ {
+ mbGrafAnimationAllowed = bNew;
+ ActionChanged();
+ }
+}
+
+// #i25616#
+sal_Bool SdrGrafObj::IsObjectTransparent() const
+{
+ if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue()
+ || pGraphic->IsTransparent())
+ {
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+Reference< XInputStream > SdrGrafObj::getInputStream()
+{
+ Reference< XInputStream > xStream;
+
+ if( pModel )
+ {
+// if( !pGraphic->HasUserData() )
+// pGraphic->SwapOut();
+
+ // kann aus dem original Doc-Stream nachgeladen werden...
+ if( pGraphic->HasUserData() )
+ {
+ SdrDocumentStreamInfo aStreamInfo;
+
+ aStreamInfo.mbDeleteAfterUse = FALSE;
+ aStreamInfo.maUserData = pGraphic->GetUserData();
+
+ SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
+
+ if( pStream )
+ xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
+ }
+ else if( pGraphic && GetGraphic().IsLink() )
+ {
+ Graphic aGraphic( GetGraphic() );
+ GfxLink aLink( aGraphic.GetLink() );
+ sal_uInt32 nSize = aLink.GetDataSize();
+ const void* pSourceData = (const void*)aLink.GetData();
+ if( nSize && pSourceData )
+ {
+ sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
+ if( pBuffer )
+ {
+ memcpy( pBuffer, pSourceData, nSize );
+
+ SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ );
+ pStream->ObjectOwnsMemory( sal_True );
+ xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
+ }
+ }
+ }
+
+ if( !xStream.is() && aFileName.Len() )
+ {
+ SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ );
+ if( pStream )
+ xStream.set( new utl::OInputStreamWrapper( pStream ) );
+ }
+ }
+
+ return xStream;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
new file mode 100644
index 000000000000..4060369f8016
--- /dev/null
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -0,0 +1,801 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <sfx2/linkmgr.hxx>
+
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/datetime.hxx>
+
+#include <svx/svdogrp.hxx>
+
+#include <sfx2/lnkbase.hxx>
+#include <tools/urlobj.hxx>
+
+#include <svl/urihelper.hxx>
+
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include "svditer.hxx"
+#include <svx/svdobj.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdattrx.hxx> // NotPersistItems
+#include <svx/svdoedge.hxx> // #32383# Die Verbinder nach Move nochmal anbroadcasten
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+
+#include <svx/svxids.hrc>
+#include <svl/whiter.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/sdr/properties/groupproperties.hxx>
+
+// #110094#
+#include <svx/sdr/contact/viewcontactofgroup.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@@ @@@@ @@@@@ @@@@ @@ @@ @@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@@ @@@@@ @@ @@ @@ @@ @@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@@@@ @@@@ @@@@@ @@ @@ @@@@ @@@@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrObjGroup::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::GroupProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #110094# DrawContact section
+
+sdr::contact::ViewContact* SdrObjGroup::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfGroup(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrObjGroup,SdrObject);
+
+SdrObjGroup::SdrObjGroup()
+{
+ pSub=new SdrObjList(NULL,NULL);
+ pSub->SetOwnerObj(this);
+ pSub->SetListKind(SDROBJLIST_GROUPOBJ);
+ bRefPoint=FALSE;
+ nDrehWink=0;
+ nShearWink=0;
+ bClosedObj=FALSE;
+}
+
+
+SdrObjGroup::~SdrObjGroup()
+{
+ delete pSub;
+}
+
+void SdrObjGroup::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bNoContortion=FALSE;
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ SdrObjTransformInfoRec aInfo;
+ pObj->TakeObjInfo(aInfo);
+ if (!aInfo.bMoveAllowed ) rInfo.bMoveAllowed =FALSE;
+ if (!aInfo.bResizeFreeAllowed ) rInfo.bResizeFreeAllowed =FALSE;
+ if (!aInfo.bResizePropAllowed ) rInfo.bResizePropAllowed =FALSE;
+ if (!aInfo.bRotateFreeAllowed ) rInfo.bRotateFreeAllowed =FALSE;
+ if (!aInfo.bRotate90Allowed ) rInfo.bRotate90Allowed =FALSE;
+ if (!aInfo.bMirrorFreeAllowed ) rInfo.bMirrorFreeAllowed =FALSE;
+ if (!aInfo.bMirror45Allowed ) rInfo.bMirror45Allowed =FALSE;
+ if (!aInfo.bMirror90Allowed ) rInfo.bMirror90Allowed =FALSE;
+ if (!aInfo.bShearAllowed ) rInfo.bShearAllowed =FALSE;
+ if (!aInfo.bEdgeRadiusAllowed ) rInfo.bEdgeRadiusAllowed =FALSE;
+ if (!aInfo.bNoOrthoDesired ) rInfo.bNoOrthoDesired =FALSE;
+ if (aInfo.bNoContortion ) rInfo.bNoContortion =TRUE;
+ if (!aInfo.bCanConvToPath ) rInfo.bCanConvToPath =FALSE;
+
+ if(!aInfo.bCanConvToContour)
+ rInfo.bCanConvToContour = FALSE;
+
+ if (!aInfo.bCanConvToPoly ) rInfo.bCanConvToPoly =FALSE;
+ if (!aInfo.bCanConvToPathLineToArea) rInfo.bCanConvToPathLineToArea=FALSE;
+ if (!aInfo.bCanConvToPolyLineToArea) rInfo.bCanConvToPolyLineToArea=FALSE;
+ }
+ if (nObjAnz==0) {
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bRotate90Allowed =FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bMirror45Allowed =FALSE;
+ rInfo.bMirror90Allowed =FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bNoContortion =TRUE;
+ }
+ if(nObjAnz != 1)
+ {
+ // only allowed if single object selected
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ }
+}
+
+
+void SdrObjGroup::SetBoundRectDirty()
+{
+ // avoid resetting aOutRect which in case of this object is model data,
+ // not re-creatable view data
+}
+
+UINT16 SdrObjGroup::GetObjIdentifier() const
+{
+ return UINT16(OBJ_GRUP);
+}
+
+
+SdrLayerID SdrObjGroup::GetLayer() const
+{
+ FASTBOOL b1st=TRUE;
+ SdrLayerID nLay=SdrLayerID(SdrObject::GetLayer());
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrLayerID nLay1=pOL->GetObj(i)->GetLayer();
+ if (b1st) { nLay=nLay1; b1st=FALSE; }
+ else if (nLay1!=nLay) return 0;
+ }
+ return nLay;
+}
+
+
+void SdrObjGroup::NbcSetLayer(SdrLayerID nLayer)
+{
+ SdrObject::NbcSetLayer(nLayer);
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ pOL->GetObj(i)->NbcSetLayer(nLayer);
+ }
+}
+
+
+void SdrObjGroup::SetObjList(SdrObjList* pNewObjList)
+{
+ SdrObject::SetObjList(pNewObjList);
+ pSub->SetUpList(pNewObjList);
+}
+
+
+void SdrObjGroup::SetPage(SdrPage* pNewPage)
+{
+ SdrObject::SetPage(pNewPage);
+ pSub->SetPage(pNewPage);
+}
+
+
+void SdrObjGroup::SetModel(SdrModel* pNewModel)
+{
+ if(pNewModel!=pModel)
+ {
+ // #i30648#
+ // This method also needs to migrate the used ItemSet
+ // when the destination model uses a different pool
+ // than the current one. Else it is possible to create
+ // SdrObjGroups which reference the old pool which might
+ // be destroyed (as the bug shows).
+ SdrModel* pOldModel = pModel;
+
+ // test for correct pool in ItemSet; move to new pool if necessary
+ if(pNewModel && GetObjectItemPool() && GetObjectItemPool() != &pNewModel->GetItemPool())
+ {
+ MigrateItemPool(GetObjectItemPool(), &pNewModel->GetItemPool(), pNewModel);
+ }
+
+ // call parent
+ SdrObject::SetModel(pNewModel);
+
+ // set new model at content
+ pSub->SetModel(pNewModel);
+
+ // modify properties
+ GetProperties().SetModel(pOldModel, pNewModel);
+ }
+}
+
+
+FASTBOOL SdrObjGroup::HasRefPoint() const
+{
+ return bRefPoint;
+}
+
+
+Point SdrObjGroup::GetRefPoint() const
+{
+ return aRefPoint;
+}
+
+
+void SdrObjGroup::SetRefPoint(const Point& rPnt)
+{
+ bRefPoint=TRUE;
+ aRefPoint=rPnt;
+}
+
+
+SdrObjList* SdrObjGroup::GetSubList() const
+{
+ return pSub;
+}
+
+const Rectangle& SdrObjGroup::GetCurrentBoundRect() const
+{
+ // --> OD 2007-02-01 #144962#
+ // <aOutRect> has to contain the bounding rectangle
+ if ( pSub->GetObjCount()!=0 )
+ {
+ const_cast<SdrObjGroup*>(this)->aOutRect = pSub->GetAllObjBoundRect();
+ }
+
+ return aOutRect;
+ // <--
+}
+
+
+const Rectangle& SdrObjGroup::GetSnapRect() const
+{
+ // --> OD 2007-02-01 #144962#
+ // <aOutRect> has to contain the bounding rectangle
+ if ( pSub->GetObjCount()!=0 )
+ {
+ return pSub->GetAllObjSnapRect();
+ }
+ else
+ {
+ return aOutRect;
+ }
+ // <--
+}
+
+void SdrObjGroup::operator=(const SdrObject& rObj)
+{
+ if(rObj.IsGroupObject())
+ {
+ // copy SdrObject stuff
+ SdrObject::operator=(rObj);
+
+ // #i36404#
+ // copy SubList, init model and page first
+ SdrObjList& rSourceSubList = *rObj.GetSubList();
+ pSub->SetPage(rSourceSubList.GetPage());
+ pSub->SetModel(rSourceSubList.GetModel());
+ pSub->CopyObjects(*rObj.GetSubList());
+
+ // copy local paremeters
+ nDrehWink =((SdrObjGroup&)rObj).nDrehWink;
+ nShearWink =((SdrObjGroup&)rObj).nShearWink;
+ aRefPoint =((SdrObjGroup&)rObj).aRefPoint;
+ bRefPoint =((SdrObjGroup&)rObj).bRefPoint;
+ }
+}
+
+
+void SdrObjGroup::TakeObjNameSingul(XubString& rName) const
+{
+ if(!pSub->GetObjCount())
+ {
+ rName = ImpGetResStr(STR_ObjNameSingulGRUPEMPTY);
+ }
+ else
+ {
+ rName = ImpGetResStr(STR_ObjNameSingulGRUP);
+ }
+
+ const String aName(GetName());
+
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+
+void SdrObjGroup::TakeObjNamePlural(XubString& rName) const
+{
+ if (pSub->GetObjCount()==0) {
+ rName=ImpGetResStr(STR_ObjNamePluralGRUPEMPTY);
+ } else {
+ rName=ImpGetResStr(STR_ObjNamePluralGRUP);
+ }
+}
+
+
+void SdrObjGroup::RecalcSnapRect()
+{
+ // nicht erforderlich, da die Rects von der SubList verwendet werden.
+}
+
+basegfx::B2DPolyPolygon SdrObjGroup::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ const sal_uInt32 nObjCount(pSub->GetObjCount());
+
+ for(sal_uInt32 a(0L); a < nObjCount; a++)
+ {
+ SdrObject* pObj = pSub->GetObj(a);
+ aRetval.append(pObj->TakeXorPoly());
+ }
+
+ if(!aRetval.count())
+ {
+ const basegfx::B2DRange aRange(aOutRect.Left(), aOutRect.Top(), aOutRect.Right(), aOutRect.Bottom());
+ aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
+ }
+
+ return aRetval;
+}
+
+bool SdrObjGroup::beginSpecialDrag(SdrDragStat& /*rDrag*/) const
+{
+ return false;
+}
+
+
+FASTBOOL SdrObjGroup::BegCreate(SdrDragStat& /*rStat*/)
+{
+ return FALSE;
+}
+
+
+long SdrObjGroup::GetRotateAngle() const
+{
+ return nDrehWink;
+}
+
+
+long SdrObjGroup::GetShearAngle(FASTBOOL /*bVertical*/) const
+{
+ return nShearWink;
+}
+
+
+void SdrObjGroup::NbcSetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aOld(GetSnapRect());
+ long nMulX=rRect.Right()-rRect.Left();
+ long nDivX=aOld.Right()-aOld.Left();
+ long nMulY=rRect.Bottom()-rRect.Top();
+ long nDivY=aOld.Bottom()-aOld.Top();
+ if (nDivX==0) { nMulX=1; nDivX=1; }
+ if (nDivY==0) { nMulY=1; nDivY=1; }
+ if (nMulX!=nDivX || nMulY!=nDivY) {
+ Fraction aX(nMulX,nDivX);
+ Fraction aY(nMulY,nDivY);
+ NbcResize(aOld.TopLeft(),aX,aY);
+ }
+ if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
+ NbcMove(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
+ }
+}
+
+
+void SdrObjGroup::NbcSetLogicRect(const Rectangle& rRect)
+{
+ NbcSetSnapRect(rRect);
+}
+
+
+void SdrObjGroup::NbcMove(const Size& rSiz)
+{
+ MovePoint(aRefPoint,rSiz);
+ if (pSub->GetObjCount()!=0) {
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcMove(rSiz);
+ }
+ } else {
+ MoveRect(aOutRect,rSiz);
+ SetRectsDirty();
+ }
+}
+
+
+void SdrObjGroup::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
+ FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
+ if (bXMirr || bYMirr) {
+ Point aRef1(GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ }
+ ResizePoint(aRefPoint,rRef,xFact,yFact);
+ if (pSub->GetObjCount()!=0) {
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcResize(rRef,xFact,yFact);
+ }
+ } else {
+ ResizeRect(aOutRect,rRef,xFact,yFact);
+ SetRectsDirty();
+ }
+}
+
+
+void SdrObjGroup::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SetGlueReallyAbsolute(TRUE);
+ nDrehWink=NormAngle360(nDrehWink+nWink);
+ RotatePoint(aRefPoint,rRef,sn,cs);
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcRotate(rRef,nWink,sn,cs);
+ }
+ NbcRotateGluePoints(rRef,nWink,sn,cs);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+
+void SdrObjGroup::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SetGlueReallyAbsolute(TRUE);
+ MirrorPoint(aRefPoint,rRef1,rRef2); // fehlende Implementation in SvdEtc !!!
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcMirror(rRef1,rRef2);
+ }
+ NbcMirrorGluePoints(rRef1,rRef2);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+
+void SdrObjGroup::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SetGlueReallyAbsolute(TRUE);
+ nShearWink+=nWink;
+ ShearPoint(aRefPoint,rRef,tn);
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcShear(rRef,nWink,tn,bVShear);
+ }
+ NbcShearGluePoints(rRef,nWink,tn,bVShear);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+
+void SdrObjGroup::NbcSetAnchorPos(const Point& rPnt)
+{
+ aAnchor=rPnt;
+ Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
+ MovePoint(aRefPoint,aSiz);
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ pObj->NbcSetAnchorPos(rPnt);
+ }
+}
+
+
+void SdrObjGroup::SetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ Rectangle aOld(GetSnapRect());
+ long nMulX=rRect.Right()-rRect.Left();
+ long nDivX=aOld.Right()-aOld.Left();
+ long nMulY=rRect.Bottom()-rRect.Top();
+ long nDivY=aOld.Bottom()-aOld.Top();
+ if (nDivX==0) { nMulX=1; nDivX=1; }
+ if (nDivY==0) { nMulY=1; nDivY=1; }
+ if (nMulX!=nDivX || nMulY!=nDivY) {
+ Fraction aX(nMulX,nDivX);
+ Fraction aY(nMulY,nDivY);
+ Resize(aOld.TopLeft(),aX,aY);
+ }
+ if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
+ Move(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+
+void SdrObjGroup::SetLogicRect(const Rectangle& rRect)
+{
+ SetSnapRect(rRect);
+}
+
+
+void SdrObjGroup::Move(const Size& rSiz)
+{
+ if (rSiz.Width()!=0 || rSiz.Height()!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ MovePoint(aRefPoint,rSiz);
+ if (pSub->GetObjCount()!=0) {
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->Move(rSiz);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->Move(rSiz);
+ }
+ } else {
+ // #110094#-14 SendRepaintBroadcast();
+ MoveRect(aOutRect,rSiz);
+ SetRectsDirty();
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+
+void SdrObjGroup::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
+ FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
+ FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
+ if (bXMirr || bYMirr) {
+ Point aRef1(GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ }
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ ResizePoint(aRefPoint,rRef,xFact,yFact);
+ if (pSub->GetObjCount()!=0) {
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact);
+ }
+ } else {
+ // #110094#-14 SendRepaintBroadcast();
+ ResizeRect(aOutRect,rRef,xFact,yFact);
+ SetRectsDirty();
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+
+void SdrObjGroup::Rotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ if (nWink!=0) {
+ SetGlueReallyAbsolute(TRUE);
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ nDrehWink=NormAngle360(nDrehWink+nWink);
+ RotatePoint(aRefPoint,rRef,sn,cs);
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
+ }
+ NbcRotateGluePoints(rRef,nWink,sn,cs);
+ SetGlueReallyAbsolute(FALSE);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+
+void SdrObjGroup::Mirror(const Point& rRef1, const Point& rRef2)
+{
+ SetGlueReallyAbsolute(TRUE);
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ MirrorPoint(aRefPoint,rRef1,rRef2); // fehlende Implementation in SvdEtc !!!
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
+ }
+ NbcMirrorGluePoints(rRef1,rRef2);
+ SetGlueReallyAbsolute(FALSE);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+
+void SdrObjGroup::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ if (nWink!=0) {
+ SetGlueReallyAbsolute(TRUE);
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ nShearWink+=nWink;
+ ShearPoint(aRefPoint,rRef,tn);
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
+ }
+ NbcShearGluePoints(rRef,nWink,tn,bVShear);
+ SetGlueReallyAbsolute(FALSE);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+
+void SdrObjGroup::SetAnchorPos(const Point& rPnt)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ FASTBOOL bChg=aAnchor!=rPnt;
+ aAnchor=rPnt;
+ Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
+ MovePoint(aRefPoint,aSiz);
+ // #32383# Erst die Verbinder verschieben, dann den Rest
+ SdrObjList* pOL=pSub;
+ ULONG nObjAnz=pOL->GetObjCount();
+ ULONG i;
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
+ }
+ for (i=0; i<nObjAnz; i++) {
+ SdrObject* pObj=pOL->GetObj(i);
+ if (!pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
+ }
+ if (bChg) {
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+
+
+void SdrObjGroup::NbcSetRelativePos(const Point& rPnt)
+{
+ Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
+ Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
+ NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
+}
+
+void SdrObjGroup::SetRelativePos(const Point& rPnt)
+{
+ Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
+ Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
+ if (aSiz.Width()!=0 || aSiz.Height()!=0) Move(aSiz); // Der ruft auch das SetRectsDirty() und Broadcast, ...
+}
+
+void SdrObjGroup::NbcReformatText()
+{
+ pSub->NbcReformatAllTextObjects();
+}
+
+void SdrObjGroup::ReformatText()
+{
+ pSub->ReformatAllTextObjects();
+}
+
+SdrObject* SdrObjGroup::DoConvertToPolyObj(BOOL bBezier) const
+{
+ SdrObject* pGroup = new SdrObjGroup;
+ pGroup->SetModel(GetModel());
+
+ for(UINT32 a=0;a<pSub->GetObjCount();a++)
+ {
+ SdrObject* pIterObj = pSub->GetObj(a);
+ SdrObject* pResult = pIterObj->DoConvertToPolyObj(bBezier);
+
+ // pResult can be NULL e.g. for empty objects
+ if( pResult )
+ pGroup->GetSubList()->NbcInsertObject(pResult);
+ }
+
+ return pGroup;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdomeas.cxx b/svx/source/svdraw/svdomeas.cxx
new file mode 100644
index 000000000000..2bcf016d0e4a
--- /dev/null
+++ b/svx/source/svdraw/svdomeas.cxx
@@ -0,0 +1,1494 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdomeas.hxx>
+#include <math.h>
+#include "svditext.hxx" //
+#include <svx/xpoly.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdattrx.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdview.hxx>
+#include "svdglob.hxx" // StringCache
+#include "svdstr.hrc" // Objektname
+#include <svl/style.hxx>
+#include <svl/smplhint.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/measfld.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdpage.hxx>
+#include <unotools/syslocale.hxx>
+#include "svdoimp.hxx"
+#include <svx/sdr/properties/measureproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdrmeasureobj.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrMeasureObjGeoData::SdrMeasureObjGeoData() {}
+SdrMeasureObjGeoData::~SdrMeasureObjGeoData() {}
+
+void SdrMeasureObj::TakeRepresentation( XubString& rStr, SdrMeasureFieldKind eMeasureFieldKind ) const
+{
+ rStr.Erase();
+ Fraction aMeasureScale(1, 1);
+ BOOL bTextRota90(FALSE);
+ BOOL bShowUnit(FALSE);
+ FieldUnit eMeasureUnit(FUNIT_NONE);
+ FieldUnit eModUIUnit(FUNIT_NONE);
+
+ const SfxItemSet& rSet = GetMergedItemSet();
+ bTextRota90 = ((SdrMeasureTextRota90Item&)rSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue();
+ eMeasureUnit = ((SdrMeasureUnitItem&)rSet.Get(SDRATTR_MEASUREUNIT)).GetValue();
+ aMeasureScale = ((SdrMeasureScaleItem&)rSet.Get(SDRATTR_MEASURESCALE)).GetValue();
+ bShowUnit = ((SdrMeasureShowUnitItem&)rSet.Get(SDRATTR_MEASURESHOWUNIT)).GetValue();
+ sal_Int16 nNumDigits = ((SdrMeasureDecimalPlacesItem&)rSet.Get(SDRATTR_MEASUREDECIMALPLACES)).GetValue();
+
+ //SdrModel* pModel = rObj.pModel;
+
+ switch(eMeasureFieldKind)
+ {
+ case SDRMEASUREFIELD_VALUE:
+ {
+ if(pModel)
+ {
+ eModUIUnit = pModel->GetUIUnit();
+
+ if(eMeasureUnit == FUNIT_NONE)
+ eMeasureUnit = eModUIUnit;
+
+ INT32 nLen(GetLen(aPt2 - aPt1));
+ Fraction aFact(1,1);
+
+ if(eMeasureUnit != eModUIUnit)
+ {
+ // Zur Umrechnung der Einheiten
+ aFact *= GetMapFactor(eModUIUnit, eMeasureUnit).X();
+ }
+
+ if(aMeasureScale.GetNumerator() != aMeasureScale.GetDenominator())
+ {
+ aFact *= aMeasureScale;
+ }
+
+ if(aFact.GetNumerator() != aFact.GetDenominator())
+ {
+ // Scaling ueber BigInt, um Ueberlaeufe zu vermeiden
+ nLen = BigMulDiv(nLen, aFact.GetNumerator(), aFact.GetDenominator());
+ }
+
+ pModel->TakeMetricStr(nLen, rStr, TRUE, nNumDigits);
+
+ if(!aFact.IsValid())
+ {
+ rStr = String();
+ rStr += sal_Unicode('?');
+ }
+
+ sal_Unicode cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0));
+
+ if(rStr.Search(cDec) != STRING_NOTFOUND)
+ {
+ xub_StrLen nLen2(rStr.Len() - 1);
+
+ while(rStr.GetChar(nLen2) == sal_Unicode('0'))
+ {
+ rStr.Erase(nLen2);
+ nLen2--;
+ }
+
+ if(rStr.GetChar(nLen2) == cDec)
+ {
+ rStr.Erase(nLen2);
+ nLen2--;
+ }
+
+ if(!rStr.Len())
+ rStr += sal_Unicode('0');
+ }
+ }
+ else
+ {
+ // falls kein Model da ... (z.B. Preview im Dialog)
+ rStr = String();
+ rStr.AppendAscii("4711");
+ }
+
+ break;
+ }
+ case SDRMEASUREFIELD_UNIT:
+ {
+ if(bShowUnit)
+ {
+ if(pModel)
+ {
+ eModUIUnit = pModel->GetUIUnit();
+
+ if(eMeasureUnit == FUNIT_NONE)
+ eMeasureUnit = eModUIUnit;
+
+ if(bShowUnit)
+ pModel->TakeUnitStr(eMeasureUnit, rStr);
+ }
+ }
+
+ break;
+ }
+ case SDRMEASUREFIELD_ROTA90BLANCS:
+ {
+ if(bTextRota90)
+ {
+ rStr = String();
+ rStr += sal_Unicode(' ');
+ }
+
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrMeasureObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::MeasureProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrMeasureObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrMeasureObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrMeasureObj,SdrTextObj);
+
+SdrMeasureObj::SdrMeasureObj():
+ bTextDirty(FALSE)
+{
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+}
+
+SdrMeasureObj::SdrMeasureObj(const Point& rPt1, const Point& rPt2):
+ aPt1(rPt1),
+ aPt2(rPt2),
+ bTextDirty(FALSE)
+{
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_False;
+}
+
+SdrMeasureObj::~SdrMeasureObj()
+{
+}
+
+void SdrMeasureObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bSelectAllowed =TRUE;
+ rInfo.bMoveAllowed =TRUE;
+ rInfo.bResizeFreeAllowed=TRUE;
+ rInfo.bResizePropAllowed=TRUE;
+ rInfo.bRotateFreeAllowed=TRUE;
+ rInfo.bRotate90Allowed =TRUE;
+ rInfo.bMirrorFreeAllowed=TRUE;
+ rInfo.bMirror45Allowed =TRUE;
+ rInfo.bMirror90Allowed =TRUE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =TRUE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bNoOrthoDesired =TRUE;
+ rInfo.bNoContortion =FALSE;
+ rInfo.bCanConvToPath =FALSE;
+ rInfo.bCanConvToPoly =TRUE;
+ rInfo.bCanConvToPathLineToArea=FALSE;
+ rInfo.bCanConvToPolyLineToArea=FALSE;
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrMeasureObj::GetObjIdentifier() const
+{
+ return (UINT16)OBJ_MEASURE;
+}
+
+struct ImpMeasureRec : public SdrDragStatUserData
+{
+ Point aPt1;
+ Point aPt2;
+ SdrMeasureKind eKind;
+ SdrMeasureTextHPos eWantTextHPos;
+ SdrMeasureTextVPos eWantTextVPos;
+ long nLineDist;
+ long nHelplineOverhang;
+ long nHelplineDist;
+ long nHelpline1Len;
+ long nHelpline2Len;
+ FASTBOOL bBelowRefEdge;
+ FASTBOOL bTextRota90;
+ FASTBOOL bTextUpsideDown;
+ long nMeasureOverhang;
+ FieldUnit eMeasureUnit;
+ Fraction aMeasureScale;
+ FASTBOOL bShowUnit;
+ String aFormatString;
+ FASTBOOL bTextAutoAngle;
+ long nTextAutoAngleView;
+ FASTBOOL bTextIsFixedAngle;
+ long nTextFixedAngle;
+};
+
+struct ImpLineRec
+{
+ Point aP1;
+ Point aP2;
+};
+
+struct ImpMeasurePoly
+{
+ ImpLineRec aMainline1; // die mit dem 1. Pfeil
+ ImpLineRec aMainline2; // die mit dem 2. Pfeil
+ ImpLineRec aMainline3; // die dazwischen
+ ImpLineRec aHelpline1;
+ ImpLineRec aHelpline2;
+ Rectangle aTextRect;
+ Size aTextSize;
+ long nLineLen;
+ long nLineWink;
+ long nTextWink;
+ long nHlpWink;
+ double nLineSin;
+ double nLineCos;
+ double nHlpSin;
+ double nHlpCos;
+ USHORT nMainlineAnz;
+ SdrMeasureTextHPos eUsedTextHPos;
+ SdrMeasureTextVPos eUsedTextVPos;
+ long nLineWdt2; // Halbe Strichstaerke
+ long nArrow1Len; // Laenge des 1. Pfeils. Bei Center nur die Haelfte
+ long nArrow2Len; // Laenge des 2. Pfeils. Bei Center nur die Haelfte
+ long nArrow1Wdt; // Breite des 1. Pfeils
+ long nArrow2Wdt; // Breite des 2. Pfeils
+ long nShortLineLen; // Linienlaenge, wenn PfeileAussen
+ FASTBOOL bArrow1Center; // Pfeil 1 zentriert?
+ FASTBOOL bArrow2Center; // Pfeil 2 zentriert?
+ FASTBOOL bAutoUpsideDown; // UpsideDown durch Automatik
+ FASTBOOL bPfeileAussen;
+ FASTBOOL bBreakedLine;
+};
+
+void SdrMeasureObj::ImpTakeAttr(ImpMeasureRec& rRec) const
+{
+ rRec.aPt1 = aPt1;
+ rRec.aPt2 = aPt2;
+
+ const SfxItemSet& rSet = GetObjectItemSet();
+ rRec.eKind =((SdrMeasureKindItem& )rSet.Get(SDRATTR_MEASUREKIND )).GetValue();
+ rRec.eWantTextHPos =((SdrMeasureTextHPosItem& )rSet.Get(SDRATTR_MEASURETEXTHPOS )).GetValue();
+ rRec.eWantTextVPos =((SdrMeasureTextVPosItem& )rSet.Get(SDRATTR_MEASURETEXTVPOS )).GetValue();
+ rRec.nLineDist =((SdrMeasureLineDistItem& )rSet.Get(SDRATTR_MEASURELINEDIST )).GetValue();
+ rRec.nHelplineOverhang=((SdrMeasureHelplineOverhangItem&)rSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue();
+ rRec.nHelplineDist =((SdrMeasureHelplineDistItem& )rSet.Get(SDRATTR_MEASUREHELPLINEDIST )).GetValue();
+ rRec.nHelpline1Len =((SdrMeasureHelpline1LenItem& )rSet.Get(SDRATTR_MEASUREHELPLINE1LEN )).GetValue();
+ rRec.nHelpline2Len =((SdrMeasureHelpline2LenItem& )rSet.Get(SDRATTR_MEASUREHELPLINE2LEN )).GetValue();
+ rRec.bBelowRefEdge =((SdrMeasureBelowRefEdgeItem& )rSet.Get(SDRATTR_MEASUREBELOWREFEDGE )).GetValue();
+ rRec.bTextRota90 =((SdrMeasureTextRota90Item& )rSet.Get(SDRATTR_MEASURETEXTROTA90 )).GetValue();
+ rRec.bTextUpsideDown =((SdrMeasureTextUpsideDownItem& )rSet.Get(SDRATTR_MEASURETEXTUPSIDEDOWN )).GetValue();
+ rRec.nMeasureOverhang =((SdrMeasureOverhangItem& )rSet.Get(SDRATTR_MEASUREOVERHANG )).GetValue();
+ rRec.eMeasureUnit =((SdrMeasureUnitItem& )rSet.Get(SDRATTR_MEASUREUNIT )).GetValue();
+ rRec.aMeasureScale =((SdrMeasureScaleItem& )rSet.Get(SDRATTR_MEASURESCALE )).GetValue();
+ rRec.bShowUnit =((SdrMeasureShowUnitItem& )rSet.Get(SDRATTR_MEASURESHOWUNIT )).GetValue();
+ rRec.aFormatString =((SdrMeasureFormatStringItem& )rSet.Get(SDRATTR_MEASUREFORMATSTRING )).GetValue();
+ rRec.bTextAutoAngle =((SdrMeasureTextAutoAngleItem& )rSet.Get(SDRATTR_MEASURETEXTAUTOANGLE )).GetValue();
+ rRec.nTextAutoAngleView=((SdrMeasureTextAutoAngleViewItem&)rSet.Get(SDRATTR_MEASURETEXTAUTOANGLEVIEW)).GetValue();
+ rRec.bTextIsFixedAngle =((SdrMeasureTextIsFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTISFIXEDANGLE )).GetValue();
+ rRec.nTextFixedAngle =((SdrMeasureTextFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTFIXEDANGLE )).GetValue();
+}
+
+long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon& rPolyPolygon, long nNewWidth, bool bCenter)
+{
+ const basegfx::B2DRange aPolygonRange(rPolyPolygon.getB2DRange());
+ const double fOldWidth(aPolygonRange.getWidth() > 1.0 ? aPolygonRange.getWidth() : 1.0);
+ const double fScale((double)nNewWidth / fOldWidth);
+ long nHeight(basegfx::fround(aPolygonRange.getHeight() * fScale));
+
+ if(bCenter)
+ {
+ nHeight /= 2L;
+ }
+
+ return nHeight;
+}
+
+void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec& rRec, ImpMeasurePoly& rPol) const
+{
+ Point aP1(rRec.aPt1);
+ Point aP2(rRec.aPt2);
+ Point aDelt(aP2); aDelt-=aP1;
+
+ rPol.aTextSize=GetTextSize();
+ rPol.nLineLen=GetLen(aDelt);
+
+ rPol.nLineWdt2=0;
+ long nArrow1Len=0; bool bArrow1Center=false;
+ long nArrow2Len=0; bool bArrow2Center=false;
+ long nArrow1Wdt=0;
+ long nArrow2Wdt=0;
+ rPol.nArrow1Wdt=0;
+ rPol.nArrow2Wdt=0;
+ long nArrowNeed=0;
+ long nShortLen=0;
+ FASTBOOL bPfeileAussen=FALSE;
+
+ const SfxItemSet& rSet = GetObjectItemSet();
+ sal_Int32 nLineWdt = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); // Strichstaerke
+ rPol.nLineWdt2 = (nLineWdt + 1) / 2;
+
+ nArrow1Wdt = ((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
+ if(nArrow1Wdt < 0)
+ nArrow1Wdt = -nLineWdt * nArrow1Wdt / 100; // <0 = relativ
+
+ nArrow2Wdt = ((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue();
+ if(nArrow2Wdt < 0)
+ nArrow2Wdt = -nLineWdt * nArrow2Wdt / 100; // <0 = relativ
+
+ basegfx::B2DPolyPolygon aPol1(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue());
+ basegfx::B2DPolyPolygon aPol2(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue());
+ bArrow1Center = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue();
+ bArrow2Center = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue();
+ nArrow1Len = impGetLineStartEndDistance(aPol1, nArrow1Wdt, bArrow1Center) - 1;
+ nArrow2Len = impGetLineStartEndDistance(aPol2, nArrow2Wdt, bArrow2Center) - 1;
+
+ // nArrowLen ist bei bCenter bereits halbiert
+ // Bei 2 Pfeilen a 4mm ist unter 10mm Schluss.
+ nArrowNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2;
+ if (rPol.nLineLen<nArrowNeed) bPfeileAussen=TRUE;
+ nShortLen=(nArrow1Len+nArrow1Wdt + nArrow2Len+nArrow2Wdt) /2;
+
+ rPol.eUsedTextHPos=rRec.eWantTextHPos;
+ rPol.eUsedTextVPos=rRec.eWantTextVPos;
+ if (rPol.eUsedTextVPos==SDRMEASURE_TEXTVAUTO) rPol.eUsedTextVPos=SDRMEASURE_ABOVE;
+ FASTBOOL bBrkLine=rPol.eUsedTextVPos==SDRMEASURETEXT_BREAKEDLINE;
+ if (rPol.eUsedTextVPos==SDRMEASURETEXT_VERTICALCENTERED)
+ {
+ OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
+ if (pOutlinerParaObject!=NULL && pOutlinerParaObject->GetTextObject().GetParagraphCount()==1)
+ {
+ bBrkLine=TRUE; // Unterbrochene Linie, wenn nur 1 Absatz.
+ }
+ }
+ rPol.bBreakedLine=bBrkLine;
+ if (rPol.eUsedTextHPos==SDRMEASURE_TEXTHAUTO) { // bei zu breitem Text diesen eventuell nach aussen schieben
+ FASTBOOL bOutside=FALSE;
+ long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
+ if (nNeedSiz>rPol.nLineLen) bOutside=TRUE; // Text passt nicht in die Mitte
+ if (bBrkLine) {
+ if (nNeedSiz+nArrowNeed>rPol.nLineLen) bPfeileAussen=TRUE; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen
+ } else {
+ long nSmallNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2/4;
+ if (nNeedSiz+nSmallNeed>rPol.nLineLen) bPfeileAussen=TRUE; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen
+ }
+ rPol.eUsedTextHPos=bOutside ? SDRMEASURE_TEXTLEFTOUTSIDE : SDRMEASURE_TEXTINSIDE;
+ }
+ if (rPol.eUsedTextHPos!=SDRMEASURE_TEXTINSIDE) bPfeileAussen=TRUE;
+ rPol.nArrow1Wdt=nArrow1Wdt;
+ rPol.nArrow2Wdt=nArrow2Wdt;
+ rPol.nShortLineLen=nShortLen;
+ rPol.bPfeileAussen=bPfeileAussen;
+ rPol.nArrow1Len=nArrow1Len;
+ rPol.bArrow1Center=bArrow1Center;
+ rPol.nArrow2Len=nArrow2Len;
+ rPol.bArrow2Center=bArrow2Center;
+
+ rPol.nLineWink=GetAngle(aDelt);
+ double a=rPol.nLineWink*nPi180;
+ double nLineSin=sin(a);
+ double nLineCos=cos(a);
+ rPol.nLineSin=nLineSin;
+ rPol.nLineCos=nLineCos;
+
+ rPol.nTextWink=rPol.nLineWink;
+ if (rRec.bTextRota90) rPol.nTextWink+=9000;
+
+ rPol.bAutoUpsideDown=FALSE;
+ if (rRec.bTextAutoAngle) {
+ long nTmpWink=NormAngle360(rPol.nTextWink-rRec.nTextAutoAngleView);
+ if (nTmpWink>=18000) {
+ rPol.nTextWink+=18000;
+ rPol.bAutoUpsideDown=TRUE;
+ }
+ }
+
+ if (rRec.bTextUpsideDown) rPol.nTextWink+=18000;
+ rPol.nTextWink=NormAngle360(rPol.nTextWink);
+ rPol.nHlpWink=rPol.nLineWink+9000;
+ if (rRec.bBelowRefEdge) rPol.nHlpWink+=18000;
+ rPol.nHlpWink=NormAngle360(rPol.nHlpWink);
+ double nHlpSin=nLineCos;
+ double nHlpCos=-nLineSin;
+ if (rRec.bBelowRefEdge) {
+ nHlpSin=-nHlpSin;
+ nHlpCos=-nHlpCos;
+ }
+ rPol.nHlpSin=nHlpSin;
+ rPol.nHlpCos=nHlpCos;
+
+ long nLineDist=rRec.nLineDist;
+ long nOverhang=rRec.nHelplineOverhang;
+ long nHelplineDist=rRec.nHelplineDist;
+
+ long dx= Round(nLineDist*nHlpCos);
+ long dy=-Round(nLineDist*nHlpSin);
+ long dxh1a= Round((nHelplineDist-rRec.nHelpline1Len)*nHlpCos);
+ long dyh1a=-Round((nHelplineDist-rRec.nHelpline1Len)*nHlpSin);
+ long dxh1b= Round((nHelplineDist-rRec.nHelpline2Len)*nHlpCos);
+ long dyh1b=-Round((nHelplineDist-rRec.nHelpline2Len)*nHlpSin);
+ long dxh2= Round((nLineDist+nOverhang)*nHlpCos);
+ long dyh2=-Round((nLineDist+nOverhang)*nHlpSin);
+
+ // Masshilfslinie 1
+ rPol.aHelpline1.aP1=Point(aP1.X()+dxh1a,aP1.Y()+dyh1a);
+ rPol.aHelpline1.aP2=Point(aP1.X()+dxh2,aP1.Y()+dyh2);
+
+ // Masshilfslinie 2
+ rPol.aHelpline2.aP1=Point(aP2.X()+dxh1b,aP2.Y()+dyh1b);
+ rPol.aHelpline2.aP2=Point(aP2.X()+dxh2,aP2.Y()+dyh2);
+
+ // Masslinie(n)
+ Point aMainlinePt1(aP1.X()+dx,aP1.Y()+dy);
+ Point aMainlinePt2(aP2.X()+dx,aP2.Y()+dy);
+ if (!bPfeileAussen) {
+ rPol.aMainline1.aP1=aMainlinePt1;
+ rPol.aMainline1.aP2=aMainlinePt2;
+ rPol.aMainline2=rPol.aMainline1;
+ rPol.aMainline3=rPol.aMainline1;
+ rPol.nMainlineAnz=1;
+ if (bBrkLine) {
+ long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
+ long nHalfLen=(rPol.nLineLen-nNeedSiz-nArrow1Wdt/4-nArrow2Wdt/4) /2;
+ rPol.nMainlineAnz=2;
+ rPol.aMainline1.aP2=aMainlinePt1;
+ rPol.aMainline1.aP2.X()+=nHalfLen;
+ RotatePoint(rPol.aMainline1.aP2,rPol.aMainline1.aP1,nLineSin,nLineCos);
+ rPol.aMainline2.aP1=aMainlinePt2;
+ rPol.aMainline2.aP1.X()-=nHalfLen;
+ RotatePoint(rPol.aMainline2.aP1,rPol.aMainline2.aP2,nLineSin,nLineCos);
+ }
+ } else {
+ long nLen1=nShortLen; // Pfeilbreite als Linienlaenge ausserhalb des Pfeils
+ long nLen2=nShortLen;
+ long nTextWdt=rRec.bTextRota90 ? rPol.aTextSize.Height() : rPol.aTextSize.Width();
+ if (!bBrkLine) {
+ if (rPol.eUsedTextHPos==SDRMEASURE_TEXTLEFTOUTSIDE) nLen1=nArrow1Len+nTextWdt;
+ if (rPol.eUsedTextHPos==SDRMEASURE_TEXTRIGHTOUTSIDE) nLen2=nArrow2Len+nTextWdt;
+ }
+ rPol.aMainline1.aP1=aMainlinePt1;
+ rPol.aMainline1.aP2=aMainlinePt1; rPol.aMainline1.aP2.X()-=nLen1; RotatePoint(rPol.aMainline1.aP2,aMainlinePt1,nLineSin,nLineCos);
+ rPol.aMainline2.aP1=aMainlinePt2; rPol.aMainline2.aP1.X()+=nLen2; RotatePoint(rPol.aMainline2.aP1,aMainlinePt2,nLineSin,nLineCos);
+ rPol.aMainline2.aP2=aMainlinePt2;
+ rPol.aMainline3.aP1=aMainlinePt1;
+ rPol.aMainline3.aP2=aMainlinePt2;
+ rPol.nMainlineAnz=3;
+ if (bBrkLine && rPol.eUsedTextHPos==SDRMEASURE_TEXTINSIDE) rPol.nMainlineAnz=2;
+ }
+}
+
+basegfx::B2DPolyPolygon SdrMeasureObj::ImpCalcXPoly(const ImpMeasurePoly& rPol) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ basegfx::B2DPolygon aPartPolyA;
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP1.X(), rPol.aMainline1.aP1.Y()));
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP2.X(), rPol.aMainline1.aP2.Y()));
+ aRetval.append(aPartPolyA);
+
+ if(rPol.nMainlineAnz > 1)
+ {
+ aPartPolyA.clear();
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP1.X(), rPol.aMainline2.aP1.Y()));
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP2.X(), rPol.aMainline2.aP2.Y()));
+ aRetval.append(aPartPolyA);
+ }
+
+ if(rPol.nMainlineAnz > 2)
+ {
+ aPartPolyA.clear();
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP1.X(), rPol.aMainline3.aP1.Y()));
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP2.X(), rPol.aMainline3.aP2.Y()));
+ aRetval.append(aPartPolyA);
+ }
+
+ aPartPolyA.clear();
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP1.X(), rPol.aHelpline1.aP1.Y()));
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP2.X(), rPol.aHelpline1.aP2.Y()));
+ aRetval.append(aPartPolyA);
+
+ aPartPolyA.clear();
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP1.X(), rPol.aHelpline2.aP1.Y()));
+ aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP2.X(), rPol.aHelpline2.aP2.Y()));
+ aRetval.append(aPartPolyA);
+
+ return aRetval;
+}
+
+FASTBOOL SdrMeasureObj::CalcFieldValue(const SvxFieldItem& rField, USHORT nPara, USHORT nPos,
+ FASTBOOL bEdit,
+ Color*& rpTxtColor, Color*& rpFldColor, XubString& rRet) const
+{
+ const SvxFieldData* pField=rField.GetField();
+ SdrMeasureField* pMeasureField=PTR_CAST(SdrMeasureField,pField);
+ if (pMeasureField!=NULL) {
+ TakeRepresentation(rRet, pMeasureField->GetMeasureFieldKind());
+ if (rpFldColor!=NULL) {
+ if (!bEdit)
+ {
+ delete rpFldColor;
+ rpFldColor=NULL;
+ }
+ }
+ return TRUE;
+ } else {
+ return SdrTextObj::CalcFieldValue(rField,nPara,nPos,bEdit,rpTxtColor,rpFldColor,rRet);
+ }
+}
+
+void SdrMeasureObj::UndirtyText() const
+{
+ if (bTextDirty)
+ {
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+ OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
+ if(pOutlinerParaObject==NULL)
+ {
+ rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD), ESelection(0,0));
+ rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_VALUE), EE_FEATURE_FIELD),ESelection(0,1));
+ rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_UNIT), EE_FEATURE_FIELD),ESelection(0,2));
+ rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD),ESelection(0,3));
+
+ if(GetStyleSheet())
+ rOutliner.SetStyleSheet(0, GetStyleSheet());
+
+ rOutliner.SetParaAttribs(0, GetObjectItemSet());
+
+ // casting auf nonconst
+ const_cast<SdrMeasureObj*>(this)->NbcSetOutlinerParaObject( rOutliner.CreateParaObject() );
+ }
+ else
+ {
+ rOutliner.SetText(*pOutlinerParaObject);
+ }
+
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.UpdateFields();
+ Size aSiz(rOutliner.CalcTextSize());
+ rOutliner.Clear();
+ // 3x casting auf nonconst
+ ((SdrMeasureObj*)this)->aTextSize=aSiz;
+ ((SdrMeasureObj*)this)->bTextSizeDirty=FALSE;
+ ((SdrMeasureObj*)this)->bTextDirty=FALSE;
+ }
+}
+
+void SdrMeasureObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ if (bTextDirty) UndirtyText();
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+ ImpTakeAttr(aRec);
+ ImpCalcGeometrics(aRec,aMPol);
+
+ // TextSize ermitteln inkl. Textrahmenabstaende
+ Size aTextSize2(aMPol.aTextSize);
+ if (aTextSize2.Width()<1) aTextSize2.Width()=1;
+ if (aTextSize2.Height()<1) aTextSize2.Height()=1;
+ aTextSize2.Width()+=GetTextLeftDistance()+GetTextRightDistance();
+ aTextSize2.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
+
+ Point aPt1b(aMPol.aMainline1.aP1);
+ long nLen=aMPol.nLineLen;
+ long nLWdt=aMPol.nLineWdt2;
+ long nArr1Len=aMPol.nArrow1Len;
+ long nArr2Len=aMPol.nArrow2Len;
+ if (aMPol.bBreakedLine) {
+ // Bei Unterbrochener Linie und Outside muss der Text nicht neben den
+ // Pfeil sondern neben die Linie an dem Pfeil plaziert werden
+ nArr1Len=aMPol.nShortLineLen+aMPol.nArrow1Wdt/4;
+ nArr2Len=aMPol.nShortLineLen+aMPol.nArrow2Wdt/4;
+ }
+
+ Point aTextPos;
+ FASTBOOL bRota90=aRec.bTextRota90;
+ FASTBOOL bUpsideDown=aRec.bTextUpsideDown!=aMPol.bAutoUpsideDown;
+ FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge;
+ SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
+ SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
+ if (!bRota90) {
+ switch (eMH) {
+ case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Width()-nArr1Len-nLWdt; break;
+ case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len+nLWdt; break;
+ default: aTextPos.X()=aPt1b.X(); aTextSize2.Width()=nLen;
+ }
+ switch (eMV) {
+ case SDRMEASURETEXT_VERTICALCENTERED:
+ case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()/2; break;
+ case SDRMEASURE_BELOW: {
+ if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()+nLWdt;
+ else aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
+ } break;
+ default: {
+ if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
+ else aTextPos.Y()=aPt1b.Y()+nLWdt;
+ }
+ }
+ if (bUpsideDown) {
+ aTextPos.X()+=aTextSize2.Width();
+ aTextPos.Y()+=aTextSize2.Height();
+ }
+ } else { // also wenn bTextRota90==TRUE
+ switch (eMH) {
+ case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Height()-nArr1Len; break;
+ case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len; break;
+ default: aTextPos.X()=aPt1b.X(); aTextSize2.Height()=nLen;
+ }
+ switch (eMV) {
+ case SDRMEASURETEXT_VERTICALCENTERED:
+ case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()/2; break;
+ case SDRMEASURE_BELOW: {
+ if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
+ else aTextPos.Y()=aPt1b.Y()-nLWdt;
+ } break;
+ default: {
+ if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()-nLWdt;
+ else aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
+ }
+ }
+ if (bUpsideDown) {
+ aTextPos.X()+=aTextSize2.Height();
+ aTextPos.Y()-=aTextSize2.Width();
+ }
+ }
+ if (aMPol.nTextWink!=aGeo.nDrehWink) {
+ ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
+ ((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
+ }
+ RotatePoint(aTextPos,aPt1b,aMPol.nLineSin,aMPol.nLineCos);
+ aTextSize2.Width()++; aTextSize2.Height()++; // wg. des komischen Verhaltens beim Rect-Ctor
+ rRect=Rectangle(aTextPos,aTextSize2);
+ rRect.Justify();
+ ((SdrMeasureObj*)this)->aRect=rRect;
+
+ if (aMPol.nTextWink!=aGeo.nDrehWink) {
+ ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
+ ((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
+ }
+}
+
+void SdrMeasureObj::operator=(const SdrObject& rObj)
+{
+ SdrTextObj::operator=(rObj);
+ aPt1=((SdrMeasureObj&)rObj).aPt1;
+ aPt2=((SdrMeasureObj&)rObj).aPt2;
+ bTextDirty=((SdrMeasureObj&)rObj).bTextDirty;
+}
+
+void SdrMeasureObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulMEASURE);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrMeasureObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralMEASURE);
+}
+
+basegfx::B2DPolyPolygon SdrMeasureObj::TakeXorPoly() const
+{
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+ ImpTakeAttr(aRec);
+ ImpCalcGeometrics(aRec,aMPol);
+ return ImpCalcXPoly(aMPol);
+}
+
+sal_uInt32 SdrMeasureObj::GetHdlCount() const
+{
+ return 6L;
+}
+
+SdrHdl* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+ ImpTakeAttr(aRec);
+ aRec.nHelplineDist=0;
+ ImpCalcGeometrics(aRec,aMPol);
+ Point aPt;
+ //SdrHdlKind eHdl=HDL_POLY;
+ switch (nHdlNum) {
+ case 0: aPt=aMPol.aHelpline1.aP1; break;
+ case 1: aPt=aMPol.aHelpline2.aP1; break;
+ case 2: aPt=aPt1; break;
+ case 3: aPt=aPt2; break;
+ case 4: aPt=aMPol.aHelpline1.aP2; break;
+ case 5: aPt=aMPol.aHelpline2.aP2; break;
+ } // switch
+ SdrHdl* pHdl=new ImpMeasureHdl(aPt,HDL_USER);
+ pHdl->SetObjHdlNum(nHdlNum);
+ pHdl->SetDrehWink(aMPol.nLineWink);
+ return pHdl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrMeasureObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrMeasureObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const SdrHdl* pHdl = rDrag.GetHdl();
+
+ if(pHdl)
+ {
+ const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
+
+ if(nHdlNum != 2 && nHdlNum != 3)
+ {
+ rDrag.SetEndDragChangesAttributes(true);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool SdrMeasureObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ ImpMeasureRec aMeasureRec;
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
+
+ ImpTakeAttr(aMeasureRec);
+ ImpEvalDrag(aMeasureRec, rDrag);
+
+ switch (nHdlNum)
+ {
+ case 2:
+ {
+ aPt1 = aMeasureRec.aPt1;
+ SetTextDirty();
+ break;
+ }
+ case 3:
+ {
+ aPt2 = aMeasureRec.aPt2;
+ SetTextDirty();
+ break;
+ }
+ default:
+ {
+ switch(nHdlNum)
+ {
+ case 0:
+ case 1:
+ {
+ ImpMeasureRec aOrigMeasureRec;
+ ImpTakeAttr(aOrigMeasureRec);
+
+ if(aMeasureRec.nHelpline1Len != aOrigMeasureRec.nHelpline1Len)
+ {
+ SetObjectItem(SdrMeasureHelpline1LenItem(aMeasureRec.nHelpline1Len));
+ }
+
+ if(aMeasureRec.nHelpline2Len != aOrigMeasureRec.nHelpline2Len)
+ {
+ SetObjectItem(SdrMeasureHelpline2LenItem(aMeasureRec.nHelpline2Len));
+ }
+
+ break;
+ }
+
+ case 4:
+ case 5:
+ {
+ ImpMeasureRec aOrigMeasureRec;
+ ImpTakeAttr(aOrigMeasureRec);
+
+ if(aMeasureRec.nLineDist != aOrigMeasureRec.nLineDist)
+ {
+ SetObjectItem(SdrMeasureLineDistItem(aMeasureRec.nLineDist));
+ }
+
+ if(aMeasureRec.bBelowRefEdge != aOrigMeasureRec.bBelowRefEdge)
+ {
+ SetObjectItem(SdrMeasureBelowRefEdgeItem(aMeasureRec.bBelowRefEdge));
+ }
+ }
+ }
+ }
+ } // switch
+
+ SetRectsDirty();
+ SetChanged();
+
+ return true;
+}
+
+String SdrMeasureObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
+{
+ XubString aStr;
+ return aStr;
+}
+
+void SdrMeasureObj::ImpEvalDrag(ImpMeasureRec& rRec, const SdrDragStat& rDrag) const
+{
+ long nLineWink=GetAngle(rRec.aPt2-rRec.aPt1);
+ double a=nLineWink*nPi180;
+ double nSin=sin(a);
+ double nCos=cos(a);
+
+ const SdrHdl* pHdl=rDrag.GetHdl();
+ sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
+ FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
+ FASTBOOL bBigOrtho=bOrtho && rDrag.GetView()->IsBigOrtho();
+ FASTBOOL bBelow=rRec.bBelowRefEdge;
+ Point aPt(rDrag.GetNow());
+
+ switch (nHdlNum) {
+ case 0: {
+ RotatePoint(aPt,aPt1,nSin,-nCos);
+ rRec.nHelpline1Len=aPt1.Y()-aPt.Y();
+ if (bBelow) rRec.nHelpline1Len=-rRec.nHelpline1Len;
+ if (bOrtho) rRec.nHelpline2Len=rRec.nHelpline1Len;
+ } break;
+ case 1: {
+ RotatePoint(aPt,aPt2,nSin,-nCos);
+ rRec.nHelpline2Len=aPt2.Y()-aPt.Y();
+ if (bBelow) rRec.nHelpline2Len=-rRec.nHelpline2Len;
+ if (bOrtho) rRec.nHelpline1Len=rRec.nHelpline2Len;
+ } break;
+ case 2: case 3: {
+ FASTBOOL bAnf=nHdlNum==2;
+ Point& rMov=bAnf ? rRec.aPt1 : rRec.aPt2;
+ Point aMov(rMov);
+ Point aFix(bAnf ? rRec.aPt2 : rRec.aPt1);
+ if (bOrtho) {
+ long ndx0=aMov.X()-aFix.X();
+ long ndy0=aMov.Y()-aFix.Y();
+ FASTBOOL bHLin=ndy0==0;
+ FASTBOOL bVLin=ndx0==0;
+ if (!bHLin || !bVLin) { // sonst ist aPt1==aPt2
+ long ndx=aPt.X()-aFix.X();
+ long ndy=aPt.Y()-aFix.Y();
+ double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
+ double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
+ FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
+ FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
+ if (bHor) ndy=long(ndy0*nXFact);
+ if (bVer) ndx=long(ndx0*nYFact);
+ aPt=aFix;
+ aPt.X()+=ndx;
+ aPt.Y()+=ndy;
+ } // else Ortho8
+ }
+ rMov=aPt;
+ } break;
+ case 4: case 5: {
+ long nVal0=rRec.nLineDist;
+ RotatePoint(aPt,(nHdlNum==4 ? aPt1 : aPt2),nSin,-nCos);
+ rRec.nLineDist=aPt.Y()- (nHdlNum==4 ? aPt1.Y() : aPt2.Y());
+ if (bBelow) rRec.nLineDist=-rRec.nLineDist;
+ if (rRec.nLineDist<0) {
+ rRec.nLineDist=-rRec.nLineDist;
+ rRec.bBelowRefEdge=!bBelow;
+ }
+ rRec.nLineDist-=rRec.nHelplineOverhang;
+ if (bOrtho) rRec.nLineDist=nVal0;
+ } break;
+ } // switch
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrMeasureObj::BegCreate(SdrDragStat& rStat)
+{
+ rStat.SetOrtho8Possible();
+ aPt1=rStat.GetStart();
+ aPt2=rStat.GetNow();
+ SetTextDirty();
+ return TRUE;
+}
+
+FASTBOOL SdrMeasureObj::MovCreate(SdrDragStat& rStat)
+{
+ SdrView* pView=rStat.GetView();
+ aPt1=rStat.GetStart();
+ aPt2=rStat.GetNow();
+ if (pView!=NULL && pView->IsCreate1stPointAsCenter()) {
+ aPt1+=aPt1;
+ aPt1-=rStat.Now();
+ }
+ SetTextDirty();
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ return TRUE;
+}
+
+FASTBOOL SdrMeasureObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ SetTextDirty();
+ SetRectsDirty();
+ return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
+}
+
+FASTBOOL SdrMeasureObj::BckCreate(SdrDragStat& /*rStat*/)
+{
+ return FALSE;
+}
+
+void SdrMeasureObj::BrkCreate(SdrDragStat& /*rStat*/)
+{
+}
+
+basegfx::B2DPolyPolygon SdrMeasureObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
+{
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+
+ ImpTakeAttr(aRec);
+ ImpCalcGeometrics(aRec, aMPol);
+
+ return ImpCalcXPoly(aMPol);
+}
+
+Pointer SdrMeasureObj::GetCreatePointer() const
+{
+ return Pointer(POINTER_CROSS);
+}
+
+void SdrMeasureObj::NbcMove(const Size& rSiz)
+{
+ SdrTextObj::NbcMove(rSiz);
+ MovePoint(aPt1,rSiz);
+ MovePoint(aPt2,rSiz);
+}
+
+void SdrMeasureObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ SdrTextObj::NbcResize(rRef,xFact,yFact);
+ ResizePoint(aPt1,rRef,xFact,yFact);
+ ResizePoint(aPt2,rRef,xFact,yFact);
+ SetTextDirty();
+}
+
+void SdrMeasureObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
+ long nLen0=GetLen(aPt2-aPt1);
+ RotatePoint(aPt1,rRef,sn,cs);
+ RotatePoint(aPt2,rRef,sn,cs);
+ long nLen1=GetLen(aPt2-aPt1);
+ if (nLen1!=nLen0) { // Aha, Rundungsfehler
+ long dx=aPt2.X()-aPt1.X();
+ long dy=aPt2.Y()-aPt1.Y();
+ dx=BigMulDiv(dx,nLen0,nLen1);
+ dy=BigMulDiv(dy,nLen0,nLen1);
+ if (rRef==aPt2) {
+ aPt1.X()=aPt2.X()-dx;
+ aPt1.Y()=aPt2.Y()-dy;
+ } else {
+ aPt2.X()=aPt1.X()+dx;
+ aPt2.Y()=aPt1.Y()+dy;
+ }
+ }
+ SetRectsDirty();
+}
+
+void SdrMeasureObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SdrTextObj::NbcMirror(rRef1,rRef2);
+ MirrorPoint(aPt1,rRef1,rRef2);
+ MirrorPoint(aPt2,rRef1,rRef2);
+ SetRectsDirty();
+}
+
+void SdrMeasureObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
+ ShearPoint(aPt1,rRef,tn,bVShear);
+ ShearPoint(aPt2,rRef,tn,bVShear);
+ SetRectsDirty();
+ SetTextDirty();
+}
+
+long SdrMeasureObj::GetRotateAngle() const
+{
+ return GetAngle(aPt2-aPt1);
+}
+
+void SdrMeasureObj::RecalcSnapRect()
+{
+ // #94520# Added correct implementation here.
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+ XPolyPolygon aXPP;
+
+ ImpTakeAttr(aRec);
+ ImpCalcGeometrics(aRec, aMPol);
+ aXPP = XPolyPolygon(ImpCalcXPoly(aMPol));
+ maSnapRect = aXPP.GetBoundRect();
+}
+
+sal_uInt32 SdrMeasureObj::GetSnapPointCount() const
+{
+ return 2L;
+}
+
+Point SdrMeasureObj::GetSnapPoint(sal_uInt32 i) const
+{
+ if (i==0) return aPt1;
+ else return aPt2;
+}
+
+sal_Bool SdrMeasureObj::IsPolyObj() const
+{
+ return sal_True;
+}
+
+sal_uInt32 SdrMeasureObj::GetPointCount() const
+{
+ return 2L;
+}
+
+Point SdrMeasureObj::GetPoint(sal_uInt32 i) const
+{
+ return (0L == i) ? aPt1 : aPt2;
+}
+
+void SdrMeasureObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
+{
+ if (0L == i)
+ aPt1=rPnt;
+ if (1L == i)
+ aPt2=rPnt;
+ SetRectsDirty();
+ SetTextDirty();
+}
+
+SdrObjGeoData* SdrMeasureObj::NewGeoData() const
+{
+ return new SdrMeasureObjGeoData;
+}
+
+void SdrMeasureObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrTextObj::SaveGeoData(rGeo);
+ SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
+ rMGeo.aPt1=aPt1;
+ rMGeo.aPt2=aPt2;
+}
+
+void SdrMeasureObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrTextObj::RestGeoData(rGeo);
+ SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
+ aPt1=rMGeo.aPt1;
+ aPt2=rMGeo.aPt2;
+ SetTextDirty();
+}
+
+SdrObject* SdrMeasureObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ // get XOR Poly as base
+ XPolyPolygon aTmpPolyPolygon(TakeXorPoly());
+
+ // get local ItemSet and StyleSheet
+ SfxItemSet aSet(GetObjectItemSet());
+ SfxStyleSheet* pStyleSheet = GetStyleSheet();
+
+ // prepare group
+ SdrObjGroup* pGroup = new SdrObjGroup;
+ pGroup->SetModel(GetModel());
+
+ // prepare parameters
+ basegfx::B2DPolyPolygon aPolyPoly;
+ SdrPathObj* pPath;
+ UINT16 nCount(aTmpPolyPolygon.Count());
+ UINT16 nLoopStart(0);
+
+ if(nCount == 3)
+ {
+ // three lines, first one is the middle one
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
+
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+ aSet.Put(XLineStartWidthItem(0L));
+ aSet.Put(XLineEndWidthItem(0L));
+ nLoopStart = 1;
+ }
+ else if(nCount == 4)
+ {
+ // four lines, middle line with gap, so there are two lines used
+ // which have one arrow each
+ //INT32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
+ INT32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
+ aSet.Put(XLineEndWidthItem(0L));
+
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+
+ aSet.Put(XLineEndWidthItem(nEndWidth));
+ aSet.Put(XLineStartWidthItem(0L));
+
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+
+ aSet.Put(XLineEndWidthItem(0L));
+ nLoopStart = 2;
+ }
+ else if(nCount == 5)
+ {
+ // five lines, first two are the outer ones
+ //INT32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
+ INT32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
+
+ aSet.Put(XLineEndWidthItem(0L));
+
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+
+ aSet.Put(XLineEndWidthItem(nEndWidth));
+ aSet.Put(XLineStartWidthItem(0L));
+
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+
+ aSet.Put(XLineEndWidthItem(0L));
+ nLoopStart = 2;
+ }
+
+ for(;nLoopStart<nCount;nLoopStart++)
+ {
+ aPolyPoly.clear();
+ aPolyPoly.append(aTmpPolyPolygon[nLoopStart].getB2DPolygon());
+ pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
+ pPath->SetModel(GetModel());
+ pPath->SetMergedItemSet(aSet);
+ pPath->SetStyleSheet(pStyleSheet, true);
+
+ pGroup->GetSubList()->NbcInsertObject(pPath);
+ }
+
+ return ImpConvertAddText(pGroup, bBezier);
+}
+
+sal_Bool SdrMeasureObj::BegTextEdit(SdrOutliner& rOutl)
+{
+ UndirtyText();
+ return SdrTextObj::BegTextEdit(rOutl);
+}
+
+const Size& SdrMeasureObj::GetTextSize() const
+{
+ if (bTextDirty) UndirtyText();
+ return SdrTextObj::GetTextSize();
+}
+
+OutlinerParaObject* SdrMeasureObj::GetOutlinerParaObject() const
+{
+ if(bTextDirty)
+ UndirtyText();
+ return SdrTextObj::GetOutlinerParaObject();
+}
+
+void SdrMeasureObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
+{
+ SdrTextObj::NbcSetOutlinerParaObject(pTextObject);
+ if(SdrTextObj::GetOutlinerParaObject())
+ SetTextDirty(); // Text neu berechnen!
+}
+
+void SdrMeasureObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
+ Rectangle* pAnchorRect, BOOL bLineWidth ) const
+{
+ if (bTextDirty) UndirtyText();
+ SdrTextObj::TakeTextRect( rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
+}
+
+void SdrMeasureObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
+{
+ if (bTextDirty) UndirtyText();
+ SdrTextObj::TakeTextAnchorRect(rAnchorRect);
+}
+
+void SdrMeasureObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
+{
+ if (bTextDirty) UndirtyText();
+ SdrTextObj::TakeTextEditArea(pPaperMin,pPaperMax,pViewInit,pViewMin);
+}
+
+USHORT SdrMeasureObj::GetOutlinerViewAnchorMode() const
+{
+ if (bTextDirty) UndirtyText();
+ ImpMeasureRec aRec;
+ ImpMeasurePoly aMPol;
+ ImpTakeAttr(aRec);
+ ImpCalcGeometrics(aRec,aMPol);
+
+ SdrTextHorzAdjust eTH=GetTextHorizontalAdjust();
+ SdrTextVertAdjust eTV=GetTextVerticalAdjust();
+ SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
+ SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
+ FASTBOOL bTextRota90=aRec.bTextRota90;
+ //FASTBOOL bTextUpsideDown=aRec.bTextUpsideDown;
+ FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge;
+
+ // bTextUpsideDown muss hier noch ausgewertet werden!!!!
+ if (!bTextRota90) {
+ if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTH=SDRTEXTHORZADJUST_RIGHT;
+ if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTH=SDRTEXTHORZADJUST_LEFT;
+ // bei eMH==SDRMEASURE_TEXTINSIDE kann horizontal geankert werden.
+ if (eMV==SDRMEASURE_ABOVE) eTV=SDRTEXTVERTADJUST_BOTTOM;
+ if (eMV==SDRMEASURE_BELOW) eTV=SDRTEXTVERTADJUST_TOP;
+ if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTV=SDRTEXTVERTADJUST_CENTER;
+ } else {
+ if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTV=SDRTEXTVERTADJUST_BOTTOM;
+ if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTV=SDRTEXTVERTADJUST_TOP;
+ // bei eMH==SDRMEASURE_TEXTINSIDE kann vertikal geankert werden.
+ if (!bBelowRefEdge) {
+ if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_LEFT;
+ if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_RIGHT;
+ } else {
+ if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_RIGHT;
+ if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_LEFT;
+ }
+ if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTH=SDRTEXTHORZADJUST_CENTER;
+ }
+
+ EVAnchorMode eRet=ANCHOR_BOTTOM_HCENTER;
+ if (eTH==SDRTEXTHORZADJUST_LEFT) {
+ if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_LEFT;
+ else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_LEFT;
+ else eRet=ANCHOR_VCENTER_LEFT;
+ } else if (eTH==SDRTEXTHORZADJUST_RIGHT) {
+ if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_RIGHT;
+ else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_RIGHT;
+ else eRet=ANCHOR_VCENTER_RIGHT;
+ } else {
+ if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_HCENTER;
+ else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_HCENTER;
+ else eRet=ANCHOR_VCENTER_HCENTER;
+ }
+ return (USHORT)eRet;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #i97878#
+// TRGetBaseGeometry/TRSetBaseGeometry needs to be based on two positions,
+// same as line geometry in SdrPathObj. Thus needs to be overloaded and
+// implemented since currently it is derived from SdrTextObj which uses
+// a functionality based on SnapRect which is not useful here
+
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+
+sal_Bool SdrMeasureObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
+{
+ // handle the same as a simple line since the definition is based on two points
+ const basegfx::B2DRange aRange(aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y());
+ basegfx::B2DTuple aScale(aRange.getRange());
+ basegfx::B2DTuple aTranslate(aRange.getMinimum());
+
+ // position maybe relative to anchorpos, convert
+ if( pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // force MapUnit to 100th mm
+ SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // postion
+ aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
+ aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplTwipsToMM(aScale.getX()));
+ aScale.setY(ImplTwipsToMM(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
+ }
+ }
+ }
+
+ // build return value matrix
+ rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
+
+ return sal_True;
+}
+
+void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+ // use given transformation to derive the two defining points from unit line
+ basegfx::B2DPoint aPosA(rMatrix * basegfx::B2DPoint(0.0, 0.0));
+ basegfx::B2DPoint aPosB(rMatrix * basegfx::B2DPoint(1.0, 0.0));
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aPosA.setX(ImplMMToTwips(aPosA.getX()));
+ aPosA.setY(ImplMMToTwips(aPosA.getY()));
+ aPosB.setX(ImplMMToTwips(aPosB.getX()));
+ aPosB.setY(ImplMMToTwips(aPosB.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ if( pModel->IsWriter() )
+ {
+ // if anchor is used, make position relative to it
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ const basegfx::B2DVector aAnchorOffset(GetAnchorPos().X(), GetAnchorPos().Y());
+
+ aPosA += aAnchorOffset;
+ aPosB += aAnchorOffset;
+ }
+ }
+
+ // derive new model data
+ const Point aNewPt1(basegfx::fround(aPosA.getX()), basegfx::fround(aPosA.getY()));
+ const Point aNewPt2(basegfx::fround(aPosB.getX()), basegfx::fround(aPosB.getY()));
+
+ if(aNewPt1 != aPt1 || aNewPt2 != aPt2)
+ {
+ // set model values and broadcast
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+
+ aPt1 = aNewPt1;
+ aPt2 = aNewPt2;
+
+ SetTextDirty();
+ ActionChanged();
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx
new file mode 100644
index 000000000000..9dd615490f9e
--- /dev/null
+++ b/svx/source/svdraw/svdomedia.cxx
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <vcl/svapp.hxx>
+
+#include <svx/svdomedia.hxx>
+#include "svdglob.hxx"
+#include "svdstr.hrc"
+#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
+#include <avmedia/mediawindow.hxx>
+
+// ---------------
+// - SdrMediaObj -
+// ---------------
+
+TYPEINIT1( SdrMediaObj, SdrRectObj );
+
+// ------------------------------------------------------------------------------
+
+SdrMediaObj::SdrMediaObj()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+SdrMediaObj::SdrMediaObj( const Rectangle& rRect ) :
+ SdrRectObj( rRect )
+{
+}
+
+// ------------------------------------------------------------------------------
+
+SdrMediaObj::~SdrMediaObj()
+{
+}
+
+// ------------------------------------------------------------------------------
+
+FASTBOOL SdrMediaObj::HasTextEdit() const
+{
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------------
+
+sdr::contact::ViewContact* SdrMediaObj::CreateObjectSpecificViewContact()
+{
+ return new ::sdr::contact::ViewContactOfSdrMediaObj( *this );
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const
+{
+ rInfo.bSelectAllowed = true;
+ rInfo.bMoveAllowed = true;
+ rInfo.bResizeFreeAllowed = true;
+ rInfo.bResizePropAllowed = true;
+ rInfo.bRotateFreeAllowed = false;
+ rInfo.bRotate90Allowed = false;
+ rInfo.bMirrorFreeAllowed = false;
+ rInfo.bMirror45Allowed = false;
+ rInfo.bMirror90Allowed = false;
+ rInfo.bTransparenceAllowed = false;
+ rInfo.bGradientAllowed = false;
+ rInfo.bShearAllowed = false;
+ rInfo.bEdgeRadiusAllowed = false;
+ rInfo.bNoOrthoDesired = false;
+ rInfo.bNoContortion = false;
+ rInfo.bCanConvToPath = false;
+ rInfo.bCanConvToPoly = false;
+ rInfo.bCanConvToContour = false;
+ rInfo.bCanConvToPathLineToArea = false;
+ rInfo.bCanConvToPolyLineToArea = false;
+}
+
+// ------------------------------------------------------------------------------
+
+UINT16 SdrMediaObj::GetObjIdentifier() const
+{
+ return UINT16( OBJ_MEDIA );
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulMEDIA);
+
+ String aName( GetName() );
+
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralMEDIA);
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::operator=(const SdrObject& rObj)
+{
+ SdrRectObj::operator=( rObj );
+
+ if( rObj.ISA( SdrMediaObj ) )
+ {
+ const SdrMediaObj& rMediaObj = static_cast< const SdrMediaObj& >( rObj );
+
+ setMediaProperties( rMediaObj.getMediaProperties() );
+ setGraphic( rMediaObj.mapGraphic.get() );
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly /* = false */ )
+{
+ Size aSize( Application::GetDefaultDevice()->PixelToLogic( getPreferredSize(), MAP_100TH_MM ) );
+ Size aMaxSize( rMaxRect.GetSize() );
+
+ if( aSize.Height() != 0 && aSize.Width() != 0 )
+ {
+ Point aPos( rMaxRect.TopLeft() );
+
+ // Falls Grafik zu gross, wird die Grafik
+ // in die Seite eingepasst
+ if ( (!bShrinkOnly ||
+ ( aSize.Height() > aMaxSize.Height() ) ||
+ ( aSize.Width() > aMaxSize.Width() ) )&&
+ aSize.Height() && aMaxSize.Height() )
+ {
+ float fGrfWH = (float)aSize.Width() /
+ (float)aSize.Height();
+ float fWinWH = (float)aMaxSize.Width() /
+ (float)aMaxSize.Height();
+
+ // Grafik an Pagesize anpassen (skaliert)
+ if ( fGrfWH < fWinWH )
+ {
+ aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
+ aSize.Height()= aMaxSize.Height();
+ }
+ else if ( fGrfWH > 0.F )
+ {
+ aSize.Width() = aMaxSize.Width();
+ aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
+ }
+
+ aPos = rMaxRect.Center();
+ }
+
+ if( bShrinkOnly )
+ aPos = aRect.TopLeft();
+
+ aPos.X() -= aSize.Width() / 2;
+ aPos.Y() -= aSize.Height() / 2;
+ SetLogicRect( Rectangle( aPos, aSize ) );
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::setURL( const ::rtl::OUString& rURL )
+{
+ ::avmedia::MediaItem aURLItem;
+
+ aURLItem.setURL( rURL );
+ setMediaProperties( aURLItem );
+}
+
+// ------------------------------------------------------------------------------
+
+const ::rtl::OUString& SdrMediaObj::getURL() const
+{
+ return getMediaProperties().getURL();
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::setMediaProperties( const ::avmedia::MediaItem& rState )
+{
+ mediaPropertiesChanged( rState );
+ static_cast< ::sdr::contact::ViewContactOfSdrMediaObj& >( GetViewContact() ).executeMediaItem( getMediaProperties() );
+}
+
+// ------------------------------------------------------------------------------
+
+const ::avmedia::MediaItem& SdrMediaObj::getMediaProperties() const
+{
+ return maMediaProperties;
+}
+
+// ------------------------------------------------------------------------------
+
+bool SdrMediaObj::hasPreferredSize() const
+{
+ return static_cast< ::sdr::contact::ViewContactOfSdrMediaObj& >( GetViewContact() ).hasPreferredSize();
+}
+
+// ------------------------------------------------------------------------------
+
+Size SdrMediaObj::getPreferredSize() const
+{
+ return static_cast< ::sdr::contact::ViewContactOfSdrMediaObj& >( GetViewContact() ).getPreferredSize();
+}
+
+// ------------------------------------------------------------------------------
+
+const Graphic& SdrMediaObj::getGraphic() const
+{
+ if( !mapGraphic.get() )
+ const_cast< SdrMediaObj* >( this )->mapGraphic.reset( new Graphic( ::avmedia::MediaWindow::grabFrame( getURL(), true ) ) );
+
+ return *mapGraphic;
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::setGraphic( const Graphic* pGraphic )
+{
+ mapGraphic.reset( pGraphic ? new Graphic( *pGraphic ) : NULL );
+}
+
+// ------------------------------------------------------------------------------
+
+void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProperties )
+{
+ const sal_uInt32 nMaskSet = rNewProperties.getMaskSet();
+
+ // use only a subset of MediaItem properties for own own properties
+ if( ( AVMEDIA_SETMASK_URL & nMaskSet ) &&
+ ( rNewProperties.getURL() != getURL() ) )
+ {
+ setGraphic();
+ maMediaProperties.setURL( rNewProperties.getURL() );
+ }
+
+ if( AVMEDIA_SETMASK_LOOP & nMaskSet )
+ maMediaProperties.setLoop( rNewProperties.isLoop() );
+
+ if( AVMEDIA_SETMASK_MUTE & nMaskSet )
+ maMediaProperties.setMute( rNewProperties.isMute() );
+
+ if( AVMEDIA_SETMASK_VOLUMEDB & nMaskSet )
+ maMediaProperties.setVolumeDB( rNewProperties.getVolumeDB() );
+
+ if( AVMEDIA_SETMASK_ZOOM & nMaskSet )
+ maMediaProperties.setZoom( rNewProperties.getZoom() );
+}
diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx
new file mode 100644
index 000000000000..483c247c064f
--- /dev/null
+++ b/svx/source/svdraw/svdoole2.cxx
@@ -0,0 +1,2242 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdoole2.hxx>
+#include <com/sun/star/util/XModifyBroadcaster.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/EmbedMisc.hpp>
+#include <com/sun/star/embed/Aspects.hpp>
+#include <com/sun/star/embed/XInplaceClient.hpp>
+#include <com/sun/star/embed/XInplaceObject.hpp>
+#include <com/sun/star/embed/XLinkageSupport.hpp>
+#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
+#include <com/sun/star/embed/XWindowSupplier.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include "com/sun/star/document/XStorageBasedDocument.hpp"
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+
+#include <toolkit/helper/vclunohelper.hxx>
+#include <toolkit/awt/vclxwindow.hxx>
+#include <toolkit/helper/convert.hxx>
+
+#include <svtools/filter.hxx>
+#include <svtools/embedhlp.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <sfx2/ipclient.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <tools/stream.hxx>
+#include <comphelper/anytostring.hxx>
+#include <svx/svdpagv.hxx>
+#include <tools/globname.hxx>
+#include <vcl/jobset.hxx>
+#include <sot/clsids.hxx>
+
+#include <sot/formats.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <svtools/transfer.hxx>
+#include <cppuhelper/implbase5.hxx>
+
+#include <svl/solar.hrc>
+#include <svl/urihelper.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svx/svdpagv.hxx>
+#include <svx/svdmodel.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdetc.hxx>
+#include <svx/svdview.hxx>
+#include "unomlstr.hxx"
+#include <svtools/chartprettypainter.hxx>
+#include <svx/sdr/contact/viewcontactofsdrole2obj.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/sdr/properties/oleproperties.hxx>
+
+// #i100710#
+#include <svx/xlnclit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbstit.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+uno::Reference < beans::XPropertySet > lcl_getFrame_throw(const SdrOle2Obj* _pObject)
+{
+ uno::Reference < beans::XPropertySet > xFrame;
+ if ( _pObject )
+ {
+ uno::Reference< frame::XController> xController = _pObject->GetParentXModel()->getCurrentController();
+ if ( xController.is() )
+ {
+ xFrame.set( xController->getFrame(),uno::UNO_QUERY_THROW);
+ }
+ } // if ( _pObject )
+ return xFrame;
+}
+
+class SdrLightEmbeddedClient_Impl : public ::cppu::WeakImplHelper5
+ < embed::XStateChangeListener
+ , document::XEventListener
+ , embed::XInplaceClient
+ , embed::XEmbeddedClient
+ , embed::XWindowSupplier
+ >
+{
+ uno::Reference< awt::XWindow > m_xWindow;
+ SdrOle2Obj* mpObj;
+
+ Fraction m_aScaleWidth;
+ Fraction m_aScaleHeight;
+
+
+public:
+ SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj );
+ void Release();
+
+ void SetSizeScale( const Fraction& aScaleWidth, const Fraction& aScaleHeight )
+ {
+ m_aScaleWidth = aScaleWidth;
+ m_aScaleHeight = aScaleHeight;
+ }
+
+ Fraction GetScaleWidth() const { return m_aScaleWidth; }
+ Fraction GetScaleHeight() const { return m_aScaleHeight; }
+
+ void setWindow(const uno::Reference< awt::XWindow >& _xWindow);
+
+private:
+ Rectangle impl_getScaledRect_nothrow() const;
+ // XStateChangeListener
+ virtual void SAL_CALL changingState( const ::com::sun::star::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::embed::WrongStateException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL stateChanged( const ::com::sun::star::lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+
+ // document::XEventListener
+ virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException );
+
+ // XEmbeddedClient
+ virtual void SAL_CALL saveObject() throw ( embed::ObjectSaveVetoException, uno::Exception, uno::RuntimeException );
+ virtual void SAL_CALL visibilityChanged( sal_Bool bVisible ) throw ( embed::WrongStateException, uno::RuntimeException );
+
+ // XComponentSupplier
+ virtual uno::Reference< util::XCloseable > SAL_CALL getComponent() throw ( uno::RuntimeException );
+
+ // XInplaceClient
+ virtual sal_Bool SAL_CALL canInplaceActivate() throw ( uno::RuntimeException );
+ virtual void SAL_CALL activatingInplace() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL activatingUI() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL deactivatedInplace() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL deactivatedUI() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual uno::Reference< ::com::sun::star::frame::XLayoutManager > SAL_CALL getLayoutManager() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual uno::Reference< frame::XDispatchProvider > SAL_CALL getInplaceDispatchProvider() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual awt::Rectangle SAL_CALL getPlacement() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual awt::Rectangle SAL_CALL getClipRectangle() throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL translateAccelerators( const uno::Sequence< awt::KeyEvent >& aKeys ) throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL scrollObject( const awt::Size& aOffset ) throw ( embed::WrongStateException, uno::RuntimeException );
+ virtual void SAL_CALL changedPlacement( const awt::Rectangle& aPosRect ) throw ( embed::WrongStateException, uno::Exception, uno::RuntimeException );
+
+ // XWindowSupplier
+ virtual uno::Reference< awt::XWindow > SAL_CALL getWindow() throw ( uno::RuntimeException );
+};
+
+//--------------------------------------------------------------------
+SdrLightEmbeddedClient_Impl::SdrLightEmbeddedClient_Impl( SdrOle2Obj* pObj )
+: mpObj( pObj )
+{
+}
+Rectangle SdrLightEmbeddedClient_Impl::impl_getScaledRect_nothrow() const
+{
+ MapUnit aContainerMapUnit( MAP_100TH_MM );
+ uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
+ if ( xParentVis.is() )
+ aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
+ Rectangle aLogicRect( mpObj->GetLogicRect() );
+ // apply scaling to object area and convert to pixels
+ aLogicRect.SetSize( Size( Fraction( aLogicRect.GetWidth() ) * m_aScaleWidth,
+ Fraction( aLogicRect.GetHeight() ) * m_aScaleHeight ) );
+ return aLogicRect;
+}
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::changingState( const ::com::sun::star::lang::EventObject& /*aEvent*/, ::sal_Int32 /*nOldState*/, ::sal_Int32 /*nNewState*/ ) throw (::com::sun::star::embed::WrongStateException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+//--------------------------------------------------------------------
+void SdrLightEmbeddedClient_Impl::Release()
+{
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ mpObj = NULL;
+ }
+
+ release();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::stateChanged( const ::com::sun::star::lang::EventObject& /*aEvent*/, ::sal_Int32 nOldState, ::sal_Int32 nNewState ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if ( mpObj && nOldState == embed::EmbedStates::LOADED && nNewState == embed::EmbedStates::RUNNING )
+ {
+ mpObj->ObjectLoaded();
+ GetSdrGlobalData().GetOLEObjCache().InsertObj(mpObj);
+ }
+ else if ( mpObj && nNewState == embed::EmbedStates::LOADED && nOldState == embed::EmbedStates::RUNNING )
+ {
+ GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
+ }
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::disposing( const ::com::sun::star::lang::EventObject& /*aEvent*/ ) throw (::com::sun::star::uno::RuntimeException)
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ GetSdrGlobalData().GetOLEObjCache().RemoveObj(mpObj);
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // the code currently makes sence only in case there is no other client
+ if ( mpObj && mpObj->GetAspect() != embed::Aspects::MSOLE_ICON && aEvent.EventName.equalsAscii("OnVisAreaChanged")
+ && mpObj->GetObjRef().is() && mpObj->GetObjRef()->getClientSite() == uno::Reference< embed::XEmbeddedClient >( this ) )
+ {
+ try
+ {
+ MapUnit aContainerMapUnit( MAP_100TH_MM );
+ uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
+ if ( xParentVis.is() )
+ aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
+
+ MapUnit aObjMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( mpObj->GetObjRef()->getMapUnit( mpObj->GetAspect() ) );
+
+ Rectangle aVisArea;
+ awt::Size aSz;
+ try
+ {
+ aSz = mpObj->GetObjRef()->getVisualAreaSize( mpObj->GetAspect() );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ OSL_ENSURE( sal_False, "No visual area size!\n" );
+ aSz.Width = 5000;
+ aSz.Height = 5000;
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Unexpected exception!\n" );
+ aSz.Width = 5000;
+ aSz.Height = 5000;
+ }
+
+ aVisArea.SetSize( Size( aSz.Width, aSz.Height ) );
+ aVisArea = OutputDevice::LogicToLogic( aVisArea, aObjMapUnit, aContainerMapUnit );
+ Size aScaledSize( static_cast< long >( m_aScaleWidth * Fraction( aVisArea.GetWidth() ) ),
+ static_cast< long >( m_aScaleHeight * Fraction( aVisArea.GetHeight() ) ) );
+ Rectangle aLogicRect( mpObj->GetLogicRect() );
+
+ // react to the change if the difference is bigger than one pixel
+ Size aPixelDiff =
+ Application::GetDefaultDevice()->LogicToPixel(
+ Size( aLogicRect.GetWidth() - aScaledSize.Width(),
+ aLogicRect.GetHeight() - aScaledSize.Height() ),
+ aContainerMapUnit );
+ if( aPixelDiff.Width() || aPixelDiff.Height() )
+ {
+ mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
+ mpObj->BroadcastObjectChange();
+ }
+ else
+ mpObj->ActionChanged();
+ }
+ catch( uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "Unexpected exception!\n" );
+ }
+ }
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::saveObject()
+ throw ( embed::ObjectSaveVetoException,
+ uno::Exception,
+ uno::RuntimeException )
+{
+ // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
+ uno::Reference< embed::XCommonEmbedPersist > xPersist;
+ uno::Reference< util::XModifiable > xModifiable;
+
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if ( !mpObj )
+ throw embed::ObjectSaveVetoException();
+
+ // the common persistance is supported by objects and links
+ xPersist = uno::Reference< embed::XCommonEmbedPersist >( mpObj->GetObjRef(), uno::UNO_QUERY_THROW );
+ xModifiable = uno::Reference< util::XModifiable >( mpObj->GetParentXModel(), uno::UNO_QUERY );
+ }
+
+ xPersist->storeOwn();
+
+ if ( xModifiable.is() )
+ xModifiable->setModified( sal_True );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::visibilityChanged( sal_Bool /*bVisible*/ )
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ // nothing to do currently
+ // TODO/LATER: when writer uses this implementation the code could be shared with SfxInPlaceClient_Impl
+ if ( mpObj )
+ {
+ Rectangle aLogicRect( mpObj->GetLogicRect() );
+ Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );
+
+ if( mpObj->IsChart() )
+ {
+ //charts never should be stretched see #i84323# for example
+ mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
+ mpObj->BroadcastObjectChange();
+ } // if( mpObj->IsChart() )
+ }
+}
+
+//--------------------------------------------------------------------
+uno::Reference< util::XCloseable > SAL_CALL SdrLightEmbeddedClient_Impl::getComponent()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< util::XCloseable > xResult;
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( mpObj )
+ xResult = uno::Reference< util::XCloseable >( mpObj->GetParentXModel(), uno::UNO_QUERY );
+
+ return xResult;
+}
+// XInplaceClient
+//--------------------------------------------------------------------
+sal_Bool SAL_CALL SdrLightEmbeddedClient_Impl::canInplaceActivate()
+ throw ( uno::RuntimeException )
+{
+ sal_Bool bRet = sal_False;
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( mpObj )
+ {
+ uno::Reference< embed::XEmbeddedObject > xObject = mpObj->GetObjRef();
+ if ( !xObject.is() )
+ throw uno::RuntimeException();
+ // we don't want to switch directly from outplace to inplace mode
+ bRet = !( xObject->getCurrentState() == embed::EmbedStates::ACTIVE || mpObj->GetAspect() == embed::Aspects::MSOLE_ICON );
+ } // if ( mpObj )
+ return bRet;
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::activatingInplace()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::activatingUI()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
+ uno::Reference < frame::XFrame > xOwnFrame( xFrame,uno::UNO_QUERY);
+ uno::Reference < frame::XFramesSupplier > xParentFrame( xOwnFrame->getCreator(), uno::UNO_QUERY );
+ if ( xParentFrame.is() )
+ xParentFrame->setActiveFrame( xOwnFrame );
+
+ OLEObjCache& rObjCache = GetSdrGlobalData().GetOLEObjCache();
+ const ULONG nCount = rObjCache.Count();
+ for(sal_Int32 i = nCount-1 ; i >= 0;--i)
+ {
+ SdrOle2Obj* pObj = reinterpret_cast<SdrOle2Obj*>(rObjCache.GetObject(i));
+ if ( pObj != mpObj )
+ {
+ // only deactivate ole objects which belongs to the same frame
+ if ( xFrame == lcl_getFrame_throw(pObj) )
+ {
+ uno::Reference< embed::XEmbeddedObject > xObject = pObj->GetObjRef();
+ try
+ {
+ if ( xObject->getStatus( pObj->GetAspect() ) & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE )
+ xObject->changeState( embed::EmbedStates::INPLACE_ACTIVE );
+ else
+ {
+ // the links should not stay in running state for long time because of locking
+ uno::Reference< embed::XLinkageSupport > xLink( xObject, uno::UNO_QUERY );
+ if ( xLink.is() && xLink->isLink() )
+ xObject->changeState( embed::EmbedStates::LOADED );
+ else
+ xObject->changeState( embed::EmbedStates::RUNNING );
+ }
+ }
+ catch (com::sun::star::uno::Exception& )
+ {}
+ }
+ }
+ } // for(sal_Int32 i = nCount-1 ; i >= 0;--i)
+
+ //m_pClient->GetViewShell()->UIActivating( m_pClient );
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedInplace()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::deactivatedUI()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager(getLayoutManager());
+ if ( xLayoutManager.is() )
+ {
+ const static rtl::OUString aMenuBarURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ));
+ if ( !xLayoutManager->isElementVisible( aMenuBarURL ) )
+ xLayoutManager->createElement( aMenuBarURL );
+ }
+}
+
+//--------------------------------------------------------------------
+uno::Reference< ::com::sun::star::frame::XLayoutManager > SAL_CALL SdrLightEmbeddedClient_Impl::getLayoutManager()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ uno::Reference< ::com::sun::star::frame::XLayoutManager > xMan;
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ uno::Reference < beans::XPropertySet > xFrame( lcl_getFrame_throw(mpObj));
+ try
+ {
+ xMan.set(xFrame->getPropertyValue( ::rtl::OUString::createFromAscii("LayoutManager") ),uno::UNO_QUERY);
+ }
+ catch ( uno::Exception& )
+ {
+ throw uno::RuntimeException();
+ }
+
+ return xMan;
+}
+
+//--------------------------------------------------------------------
+uno::Reference< frame::XDispatchProvider > SAL_CALL SdrLightEmbeddedClient_Impl::getInplaceDispatchProvider()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ return uno::Reference < frame::XDispatchProvider >( lcl_getFrame_throw(mpObj), uno::UNO_QUERY_THROW );
+}
+
+//--------------------------------------------------------------------
+awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getPlacement()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !mpObj )
+ throw uno::RuntimeException();
+
+ Rectangle aLogicRect = impl_getScaledRect_nothrow();
+ MapUnit aContainerMapUnit( MAP_100TH_MM );
+ uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
+ if ( xParentVis.is() )
+ aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
+
+ aLogicRect = Application::GetDefaultDevice()->LogicToPixel(aLogicRect,aContainerMapUnit);
+ return AWTRectangle( aLogicRect );
+}
+
+//--------------------------------------------------------------------
+awt::Rectangle SAL_CALL SdrLightEmbeddedClient_Impl::getClipRectangle()
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+ return getPlacement();
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::translateAccelerators( const uno::Sequence< awt::KeyEvent >& /*aKeys*/ )
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::scrollObject( const awt::Size& /*aOffset*/ )
+ throw ( embed::WrongStateException,
+ uno::RuntimeException )
+{
+}
+
+//--------------------------------------------------------------------
+void SAL_CALL SdrLightEmbeddedClient_Impl::changedPlacement( const awt::Rectangle& aPosRect )
+ throw ( embed::WrongStateException,
+ uno::Exception,
+ uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !mpObj )
+ throw uno::RuntimeException();
+
+ uno::Reference< embed::XInplaceObject > xInplace( mpObj->GetObjRef(), uno::UNO_QUERY );
+ if ( !xInplace.is() )
+ throw uno::RuntimeException();
+
+ // check if the change is at least one pixel in size
+ awt::Rectangle aOldRect = getPlacement();
+ Rectangle aNewPixelRect = VCLRectangle( aPosRect );
+ Rectangle aOldPixelRect = VCLRectangle( aOldRect );
+ if ( aOldPixelRect == aNewPixelRect )
+ // nothing has changed
+ return;
+
+ // new scaled object area
+ MapUnit aContainerMapUnit( MAP_100TH_MM );
+ uno::Reference< embed::XVisualObject > xParentVis( mpObj->GetParentXModel(), uno::UNO_QUERY );
+ if ( xParentVis.is() )
+ aContainerMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xParentVis->getMapUnit( mpObj->GetAspect() ) );
+
+ Rectangle aNewLogicRect = Application::GetDefaultDevice()->PixelToLogic(aNewPixelRect,aContainerMapUnit);
+ Rectangle aLogicRect = impl_getScaledRect_nothrow();
+
+ if ( aNewLogicRect != aLogicRect )
+ {
+ // the calculation of the object area has not changed the object size
+ // it should be done here then
+ //SfxBooleanFlagGuard aGuard( m_bResizeNoScale, sal_True );
+
+ // new size of the object area without scaling
+ Size aNewObjSize( Fraction( aNewLogicRect.GetWidth() ) / m_aScaleWidth,
+ Fraction( aNewLogicRect.GetHeight() ) / m_aScaleHeight );
+
+ // now remove scaling from new placement and keep this a the new object area
+ aNewLogicRect.SetSize( aNewObjSize );
+ // react to the change if the difference is bigger than one pixel
+ Size aPixelDiff =
+ Application::GetDefaultDevice()->LogicToPixel(
+ Size( aLogicRect.GetWidth() - aNewObjSize.Width(),
+ aLogicRect.GetHeight() - aNewObjSize.Height() ),
+ aContainerMapUnit );
+ if( aPixelDiff.Width() || aPixelDiff.Height() )
+ {
+ mpObj->SetLogicRect( Rectangle( aLogicRect.TopLeft(), aNewObjSize ) );
+ mpObj->BroadcastObjectChange();
+ }
+ else
+ mpObj->ActionChanged();
+
+ // let the window size be recalculated
+ //SizeHasChanged(); // TODO: OJ
+ }
+}
+// XWindowSupplier
+//--------------------------------------------------------------------
+uno::Reference< awt::XWindow > SAL_CALL SdrLightEmbeddedClient_Impl::getWindow()
+ throw ( uno::RuntimeException )
+{
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ uno::Reference< awt::XWindow > xCurrent = m_xWindow;
+ if ( !xCurrent.is() )
+ {
+ if ( !mpObj )
+ throw uno::RuntimeException();
+ uno::Reference< frame::XFrame> xFrame(lcl_getFrame_throw(mpObj),uno::UNO_QUERY_THROW);
+ xCurrent = xFrame->getComponentWindow();
+ } // if ( !xCurrent.is() )
+ return xCurrent;
+}
+void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference< awt::XWindow >& _xWindow)
+{
+ m_xWindow = _xWindow;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SdrEmbedObjectLink : public sfx2::SvBaseLink
+{
+ SdrOle2Obj* pObj;
+
+public:
+ SdrEmbedObjectLink(SdrOle2Obj* pObj);
+ virtual ~SdrEmbedObjectLink();
+
+ virtual void Closed();
+ virtual void DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+
+ sal_Bool Connect() { return GetRealObject() != NULL; }
+};
+
+// -----------------------------------------------------------------------------
+
+SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj* pObject):
+ ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB ),
+ pObj(pObject)
+{
+ SetSynchron( FALSE );
+}
+
+// -----------------------------------------------------------------------------
+
+SdrEmbedObjectLink::~SdrEmbedObjectLink()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrEmbedObjectLink::DataChanged( const String& /*rMimeType*/,
+ const ::com::sun::star::uno::Any & /*rValue*/ )
+{
+ if ( !pObj->UpdateLinkURL_Impl() )
+ {
+ // the link URL was not changed
+ uno::Reference< embed::XEmbeddedObject > xObject = pObj->GetObjRef();
+ OSL_ENSURE( xObject.is(), "The object must exist always!\n" );
+ if ( xObject.is() )
+ {
+ // let the object reload the link
+ // TODO/LATER: reload call could be used for this case
+
+ try
+ {
+ sal_Int32 nState = xObject->getCurrentState();
+ if ( nState != embed::EmbedStates::LOADED )
+ {
+ // in some cases the linked file probably is not locked so it could be changed
+ xObject->changeState( embed::EmbedStates::LOADED );
+ xObject->changeState( nState );
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ }
+
+ pObj->GetNewReplacement();
+ pObj->SetChanged();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrEmbedObjectLink::Closed()
+{
+ pObj->BreakFileLink_Impl();
+ SvBaseLink::Closed();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SdrOle2ObjImpl
+{
+public:
+ // TODO/LATER: do we really need this pointer?
+ GraphicObject* pGraphicObject;
+ String aPersistName; // name of object in persist
+ SdrLightEmbeddedClient_Impl* pLightClient; // must be registered as client only using AddOwnLightClient() call
+
+ // #107645#
+ // New local var to avoid repeated loading if load of OLE2 fails
+ sal_Bool mbLoadingOLEObjectFailed;
+ sal_Bool mbConnected;
+
+ SdrEmbedObjectLink* mpObjectLink;
+ String maLinkURL;
+
+ SdrOle2ObjImpl()
+ : pGraphicObject( NULL )
+ // #107645#
+ // init to start situation, loading did not fail
+ , mbLoadingOLEObjectFailed( sal_False )
+ , mbConnected( sal_False )
+ , mpObjectLink( NULL )
+ {
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Predicate determining whether the given OLE is an internal math
+// object
+static bool ImplIsMathObj( const uno::Reference < embed::XEmbeddedObject >& rObjRef )
+{
+ if ( !rObjRef.is() )
+ return false;
+
+ SvGlobalName aClassName( rObjRef->getClassID() );
+ if( aClassName == SvGlobalName(SO3_SM_CLASSID_30) ||
+ aClassName == SvGlobalName(SO3_SM_CLASSID_40) ||
+ aClassName == SvGlobalName(SO3_SM_CLASSID_50) ||
+ aClassName == SvGlobalName(SO3_SM_CLASSID_60) ||
+ aClassName == SvGlobalName(SO3_SM_CLASSID) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrOle2Obj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::OleProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrOle2Obj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrOle2Obj(*this);
+}
+
+// -----------------------------------------------------------------------------
+
+TYPEINIT1(SdrOle2Obj,SdrRectObj);
+DBG_NAME(SdrOle2Obj)
+SdrOle2Obj::SdrOle2Obj(FASTBOOL bFrame_) : m_bTypeAsked(false)
+,m_bChart(false)
+{
+ DBG_CTOR( SdrOle2Obj,NULL);
+ bInDestruction = FALSE;
+ Init();
+ bFrame=bFrame_;
+}
+
+// -----------------------------------------------------------------------------
+SdrOle2Obj::SdrOle2Obj( const svt::EmbeddedObjectRef& rNewObjRef, FASTBOOL bFrame_)
+ : xObjRef( rNewObjRef )
+ , m_bTypeAsked(false)
+ , m_bChart(false)
+{
+ DBG_CTOR( SdrOle2Obj,NULL);
+ bInDestruction = FALSE;
+ Init();
+
+ bFrame=bFrame_;
+
+ if ( xObjRef.is() && (xObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
+ SetResizeProtect(TRUE);
+
+ // #108759# For math objects, set closed state to transparent
+ if( ImplIsMathObj( xObjRef.GetObject() ) )
+ SetClosedObj( false );
+}
+
+// -----------------------------------------------------------------------------
+
+SdrOle2Obj::SdrOle2Obj( const svt::EmbeddedObjectRef& rNewObjRef, const XubString& rNewObjName, FASTBOOL bFrame_)
+ : xObjRef( rNewObjRef )
+ , m_bTypeAsked(false)
+ , m_bChart(false)
+{
+ DBG_CTOR( SdrOle2Obj,NULL);
+ bInDestruction = FALSE;
+ Init();
+
+ mpImpl->aPersistName = rNewObjName;
+ bFrame=bFrame_;
+
+ if ( xObjRef.is() && (xObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
+ SetResizeProtect(TRUE);
+
+ // #108759# For math objects, set closed state to transparent
+ if( ImplIsMathObj( xObjRef.GetObject() ) )
+ SetClosedObj( false );
+}
+
+// -----------------------------------------------------------------------------
+
+SdrOle2Obj::SdrOle2Obj( const svt::EmbeddedObjectRef& rNewObjRef, const XubString& rNewObjName, const Rectangle& rNewRect, FASTBOOL bFrame_)
+ : SdrRectObj(rNewRect)
+ , xObjRef( rNewObjRef )
+ , m_bTypeAsked(false)
+ , m_bChart(false)
+{
+ DBG_CTOR( SdrOle2Obj,NULL);
+ bInDestruction = FALSE;
+ Init();
+
+ mpImpl->aPersistName = rNewObjName;
+ bFrame=bFrame_;
+
+ if ( xObjRef.is() && (xObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
+ SetResizeProtect(TRUE);
+
+ // #108759# For math objects, set closed state to transparent
+ if( ImplIsMathObj( xObjRef.GetObject() ) )
+ SetClosedObj( false );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::Init()
+{
+ mpImpl = new SdrOle2ObjImpl;
+ pModifyListener = NULL;
+ pGraphic=NULL;
+ mpImpl->pGraphicObject=NULL;
+ mpImpl->pLightClient = 0;
+
+ xObjRef.Lock( TRUE );
+}
+
+// -----------------------------------------------------------------------------
+
+SdrOle2Obj::~SdrOle2Obj()
+{
+ DBG_DTOR( SdrOle2Obj,NULL);
+ bInDestruction = TRUE;
+
+ if ( mpImpl->mbConnected )
+ Disconnect();
+
+ if( pGraphic!=NULL )
+ delete pGraphic;
+
+ if(mpImpl->pGraphicObject!=NULL)
+ delete mpImpl->pGraphicObject;
+
+ if(pModifyListener)
+ {
+ pModifyListener->invalidate();
+ pModifyListener->release();
+ }
+
+ DisconnectFileLink_Impl();
+
+ if ( mpImpl->pLightClient )
+ {
+ mpImpl->pLightClient->Release();
+ mpImpl->pLightClient = NULL;
+ }
+
+ delete mpImpl;
+}
+
+// -----------------------------------------------------------------------------
+void SdrOle2Obj::SetAspect( sal_Int64 nAspect )
+{
+ xObjRef.SetViewAspect( nAspect );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetGraphic_Impl(const Graphic* pGrf)
+{
+ if ( pGraphic )
+ {
+ delete pGraphic;
+ pGraphic = NULL;
+ delete mpImpl->pGraphicObject;
+ mpImpl->pGraphicObject = NULL;
+ }
+
+ if (pGrf!=NULL)
+ {
+ pGraphic = new Graphic(*pGrf);
+ mpImpl->pGraphicObject = new GraphicObject( *pGraphic );
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+
+ //if ( ppObjRef->Is() && pGrf )
+ // BroadcastObjectChange();
+}
+
+void SdrOle2Obj::SetGraphic(const Graphic* pGrf)
+{
+ // only for setting a preview graphic
+ SetGraphic_Impl( pGrf );
+}
+
+// -----------------------------------------------------------------------------
+
+FASTBOOL SdrOle2Obj::IsEmpty() const
+{
+ return !(xObjRef.is());
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::Connect()
+{
+ if( IsEmptyPresObj() )
+ return;
+
+ if( mpImpl->mbConnected )
+ {
+ // mba: currently there are situations where it seems to be unavoidable to have multiple connects
+ // changing this would need a larger code rewrite, so for now I remove the assertion
+ // DBG_ERROR("Connect() called on connected object!");
+ return;
+ }
+
+ Connect_Impl();
+ AddListeners_Impl();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SdrOle2Obj::UpdateLinkURL_Impl()
+{
+ sal_Bool bResult = sal_False;
+
+ if ( mpImpl->mpObjectLink )
+ {
+ sfx2::LinkManager* pLinkManager = pModel ? pModel->GetLinkManager() : NULL;
+ if ( pLinkManager )
+ {
+ String aNewLinkURL;
+ pLinkManager->GetDisplayNames( mpImpl->mpObjectLink, 0, &aNewLinkURL, 0, 0 );
+ if ( !aNewLinkURL.EqualsIgnoreCaseAscii( mpImpl->maLinkURL ) )
+ {
+ const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
+ uno::Reference< embed::XCommonEmbedPersist > xPersObj( xObjRef.GetObject(), uno::UNO_QUERY );
+ OSL_ENSURE( xPersObj.is(), "The object must exist!\n" );
+ if ( xPersObj.is() )
+ {
+ try
+ {
+ sal_Int32 nCurState = xObjRef->getCurrentState();
+ if ( nCurState != embed::EmbedStates::LOADED )
+ xObjRef->changeState( embed::EmbedStates::LOADED );
+
+ // TODO/LATER: there should be possible to get current mediadescriptor settings from the object
+ uno::Sequence< beans::PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
+ aArgs[0].Value <<= ::rtl::OUString( aNewLinkURL );
+ xPersObj->reload( aArgs, uno::Sequence< beans::PropertyValue >() );
+
+ mpImpl->maLinkURL = aNewLinkURL;
+ bResult = sal_True;
+
+ if ( nCurState != embed::EmbedStates::LOADED )
+ xObjRef->changeState( nCurState );
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::UpdateLinkURL_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+
+ if ( !bResult )
+ {
+ // TODO/LATER: return the old name to the link manager, is it possible?
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::BreakFileLink_Impl()
+{
+ uno::Reference<document::XStorageBasedDocument> xDoc;
+ if ( pModel )
+ xDoc.set( pModel->getUnoModel(),uno::UNO_QUERY);
+
+ if ( xDoc.is() )
+ {
+ uno::Reference< embed::XStorage > xStorage = xDoc->getDocumentStorage();
+ if ( xStorage.is() )
+ {
+ try
+ {
+ uno::Reference< embed::XLinkageSupport > xLinkSupport( xObjRef.GetObject(), uno::UNO_QUERY_THROW );
+ xLinkSupport->breakLink( xStorage, mpImpl->aPersistName );
+ DisconnectFileLink_Impl();
+ mpImpl->maLinkURL = String();
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::BreakFileLink_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::DisconnectFileLink_Impl()
+{
+ sfx2::LinkManager* pLinkManager = pModel ? pModel->GetLinkManager() : NULL;
+ if ( pLinkManager && mpImpl->mpObjectLink )
+ {
+ pLinkManager->Remove( mpImpl->mpObjectLink );
+ mpImpl->mpObjectLink = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::CheckFileLink_Impl()
+{
+ if ( pModel && xObjRef.GetObject().is() && !mpImpl->mpObjectLink )
+ {
+ try
+ {
+ uno::Reference< embed::XLinkageSupport > xLinkSupport( xObjRef.GetObject(), uno::UNO_QUERY );
+ if ( xLinkSupport.is() && xLinkSupport->isLink() )
+ {
+ String aLinkURL = xLinkSupport->getLinkURL();
+ if ( aLinkURL.Len() )
+ {
+ // this is a file link so the model link manager should handle it
+ sfx2::LinkManager* pLinkManager = pModel->GetLinkManager();
+ if ( pLinkManager )
+ {
+ mpImpl->mpObjectLink = new SdrEmbedObjectLink( this );
+ mpImpl->maLinkURL = aLinkURL;
+ pLinkManager->InsertFileLink( *mpImpl->mpObjectLink, OBJECT_CLIENT_OLE, aLinkURL, NULL, NULL );
+ mpImpl->mpObjectLink->Connect();
+ }
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::CheckFileLink_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::Reconnect_Impl()
+{
+ DBG_ASSERT( mpImpl->mbConnected, "Assigned unconnected object?!" );
+ Connect_Impl();
+}
+
+void SdrOle2Obj::Connect_Impl()
+{
+ if( pModel && mpImpl->aPersistName.Len() )
+ {
+ try
+ {
+ ::comphelper::IEmbeddedHelper* pPers = pModel->GetPersist();
+ if ( pPers )
+ {
+ comphelper::EmbeddedObjectContainer& rContainer = pPers->getEmbeddedObjectContainer();
+ if ( !rContainer.HasEmbeddedObject( mpImpl->aPersistName )
+ || ( xObjRef.is() && !rContainer.HasEmbeddedObject( xObjRef.GetObject() ) ) )
+ {
+ // object not known to container document
+ // No object -> disaster!
+ DBG_ASSERT( xObjRef.is(), "No object in connect!");
+ if ( xObjRef.is() )
+ {
+ // object came from the outside, now add it to the container
+ ::rtl::OUString aTmp;
+ rContainer.InsertEmbeddedObject( xObjRef.GetObject(), aTmp );
+ mpImpl->aPersistName = aTmp;
+ }
+ }
+ else if ( !xObjRef.is() )
+ {
+ xObjRef.Assign( rContainer.GetEmbeddedObject( mpImpl->aPersistName ), xObjRef.GetViewAspect() );
+ m_bTypeAsked = false;
+ }
+
+ if ( xObjRef.GetObject().is() )
+ {
+ xObjRef.AssignToContainer( &rContainer, mpImpl->aPersistName );
+ mpImpl->mbConnected = true;
+ xObjRef.Lock( TRUE );
+ }
+ }
+
+ if ( xObjRef.is() )
+ {
+ if ( !mpImpl->pLightClient )
+ {
+ mpImpl->pLightClient = new SdrLightEmbeddedClient_Impl( this );
+ mpImpl->pLightClient->acquire();
+ }
+
+ xObjRef->addStateChangeListener( mpImpl->pLightClient );
+ xObjRef->addEventListener( uno::Reference< document::XEventListener >( mpImpl->pLightClient ) );
+
+ if ( xObjRef->getCurrentState() != embed::EmbedStates::LOADED )
+ GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
+
+ CheckFileLink_Impl();
+
+ uno::Reference< container::XChild > xChild( xObjRef.GetObject(), uno::UNO_QUERY );
+ if( xChild.is() )
+ {
+ uno::Reference< uno::XInterface > xParent( pModel->getUnoModel());
+ if( xParent.is())
+ xChild->setParent( pModel->getUnoModel() );
+ }
+
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::Connect_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+
+ //TODO/LATER: wait for definition of MiscStatus RESIZEONPRINTERCHANGE
+ //if ( xObjRef.is() && (*ppObjRef)->GetMiscStatus() & SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE )
+ {
+ //TODO/LATER: needs a new handling for OnPrinterChanged
+ /*
+ if (pModel && pModel->GetRefDevice() &&
+ pModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ // Kein RefDevice oder RefDevice kein Printer
+ BOOL bModified = (*ppObjRef)->IsModified();
+ Printer* pPrinter = (Printer*) pModel->GetRefDevice();
+ (*ppObjRef)->OnDocumentPrinterChanged( pPrinter );
+ (*ppObjRef)->SetModified( bModified );
+ }*/
+ }
+}
+
+void SdrOle2Obj::ObjectLoaded()
+{
+ AddListeners_Impl();
+}
+
+void SdrOle2Obj::AddListeners_Impl()
+{
+ if( xObjRef.is() && xObjRef->getCurrentState() != embed::EmbedStates::LOADED )
+ {
+ // register modify listener
+ if( !pModifyListener )
+ {
+ ((SdrOle2Obj*)this)->pModifyListener = new SvxUnoShapeModifyListener( (SdrOle2Obj*)this );
+ pModifyListener->acquire();
+ }
+
+ uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
+ if( xBC.is() && pModifyListener )
+ {
+ uno::Reference< util::XModifyListener > xListener( pModifyListener );
+ xBC->addModifyListener( xListener );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::Disconnect()
+{
+ if( IsEmptyPresObj() )
+ return;
+
+ if( !mpImpl->mbConnected )
+ {
+ DBG_ERROR("Disconnect() called on disconnected object!");
+ return;
+ }
+
+ RemoveListeners_Impl();
+ Disconnect_Impl();
+}
+
+void SdrOle2Obj::RemoveListeners_Impl()
+{
+ if( xObjRef.is() && mpImpl->aPersistName.Len() )
+ {
+ try
+ {
+ sal_Int32 nState = xObjRef->getCurrentState();
+ if ( nState != embed::EmbedStates::LOADED )
+ {
+ uno::Reference< util::XModifyBroadcaster > xBC( getXModel(), uno::UNO_QUERY );
+ if( xBC.is() && pModifyListener )
+ {
+ uno::Reference< util::XModifyListener > xListener( pModifyListener );
+ xBC->removeModifyListener( xListener );
+ }
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::RemoveListeners_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+}
+
+void SdrOle2Obj::Disconnect_Impl()
+{
+ try
+ {
+ if ( pModel && mpImpl->aPersistName.Len() )
+ {
+ if( pModel->IsInDestruction() )
+ {
+ // TODO/LATER: here we must assume that the destruction of the model is enough to make clear that we will not
+ // remove the object from the container, even if the DrawingObject itself is not destroyed (unfortunately this
+ // There is no real need to do the following removing of the object from the container
+ // in case the model has correct persistance, but in case of problems such a removing
+ // would make the behaviour of the office more stable
+
+ comphelper::EmbeddedObjectContainer* pContainer = xObjRef.GetContainer();
+ if ( pContainer )
+ {
+ pContainer->CloseEmbeddedObject( xObjRef.GetObject() );
+ xObjRef.AssignToContainer( NULL, mpImpl->aPersistName );
+ }
+
+ // happens later than the destruction of the model, so we can't assert that).
+ //DBG_ASSERT( bInDestruction, "Model is destroyed, but not me?!" );
+ //TODO/LATER: should be make sure that the ObjectShell also forgets the object, because we will close it soon?
+ /*
+ uno::Reference < util::XCloseable > xClose( xObjRef, uno::UNO_QUERY );
+ if ( xClose.is() )
+ {
+ try
+ {
+ xClose->close( sal_True );
+ }
+ catch ( util::CloseVetoException& )
+ {
+ // there's still someone who needs the object!
+ }
+ }
+
+ xObjRef = NULL;*/
+ }
+ else if ( xObjRef.is() )
+ {
+ if ( pModel->getUnoModel().is() )
+ {
+ // remove object, but don't close it (that's up to someone else)
+ comphelper::EmbeddedObjectContainer* pContainer = xObjRef.GetContainer();
+ if ( pContainer )
+ {
+ pContainer->RemoveEmbeddedObject( xObjRef.GetObject(), sal_False);
+
+ // TODO/LATER: mpImpl->aPersistName contains outdated information, to have it uptodate
+ // it should be returned from RemoveEmbeddedObject call. Currently it is no problem,
+ // since no container is adjusted, actually the empty string could be provided as a name here
+ xObjRef.AssignToContainer( NULL, mpImpl->aPersistName );
+ }
+
+ DisconnectFileLink_Impl();
+ }
+ }
+ }
+
+ if ( xObjRef.is() && mpImpl->pLightClient )
+ {
+ xObjRef->removeStateChangeListener ( mpImpl->pLightClient );
+ xObjRef->removeEventListener( uno::Reference< document::XEventListener >( mpImpl->pLightClient ) );
+ xObjRef->setClientSite( NULL );
+
+ GetSdrGlobalData().GetOLEObjCache().RemoveObj(this);
+ }
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::Disconnect_Impl(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+
+ mpImpl->mbConnected = false;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetModel(SdrModel* pNewModel)
+{
+ ::comphelper::IEmbeddedHelper* pDestPers = pNewModel ? pNewModel->GetPersist() : 0;
+ ::comphelper::IEmbeddedHelper* pSrcPers = pModel ? pModel->GetPersist() : 0;
+
+ if ( pNewModel == pModel )
+ {
+ // don't know if this is necessary or if it will ever happen, but who know?!
+ SdrRectObj::SetModel( pNewModel );
+ return;
+ }
+
+ // assignment to model has changed
+ DBG_ASSERT( pSrcPers || !mpImpl->mbConnected, "Connected object without a model?!" );
+
+ DBG_ASSERT( pDestPers, "The destination model must have a persistence! Please submit an issue!" );
+ DBG_ASSERT( pDestPers != pSrcPers, "The source and the destination models should have different persistences! Problems are possible!" );
+
+ // this is a bug if the target model has no persistence
+ // no error handling is possible so just do nothing in this method
+ if ( !pDestPers )
+ return;
+
+ RemoveListeners_Impl();
+
+ if( pDestPers && pSrcPers && !IsEmptyPresObj() )
+ {
+ try
+ {
+ // move the objects' storage; ObjectRef remains the same, but PersistName may change
+ ::rtl::OUString aTmp;
+ comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
+ uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
+ DBG_ASSERT( !xObjRef.is() || xObjRef.GetObject() == xObj, "Wrong object identity!" );
+ if ( xObj.is() )
+ {
+ pDestPers->getEmbeddedObjectContainer().MoveEmbeddedObject( rContainer, xObj, aTmp );
+ mpImpl->aPersistName = aTmp;
+ xObjRef.AssignToContainer( &pDestPers->getEmbeddedObjectContainer(), aTmp );
+ }
+ DBG_ASSERT( aTmp.getLength(), "Copying embedded object failed!" );
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::SetModel(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+
+ SdrRectObj::SetModel( pNewModel );
+
+ // #i43086#
+ // #i85304 redo the change for charts for the above bugfix, as #i43086# does not ocur anymore
+ //so maybe the ImpSetVisAreaSize call can be removed here completely
+ //Nevertheless I leave it in for other objects as I am not sure about the side effects when removing now
+ if( pModel && !pModel->isLocked() && !IsChart() )
+ ImpSetVisAreaSize();
+
+ if( pDestPers && !IsEmptyPresObj() )
+ {
+ if ( !pSrcPers || IsEmptyPresObj() )
+ // object wasn't connected, now it should
+ Connect_Impl();
+ else
+ Reconnect_Impl();
+ }
+
+ AddListeners_Impl();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetPage(SdrPage* pNewPage)
+{
+ FASTBOOL bRemove=pNewPage==NULL && pPage!=NULL;
+ FASTBOOL bInsert=pNewPage!=NULL && pPage==NULL;
+
+ if (bRemove && mpImpl->mbConnected )
+ Disconnect();
+
+ SdrRectObj::SetPage(pNewPage);
+
+ if (bInsert && !mpImpl->mbConnected )
+ Connect();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetObjRef( const com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >& rNewObjRef )
+{
+ DBG_ASSERT( !rNewObjRef.is() || !xObjRef.GetObject().is(), "SetObjRef called on already initialized object!");
+ if( rNewObjRef == xObjRef.GetObject() )
+ return;
+
+ // MBA: the caller of the method is responsible to control the old object, it will not be closed here
+ // Otherwise WW8 import crashes because it tranfers control to OLENode by this method
+ if ( xObjRef.GetObject().is() )
+ xObjRef.Lock( FALSE );
+
+ // MBA: avoid removal of object in Disconnect! It is definitely a HACK to call SetObjRef(0)!
+ // This call will try to close the objects; so if anybody else wants to keep it, it must be locked by a CloseListener
+ xObjRef.Clear();
+
+ if ( mpImpl->mbConnected )
+ Disconnect();
+
+ xObjRef.Assign( rNewObjRef, GetAspect() );
+ m_bTypeAsked = false;
+
+ if ( xObjRef.is() )
+ {
+ DELETEZ( pGraphic );
+
+ if ( (xObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
+ SetResizeProtect(TRUE);
+
+ // #108759# For math objects, set closed state to transparent
+ if( ImplIsMathObj( rNewObjRef ) )
+ SetClosedObj( false );
+
+ Connect();
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetClosedObj( bool bIsClosed )
+{
+ // TODO/LATER: do we still need this hack?
+ // #108759# Allow changes to the closed state of OLE objects
+ bClosedObj = bIsClosed;
+}
+
+// -----------------------------------------------------------------------------
+
+SdrObject* SdrOle2Obj::getFullDragClone() const
+{
+ // special handling for OLE. The default handling works, but is too
+ // slow when the whole OLE needs to be cloned. Get the Metafile and
+ // create a graphic object with it
+ Graphic* pOLEGraphic = GetGraphic();
+ SdrObject* pClone = 0;
+
+ if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ pOLEGraphic = getEmbeddedObjectRef().GetHCGraphic();
+ }
+
+ if(pOLEGraphic)
+ {
+ pClone = new SdrGrafObj(*pOLEGraphic, GetSnapRect());
+
+ // this would be the place where to copy all attributes
+ // when OLE will support fill and line style
+ // pClone->SetMergedItem(pOleObject->GetMergedItemSet());
+ }
+ else
+ {
+ // #i100710# pOLEGraphic may be zero (no visualisation available),
+ // so we need to use the OLE replacement graphic
+ pClone = new SdrRectObj(GetSnapRect());
+
+ // gray outline
+ pClone->SetMergedItem(XLineStyleItem(XLINE_SOLID));
+ const svtools::ColorConfig aColorConfig;
+ const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES));
+ pClone->SetMergedItem(XLineColorItem(String(), aColor.nColor));
+
+ // bitmap fill
+ pClone->SetMergedItem(XFillStyleItem(XFILL_BITMAP));
+ pClone->SetMergedItem(XFillBitmapItem(String(), GetEmtyOLEReplacementBitmap()));
+ pClone->SetMergedItem(XFillBmpTileItem(false));
+ pClone->SetMergedItem(XFillBmpStretchItem(false));
+ }
+
+ return pClone;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetPersistName( const String& rPersistName )
+{
+ DBG_ASSERT( !mpImpl->aPersistName.Len(), "Persist name changed!");
+
+ mpImpl->aPersistName = rPersistName;
+ mpImpl->mbLoadingOLEObjectFailed = false;
+
+ Connect();
+ SetChanged();
+}
+
+void SdrOle2Obj::AbandonObject()
+{
+ mpImpl->aPersistName.Erase();
+ mpImpl->mbLoadingOLEObjectFailed = false;
+ SetObjRef(0);
+}
+
+// -----------------------------------------------------------------------------
+
+String SdrOle2Obj::GetPersistName() const
+{
+ return mpImpl->aPersistName;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bRotate90Allowed =FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bMirror45Allowed =FALSE;
+ rInfo.bMirror90Allowed =FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bNoOrthoDesired =FALSE;
+ rInfo.bCanConvToPath =FALSE;
+ rInfo.bCanConvToPoly =FALSE;
+ rInfo.bCanConvToPathLineToArea=FALSE;
+ rInfo.bCanConvToPolyLineToArea=FALSE;
+ rInfo.bCanConvToContour = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+UINT16 SdrOle2Obj::GetObjIdentifier() const
+{
+ return bFrame ? UINT16(OBJ_FRAME) : UINT16(OBJ_OLE2);
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::TakeObjNameSingul(XubString& rName) const
+{
+ rName = ImpGetResStr(bFrame ? STR_ObjNameSingulFrame : STR_ObjNameSingulOLE2);
+
+ const String aName(GetName());
+
+ if( aName.Len() )
+ {
+ rName.AppendAscii(" '");
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(bFrame ? STR_ObjNamePluralFrame : STR_ObjNamePluralOLE2);
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::operator=(const SdrObject& rObj)
+{
+ //TODO/LATER: who takes over control of my old object?!
+ if( &rObj != this )
+ {
+ // #116235#
+ // ImpAssign( rObj );
+ const SdrOle2Obj& rOle2Obj = static_cast< const SdrOle2Obj& >( rObj );
+
+ uno::Reference < util::XCloseable > xClose( xObjRef.GetObject(), uno::UNO_QUERY );
+
+ if( pModel && mpImpl->mbConnected )
+ Disconnect();
+
+ SdrRectObj::operator=( rObj );
+
+ // #108867# Manually copying bClosedObj attribute
+ SetClosedObj( rObj.IsClosedObj() );
+
+ mpImpl->aPersistName = rOle2Obj.mpImpl->aPersistName;
+ aProgName = rOle2Obj.aProgName;
+ bFrame = rOle2Obj.bFrame;
+
+ if( rOle2Obj.pGraphic )
+ {
+ if( pGraphic )
+ {
+ delete pGraphic;
+ delete mpImpl->pGraphicObject;
+ }
+
+ pGraphic = new Graphic( *rOle2Obj.pGraphic );
+ mpImpl->pGraphicObject = new GraphicObject( *pGraphic );
+ }
+
+ if( pModel && rObj.GetModel() && !IsEmptyPresObj() )
+ {
+ ::comphelper::IEmbeddedHelper* pDestPers = pModel->GetPersist();
+ ::comphelper::IEmbeddedHelper* pSrcPers = rObj.GetModel()->GetPersist();
+ if( pDestPers && pSrcPers )
+ {
+ DBG_ASSERT( !xObjRef.is(), "Object already existing!" );
+ comphelper::EmbeddedObjectContainer& rContainer = pSrcPers->getEmbeddedObjectContainer();
+ uno::Reference < embed::XEmbeddedObject > xObj = rContainer.GetEmbeddedObject( mpImpl->aPersistName );
+ if ( xObj.is() )
+ {
+ ::rtl::OUString aTmp;
+ xObjRef.Assign( pDestPers->getEmbeddedObjectContainer().CopyAndGetEmbeddedObject( rContainer, xObj, aTmp ), rOle2Obj.GetAspect() );
+ m_bTypeAsked = false;
+ mpImpl->aPersistName = aTmp;
+ CheckFileLink_Impl();
+ }
+
+ Connect();
+
+ /* only needed for MSOLE-Objects, now handled inside implementation of Object
+ if ( xObjRef.is() && rOle2Obj.xObjRef.is() && rOle2Obj.GetAspect() != embed::Aspects::MSOLE_ICON )
+ {
+ try
+ {
+ awt::Size aVisSize = rOle2Obj.xObjRef->getVisualAreaSize( rOle2Obj.GetAspect() );
+ if( rOle2Obj.xObjRef->getMapUnit( rOle2Obj.GetAspect() ) == xObjRef->getMapUnit( GetAspect() ) )
+ xObjRef->setVisualAreaSize( GetAspect(), aVisSize );
+ }
+ catch ( embed::WrongStateException& )
+ {
+ // setting of VisArea not necessary for objects that don't cache it in loaded state
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {
+ // objects my not have visual areas
+ }
+ catch( uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR( "SdrOle2Obj::operator=(), unexcpected exception caught!" );
+ }
+ } */
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::ImpSetVisAreaSize()
+{
+ // currently there is no need to recalculate scaling for iconified objects
+ // TODO/LATER: it might be needed in future when it is possible to change the icon
+ if ( GetAspect() == embed::Aspects::MSOLE_ICON )
+ return;
+
+ // the object area of an embedded object was changed, e.g. by user interaction an a selected object
+ GetObjRef();
+ if ( xObjRef.is() )
+ {
+ OSL_ASSERT( pModel );
+ sal_Int64 nMiscStatus = xObjRef->getStatus( GetAspect() );
+
+ // the client is required to get access to scaling
+ SfxInPlaceClient* pClient = SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(pModel->GetPersist()), xObjRef.GetObject() );
+ sal_Bool bHasOwnClient =
+ ( mpImpl->pLightClient
+ && xObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->pLightClient ) );
+
+ if ( pClient || bHasOwnClient )
+ {
+ // TODO/LATER: IMHO we need to do similar things when object is UIActive or OutplaceActive?! (MBA)
+ if ( ((nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
+ svt::EmbeddedObjectRef::TryRunningState( xObjRef.GetObject() ))
+ || xObjRef->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
+ )
+ {
+ Fraction aScaleWidth;
+ Fraction aScaleHeight;
+ if ( pClient )
+ {
+ aScaleWidth = pClient->GetScaleWidth();
+ aScaleHeight = pClient->GetScaleHeight();
+ }
+ else
+ {
+ aScaleWidth = mpImpl->pLightClient->GetScaleWidth();
+ aScaleHeight = mpImpl->pLightClient->GetScaleHeight();
+ }
+
+ // The object wants to resize itself (f.e. Chart wants to recalculate the layout)
+ // or object is inplace active and so has a window that must be resized also
+ // In these cases the change in the object area size will be reflected in a change of the
+ // objects' visual area. The scaling will not change, but it might exist already and must
+ // be used in calculations
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObjRef->getMapUnit( GetAspect() ) );
+ Size aVisSize( (long)( Fraction( aRect.GetWidth() ) / aScaleWidth ),
+ (long)( Fraction( aRect.GetHeight() ) / aScaleHeight ) );
+
+ aVisSize = OutputDevice::LogicToLogic( aVisSize, pModel->GetScaleUnit(), aMapUnit);
+ awt::Size aSz;
+ aSz.Width = aVisSize.Width();
+ aSz.Height = aVisSize.Height();
+ xObjRef->setVisualAreaSize( GetAspect(), aSz );
+
+ try
+ {
+ aSz = xObjRef->getVisualAreaSize( GetAspect() );
+ }
+ catch( embed::NoVisualAreaSizeException& )
+ {}
+
+ Rectangle aAcceptedVisArea;
+ aAcceptedVisArea.SetSize( Size( (long)( Fraction( long( aSz.Width ) ) * aScaleWidth ),
+ (long)( Fraction( long( aSz.Height ) ) * aScaleHeight ) ) );
+ if (aVisSize != aAcceptedVisArea.GetSize())
+ {
+ // server changed VisArea to its liking and the VisArea is different than the suggested one
+ // store the new value as given by the object
+ MapUnit aNewMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObjRef->getMapUnit( GetAspect() ) );
+ aRect.SetSize(OutputDevice::LogicToLogic( aAcceptedVisArea.GetSize(), aNewMapUnit, pModel->GetScaleUnit()));
+ }
+
+ // make the new object area known to the client
+ // compared to the "else" branch aRect might have been changed by the object and no additional scaling was applied
+ // OJ: WHY this -> OSL_ASSERT( pClient );
+ if( pClient )
+ pClient->SetObjArea(aRect);
+
+ // we need a new replacement image as the object has resized itself
+
+ //#i79578# don't request a new replacement image for charts to often
+ //a chart sends a modified call to the framework if it was changed
+ //thus the replacement update is already handled there
+ if( !IsChart() )
+ xObjRef.UpdateReplacement();
+ }
+ else
+ {
+ // The object isn't active and does not want to resize itself so the changed object area size
+ // will be reflected in a changed object scaling
+ Fraction aScaleWidth;
+ Fraction aScaleHeight;
+ Size aObjAreaSize;
+ if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
+ {
+ if ( pClient )
+ {
+ Rectangle aScaleRect(aRect.TopLeft(), aObjAreaSize);
+ pClient->SetObjAreaAndScale( aScaleRect, aScaleWidth, aScaleHeight);
+ }
+ else
+ {
+ mpImpl->pLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
+ }
+ }
+ }
+ }
+ else if( (nMiscStatus & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE) &&
+ svt::EmbeddedObjectRef::TryRunningState( xObjRef.GetObject() ) )
+ {
+ //also handle not sfx based ole objects e.g. charts
+ //#i83860# resizing charts in impress distorts fonts
+ uno::Reference< embed::XVisualObject > xVisualObject( this->getXModel(), uno::UNO_QUERY );
+ if( xVisualObject.is() )
+ {
+ MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObjRef->getMapUnit( GetAspect() ) );
+ Point aTL( aRect.TopLeft() );
+ Point aBR( aRect.BottomRight() );
+ Point aTL2( OutputDevice::LogicToLogic( aTL, pModel->GetScaleUnit(), aMapUnit) );
+ Point aBR2( OutputDevice::LogicToLogic( aBR, pModel->GetScaleUnit(), aMapUnit) );
+ Rectangle aNewRect( aTL2, aBR2 );
+ xVisualObject->setVisualAreaSize( GetAspect(), awt::Size( aNewRect.GetWidth(), aNewRect.GetHeight() ) );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ if( pModel && !pModel->isLocked() )
+ {
+ GetObjRef();
+ if ( xObjRef.is() && ( xObjRef->getStatus( GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
+ {
+ // if the object needs recompose on resize
+ // the client site should be created before the resize will take place
+ // check whether there is no client site and create it if necessary
+ AddOwnLightClient();
+ }
+ }
+
+ SdrRectObj::NbcResize(rRef,xFact,yFact);
+ if (aGeo.nShearWink!=0 || aGeo.nDrehWink!=0) { // kleine Korrekturen
+ if (aGeo.nDrehWink>=9000 && aGeo.nDrehWink<27000) {
+ aRect.Move(aRect.Left()-aRect.Right(),aRect.Top()-aRect.Bottom());
+ }
+ aGeo.nDrehWink=0;
+ aGeo.nShearWink=0;
+ aGeo.nSin=0.0;
+ aGeo.nCos=1.0;
+ aGeo.nTan=0.0;
+ SetRectsDirty();
+ }
+ if( pModel && !pModel->isLocked() )
+ ImpSetVisAreaSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::SetGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrRectObj::SetGeoData(rGeo);
+ if( pModel && !pModel->isLocked() )
+ ImpSetVisAreaSize();
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ SdrRectObj::NbcSetSnapRect(rRect);
+ if( pModel && !pModel->isLocked() )
+ ImpSetVisAreaSize();
+
+ if ( xObjRef.is() && IsChart() )
+ {
+ //#i103460# charts do not necessaryly have an own size within ODF files,
+ //for this case they need to use the size settings from the surrounding frame,
+ //which is made available with this method as there is no other way
+ xObjRef.SetDefaultSizeForChart( Size( rRect.GetWidth(), rRect.GetHeight() ) );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ SdrRectObj::NbcSetLogicRect(rRect);
+ if( pModel && !pModel->isLocked() )
+ ImpSetVisAreaSize();
+}
+
+Graphic* SdrOle2Obj::GetGraphic() const
+{
+ if ( xObjRef.is() )
+ return xObjRef.GetGraphic();
+ return pGraphic;
+}
+
+void SdrOle2Obj::GetNewReplacement()
+{
+ if ( xObjRef.is() )
+ xObjRef.UpdateReplacement();
+}
+
+// -----------------------------------------------------------------------------
+
+Size SdrOle2Obj::GetOrigObjSize( MapMode* pTargetMapMode ) const
+{
+ return xObjRef.GetSize( pTargetMapMode );
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::NbcMove(const Size& rSize)
+{
+ SdrRectObj::NbcMove(rSize);
+ if( pModel && !pModel->isLocked() )
+ ImpSetVisAreaSize();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SdrOle2Obj::CanUnloadRunningObj( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
+{
+ sal_Bool bResult = sal_False;
+
+ sal_Int32 nState = xObj->getCurrentState();
+ if ( nState == embed::EmbedStates::LOADED )
+ {
+ // the object is already unloaded
+ bResult = sal_True;
+ }
+ else
+ {
+ uno::Reference < util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
+ if ( !xModifiable.is() )
+ bResult = sal_True;
+ else
+ {
+ sal_Int64 nMiscStatus = xObj->getStatus( nAspect );
+
+ if ( embed::EmbedMisc::MS_EMBED_ALWAYSRUN != ( nMiscStatus & embed::EmbedMisc::MS_EMBED_ALWAYSRUN ) &&
+ embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY != ( nMiscStatus & embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY ) &&
+ !( xModifiable.is() && xModifiable->isModified() ) &&
+ !( nState == embed::EmbedStates::INPLACE_ACTIVE || nState == embed::EmbedStates::UI_ACTIVE || nState == embed::EmbedStates::ACTIVE ) )
+ {
+ bResult = sal_True;
+ }
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SdrOle2Obj::Unload( const uno::Reference< embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
+{
+ sal_Bool bResult = sal_False;
+
+ if ( CanUnloadRunningObj( xObj, nAspect ) )
+ {
+ try
+ {
+ xObj->changeState( embed::EmbedStates::LOADED );
+ bResult = sal_True;
+ }
+ catch( ::com::sun::star::uno::Exception& e )
+ {
+ (void)e;
+ DBG_ERROR(
+ (OString("SdrOle2Obj::Unload=(), "
+ "exception caught: ") +
+ rtl::OUStringToOString(
+ comphelper::anyToString( cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 )).getStr() );
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SdrOle2Obj::Unload()
+{
+ BOOL bUnloaded = FALSE;
+
+ if( xObjRef.is() )
+ {
+ //TODO/LATER: no refcounting tricks anymore!
+ //"customers" must register as state change listeners
+ //Nicht notwendig im Doc DTor (MM)
+ //ULONG nRefCount = (*ppObjRef)->GetRefCount();
+ // prevent Unload if there are external references
+ //if( nRefCount > 2 )
+ // return FALSE;
+ //DBG_ASSERT( nRefCount == 2, "Wrong RefCount for unload" );
+ }
+ else
+ bUnloaded = TRUE;
+
+ if ( pModel && xObjRef.is() )
+ {
+ bUnloaded = Unload( xObjRef.GetObject(), GetAspect() );
+ }
+
+ return bUnloaded;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrOle2Obj::GetObjRef_Impl()
+{
+ if ( !xObjRef.is() && mpImpl->aPersistName.Len() && pModel && pModel->GetPersist() )
+ {
+ // #107645#
+ // Only try loading if it did not went wrong up to now
+ if(!mpImpl->mbLoadingOLEObjectFailed)
+ {
+ xObjRef.Assign( pModel->GetPersist()->getEmbeddedObjectContainer().GetEmbeddedObject( mpImpl->aPersistName ), GetAspect() );
+ m_bTypeAsked = false;
+ CheckFileLink_Impl();
+
+ // #107645#
+ // If loading of OLE object failed, remember that to not invoke a endless
+ // loop trying to load it again and again.
+ if( xObjRef.is() )
+ {
+ mpImpl->mbLoadingOLEObjectFailed = sal_True;
+ }
+
+ // #108759# For math objects, set closed state to transparent
+ if( ImplIsMathObj( xObjRef.GetObject() ) )
+ SetClosedObj( false );
+ }
+
+ if ( xObjRef.is() )
+ {
+ if( !IsEmptyPresObj() )
+ {
+ // #75637# remember modified status of model
+ const sal_Bool bWasChanged(pModel ? pModel->IsChanged() : sal_False);
+
+ // perhaps preview not valid anymore
+ // #75637# This line changes the modified state of the model
+ SetGraphic_Impl( NULL );
+
+ // #75637# if status was not set before, force it back
+ // to not set, so that SetGraphic(0L) above does not
+ // set the modified state of the model.
+ if(!bWasChanged && pModel && pModel->IsChanged())
+ {
+ pModel->SetChanged( sal_False );
+ }
+ }
+
+ sal_Int64 nMiscStatus = xObjRef->getStatus( GetAspect() );
+ (void)nMiscStatus;
+ //TODO/LATER: wait until ResizeOnPrinterChange is defined
+ //if ( nMiscStatus & SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE )
+ {
+ if (pModel && pModel->GetRefDevice() &&
+ pModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ if(!bInDestruction)
+ {
+ //TODO/LATER: printerchange notification
+ /*
+ // prevent SetModified (don't want no update here)
+ sal_Bool bWasEnabled = (*ppObjRef)->IsEnableSetModified();
+ if ( bWasEnabled )
+ (*ppObjRef)->EnableSetModified( sal_False );
+
+ // Kein RefDevice oder RefDevice kein Printer
+ Printer* pPrinter = (Printer*) pModel->GetRefDevice();
+ (*ppObjRef)->OnDocumentPrinterChanged( pPrinter );
+
+ // reset state
+ (*ppObjRef)->EnableSetModified( bWasEnabled );*/
+ }
+ }
+ }
+ }
+
+ if ( xObjRef.is() )
+ Connect();
+ }
+
+ if ( mpImpl->mbConnected )
+ // move object to first position in cache
+ GetSdrGlobalData().GetOLEObjCache().InsertObj(this);
+}
+
+uno::Reference < embed::XEmbeddedObject > SdrOle2Obj::GetObjRef() const
+{
+ const_cast<SdrOle2Obj*>(this)->GetObjRef_Impl();
+ return xObjRef.GetObject();
+}
+
+uno::Reference < embed::XEmbeddedObject > SdrOle2Obj::GetObjRef_NoInit() const
+{
+ return xObjRef.GetObject();
+}
+
+// -----------------------------------------------------------------------------
+
+uno::Reference< frame::XModel > SdrOle2Obj::getXModel() const
+{
+ GetObjRef();
+ if ( svt::EmbeddedObjectRef::TryRunningState(xObjRef.GetObject()) )
+ return uno::Reference< frame::XModel >( xObjRef->getComponent(), uno::UNO_QUERY );
+ else
+ return uno::Reference< frame::XModel >();
+}
+
+// -----------------------------------------------------------------------------
+
+// #109985#
+sal_Bool SdrOle2Obj::IsChart() const
+{
+ if ( !m_bTypeAsked )
+ {
+ m_bChart = ChartPrettyPainter::IsChart(xObjRef);
+ m_bTypeAsked = true;
+ }
+ return m_bChart;
+}
+
+// -----------------------------------------------------------------------------
+void SdrOle2Obj::SetGraphicToObj( const Graphic& aGraphic, const ::rtl::OUString& aMediaType )
+{
+ xObjRef.SetGraphic( aGraphic, aMediaType );
+}
+
+// -----------------------------------------------------------------------------
+void SdrOle2Obj::SetGraphicToObj( const uno::Reference< io::XInputStream >& xGrStream, const ::rtl::OUString& aMediaType )
+{
+ xObjRef.SetGraphicStream( xGrStream, aMediaType );
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool SdrOle2Obj::IsCalc() const
+{
+ if ( !xObjRef.is() )
+ return false;
+
+ SvGlobalName aObjClsId( xObjRef->getClassID() );
+ if( SvGlobalName(SO3_SC_CLASSID_30) == aObjClsId
+ || SvGlobalName(SO3_SC_CLASSID_40) == aObjClsId
+ || SvGlobalName(SO3_SC_CLASSID_50) == aObjClsId
+ || SvGlobalName(SO3_SC_CLASSID_60) == aObjClsId
+ || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_60) == aObjClsId
+ || SvGlobalName(SO3_SC_OLE_EMBED_CLASSID_8) == aObjClsId
+ || SvGlobalName(SO3_SC_CLASSID) == aObjClsId )
+ {
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------------
+uno::Reference< frame::XModel > SdrOle2Obj::GetParentXModel() const
+{
+ uno::Reference< frame::XModel > xDoc;
+ if ( pModel )
+ xDoc.set( pModel->getUnoModel(),uno::UNO_QUERY);
+ return xDoc;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool SdrOle2Obj::CalculateNewScaling( Fraction& aScaleWidth, Fraction& aScaleHeight, Size& aObjAreaSize )
+{
+ // TODO/LEAN: to avoid rounding errors scaling always uses the VisArea.
+ // If we don't cache it for own objects also we must load the object here
+ if ( !xObjRef.is() || !pModel )
+ return sal_False;
+
+ MapMode aMapMode( pModel->GetScaleUnit() );
+ aObjAreaSize = xObjRef.GetSize( &aMapMode );
+
+ Size aSize = aRect.GetSize();
+ aScaleWidth = Fraction(aSize.Width(), aObjAreaSize.Width() );
+ aScaleHeight = Fraction(aSize.Height(), aObjAreaSize.Height() );
+
+ // reduce to 10 binary digits
+ Kuerzen(aScaleHeight, 10);
+ Kuerzen(aScaleWidth, 10);
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------------
+sal_Bool SdrOle2Obj::AddOwnLightClient()
+{
+ // The Own Light Client must be registered in object only using this method!
+ if ( !SfxInPlaceClient::GetClient( dynamic_cast<SfxObjectShell*>(pModel->GetPersist()), xObjRef.GetObject() )
+ && !( mpImpl->pLightClient && xObjRef->getClientSite() == uno::Reference< embed::XEmbeddedClient >( mpImpl->pLightClient ) ) )
+ {
+ Connect();
+
+ if ( xObjRef.is() && mpImpl->pLightClient )
+ {
+ Fraction aScaleWidth;
+ Fraction aScaleHeight;
+ Size aObjAreaSize;
+ if ( CalculateNewScaling( aScaleWidth, aScaleHeight, aObjAreaSize ) )
+ {
+ mpImpl->pLightClient->SetSizeScale( aScaleWidth, aScaleHeight );
+ try {
+ xObjRef->setClientSite( mpImpl->pLightClient );
+ return sal_True;
+ } catch( uno::Exception& )
+ {}
+ }
+
+ }
+
+ return sal_False;
+ }
+
+ return sal_True;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+Bitmap SdrOle2Obj::GetEmtyOLEReplacementBitmap()
+{
+ return Bitmap(ResId(BMP_SVXOLEOBJ, *ImpGetResMgr()));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void SdrOle2Obj::SetWindow(const com::sun::star::uno::Reference < com::sun::star::awt::XWindow >& _xWindow)
+{
+ if ( xObjRef.is() && mpImpl->pLightClient )
+ {
+ mpImpl->pLightClient->setWindow(_xWindow);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdopage.cxx b/svx/source/svdraw/svdopage.cxx
new file mode 100644
index 000000000000..a2d21e6e2269
--- /dev/null
+++ b/svx/source/svdraw/svdopage.cxx
@@ -0,0 +1,195 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdopage.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdoutl.hxx>
+#include <svtools/colorcfg.hxx>
+#include <svl/itemset.hxx>
+#include <svx/sdr/properties/pageproperties.hxx>
+
+// #111111#
+#include <svx/sdr/contact/viewcontactofpageobj.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrPageObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::PageProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrPageObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfPageObj(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// this method is called form the destructor of the referenced page.
+// do all necessary action to forget the page. It is not necessary to call
+// RemovePageUser(), that is done form the destructor.
+void SdrPageObj::PageInDestruction(const SdrPage& rPage)
+{
+ if(mpShownPage && mpShownPage == &rPage)
+ {
+ // #i58769# Do not call ActionChanged() here, because that would
+ // lead to the construction of a view contact object for a page that
+ // is being destroyed.
+
+ mpShownPage = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrPageObj,SdrObject);
+
+SdrPageObj::SdrPageObj(SdrPage* pNewPage)
+: mpShownPage(pNewPage)
+{
+ if(mpShownPage)
+ {
+ mpShownPage->AddPageUser(*this);
+ }
+}
+
+SdrPageObj::SdrPageObj(const Rectangle& rRect, SdrPage* pNewPage)
+: mpShownPage(pNewPage)
+{
+ if(mpShownPage)
+ {
+ mpShownPage->AddPageUser(*this);
+ }
+
+ aOutRect = rRect;
+}
+
+SdrPageObj::~SdrPageObj()
+{
+ // #111111#
+ if(mpShownPage)
+ {
+ mpShownPage->RemovePageUser(*this);
+ }
+}
+
+// #111111#
+SdrPage* SdrPageObj::GetReferencedPage() const
+{
+ return mpShownPage;
+}
+
+// #111111#
+void SdrPageObj::SetReferencedPage(SdrPage* pNewPage)
+{
+ if(mpShownPage != pNewPage)
+ {
+ if(mpShownPage)
+ {
+ mpShownPage->RemovePageUser(*this);
+ }
+
+ mpShownPage = pNewPage;
+
+ if(mpShownPage)
+ {
+ mpShownPage->AddPageUser(*this);
+ }
+
+ SetChanged();
+ BroadcastObjectChange();
+ }
+}
+
+// #i96598#
+void SdrPageObj::SetBoundRectDirty()
+{
+ // avoid resetting aOutRect which in case of this object is model data,
+ // not re-creatable view data
+}
+
+UINT16 SdrPageObj::GetObjIdentifier() const
+{
+ return UINT16(OBJ_PAGE);
+}
+
+void SdrPageObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed=FALSE;
+ rInfo.bRotate90Allowed =FALSE;
+ rInfo.bMirrorFreeAllowed=FALSE;
+ rInfo.bMirror45Allowed =FALSE;
+ rInfo.bMirror90Allowed =FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed =FALSE;
+ rInfo.bEdgeRadiusAllowed=FALSE;
+ rInfo.bNoOrthoDesired =FALSE;
+ rInfo.bCanConvToPath =FALSE;
+ rInfo.bCanConvToPoly =FALSE;
+ rInfo.bCanConvToPathLineToArea=FALSE;
+ rInfo.bCanConvToPolyLineToArea=FALSE;
+}
+
+void SdrPageObj::operator=(const SdrObject& rObj)
+{
+ SdrObject::operator=(rObj);
+ SetReferencedPage(((const SdrPageObj&)rObj).GetReferencedPage());
+}
+
+void SdrPageObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNameSingulPAGE);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrPageObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName=ImpGetResStr(STR_ObjNamePluralPAGE);
+}
+
+// eof
diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx
new file mode 100644
index 000000000000..2b495725c006
--- /dev/null
+++ b/svx/source/svdraw/svdopath.cxx
@@ -0,0 +1,3117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <tools/bigint.hxx>
+#include <svx/svdopath.hxx>
+#include <math.h>
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svdview.hxx> // fuer MovCreate bei Freihandlinien
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+
+#ifdef _MSC_VER
+#pragma optimize ("",off)
+#pragma warning(disable: 4748) // "... because optimizations are disabled ..."
+#endif
+
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/polypolygoneditor.hxx>
+#include <svx/xlntrit.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include "svdoimp.hxx"
+#include <svx/sdr/contact/viewcontactofsdrpathobj.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+
+// #104018# replace macros above with type-safe methods
+inline sal_Int32 ImplTwipsToMM(sal_Int32 nVal) { return ((nVal * 127 + 36) / 72); }
+inline sal_Int32 ImplMMToTwips(sal_Int32 nVal) { return ((nVal * 72 + 63) / 127); }
+inline sal_Int64 ImplTwipsToMM(sal_Int64 nVal) { return ((nVal * 127 + 36) / 72); }
+inline sal_Int64 ImplMMToTwips(sal_Int64 nVal) { return ((nVal * 72 + 63) / 127); }
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/curve/b2dcubicbezier.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <svx/sdr/attribute/sdrtextattribute.hxx>
+#include <svx/sdr/primitive2d/sdrattributecreator.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/sdr/attribute/sdrformtextattribute.hxx>
+
+using namespace sdr;
+
+inline USHORT GetPrevPnt(USHORT nPnt, USHORT nPntMax, FASTBOOL bClosed)
+{
+ if (nPnt>0) {
+ nPnt--;
+ } else {
+ nPnt=nPntMax;
+ if (bClosed) nPnt--;
+ }
+ return nPnt;
+}
+
+inline USHORT GetNextPnt(USHORT nPnt, USHORT nPntMax, FASTBOOL bClosed)
+{
+ nPnt++;
+ if (nPnt>nPntMax || (bClosed && nPnt>=nPntMax)) nPnt=0;
+ return nPnt;
+}
+
+struct ImpSdrPathDragData : public SdrDragStatUserData
+{
+ XPolygon aXP; // Ausschnitt aud dem Originalpolygon
+ FASTBOOL bValid; // FALSE = zu wenig Punkte
+ FASTBOOL bClosed; // geschlossenes Objekt?
+ USHORT nPoly; // Nummer des Polygons im PolyPolygon
+ USHORT nPnt; // Punktnummer innerhalb des obigen Polygons
+ USHORT nPntAnz; // Punktanzahl des Polygons
+ USHORT nPntMax; // Maximaler Index
+ FASTBOOL bBegPnt; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ FASTBOOL bEndPnt; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ USHORT nPrevPnt; // Index des vorherigen Punkts
+ USHORT nNextPnt; // Index des naechsten Punkts
+ FASTBOOL bPrevIsBegPnt; // Vorheriger Punkt ist Anfangspunkt einer Polyline
+ FASTBOOL bNextIsEndPnt; // Folgepunkt ist Endpunkt einer Polyline
+ USHORT nPrevPrevPnt; // Index des vorvorherigen Punkts
+ USHORT nNextNextPnt; // Index des uebernaechsten Punkts
+ FASTBOOL bControl; // Punkt ist ein Kontrollpunkt
+ FASTBOOL bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ FASTBOOL bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ FASTBOOL bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ FASTBOOL bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+ USHORT nPrevPrevPnt0;
+ USHORT nPrevPnt0;
+ USHORT nPnt0;
+ USHORT nNextPnt0;
+ USHORT nNextNextPnt0;
+ FASTBOOL bEliminate; // Punkt loeschen? (wird von MovDrag gesetzt)
+
+ // ##
+ BOOL mbMultiPointDrag;
+ const XPolyPolygon maOrig;
+ XPolyPolygon maMove;
+ Container maHandles;
+
+public:
+ ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl, BOOL bMuPoDr, const SdrDragStat& rDrag);
+ void ResetPoly(const SdrPathObj& rPO);
+ BOOL IsMultiPointDrag() const { return mbMultiPointDrag; }
+};
+
+ImpSdrPathDragData::ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl, BOOL bMuPoDr, const SdrDragStat& rDrag)
+: aXP(5),
+ mbMultiPointDrag(bMuPoDr),
+ maOrig(rPO.GetPathPoly()),
+ maHandles(0)
+{
+ if(mbMultiPointDrag)
+ {
+ const SdrMarkView& rMarkView = *rDrag.GetView();
+ const SdrHdlList& rHdlList = rMarkView.GetHdlList();
+ const sal_uInt32 nHdlCount = rHdlList.GetHdlCount();
+ const SdrObject* pInteractionObject(nHdlCount && rHdlList.GetHdl(0) ? rHdlList.GetHdl(0)->GetObj() : 0);
+
+ for(sal_uInt32 a(0); a < nHdlCount; a++)
+ {
+ SdrHdl* pTestHdl = rHdlList.GetHdl(a);
+
+ if(pTestHdl && pTestHdl->IsSelected() && pTestHdl->GetObj() == pInteractionObject)
+ {
+ maHandles.Insert(pTestHdl, CONTAINER_APPEND);
+ }
+ }
+
+ maMove = maOrig;
+ bValid = TRUE;
+ }
+ else
+ {
+ bValid=FALSE;
+ bClosed=rPO.IsClosed(); // geschlossenes Objekt?
+ nPoly=(sal_uInt16)rHdl.GetPolyNum(); // Nummer des Polygons im PolyPolygon
+ nPnt=(sal_uInt16)rHdl.GetPointNum(); // Punktnummer innerhalb des obigen Polygons
+ const XPolygon aTmpXP(rPO.GetPathPoly().getB2DPolygon(nPoly));
+ nPntAnz=aTmpXP.GetPointCount(); // Punktanzahl des Polygons
+ if (nPntAnz==0 || (bClosed && nPntAnz==1)) return; // min. 1Pt bei Line, min. 2 bei Polygon
+ nPntMax=nPntAnz-1; // Maximaler Index
+ bBegPnt=!bClosed && nPnt==0; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ bEndPnt=!bClosed && nPnt==nPntMax; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ if (bClosed && nPntAnz<=3) { // Falls Polygon auch nur eine Linie ist
+ bBegPnt=(nPntAnz<3) || nPnt==0;
+ bEndPnt=(nPntAnz<3) || nPnt==nPntMax-1;
+ }
+ nPrevPnt=nPnt; // Index des vorherigen Punkts
+ nNextPnt=nPnt; // Index des naechsten Punkts
+ if (!bBegPnt) nPrevPnt=GetPrevPnt(nPnt,nPntMax,bClosed);
+ if (!bEndPnt) nNextPnt=GetNextPnt(nPnt,nPntMax,bClosed);
+ bPrevIsBegPnt=bBegPnt || (!bClosed && nPrevPnt==0);
+ bNextIsEndPnt=bEndPnt || (!bClosed && nNextPnt==nPntMax);
+ nPrevPrevPnt=nPnt; // Index des vorvorherigen Punkts
+ nNextNextPnt=nPnt; // Index des uebernaechsten Punkts
+ if (!bPrevIsBegPnt) nPrevPrevPnt=GetPrevPnt(nPrevPnt,nPntMax,bClosed);
+ if (!bNextIsEndPnt) nNextNextPnt=GetNextPnt(nNextPnt,nPntMax,bClosed);
+ bControl=rHdl.IsPlusHdl(); // Punkt ist ein Kontrollpunkt
+ bIsPrevControl=FALSE; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ bIsNextControl=FALSE; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ bPrevIsControl=FALSE; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ bNextIsControl=FALSE; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+ if (bControl) {
+ bIsPrevControl=aTmpXP.IsControl(nPrevPnt);
+ bIsNextControl=!bIsPrevControl;
+ } else {
+ bPrevIsControl=!bBegPnt && !bPrevIsBegPnt && aTmpXP.GetFlags(nPrevPnt)==XPOLY_CONTROL;
+ bNextIsControl=!bEndPnt && !bNextIsEndPnt && aTmpXP.GetFlags(nNextPnt)==XPOLY_CONTROL;
+ }
+ nPrevPrevPnt0=nPrevPrevPnt;
+ nPrevPnt0 =nPrevPnt;
+ nPnt0 =nPnt;
+ nNextPnt0 =nNextPnt;
+ nNextNextPnt0=nNextNextPnt;
+ nPrevPrevPnt=0;
+ nPrevPnt=1;
+ nPnt=2;
+ nNextPnt=3;
+ nNextNextPnt=4;
+ bEliminate=FALSE;
+ ResetPoly(rPO);
+ bValid=TRUE;
+ }
+}
+
+void ImpSdrPathDragData::ResetPoly(const SdrPathObj& rPO)
+{
+ const XPolygon aTmpXP(rPO.GetPathPoly().getB2DPolygon(nPoly));
+ aXP[0]=aTmpXP[nPrevPrevPnt0]; aXP.SetFlags(0,aTmpXP.GetFlags(nPrevPrevPnt0));
+ aXP[1]=aTmpXP[nPrevPnt0]; aXP.SetFlags(1,aTmpXP.GetFlags(nPrevPnt0));
+ aXP[2]=aTmpXP[nPnt0]; aXP.SetFlags(2,aTmpXP.GetFlags(nPnt0));
+ aXP[3]=aTmpXP[nNextPnt0]; aXP.SetFlags(3,aTmpXP.GetFlags(nNextPnt0));
+ aXP[4]=aTmpXP[nNextNextPnt0]; aXP.SetFlags(4,aTmpXP.GetFlags(nNextNextPnt0));
+}
+
+/*************************************************************************/
+
+struct ImpPathCreateUser : public SdrDragStatUserData
+{
+ Point aBezControl0;
+ Point aBezStart;
+ Point aBezCtrl1;
+ Point aBezCtrl2;
+ Point aBezEnd;
+ Point aCircStart;
+ Point aCircEnd;
+ Point aCircCenter;
+ Point aLineStart;
+ Point aLineEnd;
+ Point aRectP1;
+ Point aRectP2;
+ Point aRectP3;
+ long nCircRadius;
+ long nCircStWink;
+ long nCircRelWink;
+ FASTBOOL bBezier;
+ FASTBOOL bBezHasCtrl0;
+ FASTBOOL bCurve;
+ FASTBOOL bCircle;
+ FASTBOOL bAngleSnap;
+ FASTBOOL bLine;
+ FASTBOOL bLine90;
+ FASTBOOL bRect;
+ FASTBOOL bMixedCreate;
+ USHORT nBezierStartPoint;
+ SdrObjKind eStartKind;
+ SdrObjKind eAktKind;
+
+public:
+ ImpPathCreateUser(): nCircRadius(0),nCircStWink(0),nCircRelWink(0),
+ bBezier(FALSE),bBezHasCtrl0(FALSE),bCurve(FALSE),bCircle(FALSE),bAngleSnap(FALSE),bLine(FALSE),bLine90(FALSE),bRect(FALSE),
+ bMixedCreate(FALSE),nBezierStartPoint(0),eStartKind(OBJ_NONE),eAktKind(OBJ_NONE) { }
+
+ void ResetFormFlags() { bBezier=FALSE; bCurve=FALSE; bCircle=FALSE; bLine=FALSE; bRect=FALSE; }
+ FASTBOOL IsFormFlag() const { return bBezier || bCurve || bCircle || bLine || bRect; }
+ XPolygon GetFormPoly() const;
+ FASTBOOL CalcBezier(const Point& rP1, const Point& rP2, const Point& rDir, FASTBOOL bMouseDown);
+ XPolygon GetBezierPoly() const;
+ //FASTBOOL CalcCurve(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView) { return FALSE; }
+ XPolygon GetCurvePoly() const { return XPolygon(); }
+ FASTBOOL CalcCircle(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView);
+ XPolygon GetCirclePoly() const;
+ FASTBOOL CalcLine(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView);
+ Point CalcLine(const Point& rCsr, long nDirX, long nDirY, SdrView* pView) const;
+ XPolygon GetLinePoly() const;
+ FASTBOOL CalcRect(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView);
+ XPolygon GetRectPoly() const;
+};
+
+XPolygon ImpPathCreateUser::GetFormPoly() const
+{
+ if (bBezier) return GetBezierPoly();
+ if (bCurve) return GetCurvePoly();
+ if (bCircle) return GetCirclePoly();
+ if (bLine) return GetLinePoly();
+ if (bRect) return GetRectPoly();
+ return XPolygon();
+}
+
+FASTBOOL ImpPathCreateUser::CalcBezier(const Point& rP1, const Point& rP2, const Point& rDir, FASTBOOL bMouseDown)
+{
+ FASTBOOL bRet=TRUE;
+ aBezStart=rP1;
+ aBezCtrl1=rP1+rDir;
+ aBezCtrl2=rP2;
+
+ // #i21479#
+ // Also copy the end point when no end point is set yet
+ if (!bMouseDown || (0L == aBezEnd.X() && 0L == aBezEnd.Y())) aBezEnd=rP2;
+
+ bBezier=bRet;
+ return bRet;
+}
+
+XPolygon ImpPathCreateUser::GetBezierPoly() const
+{
+ XPolygon aXP(4);
+ aXP[0]=aBezStart; aXP.SetFlags(0,XPOLY_SMOOTH);
+ aXP[1]=aBezCtrl1; aXP.SetFlags(1,XPOLY_CONTROL);
+ aXP[2]=aBezCtrl2; aXP.SetFlags(2,XPOLY_CONTROL);
+ aXP[3]=aBezEnd;
+ return aXP;
+}
+
+FASTBOOL ImpPathCreateUser::CalcCircle(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView)
+{
+ long nTangAngle=GetAngle(rDir);
+ aCircStart=rP1;
+ aCircEnd=rP2;
+ aCircCenter=rP1;
+ long dx=rP2.X()-rP1.X();
+ long dy=rP2.Y()-rP1.Y();
+ long dAngle=GetAngle(Point(dx,dy))-nTangAngle;
+ dAngle=NormAngle360(dAngle);
+ long nTmpAngle=NormAngle360(9000-dAngle);
+ FASTBOOL bRet=nTmpAngle!=9000 && nTmpAngle!=27000;
+ long nRad=0;
+ if (bRet) {
+ double cs=cos(nTmpAngle*nPi180);
+ double nR=(double)GetLen(Point(dx,dy))/cs/2;
+ nRad=Abs(Round(nR));
+ }
+ if (dAngle<18000) {
+ nCircStWink=NormAngle360(nTangAngle-9000);
+ nCircRelWink=NormAngle360(2*dAngle);
+ aCircCenter.X()+=Round(nRad*cos((nTangAngle+9000)*nPi180));
+ aCircCenter.Y()-=Round(nRad*sin((nTangAngle+9000)*nPi180));
+ } else {
+ nCircStWink=NormAngle360(nTangAngle+9000);
+ nCircRelWink=-NormAngle360(36000-2*dAngle);
+ aCircCenter.X()+=Round(nRad*cos((nTangAngle-9000)*nPi180));
+ aCircCenter.Y()-=Round(nRad*sin((nTangAngle-9000)*nPi180));
+ }
+ bAngleSnap=pView!=NULL && pView->IsAngleSnapEnabled();
+ if (bAngleSnap) {
+ long nSA=pView->GetSnapAngle();
+ if (nSA!=0) { // Winkelfang
+ FASTBOOL bNeg=nCircRelWink<0;
+ if (bNeg) nCircRelWink=-nCircRelWink;
+ nCircRelWink+=nSA/2;
+ nCircRelWink/=nSA;
+ nCircRelWink*=nSA;
+ nCircRelWink=NormAngle360(nCircRelWink);
+ if (bNeg) nCircRelWink=-nCircRelWink;
+ }
+ }
+ nCircRadius=nRad;
+ if (nRad==0 || Abs(nCircRelWink)<5) bRet=FALSE;
+ bCircle=bRet;
+ return bRet;
+}
+
+XPolygon ImpPathCreateUser::GetCirclePoly() const
+{
+ if (nCircRelWink>=0) {
+ XPolygon aXP(aCircCenter,nCircRadius,nCircRadius,
+ USHORT((nCircStWink+5)/10),USHORT((nCircStWink+nCircRelWink+5)/10),FALSE);
+ aXP[0]=aCircStart; aXP.SetFlags(0,XPOLY_SMOOTH);
+ if (!bAngleSnap) aXP[aXP.GetPointCount()-1]=aCircEnd;
+ return aXP;
+ } else {
+ XPolygon aXP(aCircCenter,nCircRadius,nCircRadius,
+ USHORT(NormAngle360(nCircStWink+nCircRelWink+5)/10),USHORT((nCircStWink+5)/10),FALSE);
+ USHORT nAnz=aXP.GetPointCount();
+ for (USHORT nNum=nAnz/2; nNum>0;) {
+ nNum--; // XPoly Punktreihenfolge umkehren
+ USHORT n2=nAnz-nNum-1;
+ Point aPt(aXP[nNum]);
+ aXP[nNum]=aXP[n2];
+ aXP[n2]=aPt;
+ }
+ aXP[0]=aCircStart; aXP.SetFlags(0,XPOLY_SMOOTH);
+ if (!bAngleSnap) aXP[aXP.GetPointCount()-1]=aCircEnd;
+ return aXP;
+ }
+}
+
+Point ImpPathCreateUser::CalcLine(const Point& aCsr, long nDirX, long nDirY, SdrView* pView) const
+{
+ long x=aCsr.X(),x1=x,x2=x;
+ long y=aCsr.Y(),y1=y,y2=y;
+ FASTBOOL bHLin=nDirY==0;
+ FASTBOOL bVLin=nDirX==0;
+ if (bHLin) y=0;
+ else if (bVLin) x=0;
+ else {
+ x1=BigMulDiv(y,nDirX,nDirY);
+ y2=BigMulDiv(x,nDirY,nDirX);
+ long l1=Abs(x1)+Abs(y1);
+ long l2=Abs(x2)+Abs(y2);
+ if ((l1<=l2) != (pView!=NULL && pView->IsBigOrtho())) {
+ x=x1; y=y1;
+ } else {
+ x=x2; y=y2;
+ }
+ }
+ return Point(x,y);
+}
+
+FASTBOOL ImpPathCreateUser::CalcLine(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView)
+{
+ aLineStart=rP1;
+ aLineEnd=rP2;
+ bLine90=FALSE;
+ if (rP1==rP2 || (rDir.X()==0 && rDir.Y()==0)) { bLine=FALSE; return FALSE; }
+ Point aTmpPt(rP2-rP1);
+ long nDirX=rDir.X();
+ long nDirY=rDir.Y();
+ Point aP1(CalcLine(aTmpPt, nDirX, nDirY,pView)); aP1-=aTmpPt; long nQ1=Abs(aP1.X())+Abs(aP1.Y());
+ Point aP2(CalcLine(aTmpPt, nDirY,-nDirX,pView)); aP2-=aTmpPt; long nQ2=Abs(aP2.X())+Abs(aP2.Y());
+ if (pView!=NULL && pView->IsOrtho()) nQ1=0; // Ortho schaltet rechtwinklig aus
+ bLine90=nQ1>2*nQ2;
+ if (!bLine90) { // glatter Uebergang
+ aLineEnd+=aP1;
+ } else { // rechtwinkliger Uebergang
+ aLineEnd+=aP2;
+ }
+ bLine=TRUE;
+ return TRUE;
+}
+
+XPolygon ImpPathCreateUser::GetLinePoly() const
+{
+ XPolygon aXP(2);
+ aXP[0]=aLineStart; if (!bLine90) aXP.SetFlags(0,XPOLY_SMOOTH);
+ aXP[1]=aLineEnd;
+ return aXP;
+}
+
+FASTBOOL ImpPathCreateUser::CalcRect(const Point& rP1, const Point& rP2, const Point& rDir, SdrView* pView)
+{
+ aRectP1=rP1;
+ aRectP2=rP1;
+ aRectP3=rP2;
+ if (rP1==rP2 || (rDir.X()==0 && rDir.Y()==0)) { bRect=FALSE; return FALSE; }
+ Point aTmpPt(rP2-rP1);
+ long nDirX=rDir.X();
+ long nDirY=rDir.Y();
+ long x=aTmpPt.X();
+ long y=aTmpPt.Y();
+ FASTBOOL bHLin=nDirY==0;
+ FASTBOOL bVLin=nDirX==0;
+ if (bHLin) y=0;
+ else if (bVLin) x=0;
+ else {
+ y=BigMulDiv(x,nDirY,nDirX);
+ long nHypLen=aTmpPt.Y()-y;
+ long nTangAngle=-GetAngle(rDir);
+ // sin=g/h, g=h*sin
+ double a=nTangAngle*nPi180;
+ double sn=sin(a);
+ double cs=cos(a);
+ double nGKathLen=nHypLen*sn;
+ y+=Round(nGKathLen*sn);
+ x+=Round(nGKathLen*cs);
+ }
+ aRectP2.X()+=x;
+ aRectP2.Y()+=y;
+ if (pView!=NULL && pView->IsOrtho()) {
+ long dx1=aRectP2.X()-aRectP1.X(); long dx1a=Abs(dx1);
+ long dy1=aRectP2.Y()-aRectP1.Y(); long dy1a=Abs(dy1);
+ long dx2=aRectP3.X()-aRectP2.X(); long dx2a=Abs(dx2);
+ long dy2=aRectP3.Y()-aRectP2.Y(); long dy2a=Abs(dy2);
+ FASTBOOL b1MoreThan2=dx1a+dy1a>dx2a+dy2a;
+ if (b1MoreThan2 != pView->IsBigOrtho()) {
+ long xtemp=dy2a-dx1a; if (dx1<0) xtemp=-xtemp;
+ long ytemp=dx2a-dy1a; if (dy1<0) ytemp=-ytemp;
+ aRectP2.X()+=xtemp;
+ aRectP2.Y()+=ytemp;
+ aRectP3.X()+=xtemp;
+ aRectP3.Y()+=ytemp;
+ } else {
+ long xtemp=dy1a-dx2a; if (dx2<0) xtemp=-xtemp;
+ long ytemp=dx1a-dy2a; if (dy2<0) ytemp=-ytemp;
+ aRectP3.X()+=xtemp;
+ aRectP3.Y()+=ytemp;
+ }
+ }
+ bRect=TRUE;
+ return TRUE;
+}
+
+XPolygon ImpPathCreateUser::GetRectPoly() const
+{
+ XPolygon aXP(3);
+ aXP[0]=aRectP1; aXP.SetFlags(0,XPOLY_SMOOTH);
+ aXP[1]=aRectP2;
+ if (aRectP3!=aRectP2) aXP[2]=aRectP3;
+ return aXP;
+}
+
+/*************************************************************************/
+
+class ImpPathForDragAndCreate
+{
+ SdrPathObj& mrSdrPathObject;
+ XPolyPolygon aPathPolygon;
+ SdrObjKind meObjectKind;
+ ImpSdrPathDragData* mpSdrPathDragData;
+ bool mbCreating;
+
+public:
+ ImpPathForDragAndCreate(SdrPathObj& rSdrPathObject);
+ ~ImpPathForDragAndCreate();
+
+ // drag stuff
+ bool beginPathDrag( SdrDragStat& rDrag ) const;
+ bool movePathDrag( SdrDragStat& rDrag ) const;
+ bool endPathDrag( SdrDragStat& rDrag );
+ //void cancelSpecialDrag( SdrDragStat& rDrag ) const;
+ String getSpecialDragComment(const SdrDragStat& rDrag) const;
+ basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat& rDrag) const;
+
+ // create stuff
+ FASTBOOL BegCreate(SdrDragStat& rStat);
+ FASTBOOL MovCreate(SdrDragStat& rStat);
+ FASTBOOL EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd);
+ FASTBOOL BckCreate(SdrDragStat& rStat);
+ void BrkCreate(SdrDragStat& rStat);
+ Pointer GetCreatePointer() const;
+
+ // helping stuff
+ bool IsClosed(SdrObjKind eKind) const { return eKind==OBJ_POLY || eKind==OBJ_PATHPOLY || eKind==OBJ_PATHFILL || eKind==OBJ_FREEFILL || eKind==OBJ_SPLNFILL; }
+ bool IsFreeHand(SdrObjKind eKind) const { return eKind==OBJ_FREELINE || eKind==OBJ_FREEFILL; }
+ bool IsBezier(SdrObjKind eKind) const { return eKind==OBJ_PATHLINE || eKind==OBJ_PATHFILL; }
+ bool IsCreating() const { return mbCreating; }
+
+ // get the polygon
+ basegfx::B2DPolyPolygon TakeObjectPolyPolygon(const SdrDragStat& rDrag) const;
+ basegfx::B2DPolyPolygon TakeDragPolyPolygon(const SdrDragStat& rDrag) const;
+ basegfx::B2DPolyPolygon getModifiedPolyPolygon() const { return aPathPolygon.getB2DPolyPolygon(); }
+};
+
+ImpPathForDragAndCreate::ImpPathForDragAndCreate(SdrPathObj& rSdrPathObject)
+: mrSdrPathObject(rSdrPathObject),
+ aPathPolygon(rSdrPathObject.GetPathPoly()),
+ meObjectKind(mrSdrPathObject.meKind),
+ mpSdrPathDragData(0),
+ mbCreating(false)
+{
+}
+
+ImpPathForDragAndCreate::~ImpPathForDragAndCreate()
+{
+ if(mpSdrPathDragData)
+ {
+ delete mpSdrPathDragData;
+ }
+}
+
+bool ImpPathForDragAndCreate::beginPathDrag( SdrDragStat& rDrag ) const
+{
+ const SdrHdl* pHdl=rDrag.GetHdl();
+ if(!pHdl)
+ return FALSE;
+
+ BOOL bMultiPointDrag(TRUE);
+
+ if(aPathPolygon[(sal_uInt16)pHdl->GetPolyNum()].IsControl((sal_uInt16)pHdl->GetPointNum()))
+ bMultiPointDrag = FALSE;
+
+ if(bMultiPointDrag)
+ {
+ const SdrMarkView& rMarkView = *rDrag.GetView();
+ const SdrHdlList& rHdlList = rMarkView.GetHdlList();
+ const sal_uInt32 nHdlCount = rHdlList.GetHdlCount();
+ const SdrObject* pInteractionObject(nHdlCount && rHdlList.GetHdl(0) ? rHdlList.GetHdl(0)->GetObj() : 0);
+ sal_uInt32 nSelectedPoints(0);
+
+ for(sal_uInt32 a(0); a < nHdlCount; a++)
+ {
+ SdrHdl* pTestHdl = rHdlList.GetHdl(a);
+
+ if(pTestHdl && pTestHdl->IsSelected() && pTestHdl->GetObj() == pInteractionObject)
+ {
+ nSelectedPoints++;
+ }
+ }
+
+ if(nSelectedPoints <= 1)
+ bMultiPointDrag = FALSE;
+ }
+
+ ((ImpPathForDragAndCreate*)this)->mpSdrPathDragData = new ImpSdrPathDragData(mrSdrPathObject,*pHdl,bMultiPointDrag,rDrag);
+
+ if(!mpSdrPathDragData || !mpSdrPathDragData->bValid)
+ {
+ DBG_ERROR("ImpPathForDragAndCreate::BegDrag(): ImpSdrPathDragData ist ungueltig");
+ delete mpSdrPathDragData;
+ ((ImpPathForDragAndCreate*)this)->mpSdrPathDragData = 0;
+ return false;
+ }
+
+ return true;
+}
+
+bool ImpPathForDragAndCreate::movePathDrag( SdrDragStat& rDrag ) const
+{
+ if(!mpSdrPathDragData || !mpSdrPathDragData->bValid)
+ {
+ DBG_ERROR("ImpPathForDragAndCreate::MovDrag(): ImpSdrPathDragData ist ungueltig");
+ return false;
+ }
+
+ if(mpSdrPathDragData->IsMultiPointDrag())
+ {
+ Point aDelta(rDrag.GetNow() - rDrag.GetStart());
+
+ if(aDelta.X() || aDelta.Y())
+ {
+ for(sal_uInt32 a(0); a < mpSdrPathDragData->maHandles.Count(); a++)
+ {
+ SdrHdl* pHandle = (SdrHdl*)mpSdrPathDragData->maHandles.GetObject(a);
+ const sal_uInt16 nPolyIndex((sal_uInt16)pHandle->GetPolyNum());
+ const sal_uInt16 nPointIndex((sal_uInt16)pHandle->GetPointNum());
+ const XPolygon& rOrig = mpSdrPathDragData->maOrig[nPolyIndex];
+ XPolygon& rMove = mpSdrPathDragData->maMove[nPolyIndex];
+ const sal_uInt16 nPointCount(rOrig.GetPointCount());
+ BOOL bClosed(rOrig[0] == rOrig[nPointCount-1]);
+
+ // move point itself
+ rMove[nPointIndex] = rOrig[nPointIndex] + aDelta;
+
+ // when point is first and poly closed, move close point, too.
+ if(nPointCount > 0 && !nPointIndex && bClosed)
+ {
+ rMove[nPointCount - 1] = rOrig[nPointCount - 1] + aDelta;
+
+ // when moving the last point it may be necessary to move the
+ // control point in front of this one, too.
+ if(nPointCount > 1 && rOrig.IsControl(nPointCount - 2))
+ rMove[nPointCount - 2] = rOrig[nPointCount - 2] + aDelta;
+ }
+
+ // is a control point before this?
+ if(nPointIndex > 0 && rOrig.IsControl(nPointIndex - 1))
+ {
+ // Yes, move it, too
+ rMove[nPointIndex - 1] = rOrig[nPointIndex - 1] + aDelta;
+ }
+
+ // is a control point after this?
+ if(nPointIndex + 1 < nPointCount && rOrig.IsControl(nPointIndex + 1))
+ {
+ // Yes, move it, too
+ rMove[nPointIndex + 1] = rOrig[nPointIndex + 1] + aDelta;
+ }
+ }
+ }
+ }
+ else
+ {
+ mpSdrPathDragData->ResetPoly(mrSdrPathObject);
+
+ // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
+ FASTBOOL bClosed =mpSdrPathDragData->bClosed ; // geschlossenes Objekt?
+ USHORT nPnt =mpSdrPathDragData->nPnt ; // Punktnummer innerhalb des obigen Polygons
+ FASTBOOL bBegPnt =mpSdrPathDragData->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ FASTBOOL bEndPnt =mpSdrPathDragData->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ USHORT nPrevPnt =mpSdrPathDragData->nPrevPnt ; // Index des vorherigen Punkts
+ USHORT nNextPnt =mpSdrPathDragData->nNextPnt ; // Index des naechsten Punkts
+ FASTBOOL bPrevIsBegPnt =mpSdrPathDragData->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
+ FASTBOOL bNextIsEndPnt =mpSdrPathDragData->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
+ USHORT nPrevPrevPnt =mpSdrPathDragData->nPrevPrevPnt ; // Index des vorvorherigen Punkts
+ USHORT nNextNextPnt =mpSdrPathDragData->nNextNextPnt ; // Index des uebernaechsten Punkts
+ FASTBOOL bControl =mpSdrPathDragData->bControl ; // Punkt ist ein Kontrollpunkt
+ //FASTBOOL bIsPrevControl=mpSdrPathDragData->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ FASTBOOL bIsNextControl=mpSdrPathDragData->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ FASTBOOL bPrevIsControl=mpSdrPathDragData->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ FASTBOOL bNextIsControl=mpSdrPathDragData->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+
+ // Ortho bei Linien/Polygonen = Winkel beibehalten
+ if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho()) {
+ FASTBOOL bBigOrtho=rDrag.GetView()->IsBigOrtho();
+ Point aPos(rDrag.GetNow()); // die aktuelle Position
+ Point aPnt(mpSdrPathDragData->aXP[nPnt]); // der gedraggte Punkt
+ USHORT nPnt1=0xFFFF,nPnt2=0xFFFF; // seine Nachbarpunkte
+ Point aNeuPos1,aNeuPos2; // die neuen Alternativen fuer aPos
+ FASTBOOL bPnt1=FALSE,bPnt2=FALSE; // die neuen Alternativen gueltig?
+ if (!bClosed && mpSdrPathDragData->nPntAnz>=2) { // Mind. 2 Pt bei Linien
+ if (!bBegPnt) nPnt1=nPrevPnt;
+ if (!bEndPnt) nPnt2=nNextPnt;
+ }
+ if (bClosed && mpSdrPathDragData->nPntAnz>=3) { // Mind. 3 Pt bei Polygon
+ nPnt1=nPrevPnt;
+ nPnt2=nNextPnt;
+ }
+ if (nPnt1!=0xFFFF && !bPrevIsControl) {
+ Point aPnt1=mpSdrPathDragData->aXP[nPnt1];
+ long ndx0=aPnt.X()-aPnt1.X();
+ long ndy0=aPnt.Y()-aPnt1.Y();
+ FASTBOOL bHLin=ndy0==0;
+ FASTBOOL bVLin=ndx0==0;
+ if (!bHLin || !bVLin) {
+ long ndx=aPos.X()-aPnt1.X();
+ long ndy=aPos.Y()-aPnt1.Y();
+ bPnt1=TRUE;
+ double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
+ double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
+ FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
+ FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
+ if (bHor) ndy=long(ndy0*nXFact);
+ if (bVer) ndx=long(ndx0*nYFact);
+ aNeuPos1=aPnt1;
+ aNeuPos1.X()+=ndx;
+ aNeuPos1.Y()+=ndy;
+ }
+ }
+ if (nPnt2!=0xFFFF && !bNextIsControl) {
+ Point aPnt2=mpSdrPathDragData->aXP[nPnt2];
+ long ndx0=aPnt.X()-aPnt2.X();
+ long ndy0=aPnt.Y()-aPnt2.Y();
+ FASTBOOL bHLin=ndy0==0;
+ FASTBOOL bVLin=ndx0==0;
+ if (!bHLin || !bVLin) {
+ long ndx=aPos.X()-aPnt2.X();
+ long ndy=aPos.Y()-aPnt2.Y();
+ bPnt2=TRUE;
+ double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
+ double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
+ FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
+ FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
+ if (bHor) ndy=long(ndy0*nXFact);
+ if (bVer) ndx=long(ndx0*nYFact);
+ aNeuPos2=aPnt2;
+ aNeuPos2.X()+=ndx;
+ aNeuPos2.Y()+=ndy;
+ }
+ }
+ if (bPnt1 && bPnt2) { // beide Alternativen vorhanden (Konkurenz)
+ BigInt nX1(aNeuPos1.X()-aPos.X()); nX1*=nX1;
+ BigInt nY1(aNeuPos1.Y()-aPos.Y()); nY1*=nY1;
+ BigInt nX2(aNeuPos2.X()-aPos.X()); nX2*=nX2;
+ BigInt nY2(aNeuPos2.Y()-aPos.Y()); nY2*=nY2;
+ nX1+=nY1; // Korrekturabstand zum Quadrat
+ nX2+=nY2; // Korrekturabstand zum Quadrat
+ // Die Alternative mit dem geringeren Korrekturbedarf gewinnt
+ if (nX1<nX2) bPnt2=FALSE; else bPnt1=FALSE;
+ }
+ if (bPnt1) rDrag.Now()=aNeuPos1;
+ if (bPnt2) rDrag.Now()=aNeuPos2;
+ }
+ rDrag.SetActionRect(Rectangle(rDrag.GetNow(),rDrag.GetNow()));
+
+ // IBM Special: Punkte eliminieren, wenn die beiden angrenzenden
+ // Linien eh' fast 180 deg sind.
+ if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsEliminatePolyPoints() &&
+ !bBegPnt && !bEndPnt && !bPrevIsControl && !bNextIsControl)
+ {
+ Point aPt(mpSdrPathDragData->aXP[nNextPnt]);
+ aPt-=rDrag.GetNow();
+ long nWink1=GetAngle(aPt);
+ aPt=rDrag.GetNow();
+ aPt-=mpSdrPathDragData->aXP[nPrevPnt];
+ long nWink2=GetAngle(aPt);
+ long nDiff=nWink1-nWink2;
+ nDiff=Abs(nDiff);
+ mpSdrPathDragData->bEliminate=nDiff<=rDrag.GetView()->GetEliminatePolyPointLimitAngle();
+ if (mpSdrPathDragData->bEliminate) { // Position anpassen, damit Smooth an den Enden stimmt
+ aPt=mpSdrPathDragData->aXP[nNextPnt];
+ aPt+=mpSdrPathDragData->aXP[nPrevPnt];
+ aPt/=2;
+ rDrag.Now()=aPt;
+ }
+ }
+
+ // Um diese Entfernung wurde insgesamt gedraggd
+ Point aDiff(rDrag.GetNow()); aDiff-=mpSdrPathDragData->aXP[nPnt];
+
+ // Insgesamt sind 8 Faelle moeglich:
+ // X 1. Weder rechts noch links Ctrl.
+ // o--X--o 2. Rechts und links Ctrl, gedraggd wird St.
+ // o--X 3. Nur links Ctrl, gedraggd wird St.
+ // X--o 4. Nur rechts Ctrl, gedraggd wird St.
+ // x--O--o 5. Rechts und links Ctrl, gedraggd wird links.
+ // x--O 6. Nur links Ctrl, gedraggd wird links.
+ // o--O--x 7. Rechts und links Ctrl, gedraggd wird rechts.
+ // O--x 8. Nur rechts Ctrl, gedraggd wird rechts.
+ // Zusaetzlich ist zu beachten, dass das Veraendern einer Linie (keine Kurve)
+ // eine evtl. Kurve am anderen Ende der Linie bewirkt, falls dort Smooth
+ // gesetzt ist (Kontrollpunktausrichtung an Gerade).
+
+ mpSdrPathDragData->aXP[nPnt]+=aDiff;
+
+ // Nun symmetrische PlusHandles etc. checken
+ if (bControl) { // Faelle 5,6,7,8
+ USHORT nSt=nPnt; // der zugehoerige Stuetzpunkt
+ USHORT nFix=nPnt; // der gegenueberliegende Kontrollpunkt
+ if (bIsNextControl) { // Wenn der naechste ein Kontrollpunkt ist, muss der vorh. der Stuetzpunkt sein
+ nSt=nPrevPnt;
+ nFix=nPrevPrevPnt;
+ } else {
+ nSt=nNextPnt;
+ nFix=nNextNextPnt;
+ }
+ if (mpSdrPathDragData->aXP.IsSmooth(nSt)) {
+ mpSdrPathDragData->aXP.CalcSmoothJoin(nSt,nPnt,nFix);
+ }
+ }
+
+ if (!bControl) { // Faelle 1,2,3,4 wobei bei 1 nix passiert und bei 3+4 unten noch mehr folgt
+ // die beiden Kontrollpunkte mit verschieben
+ if (bPrevIsControl) mpSdrPathDragData->aXP[nPrevPnt]+=aDiff;
+ if (bNextIsControl) mpSdrPathDragData->aXP[nNextPnt]+=aDiff;
+ // Kontrollpunkt ggf. an Gerade ausrichten
+ if (mpSdrPathDragData->aXP.IsSmooth(nPnt)) {
+ if (bPrevIsControl && !bNextIsControl && !bEndPnt) { // Fall 3
+ mpSdrPathDragData->aXP.CalcSmoothJoin(nPnt,nNextPnt,nPrevPnt);
+ }
+ if (bNextIsControl && !bPrevIsControl && !bBegPnt) { // Fall 4
+ mpSdrPathDragData->aXP.CalcSmoothJoin(nPnt,nPrevPnt,nNextPnt);
+ }
+ }
+ // Und nun noch die anderen Enden der Strecken ueberpruefen (nPnt+-1).
+ // Ist dort eine Kurve (IsControl(nPnt+-2)) mit SmoothJoin (nPnt+-1),
+ // so muss der entsprechende Kontrollpunkt (nPnt+-2) angepasst werden.
+ if (!bBegPnt && !bPrevIsControl && !bPrevIsBegPnt && mpSdrPathDragData->aXP.IsSmooth(nPrevPnt)) {
+ if (mpSdrPathDragData->aXP.IsControl(nPrevPrevPnt)) {
+ mpSdrPathDragData->aXP.CalcSmoothJoin(nPrevPnt,nPnt,nPrevPrevPnt);
+ }
+ }
+ if (!bEndPnt && !bNextIsControl && !bNextIsEndPnt && mpSdrPathDragData->aXP.IsSmooth(nNextPnt)) {
+ if (mpSdrPathDragData->aXP.IsControl(nNextNextPnt)) {
+ mpSdrPathDragData->aXP.CalcSmoothJoin(nNextPnt,nPnt,nNextNextPnt);
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ImpPathForDragAndCreate::endPathDrag(SdrDragStat& rDrag)
+{
+ Point aLinePt1;
+ Point aLinePt2;
+ bool bLineGlueMirror(OBJ_LINE == meObjectKind);
+ if (bLineGlueMirror) { // #40549#
+ XPolygon& rXP=aPathPolygon[0];
+ aLinePt1=rXP[0];
+ aLinePt2=rXP[1];
+ }
+
+ if(!mpSdrPathDragData || !mpSdrPathDragData->bValid)
+ {
+ DBG_ERROR("ImpPathForDragAndCreate::MovDrag(): ImpSdrPathDragData ist ungueltig");
+ return false;
+ }
+
+ if(mpSdrPathDragData->IsMultiPointDrag())
+ {
+ aPathPolygon = mpSdrPathDragData->maMove;
+ }
+ else
+ {
+ const SdrHdl* pHdl=rDrag.GetHdl();
+
+ // Referenz auf das Polygon
+ XPolygon& rXP=aPathPolygon[(sal_uInt16)pHdl->GetPolyNum()];
+
+ // Die 5 Punkte die sich evtl. geaendert haben
+ if (!mpSdrPathDragData->bPrevIsBegPnt) rXP[mpSdrPathDragData->nPrevPrevPnt0]=mpSdrPathDragData->aXP[mpSdrPathDragData->nPrevPrevPnt];
+ if (!mpSdrPathDragData->bNextIsEndPnt) rXP[mpSdrPathDragData->nNextNextPnt0]=mpSdrPathDragData->aXP[mpSdrPathDragData->nNextNextPnt];
+ if (!mpSdrPathDragData->bBegPnt) rXP[mpSdrPathDragData->nPrevPnt0] =mpSdrPathDragData->aXP[mpSdrPathDragData->nPrevPnt];
+ if (!mpSdrPathDragData->bEndPnt) rXP[mpSdrPathDragData->nNextPnt0] =mpSdrPathDragData->aXP[mpSdrPathDragData->nNextPnt];
+ rXP[mpSdrPathDragData->nPnt0] =mpSdrPathDragData->aXP[mpSdrPathDragData->nPnt];
+
+ // Letzter Punkt muss beim Geschlossenen immer gleich dem Ersten sein
+ if (mpSdrPathDragData->bClosed) rXP[rXP.GetPointCount()-1]=rXP[0];
+
+ if (mpSdrPathDragData->bEliminate)
+ {
+ basegfx::B2DPolyPolygon aTempPolyPolygon(aPathPolygon.getB2DPolyPolygon());
+ sal_uInt32 nPoly,nPnt;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(aTempPolyPolygon, rDrag.GetHdl()->GetSourceHdlNum(), nPoly, nPnt))
+ {
+ basegfx::B2DPolygon aCandidate(aTempPolyPolygon.getB2DPolygon(nPoly));
+ aCandidate.remove(nPnt);
+
+ if((IsClosed(meObjectKind) && aCandidate.count() < 3L) || aCandidate.count() < 2L)
+ {
+ aTempPolyPolygon.remove(nPoly);
+ }
+ else
+ {
+ aTempPolyPolygon.setB2DPolygon(nPoly, aCandidate);
+ }
+ }
+
+ aPathPolygon = XPolyPolygon(aTempPolyPolygon);
+ }
+
+ // Winkel anpassen fuer Text an einfacher Linie
+ if (bLineGlueMirror)
+ { // #40549#
+ Point aLinePt1_(aPathPolygon[0][0]);
+ Point aLinePt2_(aPathPolygon[0][1]);
+ FASTBOOL bXMirr=(aLinePt1_.X()>aLinePt2_.X())!=(aLinePt1.X()>aLinePt2.X());
+ FASTBOOL bYMirr=(aLinePt1_.Y()>aLinePt2_.Y())!=(aLinePt1.Y()>aLinePt2.Y());
+ if (bXMirr || bYMirr) {
+ Point aRef1(mrSdrPathObject.GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ mrSdrPathObject.NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ mrSdrPathObject.NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ }
+ }
+ }
+
+ delete mpSdrPathDragData;
+ mpSdrPathDragData = 0;
+
+ return true;
+}
+
+/*void ImpPathForDragAndCreate::cancelSpecialDrag( SdrDragStat& rDrag ) const
+{
+ ImpSdrPathDragData* pID=(ImpSdrPathDragData*)rDrag.GetUser();
+ if (pID!=NULL) {
+ delete pID;
+ rDrag.SetUser(NULL);
+ }
+}*/
+
+String ImpPathForDragAndCreate::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ XubString aStr;
+ const SdrHdl* pHdl = rDrag.GetHdl();
+ const bool bCreateComment(rDrag.GetView() && &mrSdrPathObject == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment && rDrag.GetUser())
+ {
+ // #i103058# re-add old creation comment mode
+ ImpPathCreateUser* pU = (ImpPathCreateUser*)rDrag.GetUser();
+ const SdrObjKind eKindMerk(meObjectKind);
+ mrSdrPathObject.meKind = pU->eAktKind;
+ mrSdrPathObject.ImpTakeDescriptionStr(STR_ViewCreateObj, aStr);
+ mrSdrPathObject.meKind = eKindMerk;
+
+ Point aPrev(rDrag.GetPrev());
+ Point aNow(rDrag.GetNow());
+
+ if(pU->bLine)
+ aNow = pU->aLineEnd;
+
+ aNow -= aPrev;
+ aStr.AppendAscii(" (");
+
+ XubString aMetr;
+
+ if(pU->bCircle)
+ {
+ mrSdrPathObject.GetModel()->TakeWinkStr(Abs(pU->nCircRelWink), aMetr);
+ aStr += aMetr;
+ aStr.AppendAscii(" r=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(pU->nCircRadius, aMetr, TRUE);
+ aStr += aMetr;
+ }
+
+ aStr.AppendAscii("dx=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(aNow.X(), aMetr, TRUE);
+ aStr += aMetr;
+
+ aStr.AppendAscii(" dy=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(aNow.Y(), aMetr, TRUE);
+ aStr += aMetr;
+
+ if(!IsFreeHand(meObjectKind))
+ {
+ INT32 nLen(GetLen(aNow));
+ aStr.AppendAscii(" l=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aNow));
+ aStr += sal_Unicode(' ');
+ mrSdrPathObject.GetModel()->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
+
+ aStr += sal_Unicode(')');
+ }
+ else if(!mrSdrPathObject.GetModel() || !pHdl)
+ {
+ // #i103058# fallback when no model and/or Handle, both needed
+ // for else-path
+ mrSdrPathObject.ImpTakeDescriptionStr(STR_DragPathObj, aStr);
+ }
+ else
+ {
+ // #i103058# standard for modification; model and handle needed
+ ImpSdrPathDragData* pDragData = mpSdrPathDragData;
+
+ if(!pDragData)
+ {
+ // getSpecialDragComment is also used from create, so fallback to GetUser()
+ // when mpSdrPathDragData is not set
+ pDragData = (ImpSdrPathDragData*)rDrag.GetUser();
+ }
+
+ if(!pDragData)
+ {
+ DBG_ERROR("ImpPathForDragAndCreate::MovDrag(): ImpSdrPathDragData ist ungueltig");
+ return String();
+ }
+
+ if(!pDragData->IsMultiPointDrag() && pDragData->bEliminate)
+ {
+ // Punkt von ...
+ mrSdrPathObject.ImpTakeDescriptionStr(STR_ViewMarkedPoint, aStr);
+
+ // %O loeschen
+ XubString aStr2(ImpGetResStr(STR_EditDelete));
+
+ // UNICODE: Punkt von ... loeschen
+ aStr2.SearchAndReplaceAscii("%1", aStr);
+
+ return aStr2;
+ }
+
+ // dx=0.00 dy=0.00 // Beide Seiten Bezier
+ // dx=0.00 dy=0.00 l=0.00 0.00ø // Anfang oder Ende oder eine Seite Bezier bzw. Hebel
+ // dx=0.00 dy=0.00 l=0.00 0.00ø / l=0.00 0.00ø // Mittendrin
+ XubString aMetr;
+ Point aBeg(rDrag.GetStart());
+ Point aNow(rDrag.GetNow());
+
+ aStr = String();
+ aStr.AppendAscii("dx=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(aNow.X() - aBeg.X(), aMetr, TRUE);
+ aStr += aMetr;
+
+ aStr.AppendAscii(" dy=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(aNow.Y() - aBeg.Y(), aMetr, TRUE);
+ aStr += aMetr;
+
+ if(!pDragData->IsMultiPointDrag())
+ {
+ UINT16 nPntNum((sal_uInt16)pHdl->GetPointNum());
+ const XPolygon& rXPoly = aPathPolygon[(sal_uInt16)rDrag.GetHdl()->GetPolyNum()];
+ UINT16 nPntAnz((sal_uInt16)rXPoly.GetPointCount());
+ BOOL bClose(IsClosed(meObjectKind));
+
+ if(bClose)
+ nPntAnz--;
+
+ if(pHdl->IsPlusHdl())
+ {
+ // Hebel
+ UINT16 nRef(nPntNum);
+
+ if(rXPoly.IsControl(nPntNum + 1))
+ nRef--;
+ else
+ nRef++;
+
+ aNow -= rXPoly[nRef];
+
+ INT32 nLen(GetLen(aNow));
+ aStr.AppendAscii(" l=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aNow));
+ aStr += sal_Unicode(' ');
+ mrSdrPathObject.GetModel()->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
+ else if(nPntAnz > 1)
+ {
+ UINT16 nPntMax(nPntAnz - 1);
+ Point aPt1,aPt2;
+ BOOL bIsClosed(IsClosed(meObjectKind));
+ BOOL bPt1(nPntNum > 0);
+ BOOL bPt2(nPntNum < nPntMax);
+
+ if(bIsClosed && nPntAnz > 2)
+ {
+ bPt1 = TRUE;
+ bPt2 = TRUE;
+ }
+
+ UINT16 nPt1,nPt2;
+
+ if(nPntNum > 0)
+ nPt1 = nPntNum - 1;
+ else
+ nPt1 = nPntMax;
+
+ if(nPntNum < nPntMax)
+ nPt2 = nPntNum + 1;
+ else
+ nPt2 = 0;
+
+ if(bPt1 && rXPoly.IsControl(nPt1))
+ bPt1 = FALSE; // Keine Anzeige
+
+ if(bPt2 && rXPoly.IsControl(nPt2))
+ bPt2 = FALSE; // von Bezierdaten
+
+ if(bPt1)
+ {
+ Point aPt(aNow);
+ aPt -= rXPoly[nPt1];
+
+ INT32 nLen(GetLen(aPt));
+ aStr.AppendAscii(" l=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aPt));
+ aStr += sal_Unicode(' ');
+ mrSdrPathObject.GetModel()->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
+
+ if(bPt2)
+ {
+ if(bPt1)
+ aStr.AppendAscii(" / ");
+ else
+ aStr.AppendAscii(" ");
+
+ Point aPt(aNow);
+ aPt -= rXPoly[nPt2];
+
+ INT32 nLen(GetLen(aPt));
+ aStr.AppendAscii("l=");
+ mrSdrPathObject.GetModel()->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aPt));
+ aStr += sal_Unicode(' ');
+ mrSdrPathObject.GetModel()->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
+ }
+ }
+ }
+
+ return aStr;
+}
+
+basegfx::B2DPolyPolygon ImpPathForDragAndCreate::getSpecialDragPoly(const SdrDragStat& rDrag) const
+{
+ if(!mpSdrPathDragData || !mpSdrPathDragData->bValid)
+ {
+ DBG_ERROR("ImpPathForDragAndCreate::MovDrag(): ImpSdrPathDragData ist ungueltig");
+ return basegfx::B2DPolyPolygon();
+ }
+
+ XPolyPolygon aRetval;
+
+ if(mpSdrPathDragData->IsMultiPointDrag())
+ {
+ aRetval.Insert(mpSdrPathDragData->maMove);
+ }
+ else
+ {
+ const XPolygon& rXP=aPathPolygon[(sal_uInt16)rDrag.GetHdl()->GetPolyNum()];
+ if (rXP.GetPointCount()<=2) { //|| rXPoly.GetFlags(1)==XPOLY_CONTROL && rXPoly.GetPointCount()<=4
+ XPolygon aXPoly(rXP);
+ aXPoly[(sal_uInt16)rDrag.GetHdl()->GetPointNum()]=rDrag.GetNow();
+ aRetval.Insert(aXPoly);
+ return aRetval.getB2DPolyPolygon();
+ }
+ // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
+ FASTBOOL bClosed =mpSdrPathDragData->bClosed ; // geschlossenes Objekt?
+ USHORT nPntAnz =mpSdrPathDragData->nPntAnz ; // Punktanzahl
+ USHORT nPnt =mpSdrPathDragData->nPnt ; // Punktnummer innerhalb des Polygons
+ FASTBOOL bBegPnt =mpSdrPathDragData->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ FASTBOOL bEndPnt =mpSdrPathDragData->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ USHORT nPrevPnt =mpSdrPathDragData->nPrevPnt ; // Index des vorherigen Punkts
+ USHORT nNextPnt =mpSdrPathDragData->nNextPnt ; // Index des naechsten Punkts
+ FASTBOOL bPrevIsBegPnt =mpSdrPathDragData->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
+ FASTBOOL bNextIsEndPnt =mpSdrPathDragData->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
+ USHORT nPrevPrevPnt =mpSdrPathDragData->nPrevPrevPnt ; // Index des vorvorherigen Punkts
+ USHORT nNextNextPnt =mpSdrPathDragData->nNextNextPnt ; // Index des uebernaechsten Punkts
+ FASTBOOL bControl =mpSdrPathDragData->bControl ; // Punkt ist ein Kontrollpunkt
+ //FASTBOOL bIsPrevControl=mpSdrPathDragData->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ FASTBOOL bIsNextControl=mpSdrPathDragData->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ FASTBOOL bPrevIsControl=mpSdrPathDragData->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ FASTBOOL bNextIsControl=mpSdrPathDragData->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+ XPolygon aXPoly(mpSdrPathDragData->aXP);
+ XPolygon aLine1(2);
+ XPolygon aLine2(2);
+ XPolygon aLine3(2);
+ XPolygon aLine4(2);
+ if (bControl) {
+ aLine1[1]=mpSdrPathDragData->aXP[nPnt];
+ if (bIsNextControl) { // bin ich Kontrollpunkt hinter der Stuetzstelle?
+ aLine1[0]=mpSdrPathDragData->aXP[nPrevPnt];
+ aLine2[0]=mpSdrPathDragData->aXP[nNextNextPnt];
+ aLine2[1]=mpSdrPathDragData->aXP[nNextPnt];
+ if (mpSdrPathDragData->aXP.IsSmooth(nPrevPnt) && !bPrevIsBegPnt && mpSdrPathDragData->aXP.IsControl(nPrevPrevPnt)) {
+ aXPoly.Insert(0,rXP[mpSdrPathDragData->nPrevPrevPnt0-1],XPOLY_CONTROL);
+ aXPoly.Insert(0,rXP[mpSdrPathDragData->nPrevPrevPnt0-2],XPOLY_NORMAL);
+ // Hebellienien fuer das gegenueberliegende Kurvensegment
+ aLine3[0]=mpSdrPathDragData->aXP[nPrevPnt];
+ aLine3[1]=mpSdrPathDragData->aXP[nPrevPrevPnt];
+ aLine4[0]=rXP[mpSdrPathDragData->nPrevPrevPnt0-2];
+ aLine4[1]=rXP[mpSdrPathDragData->nPrevPrevPnt0-1];
+ } else {
+ aXPoly.Remove(0,1);
+ }
+ } else { // ansonsten bin ich Kontrollpunkt vor der Stuetzstelle
+ aLine1[0]=mpSdrPathDragData->aXP[nNextPnt];
+ aLine2[0]=mpSdrPathDragData->aXP[nPrevPrevPnt];
+ aLine2[1]=mpSdrPathDragData->aXP[nPrevPnt];
+ if (mpSdrPathDragData->aXP.IsSmooth(nNextPnt) && !bNextIsEndPnt && mpSdrPathDragData->aXP.IsControl(nNextNextPnt)) {
+ aXPoly.Insert(XPOLY_APPEND,rXP[mpSdrPathDragData->nNextNextPnt0+1],XPOLY_CONTROL);
+ aXPoly.Insert(XPOLY_APPEND,rXP[mpSdrPathDragData->nNextNextPnt0+2],XPOLY_NORMAL);
+ // Hebellinien fuer das gegenueberliegende Kurvensegment
+ aLine3[0]=mpSdrPathDragData->aXP[nNextPnt];
+ aLine3[1]=mpSdrPathDragData->aXP[nNextNextPnt];
+ aLine4[0]=rXP[mpSdrPathDragData->nNextNextPnt0+2];
+ aLine4[1]=rXP[mpSdrPathDragData->nNextNextPnt0+1];
+ } else {
+ aXPoly.Remove(aXPoly.GetPointCount()-1,1);
+ }
+ }
+ } else { // ansonsten kein Kontrollpunkt
+ if (mpSdrPathDragData->bEliminate) {
+ aXPoly.Remove(2,1);
+ }
+ if (bPrevIsControl) aXPoly.Insert(0,rXP[mpSdrPathDragData->nPrevPrevPnt0-1],XPOLY_NORMAL);
+ else if (!bBegPnt && !bPrevIsBegPnt && mpSdrPathDragData->aXP.IsControl(nPrevPrevPnt)) {
+ aXPoly.Insert(0,rXP[mpSdrPathDragData->nPrevPrevPnt0-1],XPOLY_CONTROL);
+ aXPoly.Insert(0,rXP[mpSdrPathDragData->nPrevPrevPnt0-2],XPOLY_NORMAL);
+ } else {
+ aXPoly.Remove(0,1);
+ if (bBegPnt) aXPoly.Remove(0,1);
+ }
+ if (bNextIsControl) aXPoly.Insert(XPOLY_APPEND,rXP[mpSdrPathDragData->nNextNextPnt0+1],XPOLY_NORMAL);
+ else if (!bEndPnt && !bNextIsEndPnt && mpSdrPathDragData->aXP.IsControl(nNextNextPnt)) {
+ aXPoly.Insert(XPOLY_APPEND,rXP[mpSdrPathDragData->nNextNextPnt0+1],XPOLY_CONTROL);
+ aXPoly.Insert(XPOLY_APPEND,rXP[mpSdrPathDragData->nNextNextPnt0+2],XPOLY_NORMAL);
+ } else {
+ aXPoly.Remove(aXPoly.GetPointCount()-1,1);
+ if (bEndPnt) aXPoly.Remove(aXPoly.GetPointCount()-1,1);
+ }
+ if (bClosed) { // "Birnenproblem": 2 Linien, 1 Kurve, alles Smooth, Punkt zw. beiden Linien wird gedraggt
+ if (aXPoly.GetPointCount()>nPntAnz && aXPoly.IsControl(1)) {
+ USHORT a=aXPoly.GetPointCount();
+ aXPoly[a-2]=aXPoly[2]; aXPoly.SetFlags(a-2,aXPoly.GetFlags(2));
+ aXPoly[a-1]=aXPoly[3]; aXPoly.SetFlags(a-1,aXPoly.GetFlags(3));
+ aXPoly.Remove(0,3);
+ }
+ }
+ }
+ aRetval.Insert(aXPoly);
+ if (aLine1.GetPointCount()>1) aRetval.Insert(aLine1);
+ if (aLine2.GetPointCount()>1) aRetval.Insert(aLine2);
+ if (aLine3.GetPointCount()>1) aRetval.Insert(aLine3);
+ if (aLine4.GetPointCount()>1) aRetval.Insert(aLine4);
+ }
+
+ return aRetval.getB2DPolyPolygon();
+}
+
+FASTBOOL ImpPathForDragAndCreate::BegCreate(SdrDragStat& rStat)
+{
+ bool bFreeHand(IsFreeHand(meObjectKind));
+ rStat.SetNoSnap(bFreeHand);
+ rStat.SetOrtho8Possible();
+ aPathPolygon.Clear();
+ mbCreating=TRUE;
+ FASTBOOL bMakeStartPoint=TRUE;
+ SdrView* pView=rStat.GetView();
+ if (pView!=NULL && pView->IsUseIncompatiblePathCreateInterface() &&
+ (meObjectKind==OBJ_POLY || meObjectKind==OBJ_PLIN || meObjectKind==OBJ_PATHLINE || meObjectKind==OBJ_PATHFILL)) {
+ bMakeStartPoint=FALSE;
+ }
+ aPathPolygon.Insert(XPolygon());
+ aPathPolygon[0][0]=rStat.GetStart();
+ if (bMakeStartPoint) {
+ aPathPolygon[0][1]=rStat.GetNow();
+ }
+ ImpPathCreateUser* pU=new ImpPathCreateUser;
+ pU->eStartKind=meObjectKind;
+ pU->eAktKind=meObjectKind;
+ rStat.SetUser(pU);
+ return TRUE;
+}
+
+FASTBOOL ImpPathForDragAndCreate::MovCreate(SdrDragStat& rStat)
+{
+ ImpPathCreateUser* pU=(ImpPathCreateUser*)rStat.GetUser();
+ SdrView* pView=rStat.GetView();
+ XPolygon& rXPoly=aPathPolygon[aPathPolygon.Count()-1];
+ if (pView!=NULL && pView->IsCreateMode()) {
+ // ggf. auf anderes CreateTool umschalten
+ UINT16 nIdent;
+ UINT32 nInvent;
+ pView->TakeCurrentObj(nIdent,nInvent);
+ if (nInvent==SdrInventor && pU->eAktKind!=(SdrObjKind)nIdent) {
+ SdrObjKind eNewKind=(SdrObjKind)nIdent;
+ switch (eNewKind) {
+ case OBJ_CARC: case OBJ_CIRC: case OBJ_CCUT: case OBJ_SECT: eNewKind=OBJ_CARC;
+ case OBJ_RECT:
+ case OBJ_LINE: case OBJ_PLIN: case OBJ_POLY:
+ case OBJ_PATHLINE: case OBJ_PATHFILL:
+ case OBJ_FREELINE: case OBJ_FREEFILL:
+ case OBJ_SPLNLINE: case OBJ_SPLNFILL: {
+ pU->eAktKind=eNewKind;
+ pU->bMixedCreate=TRUE;
+ pU->nBezierStartPoint=rXPoly.GetPointCount();
+ if (pU->nBezierStartPoint>0) pU->nBezierStartPoint--;
+ } break;
+ default: break;
+ } // switch
+ }
+ }
+ USHORT nActPoint=rXPoly.GetPointCount();
+ if (aPathPolygon.Count()>1 && rStat.IsMouseDown() && nActPoint<2) {
+ rXPoly[0]=rStat.GetPos0();
+ rXPoly[1]=rStat.GetNow();
+ nActPoint=2;
+ }
+ if (nActPoint==0) {
+ rXPoly[0]=rStat.GetPos0();
+ } else nActPoint--;
+ FASTBOOL bFreeHand=IsFreeHand(pU->eAktKind);
+ rStat.SetNoSnap(bFreeHand /*|| (pU->bMixed && pU->eAktKind==OBJ_LINE)*/);
+ rStat.SetOrtho8Possible(pU->eAktKind!=OBJ_CARC && pU->eAktKind!=OBJ_RECT && (!pU->bMixedCreate || pU->eAktKind!=OBJ_LINE));
+ Point aActMerk(rXPoly[nActPoint]);
+ rXPoly[nActPoint]=rStat.Now();
+ if (!pU->bMixedCreate && pU->eStartKind==OBJ_LINE && rXPoly.GetPointCount()>=1) {
+ Point aPt(rStat.Start());
+ if (pView!=NULL && pView->IsCreate1stPointAsCenter()) {
+ aPt+=aPt;
+ aPt-=rStat.Now();
+ }
+ rXPoly[0]=aPt;
+ }
+ OutputDevice* pOut=pView==NULL ? NULL : pView->GetFirstOutputDevice(); // GetWin(0);
+ if (bFreeHand) {
+ if (pU->nBezierStartPoint>nActPoint) pU->nBezierStartPoint=nActPoint;
+ if (rStat.IsMouseDown() && nActPoint>0) {
+ // keine aufeinanderfolgenden Punkte an zu Nahe gelegenen Positionen zulassen
+ long nMinDist=1;
+ if (pView!=NULL) nMinDist=pView->GetFreeHandMinDistPix();
+ if (pOut!=NULL) nMinDist=pOut->PixelToLogic(Size(nMinDist,0)).Width();
+ if (nMinDist<1) nMinDist=1;
+
+ Point aPt0(rXPoly[nActPoint-1]);
+ Point aPt1(rStat.Now());
+ long dx=aPt0.X()-aPt1.X(); if (dx<0) dx=-dx;
+ long dy=aPt0.Y()-aPt1.Y(); if (dy<0) dy=-dy;
+ if (dx<nMinDist && dy<nMinDist) return FALSE;
+
+ // folgendes ist aus EndCreate kopiert (nur kleine Modifikationen)
+ // und sollte dann mal in eine Methode zusammengefasst werden:
+
+ if (nActPoint-pU->nBezierStartPoint>=3 && ((nActPoint-pU->nBezierStartPoint)%3)==0) {
+ rXPoly.PointsToBezier(nActPoint-3);
+ rXPoly.SetFlags(nActPoint-1,XPOLY_CONTROL);
+ rXPoly.SetFlags(nActPoint-2,XPOLY_CONTROL);
+
+ if (nActPoint>=6 && rXPoly.IsControl(nActPoint-4)) {
+ rXPoly.CalcTangent(nActPoint-3,nActPoint-4,nActPoint-2);
+ rXPoly.SetFlags(nActPoint-3,XPOLY_SMOOTH);
+ }
+ }
+ rXPoly[nActPoint+1]=rStat.Now();
+ rStat.NextPoint();
+ } else {
+ pU->nBezierStartPoint=nActPoint;
+ }
+ }
+
+ pU->ResetFormFlags();
+ if (IsBezier(pU->eAktKind)) {
+ if (nActPoint>=2) {
+ pU->CalcBezier(rXPoly[nActPoint-1],rXPoly[nActPoint],rXPoly[nActPoint-1]-rXPoly[nActPoint-2],rStat.IsMouseDown());
+ } else if (pU->bBezHasCtrl0) {
+ pU->CalcBezier(rXPoly[nActPoint-1],rXPoly[nActPoint],pU->aBezControl0-rXPoly[nActPoint-1],rStat.IsMouseDown());
+ }
+ }
+ if (pU->eAktKind==OBJ_CARC && nActPoint>=2) {
+ pU->CalcCircle(rXPoly[nActPoint-1],rXPoly[nActPoint],rXPoly[nActPoint-1]-rXPoly[nActPoint-2],pView);
+ }
+ if (pU->eAktKind==OBJ_LINE && nActPoint>=2) {
+ pU->CalcLine(rXPoly[nActPoint-1],rXPoly[nActPoint],rXPoly[nActPoint-1]-rXPoly[nActPoint-2],pView);
+ }
+ if (pU->eAktKind==OBJ_RECT && nActPoint>=2) {
+ pU->CalcRect(rXPoly[nActPoint-1],rXPoly[nActPoint],rXPoly[nActPoint-1]-rXPoly[nActPoint-2],pView);
+ }
+
+ return TRUE;
+}
+
+FASTBOOL ImpPathForDragAndCreate::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ ImpPathCreateUser* pU=(ImpPathCreateUser*)rStat.GetUser();
+ FASTBOOL bRet=FALSE;
+ SdrView* pView=rStat.GetView();
+ FASTBOOL bIncomp=pView!=NULL && pView->IsUseIncompatiblePathCreateInterface();
+ XPolygon& rXPoly=aPathPolygon[aPathPolygon.Count()-1];
+ USHORT nActPoint=rXPoly.GetPointCount()-1;
+ Point aAktMerk(rXPoly[nActPoint]);
+ rXPoly[nActPoint]=rStat.Now();
+ if (!pU->bMixedCreate && pU->eStartKind==OBJ_LINE) {
+ if (rStat.GetPointAnz()>=2) eCmd=SDRCREATE_FORCEEND;
+ bRet=eCmd==SDRCREATE_FORCEEND;
+ if (bRet) {
+ mbCreating=FALSE;
+ delete pU;
+ rStat.SetUser(NULL);
+ }
+ return bRet;
+ }
+
+ if (!pU->bMixedCreate && IsFreeHand(pU->eStartKind)) {
+ if (rStat.GetPointAnz()>=2) eCmd=SDRCREATE_FORCEEND;
+ bRet=eCmd==SDRCREATE_FORCEEND;
+ if (bRet) {
+ mbCreating=FALSE;
+ delete pU;
+ rStat.SetUser(NULL);
+ }
+ return bRet;
+ }
+ if (eCmd==SDRCREATE_NEXTPOINT || eCmd==SDRCREATE_NEXTOBJECT) {
+ // keine aufeinanderfolgenden Punkte an identischer Position zulassen
+ if (nActPoint==0 || rStat.Now()!=rXPoly[nActPoint-1]) {
+ if (bIncomp) {
+ if (pU->nBezierStartPoint>nActPoint) pU->nBezierStartPoint=nActPoint;
+ if (IsBezier(pU->eAktKind) && nActPoint-pU->nBezierStartPoint>=3 && ((nActPoint-pU->nBezierStartPoint)%3)==0) {
+ rXPoly.PointsToBezier(nActPoint-3);
+ rXPoly.SetFlags(nActPoint-1,XPOLY_CONTROL);
+ rXPoly.SetFlags(nActPoint-2,XPOLY_CONTROL);
+
+ if (nActPoint>=6 && rXPoly.IsControl(nActPoint-4)) {
+ rXPoly.CalcTangent(nActPoint-3,nActPoint-4,nActPoint-2);
+ rXPoly.SetFlags(nActPoint-3,XPOLY_SMOOTH);
+ }
+ }
+ } else {
+ if (nActPoint==1 && IsBezier(pU->eAktKind) && !pU->bBezHasCtrl0) {
+ pU->aBezControl0=rStat.GetNow();;
+ pU->bBezHasCtrl0=TRUE;
+ nActPoint--;
+ }
+ if (pU->IsFormFlag()) {
+ USHORT nPtAnz0=rXPoly.GetPointCount();
+ rXPoly.Remove(nActPoint-1,2); // die letzten beiden Punkte entfernen und durch die Form ersetzen
+ rXPoly.Insert(XPOLY_APPEND,pU->GetFormPoly());
+ USHORT nPtAnz1=rXPoly.GetPointCount();
+ for (USHORT i=nPtAnz0+1; i<nPtAnz1-1; i++) { // Damit BckAction richtig funktioniert
+ if (!rXPoly.IsControl(i)) rStat.NextPoint();
+ }
+ nActPoint=rXPoly.GetPointCount()-1;
+ }
+ }
+ nActPoint++;
+ rXPoly[nActPoint]=rStat.GetNow();
+ }
+ if (eCmd==SDRCREATE_NEXTOBJECT) {
+ if (rXPoly.GetPointCount()>=2) {
+ pU->bBezHasCtrl0=FALSE;
+ // nur einzelnes Polygon kann offen sein, deshalb schliessen
+ rXPoly[nActPoint]=rXPoly[0];
+ XPolygon aXP;
+ aXP[0]=rStat.GetNow();
+ aPathPolygon.Insert(aXP);
+ }
+ }
+ }
+
+ USHORT nPolyAnz=aPathPolygon.Count();
+ if (nPolyAnz!=0) {
+ // den letzten Punkt ggf. wieder loeschen
+ if (eCmd==SDRCREATE_FORCEEND) {
+ XPolygon& rXP=aPathPolygon[nPolyAnz-1];
+ USHORT nPtAnz=rXP.GetPointCount();
+ if (nPtAnz>=2) {
+ if (!rXP.IsControl(nPtAnz-2)) {
+ if (rXP[nPtAnz-1]==rXP[nPtAnz-2]) {
+ rXP.Remove(nPtAnz-1,1);
+ }
+ } else {
+ if (rXP[nPtAnz-3]==rXP[nPtAnz-2]) {
+ rXP.Remove(nPtAnz-3,3);
+ }
+ }
+ }
+ }
+ for (USHORT nPolyNum=nPolyAnz; nPolyNum>0;) {
+ nPolyNum--;
+ XPolygon& rXP=aPathPolygon[nPolyNum];
+ USHORT nPtAnz=rXP.GetPointCount();
+ // Polygone mit zu wenig Punkten werden geloescht
+ if (nPolyNum<nPolyAnz-1 || eCmd==SDRCREATE_FORCEEND) {
+ if (nPtAnz<2) aPathPolygon.Remove(nPolyNum);
+ }
+ }
+ }
+ pU->ResetFormFlags();
+ bRet=eCmd==SDRCREATE_FORCEEND;
+ if (bRet) {
+ mbCreating=FALSE;
+ delete pU;
+ rStat.SetUser(NULL);
+ }
+ return bRet;
+}
+
+FASTBOOL ImpPathForDragAndCreate::BckCreate(SdrDragStat& rStat)
+{
+ ImpPathCreateUser* pU=(ImpPathCreateUser*)rStat.GetUser();
+ if (aPathPolygon.Count()>0) {
+ XPolygon& rXPoly=aPathPolygon[aPathPolygon.Count()-1];
+ USHORT nActPoint=rXPoly.GetPointCount();
+ if (nActPoint>0) {
+ nActPoint--;
+ // Das letzte Stueck einer Bezierkurve wird erstmal zu 'ner Linie
+ rXPoly.Remove(nActPoint,1);
+ if (nActPoint>=3 && rXPoly.IsControl(nActPoint-1)) {
+ // Beziersegment am Ende sollte zwar nicht vorkommen, aber falls doch ...
+ rXPoly.Remove(nActPoint-1,1);
+ if (rXPoly.IsControl(nActPoint-2)) rXPoly.Remove(nActPoint-2,1);
+ }
+ }
+ nActPoint=rXPoly.GetPointCount();
+ if (nActPoint>=4) { // Kein Beziersegment am Ende
+ nActPoint--;
+ if (rXPoly.IsControl(nActPoint-1)) {
+ rXPoly.Remove(nActPoint-1,1);
+ if (rXPoly.IsControl(nActPoint-2)) rXPoly.Remove(nActPoint-2,1);
+ }
+ }
+ if (rXPoly.GetPointCount()<2) {
+ aPathPolygon.Remove(aPathPolygon.Count()-1);
+ }
+ if (aPathPolygon.Count()>0) {
+ XPolygon& rLocalXPoly=aPathPolygon[aPathPolygon.Count()-1];
+ USHORT nLocalActPoint=rLocalXPoly.GetPointCount();
+ if (nLocalActPoint>0) {
+ nLocalActPoint--;
+ rLocalXPoly[nLocalActPoint]=rStat.Now();
+ }
+ }
+ }
+ pU->ResetFormFlags();
+ return aPathPolygon.Count()!=0;
+}
+
+void ImpPathForDragAndCreate::BrkCreate(SdrDragStat& rStat)
+{
+ ImpPathCreateUser* pU=(ImpPathCreateUser*)rStat.GetUser();
+ aPathPolygon.Clear();
+ mbCreating=FALSE;
+ delete pU;
+ rStat.SetUser(NULL);
+}
+
+basegfx::B2DPolyPolygon ImpPathForDragAndCreate::TakeObjectPolyPolygon(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval(aPathPolygon.getB2DPolyPolygon());
+ SdrView* pView = rDrag.GetView();
+
+ if(pView && pView->IsUseIncompatiblePathCreateInterface())
+ return aRetval;
+
+ ImpPathCreateUser* pU = (ImpPathCreateUser*)rDrag.GetUser();
+ basegfx::B2DPolygon aNewPolygon(aRetval.count() ? aRetval.getB2DPolygon(aRetval.count() - 1L) : basegfx::B2DPolygon());
+
+ if(pU->IsFormFlag() && aNewPolygon.count() > 1L)
+ {
+ // remove last segment and replace with current
+ // do not forget to rescue the previous control point which will be lost when
+ // the point it's associated with is removed
+ const sal_uInt32 nChangeIndex(aNewPolygon.count() - 2);
+ const basegfx::B2DPoint aSavedPrevCtrlPoint(aNewPolygon.getPrevControlPoint(nChangeIndex));
+
+ aNewPolygon.remove(nChangeIndex, 2L);
+ aNewPolygon.append(pU->GetFormPoly().getB2DPolygon());
+
+ if(nChangeIndex < aNewPolygon.count())
+ {
+ // if really something was added, set the saved prev control point at the
+ // point where it belongs
+ aNewPolygon.setPrevControlPoint(nChangeIndex, aSavedPrevCtrlPoint);
+ }
+ }
+
+ if(aRetval.count())
+ {
+ aRetval.setB2DPolygon(aRetval.count() - 1L, aNewPolygon);
+ }
+ else
+ {
+ aRetval.append(aNewPolygon);
+ }
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon ImpPathForDragAndCreate::TakeDragPolyPolygon(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ SdrView* pView = rDrag.GetView();
+
+ if(pView && pView->IsUseIncompatiblePathCreateInterface())
+ return aRetval;
+
+ ImpPathCreateUser* pU = (ImpPathCreateUser*)rDrag.GetUser();
+
+ if(pU && pU->bBezier && rDrag.IsMouseDown())
+ {
+ // no more XOR, no need for complicated helplines
+ basegfx::B2DPolygon aHelpline;
+ aHelpline.append(basegfx::B2DPoint(pU->aBezCtrl2.X(), pU->aBezCtrl2.Y()));
+ aHelpline.append(basegfx::B2DPoint(pU->aBezEnd.X(), pU->aBezEnd.Y()));
+ aRetval.append(aHelpline);
+ }
+
+ return aRetval;
+}
+
+Pointer ImpPathForDragAndCreate::GetCreatePointer() const
+{
+ switch (meObjectKind) {
+ case OBJ_LINE : return Pointer(POINTER_DRAW_LINE);
+ case OBJ_POLY : return Pointer(POINTER_DRAW_POLYGON);
+ case OBJ_PLIN : return Pointer(POINTER_DRAW_POLYGON);
+ case OBJ_PATHLINE: return Pointer(POINTER_DRAW_BEZIER);
+ case OBJ_PATHFILL: return Pointer(POINTER_DRAW_BEZIER);
+ case OBJ_FREELINE: return Pointer(POINTER_DRAW_FREEHAND);
+ case OBJ_FREEFILL: return Pointer(POINTER_DRAW_FREEHAND);
+ case OBJ_SPLNLINE: return Pointer(POINTER_DRAW_FREEHAND);
+ case OBJ_SPLNFILL: return Pointer(POINTER_DRAW_FREEHAND);
+ case OBJ_PATHPOLY: return Pointer(POINTER_DRAW_POLYGON);
+ case OBJ_PATHPLIN: return Pointer(POINTER_DRAW_POLYGON);
+ default: break;
+ } // switch
+ return Pointer(POINTER_CROSS);
+}
+
+/*************************************************************************/
+
+SdrPathObjGeoData::SdrPathObjGeoData()
+{
+}
+
+SdrPathObjGeoData::~SdrPathObjGeoData()
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrPathObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrPathObj(*this);
+}
+
+/*************************************************************************/
+
+TYPEINIT1(SdrPathObj,SdrTextObj);
+
+SdrPathObj::SdrPathObj(SdrObjKind eNewKind)
+: meKind(eNewKind),
+ mpDAC(0L)
+{
+ bClosedObj = IsClosed();
+}
+
+SdrPathObj::SdrPathObj(SdrObjKind eNewKind, const basegfx::B2DPolyPolygon& rPathPoly)
+: maPathPolygon(rPathPoly),
+ meKind(eNewKind),
+ mpDAC(0L)
+{
+ bClosedObj = IsClosed();
+ ImpForceKind();
+}
+
+SdrPathObj::~SdrPathObj()
+{
+ impDeleteDAC();
+}
+
+sal_Bool ImpIsLine(const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ return (1L == rPolyPolygon.count() && 2L == rPolyPolygon.getB2DPolygon(0L).count());
+}
+
+Rectangle ImpGetBoundRect(const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ basegfx::B2DRange aRange(basegfx::tools::getRange(rPolyPolygon));
+
+ return Rectangle(
+ FRound(aRange.getMinX()), FRound(aRange.getMinY()),
+ FRound(aRange.getMaxX()), FRound(aRange.getMaxY()));
+}
+
+void SdrPathObj::ImpForceLineWink()
+{
+ if(OBJ_LINE == meKind && ImpIsLine(GetPathPoly()))
+ {
+ const basegfx::B2DPolygon aPoly(GetPathPoly().getB2DPolygon(0L));
+ const basegfx::B2DPoint aB2DPoint0(aPoly.getB2DPoint(0L));
+ const basegfx::B2DPoint aB2DPoint1(aPoly.getB2DPoint(1L));
+ const Point aPoint0(FRound(aB2DPoint0.getX()), FRound(aB2DPoint0.getY()));
+ const Point aPoint1(FRound(aB2DPoint1.getX()), FRound(aB2DPoint1.getY()));
+ const Point aDelt(aPoint1 - aPoint0);
+
+ aGeo.nDrehWink=GetAngle(aDelt);
+ aGeo.nShearWink=0;
+ aGeo.RecalcSinCos();
+ aGeo.RecalcTan();
+
+ // #101412# for SdrTextObj, keep aRect up to date
+ aRect = Rectangle(aPoint0, aPoint1);
+ aRect.Justify();
+ }
+}
+
+void SdrPathObj::ImpForceKind()
+{
+ if (meKind==OBJ_PATHPLIN) meKind=OBJ_PLIN;
+ if (meKind==OBJ_PATHPOLY) meKind=OBJ_POLY;
+
+ if(GetPathPoly().areControlPointsUsed())
+ {
+ switch (meKind)
+ {
+ case OBJ_LINE: meKind=OBJ_PATHLINE; break;
+ case OBJ_PLIN: meKind=OBJ_PATHLINE; break;
+ case OBJ_POLY: meKind=OBJ_PATHFILL; break;
+ default: break;
+ }
+ }
+ else
+ {
+ switch (meKind)
+ {
+ case OBJ_PATHLINE: meKind=OBJ_PLIN; break;
+ case OBJ_FREELINE: meKind=OBJ_PLIN; break;
+ case OBJ_PATHFILL: meKind=OBJ_POLY; break;
+ case OBJ_FREEFILL: meKind=OBJ_POLY; break;
+ default: break;
+ }
+ }
+
+ if (meKind==OBJ_LINE && !ImpIsLine(GetPathPoly())) meKind=OBJ_PLIN;
+ if (meKind==OBJ_PLIN && ImpIsLine(GetPathPoly())) meKind=OBJ_LINE;
+
+ bClosedObj=IsClosed();
+
+ if (meKind==OBJ_LINE)
+ {
+ ImpForceLineWink();
+ }
+ else
+ {
+ // #i10659#, similar to #101412# but for polys with more than 2 points.
+ //
+ // Here i again need to fix something, because when Path-Polys are Copy-Pasted
+ // between Apps with different measurements (e.g. 100TH_MM and TWIPS) there is
+ // a scaling loop started from SdrExchangeView::Paste. This is principally nothing
+ // wrong, but aRect is wrong here and not even updated by RecalcSnapRect(). If
+ // this is the case, some size needs to be set here in aRect to avoid that the cyclus
+ // through Rect2Poly - Poly2Rect does something badly wrong since that cycle is
+ // BASED on aRect. That cycle is triggered in SdrTextObj::NbcResize() which is called
+ // from the local Resize() implementation.
+ //
+ // Basic problem is that the member aRect in SdrTextObj basically is a unrotated
+ // text rectangle for the text object itself and methods at SdrTextObj do handle it
+ // in that way. Many draw objects derived from SdrTextObj 'abuse' aRect as SnapRect
+ // which is basically wrong. To make the SdrText methods which deal with aRect directly
+ // work it is necessary to always keep aRect updated. This e.g. not done after a Clone()
+ // command for SdrPathObj. Since adding this update mechanism with #101412# to
+ // ImpForceLineWink() for lines was very successful, i add it to where ImpForceLineWink()
+ // was called, once here below and once on a 2nd place below.
+
+ // #i10659# for SdrTextObj, keep aRect up to date
+ if(GetPathPoly().count())
+ {
+ aRect = ImpGetBoundRect(GetPathPoly());
+ }
+ }
+
+ // #i75974# adapt polygon state to object type. This may include a reinterpretation
+ // of a closed geometry as open one, but with identical first and last point
+ for(sal_uInt32 a(0); a < maPathPolygon.count(); a++)
+ {
+ basegfx::B2DPolygon aCandidate(maPathPolygon.getB2DPolygon(a));
+
+ if((bool)IsClosed() != aCandidate.isClosed())
+ {
+ // #i80213# really change polygon geometry; else e.g. the last point which
+ // needs to be identical with the first one will be missing when opening
+ // due to OBJ_PATH type
+ if(aCandidate.isClosed())
+ {
+ basegfx::tools::openWithGeometryChange(aCandidate);
+ }
+ else
+ {
+ basegfx::tools::closeWithGeometryChange(aCandidate);
+ }
+
+ maPathPolygon.setB2DPolygon(a, aCandidate);
+ }
+ }
+}
+
+void SdrPathObj::ImpSetClosed(sal_Bool bClose)
+{
+ if(bClose)
+ {
+ switch (meKind)
+ {
+ case OBJ_LINE : meKind=OBJ_POLY; break;
+ case OBJ_PLIN : meKind=OBJ_POLY; break;
+ case OBJ_PATHLINE: meKind=OBJ_PATHFILL; break;
+ case OBJ_FREELINE: meKind=OBJ_FREEFILL; break;
+ case OBJ_SPLNLINE: meKind=OBJ_SPLNFILL; break;
+ default: break;
+ }
+
+ bClosedObj = TRUE;
+ }
+ else
+ {
+ switch (meKind)
+ {
+ case OBJ_POLY : meKind=OBJ_PLIN; break;
+ case OBJ_PATHFILL: meKind=OBJ_PATHLINE; break;
+ case OBJ_FREEFILL: meKind=OBJ_FREELINE; break;
+ case OBJ_SPLNFILL: meKind=OBJ_SPLNLINE; break;
+ default: break;
+ }
+
+ bClosedObj = FALSE;
+ }
+
+ ImpForceKind();
+}
+
+void SdrPathObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bNoContortion=FALSE;
+
+ FASTBOOL bCanConv = !HasText() || ImpCanConvTextToCurve();
+ FASTBOOL bIsPath = IsBezier() || IsSpline();
+
+ rInfo.bEdgeRadiusAllowed = FALSE;
+ rInfo.bCanConvToPath = bCanConv && !bIsPath;
+ rInfo.bCanConvToPoly = bCanConv && bIsPath;
+ rInfo.bCanConvToContour = !IsFontwork() && (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrPathObj::GetObjIdentifier() const
+{
+ return USHORT(meKind);
+}
+
+void SdrPathObj::operator=(const SdrObject& rObj)
+{
+ SdrTextObj::operator=(rObj);
+ SdrPathObj& rPath=(SdrPathObj&)rObj;
+ maPathPolygon=rPath.GetPathPoly();
+}
+
+void SdrPathObj::TakeObjNameSingul(XubString& rName) const
+{
+ if(OBJ_LINE == meKind)
+ {
+ sal_uInt16 nId(STR_ObjNameSingulLINE);
+
+ if(ImpIsLine(GetPathPoly()))
+ {
+ const basegfx::B2DPolygon aPoly(GetPathPoly().getB2DPolygon(0L));
+ const basegfx::B2DPoint aB2DPoint0(aPoly.getB2DPoint(0L));
+ const basegfx::B2DPoint aB2DPoint1(aPoly.getB2DPoint(1L));
+ const Point aPoint0(FRound(aB2DPoint0.getX()), FRound(aB2DPoint0.getY()));
+ const Point aPoint1(FRound(aB2DPoint0.getX()), FRound(aB2DPoint0.getY()));
+
+ if(aB2DPoint0 != aB2DPoint1)
+ {
+ if(aB2DPoint0.getY() == aB2DPoint1.getY())
+ {
+ nId = STR_ObjNameSingulLINE_Hori;
+ }
+ else if(aB2DPoint0.getX() == aB2DPoint1.getX())
+ {
+ nId = STR_ObjNameSingulLINE_Vert;
+ }
+ else
+ {
+ const double fDx(fabs(aB2DPoint0.getX() - aB2DPoint1.getX()));
+ const double fDy(fabs(aB2DPoint0.getY() - aB2DPoint1.getY()));
+
+ if(fDx == fDy)
+ {
+ nId = STR_ObjNameSingulLINE_Diag;
+ }
+ }
+ }
+ }
+
+ rName = ImpGetResStr(nId);
+ }
+ else if(OBJ_PLIN == meKind || OBJ_POLY == meKind)
+ {
+ const sal_Bool bClosed(OBJ_POLY == meKind);
+ sal_uInt16 nId(0);
+
+ if(mpDAC && mpDAC->IsCreating())
+ {
+ if(bClosed)
+ {
+ nId = STR_ObjNameSingulPOLY;
+ }
+ else
+ {
+ nId = STR_ObjNameSingulPLIN;
+ }
+
+ rName = ImpGetResStr(nId);
+ }
+ else
+ {
+ // get point count
+ sal_uInt32 nPointCount(0L);
+ const sal_uInt32 nPolyCount(GetPathPoly().count());
+
+ for(sal_uInt32 a(0L); a < nPolyCount; a++)
+ {
+ nPointCount += GetPathPoly().getB2DPolygon(a).count();
+ }
+
+ if(bClosed)
+ {
+ nId = STR_ObjNameSingulPOLY_PntAnz;
+ }
+ else
+ {
+ nId = STR_ObjNameSingulPLIN_PntAnz;
+ }
+
+ rName = ImpGetResStr(nId);
+ sal_uInt16 nPos(rName.SearchAscii("%2")); // #i96537#
+
+ if(STRING_NOTFOUND != nPos)
+ {
+ rName.Erase(nPos, 2);
+ rName.Insert(UniString::CreateFromInt32(nPointCount), nPos);
+ }
+ }
+ }
+ else
+ {
+ switch (meKind)
+ {
+ case OBJ_PATHLINE: rName=ImpGetResStr(STR_ObjNameSingulPATHLINE); break;
+ case OBJ_FREELINE: rName=ImpGetResStr(STR_ObjNameSingulFREELINE); break;
+ case OBJ_SPLNLINE: rName=ImpGetResStr(STR_ObjNameSingulNATSPLN); break;
+ case OBJ_PATHFILL: rName=ImpGetResStr(STR_ObjNameSingulPATHFILL); break;
+ case OBJ_FREEFILL: rName=ImpGetResStr(STR_ObjNameSingulFREEFILL); break;
+ case OBJ_SPLNFILL: rName=ImpGetResStr(STR_ObjNameSingulPERSPLN); break;
+ default: break;
+ }
+ }
+
+ String aName(GetName());
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrPathObj::TakeObjNamePlural(XubString& rName) const
+{
+ switch(meKind)
+ {
+ case OBJ_LINE : rName=ImpGetResStr(STR_ObjNamePluralLINE ); break;
+ case OBJ_PLIN : rName=ImpGetResStr(STR_ObjNamePluralPLIN ); break;
+ case OBJ_POLY : rName=ImpGetResStr(STR_ObjNamePluralPOLY ); break;
+ case OBJ_PATHLINE: rName=ImpGetResStr(STR_ObjNamePluralPATHLINE); break;
+ case OBJ_FREELINE: rName=ImpGetResStr(STR_ObjNamePluralFREELINE); break;
+ case OBJ_SPLNLINE: rName=ImpGetResStr(STR_ObjNamePluralNATSPLN); break;
+ case OBJ_PATHFILL: rName=ImpGetResStr(STR_ObjNamePluralPATHFILL); break;
+ case OBJ_FREEFILL: rName=ImpGetResStr(STR_ObjNamePluralFREEFILL); break;
+ case OBJ_SPLNFILL: rName=ImpGetResStr(STR_ObjNamePluralPERSPLN); break;
+ default: break;
+ }
+}
+
+basegfx::B2DPolyPolygon SdrPathObj::TakeXorPoly() const
+{
+ return GetPathPoly();
+}
+
+sal_uInt32 SdrPathObj::GetHdlCount() const
+{
+ sal_uInt32 nRetval(0L);
+ const sal_uInt32 nPolyCount(GetPathPoly().count());
+
+ for(sal_uInt32 a(0L); a < nPolyCount; a++)
+ {
+ nRetval += GetPathPoly().getB2DPolygon(a).count();
+ }
+
+ return nRetval;
+}
+
+SdrHdl* SdrPathObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ // #i73248#
+ // Warn the user that this is ineffective and show alternatives. Should not be used at all.
+ OSL_ENSURE(false, "SdrPathObj::GetHdl(): ineffective, use AddToHdlList instead (!)");
+
+ // to have an alternative, get single handle using the ineffective way
+ SdrHdl* pRetval = 0;
+ SdrHdlList aLocalList(0);
+ AddToHdlList(aLocalList);
+ const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());
+
+ if(nHdlCount && nHdlNum < nHdlCount)
+ {
+ // remove and remember. The other created handles will be deleted again with the
+ // destruction of the local list
+ pRetval = aLocalList.RemoveHdl(nHdlNum);
+ }
+
+ return pRetval;
+}
+
+void SdrPathObj::AddToHdlList(SdrHdlList& rHdlList) const
+{
+ // keep old stuff to be able to keep old SdrHdl stuff, too
+ const XPolyPolygon aOldPathPolygon(GetPathPoly());
+ USHORT nPolyCnt=aOldPathPolygon.Count();
+ FASTBOOL bClosed=IsClosed();
+ USHORT nIdx=0;
+
+ for (USHORT i=0; i<nPolyCnt; i++) {
+ const XPolygon& rXPoly=aOldPathPolygon.GetObject(i);
+ USHORT nPntCnt=rXPoly.GetPointCount();
+ if (bClosed && nPntCnt>1) nPntCnt--;
+
+ for (USHORT j=0; j<nPntCnt; j++) {
+ if (rXPoly.GetFlags(j)!=XPOLY_CONTROL) {
+ const Point& rPnt=rXPoly[j];
+ SdrHdl* pHdl=new SdrHdl(rPnt,HDL_POLY);
+ pHdl->SetPolyNum(i);
+ pHdl->SetPointNum(j);
+ pHdl->Set1PixMore(j==0);
+ pHdl->SetSourceHdlNum(nIdx);
+ nIdx++;
+ rHdlList.AddHdl(pHdl);
+ }
+ }
+ }
+}
+
+sal_uInt32 SdrPathObj::GetPlusHdlCount(const SdrHdl& rHdl) const
+{
+ // keep old stuff to be able to keep old SdrHdl stuff, too
+ const XPolyPolygon aOldPathPolygon(GetPathPoly());
+ sal_uInt16 nCnt = 0;
+ sal_uInt16 nPnt = (sal_uInt16)rHdl.GetPointNum();
+ sal_uInt16 nPolyNum = (sal_uInt16)rHdl.GetPolyNum();
+
+ if(nPolyNum < aOldPathPolygon.Count())
+ {
+ const XPolygon& rXPoly = aOldPathPolygon[nPolyNum];
+ sal_uInt16 nPntMax = rXPoly.GetPointCount();
+ if (nPntMax>0)
+ {
+ nPntMax--;
+ if (nPnt<=nPntMax)
+ {
+ if (rXPoly.GetFlags(nPnt)!=XPOLY_CONTROL)
+ {
+ if (nPnt==0 && IsClosed()) nPnt=nPntMax;
+ if (nPnt>0 && rXPoly.GetFlags(nPnt-1)==XPOLY_CONTROL) nCnt++;
+ if (nPnt==nPntMax && IsClosed()) nPnt=0;
+ if (nPnt<nPntMax && rXPoly.GetFlags(nPnt+1)==XPOLY_CONTROL) nCnt++;
+ }
+ }
+ }
+ }
+
+ return nCnt;
+}
+
+SdrHdl* SdrPathObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlusNum) const
+{
+ // keep old stuff to be able to keep old SdrHdl stuff, too
+ const XPolyPolygon aOldPathPolygon(GetPathPoly());
+ SdrHdl* pHdl = 0L;
+ sal_uInt16 nPnt = (sal_uInt16)rHdl.GetPointNum();
+ sal_uInt16 nPolyNum = (sal_uInt16)rHdl.GetPolyNum();
+
+ if (nPolyNum<aOldPathPolygon.Count())
+ {
+ const XPolygon& rXPoly = aOldPathPolygon[nPolyNum];
+ sal_uInt16 nPntMax = rXPoly.GetPointCount();
+
+ if (nPntMax>0)
+ {
+ nPntMax--;
+ if (nPnt<=nPntMax)
+ {
+ pHdl=new SdrHdlBezWgt(&rHdl);
+ pHdl->SetPolyNum(rHdl.GetPolyNum());
+
+ if (nPnt==0 && IsClosed()) nPnt=nPntMax;
+ if (nPnt>0 && rXPoly.GetFlags(nPnt-1)==XPOLY_CONTROL && nPlusNum==0)
+ {
+ pHdl->SetPos(rXPoly[nPnt-1]);
+ pHdl->SetPointNum(nPnt-1);
+ }
+ else
+ {
+ if (nPnt==nPntMax && IsClosed()) nPnt=0;
+ if (nPnt<rXPoly.GetPointCount()-1 && rXPoly.GetFlags(nPnt+1)==XPOLY_CONTROL)
+ {
+ pHdl->SetPos(rXPoly[nPnt+1]);
+ pHdl->SetPointNum(nPnt+1);
+ }
+ }
+
+ pHdl->SetSourceHdlNum(rHdl.GetSourceHdlNum());
+ pHdl->SetPlusHdl(TRUE);
+ }
+ }
+ }
+ return pHdl;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrPathObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrPathObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ ImpPathForDragAndCreate aDragAndCreate(*((SdrPathObj*)this));
+
+ return aDragAndCreate.beginPathDrag(rDrag);
+}
+
+bool SdrPathObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ ImpPathForDragAndCreate aDragAndCreate(*this);
+ bool bRetval(aDragAndCreate.beginPathDrag(rDrag));
+
+ if(bRetval)
+ {
+ bRetval = aDragAndCreate.movePathDrag(rDrag);
+ }
+
+ if(bRetval)
+ {
+ bRetval = aDragAndCreate.endPathDrag(rDrag);
+ }
+
+ if(bRetval)
+ {
+ NbcSetPathPoly(aDragAndCreate.getModifiedPolyPolygon());
+ }
+
+ return bRetval;
+}
+
+String SdrPathObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ String aRetval;
+
+ if(mpDAC)
+ {
+ // #i103058# also get a comment when in creation
+ const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment)
+ {
+ aRetval = mpDAC->getSpecialDragComment(rDrag);
+ }
+ }
+ else
+ {
+ ImpPathForDragAndCreate aDragAndCreate(*((SdrPathObj*)this));
+ bool bDidWork(aDragAndCreate.beginPathDrag((SdrDragStat&)rDrag));
+
+ if(bDidWork)
+ {
+ aRetval = aDragAndCreate.getSpecialDragComment(rDrag);
+ }
+ }
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SdrPathObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+ ImpPathForDragAndCreate aDragAndCreate(*((SdrPathObj*)this));
+ bool bDidWork(aDragAndCreate.beginPathDrag((SdrDragStat&)rDrag));
+
+ if(bDidWork)
+ {
+ aRetval = aDragAndCreate.getSpecialDragPoly(rDrag);
+ }
+
+ return aRetval;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrPathObj::BegCreate(SdrDragStat& rStat)
+{
+ impDeleteDAC();
+ return impGetDAC().BegCreate(rStat);
+}
+
+FASTBOOL SdrPathObj::MovCreate(SdrDragStat& rStat)
+{
+ return impGetDAC().MovCreate(rStat);
+}
+
+FASTBOOL SdrPathObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ FASTBOOL bRetval(impGetDAC().EndCreate(rStat, eCmd));
+
+ if(bRetval && mpDAC)
+ {
+ SetPathPoly(mpDAC->getModifiedPolyPolygon());
+
+ // #i75974# Check for AutoClose feature. Moved here from ImpPathForDragAndCreate::EndCreate
+ // to be able to use the type-changing ImpSetClosed method
+ if(!IsClosedObj())
+ {
+ SdrView* pView = rStat.GetView();
+
+ if(pView && pView->IsAutoClosePolys() && !pView->IsUseIncompatiblePathCreateInterface())
+ {
+ OutputDevice* pOut = pView->GetFirstOutputDevice();
+
+ if(pOut)
+ {
+ if(GetPathPoly().count())
+ {
+ const basegfx::B2DPolygon aCandidate(GetPathPoly().getB2DPolygon(0));
+
+ if(aCandidate.count() > 2)
+ {
+ // check distance of first and last point
+ const sal_Int32 nCloseDist(pOut->PixelToLogic(Size(pView->GetAutoCloseDistPix(), 0)).Width());
+ const basegfx::B2DVector aDistVector(aCandidate.getB2DPoint(aCandidate.count() - 1) - aCandidate.getB2DPoint(0));
+
+ if(aDistVector.getLength() <= (double)nCloseDist)
+ {
+ // close it
+ ImpSetClosed(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ impDeleteDAC();
+ }
+
+ return bRetval;
+}
+
+FASTBOOL SdrPathObj::BckCreate(SdrDragStat& rStat)
+{
+ return impGetDAC().BckCreate(rStat);
+}
+
+void SdrPathObj::BrkCreate(SdrDragStat& rStat)
+{
+ impGetDAC().BrkCreate(rStat);
+ impDeleteDAC();
+}
+
+basegfx::B2DPolyPolygon SdrPathObj::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ if(mpDAC)
+ {
+ aRetval = mpDAC->TakeObjectPolyPolygon(rDrag);
+ aRetval.append(mpDAC->TakeDragPolyPolygon(rDrag));
+ }
+
+ return aRetval;
+}
+
+// during drag or create, allow accessing the so-far created/modified polyPolygon
+basegfx::B2DPolyPolygon SdrPathObj::getObjectPolyPolygon(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ if(mpDAC)
+ {
+ aRetval = mpDAC->TakeObjectPolyPolygon(rDrag);
+ }
+
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SdrPathObj::getDragPolyPolygon(const SdrDragStat& rDrag) const
+{
+ basegfx::B2DPolyPolygon aRetval;
+
+ if(mpDAC)
+ {
+ aRetval = mpDAC->TakeDragPolyPolygon(rDrag);
+ }
+
+ return aRetval;
+}
+
+Pointer SdrPathObj::GetCreatePointer() const
+{
+ return impGetDAC().GetCreatePointer();
+}
+
+void SdrPathObj::NbcMove(const Size& rSiz)
+{
+ maPathPolygon.transform(basegfx::tools::createTranslateB2DHomMatrix(rSiz.Width(), rSiz.Height()));
+
+ // #i19871# first modify locally, then call parent (to get correct SnapRect with GluePoints)
+ SdrTextObj::NbcMove(rSiz);
+}
+
+void SdrPathObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-rRef.X(), -rRef.Y()));
+ aTrans = basegfx::tools::createScaleTranslateB2DHomMatrix(
+ double(xFact), double(yFact), rRef.X(), rRef.Y()) * aTrans;
+ maPathPolygon.transform(aTrans);
+
+ // #i19871# first modify locally, then call parent (to get correct SnapRect with GluePoints)
+ SdrTextObj::NbcResize(rRef,xFact,yFact);
+}
+
+void SdrPathObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ // Thank JOE, the angles are defined mirrored to the mathematical meanings
+ const basegfx::B2DHomMatrix aTrans(basegfx::tools::createRotateAroundPoint(rRef.X(), rRef.Y(), -nWink * nPi180));
+ maPathPolygon.transform(aTrans);
+
+ // #i19871# first modify locally, then call parent (to get correct SnapRect with GluePoints)
+ SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
+}
+
+void SdrPathObj::NbcShear(const Point& rRefPnt, long nAngle, double fTan, FASTBOOL bVShear)
+{
+ basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-rRefPnt.X(), -rRefPnt.Y()));
+
+ if(bVShear)
+ {
+ // Thank JOE, the angles are defined mirrored to the mathematical meanings
+ aTrans.shearY(-fTan);
+ }
+ else
+ {
+ aTrans.shearX(-fTan);
+ }
+
+ aTrans.translate(rRefPnt.X(), rRefPnt.Y());
+ maPathPolygon.transform(aTrans);
+
+ // #i19871# first modify locally, then call parent (to get correct SnapRect with GluePoints)
+ SdrTextObj::NbcShear(rRefPnt,nAngle,fTan,bVShear);
+}
+
+void SdrPathObj::NbcMirror(const Point& rRefPnt1, const Point& rRefPnt2)
+{
+ const double fDiffX(rRefPnt2.X() - rRefPnt1.X());
+ const double fDiffY(rRefPnt2.Y() - rRefPnt1.Y());
+ const double fRot(atan2(fDiffY, fDiffX));
+ basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-rRefPnt1.X(), -rRefPnt1.Y()));
+ aTrans.rotate(-fRot);
+ aTrans.scale(1.0, -1.0);
+ aTrans.rotate(fRot);
+ aTrans.translate(rRefPnt1.X(), rRefPnt1.Y());
+ maPathPolygon.transform(aTrans);
+
+ // #97538# Do Joe's special handling for lines when mirroring, too
+ ImpForceKind();
+
+ // #i19871# first modify locally, then call parent (to get correct SnapRect with GluePoints)
+ SdrTextObj::NbcMirror(rRefPnt1,rRefPnt2);
+}
+
+void SdrPathObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ if(!aGeo.nDrehWink)
+ {
+ rRect = GetSnapRect();
+ }
+ else
+ {
+ XPolyPolygon aXPP(GetPathPoly());
+ RotateXPoly(aXPP,Point(),-aGeo.nSin,aGeo.nCos);
+ rRect=aXPP.GetBoundRect();
+ Point aTmp(rRect.TopLeft());
+ RotatePoint(aTmp,Point(),aGeo.nSin,aGeo.nCos);
+ aTmp-=rRect.TopLeft();
+ rRect.Move(aTmp.X(),aTmp.Y());
+ }
+}
+
+void SdrPathObj::RecalcSnapRect()
+{
+ if(GetPathPoly().count())
+ {
+ maSnapRect = ImpGetBoundRect(GetPathPoly());
+ }
+}
+
+void SdrPathObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aOld(GetSnapRect());
+
+ // #95736# Take RECT_EMPTY into account when calculating scale factors
+ long nMulX = (RECT_EMPTY == rRect.Right()) ? 0 : rRect.Right() - rRect.Left();
+
+ long nDivX = aOld.Right() - aOld.Left();
+
+ // #95736# Take RECT_EMPTY into account when calculating scale factors
+ long nMulY = (RECT_EMPTY == rRect.Bottom()) ? 0 : rRect.Bottom() - rRect.Top();
+
+ long nDivY = aOld.Bottom() - aOld.Top();
+ if ( nDivX == 0 ) { nMulX = 1; nDivX = 1; }
+ if ( nDivY == 0 ) { nMulY = 1; nDivY = 1; }
+ Fraction aX(nMulX,nDivX);
+ Fraction aY(nMulY,nDivY);
+ NbcResize(aOld.TopLeft(), aX, aY);
+ NbcMove(Size(rRect.Left() - aOld.Left(), rRect.Top() - aOld.Top()));
+}
+
+sal_uInt32 SdrPathObj::GetSnapPointCount() const
+{
+ return GetHdlCount();
+}
+
+Point SdrPathObj::GetSnapPoint(sal_uInt32 nSnapPnt) const
+{
+ sal_uInt32 nPoly,nPnt;
+ if(!PolyPolygonEditor::GetRelativePolyPoint(GetPathPoly(), nSnapPnt, nPoly, nPnt))
+ {
+ DBG_ASSERT(FALSE,"SdrPathObj::GetSnapPoint: Punkt nSnapPnt nicht vorhanden!");
+ }
+
+ const basegfx::B2DPoint aB2DPoint(GetPathPoly().getB2DPolygon(nPoly).getB2DPoint(nPnt));
+ return Point(FRound(aB2DPoint.getX()), FRound(aB2DPoint.getY()));
+}
+
+sal_Bool SdrPathObj::IsPolyObj() const
+{
+ return sal_True;
+}
+
+sal_uInt32 SdrPathObj::GetPointCount() const
+{
+ const sal_uInt32 nPolyCount(GetPathPoly().count());
+ sal_uInt32 nRetval(0L);
+
+ for(sal_uInt32 a(0L); a < nPolyCount; a++)
+ {
+ nRetval += GetPathPoly().getB2DPolygon(a).count();
+ }
+
+ return nRetval;
+}
+
+Point SdrPathObj::GetPoint(sal_uInt32 nHdlNum) const
+{
+ Point aRetval;
+ sal_uInt32 nPoly,nPnt;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(GetPathPoly(), nHdlNum, nPoly, nPnt))
+ {
+ const basegfx::B2DPolygon aPoly(GetPathPoly().getB2DPolygon(nPoly));
+ const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(nPnt));
+ aRetval = Point(FRound(aPoint.getX()), FRound(aPoint.getY()));
+ }
+
+ return aRetval;
+}
+
+void SdrPathObj::NbcSetPoint(const Point& rPnt, sal_uInt32 nHdlNum)
+{
+ sal_uInt32 nPoly,nPnt;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(GetPathPoly(), nHdlNum, nPoly, nPnt))
+ {
+ basegfx::B2DPolygon aNewPolygon(GetPathPoly().getB2DPolygon(nPoly));
+ aNewPolygon.setB2DPoint(nPnt, basegfx::B2DPoint(rPnt.X(), rPnt.Y()));
+ maPathPolygon.setB2DPolygon(nPoly, aNewPolygon);
+
+ if(meKind==OBJ_LINE)
+ {
+ ImpForceLineWink();
+ }
+ else
+ {
+ if(GetPathPoly().count())
+ {
+ // #i10659# for SdrTextObj, keep aRect up to date
+ aRect = ImpGetBoundRect(GetPathPoly()); // fuer SdrTextObj#
+ }
+ }
+
+ SetRectsDirty();
+ }
+}
+
+sal_uInt32 SdrPathObj::NbcInsPointOld(const Point& rPos, sal_Bool bNewObj, sal_Bool bHideHim)
+{
+ sal_uInt32 nNewHdl;
+
+ if(bNewObj)
+ {
+ nNewHdl = NbcInsPoint(0L, rPos, sal_True, bHideHim);
+ }
+ else
+ {
+ // look for smallest distance data
+ const basegfx::B2DPoint aTestPoint(rPos.X(), rPos.Y());
+ sal_uInt32 nSmallestPolyIndex(0L);
+ sal_uInt32 nSmallestEdgeIndex(0L);
+ double fSmallestCut;
+ basegfx::tools::getSmallestDistancePointToPolyPolygon(GetPathPoly(), aTestPoint, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut);
+
+ // create old polygon index from it
+ sal_uInt32 nPolyIndex(nSmallestEdgeIndex);
+
+ for(sal_uInt32 a(0L); a < nSmallestPolyIndex; a++)
+ {
+ nPolyIndex += GetPathPoly().getB2DPolygon(a).count();
+ }
+
+ nNewHdl = NbcInsPoint(nPolyIndex, rPos, sal_False, bHideHim);
+ }
+
+ ImpForceKind();
+ return nNewHdl;
+}
+
+sal_uInt32 SdrPathObj::NbcInsPoint(sal_uInt32 /*nHdlNum*/, const Point& rPos, sal_Bool bNewObj, sal_Bool /*bHideHim*/)
+{
+ sal_uInt32 nNewHdl;
+
+ if(bNewObj)
+ {
+ basegfx::B2DPolygon aNewPoly;
+ const basegfx::B2DPoint aPoint(rPos.X(), rPos.Y());
+ aNewPoly.append(aPoint);
+ aNewPoly.setClosed(IsClosed());
+ maPathPolygon.append(aNewPoly);
+ SetRectsDirty();
+ nNewHdl = GetHdlCount();
+ }
+ else
+ {
+ // look for smallest distance data
+ const basegfx::B2DPoint aTestPoint(rPos.X(), rPos.Y());
+ sal_uInt32 nSmallestPolyIndex(0L);
+ sal_uInt32 nSmallestEdgeIndex(0L);
+ double fSmallestCut;
+ basegfx::tools::getSmallestDistancePointToPolyPolygon(GetPathPoly(), aTestPoint, nSmallestPolyIndex, nSmallestEdgeIndex, fSmallestCut);
+ basegfx::B2DPolygon aCandidate(GetPathPoly().getB2DPolygon(nSmallestPolyIndex));
+ const bool bBefore(!aCandidate.isClosed() && 0L == nSmallestEdgeIndex && 0.0 == fSmallestCut);
+ const bool bAfter(!aCandidate.isClosed() && aCandidate.count() == nSmallestEdgeIndex + 2L && 1.0 == fSmallestCut);
+
+ if(bBefore)
+ {
+ // before first point
+ aCandidate.insert(0L, aTestPoint);
+
+ if(aCandidate.areControlPointsUsed())
+ {
+ if(aCandidate.isNextControlPointUsed(1))
+ {
+ aCandidate.setNextControlPoint(0, interpolate(aTestPoint, aCandidate.getB2DPoint(1), (1.0 / 3.0)));
+ aCandidate.setPrevControlPoint(1, interpolate(aTestPoint, aCandidate.getB2DPoint(1), (2.0 / 3.0)));
+ }
+ }
+
+ nNewHdl = 0L;
+ }
+ else if(bAfter)
+ {
+ // after last point
+ aCandidate.append(aTestPoint);
+
+ if(aCandidate.areControlPointsUsed())
+ {
+ if(aCandidate.isPrevControlPointUsed(aCandidate.count() - 2))
+ {
+ aCandidate.setNextControlPoint(aCandidate.count() - 2, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), aTestPoint, (1.0 / 3.0)));
+ aCandidate.setPrevControlPoint(aCandidate.count() - 1, interpolate(aCandidate.getB2DPoint(aCandidate.count() - 2), aTestPoint, (2.0 / 3.0)));
+ }
+ }
+
+ nNewHdl = aCandidate.count() - 1L;
+ }
+ else
+ {
+ // in between
+ bool bSegmentSplit(false);
+ const sal_uInt32 nNextIndex((nSmallestEdgeIndex + 1) % aCandidate.count());
+
+ if(aCandidate.areControlPointsUsed())
+ {
+ if(aCandidate.isNextControlPointUsed(nSmallestEdgeIndex) || aCandidate.isPrevControlPointUsed(nNextIndex))
+ {
+ bSegmentSplit = true;
+ }
+ }
+
+ if(bSegmentSplit)
+ {
+ // rebuild original segment to get the split data
+ basegfx::B2DCubicBezier aBezierA, aBezierB;
+ const basegfx::B2DCubicBezier aBezier(
+ aCandidate.getB2DPoint(nSmallestEdgeIndex),
+ aCandidate.getNextControlPoint(nSmallestEdgeIndex),
+ aCandidate.getPrevControlPoint(nNextIndex),
+ aCandidate.getB2DPoint(nNextIndex));
+
+ // split and insert hit point
+ aBezier.split(fSmallestCut, &aBezierA, &aBezierB);
+ aCandidate.insert(nSmallestEdgeIndex + 1, aTestPoint);
+
+ // since we inserted hit point and not split point, we need to add an offset
+ // to the control points to get the C1 continuity we want to achieve
+ const basegfx::B2DVector aOffset(aTestPoint - aBezierA.getEndPoint());
+ aCandidate.setNextControlPoint(nSmallestEdgeIndex, aBezierA.getControlPointA() + aOffset);
+ aCandidate.setPrevControlPoint(nSmallestEdgeIndex + 1, aBezierA.getControlPointB() + aOffset);
+ aCandidate.setNextControlPoint(nSmallestEdgeIndex + 1, aBezierB.getControlPointA() + aOffset);
+ aCandidate.setPrevControlPoint((nSmallestEdgeIndex + 2) % aCandidate.count(), aBezierB.getControlPointB() + aOffset);
+ }
+ else
+ {
+ aCandidate.insert(nSmallestEdgeIndex + 1L, aTestPoint);
+ }
+
+ nNewHdl = nSmallestEdgeIndex + 1L;
+ }
+
+ maPathPolygon.setB2DPolygon(nSmallestPolyIndex, aCandidate);
+
+ // create old polygon index from it
+ for(sal_uInt32 a(0L); a < nSmallestPolyIndex; a++)
+ {
+ nNewHdl += GetPathPoly().getB2DPolygon(a).count();
+ }
+ }
+
+ ImpForceKind();
+ return nNewHdl;
+}
+
+SdrObject* SdrPathObj::RipPoint(sal_uInt32 nHdlNum, sal_uInt32& rNewPt0Index)
+{
+ SdrPathObj* pNewObj = 0L;
+ const basegfx::B2DPolyPolygon aLocalPolyPolygon(GetPathPoly());
+ sal_uInt32 nPoly, nPnt;
+
+ if(PolyPolygonEditor::GetRelativePolyPoint(aLocalPolyPolygon, nHdlNum, nPoly, nPnt))
+ {
+ if(0L == nPoly)
+ {
+ const basegfx::B2DPolygon aCandidate(aLocalPolyPolygon.getB2DPolygon(nPoly));
+ const sal_uInt32 nPointCount(aCandidate.count());
+
+ if(nPointCount)
+ {
+ if(IsClosed())
+ {
+ // when closed, RipPoint means to open the polygon at the selected point. To
+ // be able to do that, it is necessary to make the selected point the first one
+ basegfx::B2DPolygon aNewPolygon(basegfx::tools::makeStartPoint(aCandidate, nPnt));
+ SetPathPoly(basegfx::B2DPolyPolygon(aNewPolygon));
+ ToggleClosed();
+
+ // give back new position of old start point (historical reasons)
+ rNewPt0Index = (nPointCount - nPnt) % nPointCount;
+ }
+ else
+ {
+ if(nPointCount >= 3L && nPnt != 0L && nPnt + 1L < nPointCount)
+ {
+ // split in two objects at point nPnt
+ basegfx::B2DPolygon aSplitPolyA(aCandidate, 0L, nPnt + 1L);
+ SetPathPoly(basegfx::B2DPolyPolygon(aSplitPolyA));
+
+ pNewObj = (SdrPathObj*)Clone();
+ basegfx::B2DPolygon aSplitPolyB(aCandidate, nPnt, nPointCount - nPnt);
+ pNewObj->SetPathPoly(basegfx::B2DPolyPolygon(aSplitPolyB));
+ }
+ }
+ }
+ }
+ }
+
+ return pNewObj;
+}
+
+SdrObject* SdrPathObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ // #i89784# check for FontWork with activated HideContour
+ const drawinglayer::attribute::SdrTextAttribute aText(
+ drawinglayer::primitive2d::createNewSdrTextAttribute(GetObjectItemSet(), *getText(0)));
+ const bool bHideContour(
+ !aText.isDefault() && !aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour());
+
+ SdrObject* pRet = bHideContour ?
+ 0 :
+ ImpConvertMakeObj(GetPathPoly(), IsClosed(), bBezier);
+
+ SdrPathObj* pPath = PTR_CAST(SdrPathObj, pRet);
+
+ if(pPath)
+ {
+ if(pPath->GetPathPoly().areControlPointsUsed())
+ {
+ if(!bBezier)
+ {
+ // reduce all bezier curves
+ pPath->SetPathPoly(basegfx::tools::adaptiveSubdivideByAngle(pPath->GetPathPoly()));
+ }
+ }
+ else
+ {
+ if(bBezier)
+ {
+ // create bezier curves
+ pPath->SetPathPoly(basegfx::tools::expandToCurve(pPath->GetPathPoly()));
+ }
+ }
+ }
+
+ pRet = ImpConvertAddText(pRet, bBezier);
+
+ return pRet;
+}
+
+SdrObjGeoData* SdrPathObj::NewGeoData() const
+{
+ return new SdrPathObjGeoData;
+}
+
+void SdrPathObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrTextObj::SaveGeoData(rGeo);
+ SdrPathObjGeoData& rPGeo = (SdrPathObjGeoData&) rGeo;
+ rPGeo.maPathPolygon=GetPathPoly();
+ rPGeo.meKind=meKind;
+}
+
+void SdrPathObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrTextObj::RestGeoData(rGeo);
+ SdrPathObjGeoData& rPGeo=(SdrPathObjGeoData&)rGeo;
+ maPathPolygon=rPGeo.maPathPolygon;
+ meKind=rPGeo.meKind;
+ ImpForceKind(); // damit u.a. bClosed gesetzt wird
+}
+
+void SdrPathObj::NbcSetPathPoly(const basegfx::B2DPolyPolygon& rPathPoly)
+{
+ if(GetPathPoly() != rPathPoly)
+ {
+ maPathPolygon=rPathPoly;
+ ImpForceKind();
+ SetRectsDirty();
+ }
+}
+
+void SdrPathObj::SetPathPoly(const basegfx::B2DPolyPolygon& rPathPoly)
+{
+ if(GetPathPoly() != rPathPoly)
+ {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ NbcSetPathPoly(rPathPoly);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrPathObj::ToggleClosed() // long nOpenDistance)
+{
+ Rectangle aBoundRect0;
+ if(pUserCall != NULL)
+ aBoundRect0 = GetLastBoundRect();
+ ImpSetClosed(!IsClosed()); // neuen ObjKind setzen
+ ImpForceKind(); // wg. Line->Poly->PolyLine statt Line->Poly->Line
+ SetRectsDirty();
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE, aBoundRect0);
+}
+
+// fuer friend class SdrPolyEditView auf einigen Compilern:
+void SdrPathObj::SetRectsDirty(sal_Bool bNotMyself)
+{
+ SdrTextObj::SetRectsDirty(bNotMyself);
+}
+
+ImpPathForDragAndCreate& SdrPathObj::impGetDAC() const
+{
+ if(!mpDAC)
+ {
+ ((SdrPathObj*)this)->mpDAC = new ImpPathForDragAndCreate(*((SdrPathObj*)this));
+ }
+
+ return *mpDAC;
+}
+
+void SdrPathObj::impDeleteDAC() const
+{
+ if(mpDAC)
+ {
+ delete mpDAC;
+ ((SdrPathObj*)this)->mpDAC = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// transformation interface for StarOfficeAPI. This implements support for
+// homogen 3x3 matrices containing the transformation of the SdrObject. At the
+// moment it contains a shearX, rotation and translation, but for setting all linear
+// transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
+// with the base geometry and returns TRUE. Otherwise it returns FALSE.
+sal_Bool SdrPathObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const
+{
+ double fRotate(0.0);
+ double fShearX(0.0);
+ basegfx::B2DTuple aScale(1.0, 1.0);
+ basegfx::B2DTuple aTranslate(0.0, 0.0);
+
+ if(GetPathPoly().count())
+ {
+ // copy geometry
+ basegfx::B2DHomMatrix aMoveToZeroMatrix;
+ rPolyPolygon = GetPathPoly();
+
+ if(OBJ_LINE == meKind)
+ {
+ // ignore shear and rotate, just use scale and translate
+ OSL_ENSURE(GetPathPoly().count() > 0L && GetPathPoly().getB2DPolygon(0L).count() > 1L, "OBJ_LINE with too less polygons (!)");
+ // #i72287# use polygon without control points for range calculation. Do not change rPolyPolygon
+ // itself, else this method will no longer return the full polygon information (curve will
+ // be lost)
+ const basegfx::B2DRange aPolyRangeNoCurve(basegfx::tools::getRange(rPolyPolygon));
+ aScale = aPolyRangeNoCurve.getRange();
+ aTranslate = aPolyRangeNoCurve.getMinimum();
+
+ // define matrix for move polygon to zero point
+ aMoveToZeroMatrix.translate(-aTranslate.getX(), -aTranslate.getY());
+ }
+ else
+ {
+ if(aGeo.nShearWink || aGeo.nDrehWink)
+ {
+ // get rotate and shear in drawingLayer notation
+ fRotate = aGeo.nDrehWink * F_PI18000;
+ fShearX = aGeo.nShearWink * F_PI18000;
+
+ // build mathematically correct (negative shear and rotate) object transform
+ // containing shear and rotate to extract unsheared, unrotated polygon
+ basegfx::B2DHomMatrix aObjectMatrix;
+ aObjectMatrix.shearX(tan((36000 - aGeo.nShearWink) * F_PI18000));
+ aObjectMatrix.rotate((36000 - aGeo.nDrehWink) * F_PI18000);
+
+ // create inverse from it and back-transform polygon
+ basegfx::B2DHomMatrix aInvObjectMatrix(aObjectMatrix);
+ aInvObjectMatrix.invert();
+ rPolyPolygon.transform(aInvObjectMatrix);
+
+ // get range from unsheared, unrotated polygon and extract scale and translate.
+ // transform topLeft from it back to transformed state to get original
+ // topLeft (rotation center)
+ // #i72287# use polygon without control points for range calculation. Do not change rPolyPolygon
+ // itself, else this method will no longer return the full polygon information (curve will
+ // be lost)
+ const basegfx::B2DRange aCorrectedRangeNoCurve(basegfx::tools::getRange(rPolyPolygon));
+ aTranslate = aObjectMatrix * aCorrectedRangeNoCurve.getMinimum();
+ aScale = aCorrectedRangeNoCurve.getRange();
+
+ // define matrix for move polygon to zero point
+ aMoveToZeroMatrix.translate(-aCorrectedRangeNoCurve.getMinX(), aCorrectedRangeNoCurve.getMinY());
+ }
+ else
+ {
+ // get scale and translate from unsheared, unrotated polygon
+ // #i72287# use polygon without control points for range calculation. Do not change rPolyPolygon
+ // itself, else this method will no longer return the full polygon information (curve will
+ // be lost)
+ const basegfx::B2DRange aPolyRangeNoCurve(basegfx::tools::getRange(rPolyPolygon));
+ aScale = aPolyRangeNoCurve.getRange();
+ aTranslate = aPolyRangeNoCurve.getMinimum();
+
+ // define matrix for move polygon to zero point
+ aMoveToZeroMatrix.translate(-aTranslate.getX(), -aTranslate.getY());
+ }
+ }
+
+ // move polygon to zero point with pre-defined matrix
+ rPolyPolygon.transform(aMoveToZeroMatrix);
+ }
+
+ // position maybe relative to anchorpos, convert
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // force MapUnit to 100th mm
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // postion
+ aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
+ aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplTwipsToMM(aScale.getX()));
+ aScale.setY(ImplTwipsToMM(aScale.getY()));
+
+ // polygon
+ basegfx::B2DHomMatrix aTwipsToMM;
+ const double fFactorTwipsToMM(127.0 / 72.0);
+ aTwipsToMM.scale(fFactorTwipsToMM, fFactorTwipsToMM);
+ rPolyPolygon.transform(aTwipsToMM);
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
+ }
+ }
+ }
+
+ // build return value matrix
+ rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ aScale,
+ basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
+ basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
+ aTranslate);
+
+ return sal_True;
+}
+
+// sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
+// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
+// to use (0,0) as upper left and will be scaled to the given size in the matrix.
+void SdrPathObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ // break up matrix
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate, fShearX;
+ rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
+ // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale.setX(fabs(aScale.getX()));
+ aScale.setY(fabs(aScale.getY()));
+ fRotate = fmod(fRotate + F_PI, F_2PI);
+ }
+
+ // copy poly
+ basegfx::B2DPolyPolygon aNewPolyPolygon(rPolyPolygon);
+
+ // reset object shear and rotations
+ aGeo.nDrehWink = 0;
+ aGeo.RecalcSinCos();
+ aGeo.nShearWink = 0;
+ aGeo.RecalcTan();
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
+ aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplMMToTwips(aScale.getX()));
+ aScale.setY(ImplMMToTwips(aScale.getY()));
+
+ // polygon
+ basegfx::B2DHomMatrix aMMToTwips;
+ const double fFactorMMToTwips(72.0 / 127.0);
+ aMMToTwips.scale(fFactorMMToTwips, fFactorMMToTwips);
+ aNewPolyPolygon.transform(aMMToTwips);
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ if( pModel && pModel->IsWriter() )
+ {
+ // if anchor is used, make position relative to it
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // create transformation for polygon, set values at aGeo direct
+ basegfx::B2DHomMatrix aTransform;
+
+ // #i75086#
+ // Given polygon is already scaled (for historical reasons), but not mirrored yet.
+ // Thus, when scale is negative in X or Y, apply the needed mirroring accordingly.
+ if(basegfx::fTools::less(aScale.getX(), 0.0) || basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aTransform.scale(
+ basegfx::fTools::less(aScale.getX(), 0.0) ? -1.0 : 1.0,
+ basegfx::fTools::less(aScale.getY(), 0.0) ? -1.0 : 1.0);
+ }
+
+ if(!basegfx::fTools::equalZero(fShearX))
+ {
+ aTransform.shearX(tan(-atan(fShearX)));
+ aGeo.nShearWink = FRound(atan(fShearX) / F_PI18000);
+ aGeo.RecalcTan();
+ }
+
+ if(!basegfx::fTools::equalZero(fRotate))
+ {
+ // #i78696#
+ // fRotate is matematically correct for linear transformations, so it's
+ // the one to use for the geometry change
+ aTransform.rotate(fRotate);
+
+ // #i78696#
+ // fRotate is matematically correct, but aGeoStat.nDrehWink is
+ // mirrored -> mirror value here
+ aGeo.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
+ aGeo.RecalcSinCos();
+ }
+
+ if(!aTranslate.equalZero())
+ {
+ // #i39529# absolute positioning, so get current position (without control points (!))
+ const basegfx::B2DRange aCurrentRange(basegfx::tools::getRange(aNewPolyPolygon));
+ aTransform.translate(aTranslate.getX() - aCurrentRange.getMinX(), aTranslate.getY() - aCurrentRange.getMinY());
+ }
+
+ // transform polygon and trigger change
+ aNewPolyPolygon.transform(aTransform);
+ SetPathPoly(aNewPolyPolygon);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx
new file mode 100644
index 000000000000..b03dbf5b903a
--- /dev/null
+++ b/svx/source/svdraw/svdorect.cxx
@@ -0,0 +1,620 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdorect.hxx>
+#include <math.h>
+#include <stdlib.h>
+#include <svx/xpool.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdattr.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdocapt.hxx> // fuer Import von SdrFileVersion 2
+#include <svx/svdpagv.hxx> // fuer
+#include <svx/svdview.hxx> // das
+#include <svx/svdundo.hxx> // Macro-Beispiel
+#include <svx/svdopath.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <svx/xflclit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+#include "svdoimp.hxx"
+#include <svx/sdr/properties/rectangleproperties.hxx>
+#include <svx/sdr/contact/viewcontactofsdrrectobj.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrRectObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::RectangleProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrRectObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrRectObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrRectObj,SdrTextObj);
+
+SdrRectObj::SdrRectObj()
+: mpXPoly(0L)
+{
+ bClosedObj=TRUE;
+}
+
+SdrRectObj::SdrRectObj(const Rectangle& rRect)
+: SdrTextObj(rRect),
+ mpXPoly(NULL)
+{
+ bClosedObj=TRUE;
+}
+
+SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind)
+: SdrTextObj(eNewTextKind),
+ mpXPoly(NULL)
+{
+ DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
+ eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
+ "SdrRectObj::SdrRectObj(SdrObjKind) ist nur fuer Textrahmen gedacht");
+ bClosedObj=TRUE;
+}
+
+SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind, const Rectangle& rRect)
+: SdrTextObj(eNewTextKind,rRect),
+ mpXPoly(NULL)
+{
+ DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
+ eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
+ "SdrRectObj::SdrRectObj(SdrObjKind,...) ist nur fuer Textrahmen gedacht");
+ bClosedObj=TRUE;
+}
+
+SdrRectObj::SdrRectObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, USHORT eFormat)
+: SdrTextObj(eNewTextKind,rNewRect,rInput,rBaseURL,eFormat),
+ mpXPoly(NULL)
+{
+ DBG_ASSERT(eTextKind==OBJ_TEXT || eTextKind==OBJ_TEXTEXT ||
+ eTextKind==OBJ_OUTLINETEXT || eTextKind==OBJ_TITLETEXT,
+ "SdrRectObj::SdrRectObj(SdrObjKind,...) ist nur fuer Textrahmen gedacht");
+ bClosedObj=TRUE;
+}
+
+SdrRectObj::~SdrRectObj()
+{
+ if(mpXPoly)
+ {
+ delete mpXPoly;
+ }
+}
+
+void SdrRectObj::SetXPolyDirty()
+{
+ if(mpXPoly)
+ {
+ delete mpXPoly;
+ mpXPoly = 0L;
+ }
+}
+
+FASTBOOL SdrRectObj::PaintNeedsXPoly(long nEckRad) const
+{
+ FASTBOOL bNeed=aGeo.nDrehWink!=0 || aGeo.nShearWink!=0 || nEckRad!=0;
+ return bNeed;
+}
+
+XPolygon SdrRectObj::ImpCalcXPoly(const Rectangle& rRect1, long nRad1) const
+{
+ XPolygon aXPoly(rRect1,nRad1,nRad1);
+ const sal_uInt16 nPointAnz(aXPoly.GetPointCount());
+ XPolygon aNeuPoly(nPointAnz+1);
+ sal_uInt16 nShift=nPointAnz-2;
+ if (nRad1!=0) nShift=nPointAnz-5;
+ sal_uInt16 j=nShift;
+ for (sal_uInt16 i=1; i<nPointAnz; i++) {
+ aNeuPoly[i]=aXPoly[j];
+ aNeuPoly.SetFlags(i,aXPoly.GetFlags(j));
+ j++;
+ if (j>=nPointAnz) j=1;
+ }
+ aNeuPoly[0]=rRect1.BottomCenter();
+ aNeuPoly[nPointAnz]=aNeuPoly[0];
+ aXPoly=aNeuPoly;
+
+ // Die Winkelangaben beziehen sich immer auf die linke obere Ecke von !aRect!
+ if (aGeo.nShearWink!=0) ShearXPoly(aXPoly,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotateXPoly(aXPoly,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ return aXPoly;
+}
+
+void SdrRectObj::RecalcXPoly()
+{
+ mpXPoly = new XPolygon(ImpCalcXPoly(aRect,GetEckenradius()));
+}
+
+const XPolygon& SdrRectObj::GetXPoly() const
+{
+ if(!mpXPoly)
+ {
+ ((SdrRectObj*)this)->RecalcXPoly();
+ }
+
+ return *mpXPoly;
+}
+
+void SdrRectObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ FASTBOOL bNoTextFrame=!IsTextFrame();
+ rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
+ rInfo.bResizePropAllowed=TRUE;
+ rInfo.bRotateFreeAllowed=TRUE;
+ rInfo.bRotate90Allowed =TRUE;
+ rInfo.bMirrorFreeAllowed=bNoTextFrame;
+ rInfo.bMirror45Allowed =bNoTextFrame;
+ rInfo.bMirror90Allowed =bNoTextFrame;
+
+ // allow transparence
+ rInfo.bTransparenceAllowed = TRUE;
+
+ // gradient depends on fillstyle
+ XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
+ rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
+
+ rInfo.bShearAllowed =bNoTextFrame;
+ rInfo.bEdgeRadiusAllowed=TRUE;
+
+ FASTBOOL bCanConv=!HasText() || ImpCanConvTextToCurve();
+ if (bCanConv && !bNoTextFrame && !HasText()) {
+ bCanConv=HasFill() || HasLine();
+ }
+ rInfo.bCanConvToPath =bCanConv;
+ rInfo.bCanConvToPoly =bCanConv;
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrRectObj::GetObjIdentifier() const
+{
+ if (IsTextFrame()) return UINT16(eTextKind);
+ else return UINT16(OBJ_RECT);
+}
+
+void SdrRectObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ rRect=aRect;
+ if (aGeo.nShearWink!=0) {
+ long nDst=Round((aRect.Bottom()-aRect.Top())*aGeo.nTan);
+ if (aGeo.nShearWink>0) {
+ Point aRef(rRect.TopLeft());
+ rRect.Left()-=nDst;
+ Point aTmpPt(rRect.TopLeft());
+ RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
+ aTmpPt-=rRect.TopLeft();
+ rRect.Move(aTmpPt.X(),aTmpPt.Y());
+ } else {
+ rRect.Right()-=nDst;
+ }
+ }
+}
+
+void SdrRectObj::TakeObjNameSingul(XubString& rName) const
+{
+ if (IsTextFrame())
+ {
+ SdrTextObj::TakeObjNameSingul(rName);
+ }
+ else
+ {
+ USHORT nResId=STR_ObjNameSingulRECT;
+ if (aGeo.nShearWink!=0) {
+ nResId+=4; // Parallelogramm oder Raute
+ // Raute ist nicht, weil Shear die vertikalen Kanten verlaengert!
+ // Wenn Zeit ist, werde ich das mal berechnen.
+ } else {
+ if (aRect.GetWidth()==aRect.GetHeight()) nResId+=2; // Quadrat
+ }
+ if (GetEckenradius()!=0) nResId+=8; // abgerundet
+ rName=ImpGetResStr(nResId);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+ }
+}
+
+void SdrRectObj::TakeObjNamePlural(XubString& rName) const
+{
+ if (IsTextFrame()) SdrTextObj::TakeObjNamePlural(rName);
+ else {
+ USHORT nResId=STR_ObjNamePluralRECT;
+ if (aGeo.nShearWink!=0) {
+ nResId+=4; // Parallelogramm oder Raute
+ } else {
+ if (aRect.GetWidth()==aRect.GetHeight()) nResId+=2; // Quadrat
+ }
+ if (GetEckenradius()!=0) nResId+=8; // abgerundet
+ rName=ImpGetResStr(nResId);
+ }
+}
+
+void SdrRectObj::operator=(const SdrObject& rObj)
+{
+ SdrTextObj::operator=(rObj);
+}
+
+basegfx::B2DPolyPolygon SdrRectObj::TakeXorPoly() const
+{
+ XPolyPolygon aXPP;
+ aXPP.Insert(ImpCalcXPoly(aRect,GetEckenradius()));
+ return aXPP.getB2DPolyPolygon();
+}
+
+void SdrRectObj::RecalcSnapRect()
+{
+ long nEckRad=GetEckenradius();
+ if ((aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) && nEckRad!=0) {
+ maSnapRect=GetXPoly().GetBoundRect();
+ } else {
+ SdrTextObj::RecalcSnapRect();
+ }
+}
+
+void SdrRectObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ SdrTextObj::NbcSetSnapRect(rRect);
+ SetXPolyDirty();
+}
+
+void SdrRectObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ SdrTextObj::NbcSetLogicRect(rRect);
+ SetXPolyDirty();
+}
+
+sal_uInt32 SdrRectObj::GetHdlCount() const
+{
+ return IsTextFrame() ? 10 : 9;
+}
+
+SdrHdl* SdrRectObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pH = NULL;
+ Point aPnt;
+ SdrHdlKind eKind = HDL_MOVE;
+
+ if(!IsTextFrame())
+ {
+ nHdlNum++;
+ }
+
+ switch(nHdlNum)
+ {
+ case 0:
+ {
+ pH = new ImpTextframeHdl(aRect);
+ pH->SetObj((SdrObject*)this);
+ pH->SetDrehWink(aGeo.nDrehWink);
+ break;
+ }
+ case 1:
+ {
+ long a = GetEckenradius();
+ long b = Max(aRect.GetWidth(),aRect.GetHeight())/2; // Wird aufgerundet, da GetWidth() eins draufaddiert
+ if (a>b) a=b;
+ if (a<0) a=0;
+ aPnt=aRect.TopLeft();
+ aPnt.X()+=a;
+ eKind = HDL_CIRC;
+ break;
+ }
+ case 2: aPnt=aRect.TopLeft(); eKind = HDL_UPLFT; break; // Oben links
+ case 3: aPnt=aRect.TopCenter(); eKind = HDL_UPPER; break; // Oben
+ case 4: aPnt=aRect.TopRight(); eKind = HDL_UPRGT; break; // Oben rechts
+ case 5: aPnt=aRect.LeftCenter(); eKind = HDL_LEFT ; break; // Links
+ case 6: aPnt=aRect.RightCenter(); eKind = HDL_RIGHT; break; // Rechts
+ case 7: aPnt=aRect.BottomLeft(); eKind = HDL_LWLFT; break; // Unten links
+ case 8: aPnt=aRect.BottomCenter(); eKind = HDL_LOWER; break; // Unten
+ case 9: aPnt=aRect.BottomRight(); eKind = HDL_LWRGT; break; // Unten rechts
+ }
+
+ if(!pH)
+ {
+ if(aGeo.nShearWink)
+ {
+ ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
+ }
+
+ if(aGeo.nDrehWink)
+ {
+ RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ }
+
+ pH = new SdrHdl(aPnt,eKind);
+ pH->SetObj((SdrObject*)this);
+ pH->SetDrehWink(aGeo.nDrehWink);
+ }
+
+ return pH;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrRectObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+bool SdrRectObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if(bRad)
+ {
+ rDrag.SetEndDragChangesAttributes(true);
+
+ return true;
+ }
+
+ return SdrTextObj::beginSpecialDrag(rDrag);
+}
+
+bool SdrRectObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if (bRad)
+ {
+ Rectangle aBoundRect0;
+ Point aPt(rDrag.GetNow());
+
+ if(aGeo.nDrehWink)
+ RotatePoint(aPt,aRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
+
+ sal_Int32 nRad(aPt.X() - aRect.Left());
+
+ if (nRad < 0)
+ nRad = 0;
+
+ if(nRad != GetEckenradius())
+ {
+ NbcSetEckenradius(nRad);
+ }
+
+ return true;
+ }
+ else
+ {
+ return SdrTextObj::applySpecialDrag(rDrag);
+ }
+}
+
+String SdrRectObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
+
+ if(bCreateComment)
+ {
+ return String();
+ }
+ else
+ {
+ const bool bRad(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
+
+ if(bRad)
+ {
+ Point aPt(rDrag.GetNow());
+
+ // -sin fuer Umkehrung
+ if(aGeo.nDrehWink)
+ RotatePoint(aPt, aRect.TopLeft(), -aGeo.nSin, aGeo.nCos);
+
+ sal_Int32 nRad(aPt.X() - aRect.Left());
+
+ if(nRad < 0)
+ nRad = 0;
+
+ XubString aStr;
+
+ ImpTakeDescriptionStr(STR_DragRectEckRad, aStr);
+ aStr.AppendAscii(" (");
+ aStr += GetMetrStr(nRad);
+ aStr += sal_Unicode(')');
+
+ return aStr;
+ }
+ else
+ {
+ return SdrTextObj::getSpecialDragComment(rDrag);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+basegfx::B2DPolyPolygon SdrRectObj::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ Rectangle aRect1;
+ rDrag.TakeCreateRect(aRect1);
+ aRect1.Justify();
+
+ basegfx::B2DPolyPolygon aRetval;
+ aRetval.append(ImpCalcXPoly(aRect1,GetEckenradius()).getB2DPolygon());
+ return aRetval;
+}
+
+Pointer SdrRectObj::GetCreatePointer() const
+{
+ if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT);
+ return Pointer(POINTER_DRAW_RECT);
+}
+
+void SdrRectObj::NbcMove(const Size& rSiz)
+{
+ SdrTextObj::NbcMove(rSiz);
+ SetXPolyDirty();
+}
+
+void SdrRectObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ SdrTextObj::NbcResize(rRef,xFact,yFact);
+ SetXPolyDirty();
+}
+
+void SdrRectObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
+ SetXPolyDirty();
+}
+
+void SdrRectObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
+ SetXPolyDirty();
+}
+
+void SdrRectObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SdrTextObj::NbcMirror(rRef1,rRef2);
+ SetXPolyDirty();
+}
+
+FASTBOOL SdrRectObj::DoMacro(const SdrObjMacroHitRec& rRec)
+{
+ return SdrTextObj::DoMacro(rRec);
+}
+
+XubString SdrRectObj::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
+{
+ return SdrTextObj::GetMacroPopupComment(rRec);
+}
+
+SdrGluePoint SdrRectObj::GetVertexGluePoint(USHORT nPosNum) const
+{
+ INT32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
+
+ // #i25616#
+ if(!LineIsOutsideGeometry())
+ {
+ nWdt++;
+ nWdt /= 2;
+ }
+
+ Point aPt;
+ switch (nPosNum) {
+ case 0: aPt=aRect.TopCenter(); aPt.Y()-=nWdt; break;
+ case 1: aPt=aRect.RightCenter(); aPt.X()+=nWdt; break;
+ case 2: aPt=aRect.BottomCenter(); aPt.Y()+=nWdt; break;
+ case 3: aPt=aRect.LeftCenter(); aPt.X()-=nWdt; break;
+ }
+ if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ aPt-=GetSnapRect().Center();
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+ return aGP;
+}
+
+SdrGluePoint SdrRectObj::GetCornerGluePoint(USHORT nPosNum) const
+{
+ INT32 nWdt = ImpGetLineWdt(); // #i25616# ((XLineWidthItem&)(GetObjectItem(XATTR_LINEWIDTH))).GetValue();
+
+ // #i25616#
+ if(!LineIsOutsideGeometry())
+ {
+ nWdt++;
+ nWdt /= 2;
+ }
+
+ Point aPt;
+ switch (nPosNum) {
+ case 0: aPt=aRect.TopLeft(); aPt.X()-=nWdt; aPt.Y()-=nWdt; break;
+ case 1: aPt=aRect.TopRight(); aPt.X()+=nWdt; aPt.Y()-=nWdt; break;
+ case 2: aPt=aRect.BottomRight(); aPt.X()+=nWdt; aPt.Y()+=nWdt; break;
+ case 3: aPt=aRect.BottomLeft(); aPt.X()-=nWdt; aPt.Y()+=nWdt; break;
+ }
+ if (aGeo.nShearWink!=0) ShearPoint(aPt,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoint(aPt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ aPt-=GetSnapRect().Center();
+ SdrGluePoint aGP(aPt);
+ aGP.SetPercent(FALSE);
+ return aGP;
+}
+
+SdrObject* SdrRectObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ XPolygon aXP(ImpCalcXPoly(aRect,GetEckenradius()));
+ { // #40608# Nur Uebergangsweise bis zum neuen TakeContour()
+ aXP.Remove(0,1);
+ aXP[aXP.GetPointCount()-1]=aXP[0];
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon(aXP.getB2DPolygon());
+ aPolyPolygon.removeDoublePoints();
+ SdrObject* pRet = 0L;
+
+ if(!IsTextFrame() || HasFill() || HasLine())
+ {
+ pRet = ImpConvertMakeObj(aPolyPolygon, sal_True, bBezier);
+ }
+
+ pRet = ImpConvertAddText(pRet, bBezier);
+
+ return pRet;
+}
+
+void SdrRectObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ SdrTextObj::Notify(rBC,rHint);
+ SetXPolyDirty(); // wg. Eckenradius
+}
+
+void SdrRectObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ SdrTextObj::RestGeoData(rGeo);
+ SetXPolyDirty();
+}
+
+// eof
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
new file mode 100644
index 000000000000..6a79359e1a00
--- /dev/null
+++ b/svx/source/svdraw/svdotext.cxx
@@ -0,0 +1,2132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include "svditext.hxx"
+#include <svx/svdpagv.hxx> // fuer Abfrage im Paint, ob das
+#include <svx/svdview.hxx> // Objekt gerade editiert wird
+#include <svx/svdpage.hxx> // und fuer AnimationHandler (Laufschrift)
+#include <svx/svdetc.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdmodel.hxx> // OutlinerDefaults
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <editeng/writingmodeitem.hxx>
+#include <svx/sdtfchim.hxx>
+#include <svtools/colorcfg.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editstat.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/xftouit.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <svx/xflgrit.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/xflclit.hxx>
+#include <svl/style.hxx>
+#include <editeng/editeng.hxx>
+#include <svl/itemiter.hxx>
+#include <svx/sdr/properties/textproperties.hxx>
+#include <vcl/metaact.hxx>
+#include <svx/sdr/contact/viewcontactoftextobj.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <vcl/virdev.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+// #104018# replace macros above with type-safe methods
+inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
+inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// BaseProperties section
+
+sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
+{
+ return new sdr::properties::TextProperties(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// DrawContact section
+
+sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfTextObj(*this);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrTextObj,SdrAttrObj);
+
+SdrTextObj::SdrTextObj()
+: SdrAttrObj(),
+ mpText(NULL),
+ pEdtOutl(NULL),
+ pFormTextBoundRect(NULL),
+ eTextKind(OBJ_TEXT)
+{
+ bTextSizeDirty=FALSE;
+ bTextFrame=FALSE;
+ bNoShear=FALSE;
+ bNoRotate=FALSE;
+ bNoMirror=FALSE;
+ bDisableAutoWidthOnDragging=FALSE;
+
+ // #101684#
+ mbInEditMode = FALSE;
+
+ // #111096#
+ mbTextHidden = sal_False;
+
+ // #111096#
+ mbTextAnimationAllowed = sal_True;
+
+ // #108784#
+ maTextEditOffset = Point(0, 0);
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_True;
+}
+
+SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
+: SdrAttrObj(),
+ aRect(rNewRect),
+ mpText(NULL),
+ pEdtOutl(NULL),
+ pFormTextBoundRect(NULL)
+{
+ bTextSizeDirty=FALSE;
+ bTextFrame=FALSE;
+ bNoShear=FALSE;
+ bNoRotate=FALSE;
+ bNoMirror=FALSE;
+ bDisableAutoWidthOnDragging=FALSE;
+ ImpJustifyRect(aRect);
+
+ // #101684#
+ mbInEditMode = FALSE;
+
+ // #111096#
+ mbTextHidden = sal_False;
+
+ // #111096#
+ mbTextAnimationAllowed = sal_True;
+
+ // #108784#
+ maTextEditOffset = Point(0, 0);
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_True;
+}
+
+SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
+: SdrAttrObj(),
+ mpText(NULL),
+ pEdtOutl(NULL),
+ pFormTextBoundRect(NULL),
+ eTextKind(eNewTextKind)
+{
+ bTextSizeDirty=FALSE;
+ bTextFrame=TRUE;
+ bNoShear=TRUE;
+ bNoRotate=FALSE;
+ bNoMirror=TRUE;
+ bDisableAutoWidthOnDragging=FALSE;
+
+ // #101684#
+ mbInEditMode = FALSE;
+
+ // #111096#
+ mbTextHidden = sal_False;
+
+ // #111096#
+ mbTextAnimationAllowed = sal_True;
+
+ // #108784#
+ maTextEditOffset = Point(0, 0);
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_True;
+}
+
+SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
+: SdrAttrObj(),
+ aRect(rNewRect),
+ mpText(NULL),
+ pEdtOutl(NULL),
+ pFormTextBoundRect(NULL),
+ eTextKind(eNewTextKind)
+{
+ bTextSizeDirty=FALSE;
+ bTextFrame=TRUE;
+ bNoShear=TRUE;
+ bNoRotate=FALSE;
+ bNoMirror=TRUE;
+ bDisableAutoWidthOnDragging=FALSE;
+ ImpJustifyRect(aRect);
+
+ // #101684#
+ mbInEditMode = FALSE;
+
+ // #111096#
+ mbTextHidden = sal_False;
+
+ // #111096#
+ mbTextAnimationAllowed = sal_True;
+
+ // #108784#
+ maTextEditOffset = Point(0, 0);
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_True;
+}
+
+SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, USHORT eFormat)
+: SdrAttrObj(),
+ aRect(rNewRect),
+ mpText(NULL),
+ pEdtOutl(NULL),
+ pFormTextBoundRect(NULL),
+ eTextKind(eNewTextKind)
+{
+ bTextSizeDirty=FALSE;
+ bTextFrame=TRUE;
+ bNoShear=TRUE;
+ bNoRotate=FALSE;
+ bNoMirror=TRUE;
+ bDisableAutoWidthOnDragging=FALSE;
+ ImpJustifyRect(aRect);
+
+ NbcSetText(rInput, rBaseURL, eFormat);
+
+ // #101684#
+ mbInEditMode = FALSE;
+
+ // #111096#
+ mbTextHidden = sal_False;
+
+ // #111096#
+ mbTextAnimationAllowed = sal_True;
+
+ // #108784#
+ maTextEditOffset = Point(0, 0);
+
+ // #i25616#
+ mbSupportTextIndentingOnLineWidthChange = sal_True;
+}
+
+SdrTextObj::~SdrTextObj()
+{
+ if( pModel )
+ {
+ SdrOutliner& rOutl = pModel->GetHitTestOutliner();
+ if( rOutl.GetTextObj() == this )
+ rOutl.SetTextObj( NULL );
+ }
+
+ if(mpText!=NULL)
+ delete mpText;
+
+ if (pFormTextBoundRect!=NULL)
+ delete pFormTextBoundRect;
+
+ ImpLinkAbmeldung();
+}
+
+void SdrTextObj::FitFrameToTextSize()
+{
+ DBG_ASSERT(pModel!=NULL,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
+ ImpJustifyRect(aRect);
+
+ SdrText* pText = getActiveText();
+ if( pText!=NULL && pText->GetOutlinerParaObject() && pModel!=NULL)
+ {
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetPaperSize(Size(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top()));
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetText(*pText->GetOutlinerParaObject());
+ Rectangle aTextRect;
+ Size aNewSize(rOutliner.CalcTextSize());
+ rOutliner.Clear();
+ aNewSize.Width()++; // wegen evtl. Rundungsfehler
+ aNewSize.Width()+=GetTextLeftDistance()+GetTextRightDistance();
+ aNewSize.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
+ Rectangle aNewRect(aRect);
+ aNewRect.SetSize(aNewSize);
+ ImpJustifyRect(aNewRect);
+ if (aNewRect!=aRect) {
+ SetLogicRect(aNewRect);
+ }
+ }
+}
+
+void SdrTextObj::NbcSetText(const XubString& rStr)
+{
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetStyleSheet( 0, GetStyleSheet());
+ //OutputDevice* pRef1=rOutliner.GetRefDevice();
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetText(rStr,rOutliner.GetParagraph( 0 ));
+ OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
+ Size aSiz(rOutliner.CalcTextSize());
+ //OutputDevice* pRef2=rOutliner.GetRefDevice();
+ rOutliner.Clear();
+ NbcSetOutlinerParaObject(pNewText);
+ aTextSize=aSiz;
+ bTextSizeDirty=FALSE;
+}
+
+void SdrTextObj::SetText(const XubString& rStr)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetText(rStr);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ //if (GetBoundRect()!=aBoundRect0) {
+ // SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ //}
+}
+
+void SdrTextObj::NbcSetText(SvStream& rInput, const String& rBaseURL, USHORT eFormat)
+{
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetStyleSheet( 0, GetStyleSheet());
+ rOutliner.Read(rInput,rBaseURL,eFormat);
+ OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
+ rOutliner.SetUpdateMode(TRUE);
+ Size aSiz(rOutliner.CalcTextSize());
+ rOutliner.Clear();
+ NbcSetOutlinerParaObject(pNewText);
+ aTextSize=aSiz;
+ bTextSizeDirty=FALSE;
+}
+
+void SdrTextObj::SetText(SvStream& rInput, const String& rBaseURL, USHORT eFormat)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcSetText(rInput,rBaseURL,eFormat);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+const Size& SdrTextObj::GetTextSize() const
+{
+ if (bTextSizeDirty)
+ {
+ Size aSiz;
+ SdrText* pText = getActiveText();
+ if( pText && pText->GetOutlinerParaObject ())
+ {
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetText(*pText->GetOutlinerParaObject());
+ rOutliner.SetUpdateMode(TRUE);
+ aSiz=rOutliner.CalcTextSize();
+ rOutliner.Clear();
+ }
+ // 2x casting auf nonconst
+ ((SdrTextObj*)this)->aTextSize=aSiz;
+ ((SdrTextObj*)this)->bTextSizeDirty=FALSE;
+ }
+ return aTextSize;
+}
+
+FASTBOOL SdrTextObj::IsAutoGrowHeight() const
+{
+ if(!bTextFrame)
+ return FALSE; // AutoGrow nur bei TextFrames
+
+ const SfxItemSet& rSet = GetObjectItemSet();
+ BOOL bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
+
+ if(bRet)
+ {
+ SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
+
+ if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
+ {
+ SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+
+ if(eDirection == SDRTEXTANI_UP || eDirection == SDRTEXTANI_DOWN)
+ {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+FASTBOOL SdrTextObj::IsAutoGrowWidth() const
+{
+ if(!bTextFrame)
+ return FALSE; // AutoGrow nur bei TextFrames
+
+ const SfxItemSet& rSet = GetObjectItemSet();
+ BOOL bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
+
+ // #101684#
+ BOOL bInEditMOde = IsInEditMode();
+
+ if(!bInEditMOde && bRet)
+ {
+ SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
+
+ if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
+ {
+ SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+
+ if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
+ {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
+{
+ return GetTextHorizontalAdjust(GetObjectItemSet());
+}
+
+SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet& rSet) const
+{
+ if(IsContourTextFrame())
+ return SDRTEXTHORZADJUST_BLOCK;
+
+ SdrTextHorzAdjust eRet = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
+
+ // #101684#
+ BOOL bInEditMode = IsInEditMode();
+
+ if(!bInEditMode && eRet == SDRTEXTHORZADJUST_BLOCK)
+ {
+ SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
+
+ if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
+ {
+ SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+
+ if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
+ {
+ eRet = SDRTEXTHORZADJUST_LEFT;
+ }
+ }
+ }
+
+ return eRet;
+} // defaults: BLOCK fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
+
+SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
+{
+ return GetTextVerticalAdjust(GetObjectItemSet());
+}
+
+SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust(const SfxItemSet& rSet) const
+{
+ if(IsContourTextFrame())
+ return SDRTEXTVERTADJUST_TOP;
+
+ // #103516# Take care for vertical text animation here
+ SdrTextVertAdjust eRet = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
+ BOOL bInEditMode = IsInEditMode();
+
+ // #103516# Take care for vertical text animation here
+ if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
+ {
+ SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
+
+ if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
+ {
+ SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+
+ if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
+ {
+ eRet = SDRTEXTVERTADJUST_TOP;
+ }
+ }
+ }
+
+ return eRet;
+} // defaults: TOP fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
+
+void SdrTextObj::ImpJustifyRect(Rectangle& rRect) const
+{
+ if (!rRect.IsEmpty()) {
+ rRect.Justify();
+ if (rRect.Left()==rRect.Right()) rRect.Right()++;
+ if (rRect.Top()==rRect.Bottom()) rRect.Bottom()++;
+ }
+}
+
+void SdrTextObj::ImpCheckShear()
+{
+ if (bNoShear && aGeo.nShearWink!=0) {
+ aGeo.nShearWink=0;
+ aGeo.nTan=0;
+ }
+}
+
+void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ FASTBOOL bNoTextFrame=!IsTextFrame();
+ rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
+ rInfo.bResizePropAllowed=TRUE;
+ rInfo.bRotateFreeAllowed=TRUE;
+ rInfo.bRotate90Allowed =TRUE;
+ rInfo.bMirrorFreeAllowed=bNoTextFrame;
+ rInfo.bMirror45Allowed =bNoTextFrame;
+ rInfo.bMirror90Allowed =bNoTextFrame;
+
+ // allow transparence
+ rInfo.bTransparenceAllowed = TRUE;
+
+ // gradient depends on fillstyle
+ XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
+ rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
+ rInfo.bShearAllowed =bNoTextFrame;
+ rInfo.bEdgeRadiusAllowed=TRUE;
+ FASTBOOL bCanConv=ImpCanConvTextToCurve();
+ rInfo.bCanConvToPath =bCanConv;
+ rInfo.bCanConvToPoly =bCanConv;
+ rInfo.bCanConvToPathLineToArea=bCanConv;
+ rInfo.bCanConvToPolyLineToArea=bCanConv;
+ rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
+}
+
+UINT16 SdrTextObj::GetObjIdentifier() const
+{
+ return USHORT(eTextKind);
+}
+
+bool SdrTextObj::HasTextImpl( SdrOutliner* pOutliner )
+{
+ bool bRet=false;
+ if(pOutliner)
+ {
+ Paragraph* p1stPara=pOutliner->GetParagraph( 0 );
+ ULONG nParaAnz=pOutliner->GetParagraphCount();
+ if(p1stPara==NULL)
+ nParaAnz=0;
+
+ if(nParaAnz==1)
+ {
+ // if it is only one paragraph, check if that paragraph is empty
+ XubString aStr(pOutliner->GetText(p1stPara));
+
+ if(!aStr.Len())
+ nParaAnz = 0;
+ }
+
+ bRet= nParaAnz!=0;
+ }
+ return bRet;
+}
+
+FASTBOOL SdrTextObj::HasEditText() const
+{
+ return HasTextImpl( pEdtOutl );
+}
+
+void SdrTextObj::SetPage(SdrPage* pNewPage)
+{
+ FASTBOOL bRemove=pNewPage==NULL && pPage!=NULL;
+ FASTBOOL bInsert=pNewPage!=NULL && pPage==NULL;
+ FASTBOOL bLinked=IsLinkedText();
+
+ if (bLinked && bRemove) {
+ ImpLinkAbmeldung();
+ }
+
+ SdrAttrObj::SetPage(pNewPage);
+
+ if (bLinked && bInsert) {
+ ImpLinkAnmeldung();
+ }
+}
+
+void SdrTextObj::SetModel(SdrModel* pNewModel)
+{
+ SdrModel* pOldModel=pModel;
+ bool bLinked=IsLinkedText();
+ bool bChg=pNewModel!=pModel;
+
+ if (bLinked && bChg)
+ {
+ ImpLinkAbmeldung();
+ }
+
+ SdrAttrObj::SetModel(pNewModel);
+
+ if( bChg )
+ {
+ if( pNewModel != 0 && pOldModel != 0 )
+ SetTextSizeDirty();
+
+ sal_Int32 nCount = getTextCount();
+ for( sal_Int32 nText = 0; nText < nCount; nText++ )
+ {
+ SdrText* pText = getText( nText );
+ if( pText )
+ pText->SetModel( pNewModel );
+ }
+ }
+
+ if (bLinked && bChg)
+ {
+ ImpLinkAnmeldung();
+ }
+}
+
+FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad)
+{
+ SetObjectItem(SdrEckenradiusItem(nRad));
+ return TRUE;
+}
+
+FASTBOOL SdrTextObj::NbcSetAutoGrowHeight(bool bAuto)
+{
+ if(bTextFrame)
+ {
+ SetObjectItem(SdrTextAutoGrowHeightItem(bAuto));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetMinTextFrameHeight(long nHgt)
+{
+ if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // SJ: #i44922#
+ {
+ SetObjectItem(SdrTextMinFrameHeightItem(nHgt));
+
+ // #84974# use bDisableAutoWidthOnDragging as
+ // bDisableAutoHeightOnDragging if vertical.
+ if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
+ {
+ bDisableAutoWidthOnDragging = FALSE;
+ SetObjectItem(SdrTextAutoGrowHeightItem(FALSE));
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetMaxTextFrameHeight(long nHgt)
+{
+ if(bTextFrame)
+ {
+ SetObjectItem(SdrTextMaxFrameHeightItem(nHgt));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetAutoGrowWidth(bool bAuto)
+{
+ if(bTextFrame)
+ {
+ SetObjectItem(SdrTextAutoGrowWidthItem(bAuto));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetMinTextFrameWidth(long nWdt)
+{
+ if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // SJ: #i44922#
+ {
+ SetObjectItem(SdrTextMinFrameWidthItem(nWdt));
+
+ // #84974# use bDisableAutoWidthOnDragging only
+ // when not vertical.
+ if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
+ {
+ bDisableAutoWidthOnDragging = FALSE;
+ SetObjectItem(SdrTextAutoGrowWidthItem(FALSE));
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetMaxTextFrameWidth(long nWdt)
+{
+ if(bTextFrame)
+ {
+ SetObjectItem(SdrTextMaxFrameWidthItem(nWdt));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcSetFitToSize(SdrFitToSizeType eFit)
+{
+ if(bTextFrame)
+ {
+ SetObjectItem(SdrTextFitToSizeTypeItem(eFit));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, BOOL bLineWidth ) const
+{
+ basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
+ basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
+ basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
+ -rAnchorRect.Left(), -rAnchorRect.Top()));
+
+ if(aGeo.nDrehWink)
+ {
+ // Unrotate!
+ aMatrix.rotate(-aGeo.nDrehWink * nPi180);
+ }
+
+ aXorPolyPolygon.transform(aMatrix);
+
+ if( bLineWidth )
+ {
+ // Strichstaerke beruecksichtigen
+ // Beim Hittest muss das unterbleiben (Performance!)
+ pContourPolyPolygon = new basegfx::B2DPolyPolygon();
+
+ // #86258# test if shadow needs to be avoided for TakeContour()
+ const SfxItemSet& rSet = GetObjectItemSet();
+ sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
+
+ // #i33696#
+ // Remember TextObject currently set at the DrawOutliner, it WILL be
+ // replaced during calculating the outline since it uses an own paint
+ // and that one uses the DrawOutliner, too.
+ const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
+
+ if(bShadowOn)
+ {
+ // #86258# force shadow off
+ SdrObject* pCopy = Clone();
+ pCopy->SetMergedItem(SdrShadowItem(FALSE));
+ *pContourPolyPolygon = pCopy->TakeContour();
+ SdrObject::Free( pCopy );
+ }
+ else
+ {
+ *pContourPolyPolygon = TakeContour();
+ }
+
+ // #i33696#
+ // restore remembered text object
+ if(pLastTextObject != rOutliner.GetTextObj())
+ {
+ rOutliner.SetTextObj(pLastTextObject);
+ }
+
+ pContourPolyPolygon->transform(aMatrix);
+ }
+
+ rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
+}
+
+void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
+{
+ rRect=aRect;
+}
+
+void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
+{
+ long nLeftDist=GetTextLeftDistance();
+ long nRightDist=GetTextRightDistance();
+ long nUpperDist=GetTextUpperDistance();
+ long nLowerDist=GetTextLowerDistance();
+ Rectangle aAnkRect(aRect); // Rect innerhalb dem geankert wird
+ FASTBOOL bFrame=IsTextFrame();
+ if (!bFrame) {
+ TakeUnrotatedSnapRect(aAnkRect);
+ }
+ Point aRotateRef(aAnkRect.TopLeft());
+ aAnkRect.Left()+=nLeftDist;
+ aAnkRect.Top()+=nUpperDist;
+ aAnkRect.Right()-=nRightDist;
+ aAnkRect.Bottom()-=nLowerDist;
+
+ // #108816#
+ // Since sizes may be bigger than the object bounds it is necessary to
+ // justify the rect now.
+ ImpJustifyRect(aAnkRect);
+
+ if (bFrame) {
+ // !!! hier noch etwas verfeinern !!!
+ if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1; // Mindestgroesse 2
+ if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1; // Mindestgroesse 2
+ }
+ if (aGeo.nDrehWink!=0) {
+ Point aTmpPt(aAnkRect.TopLeft());
+ RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
+ aTmpPt-=aAnkRect.TopLeft();
+ aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
+ }
+ rAnchorRect=aAnkRect;
+}
+
+void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
+ Rectangle* pAnchorRect, BOOL bLineWidth ) const
+{
+ Rectangle aAnkRect; // Rect innerhalb dem geankert wird
+ TakeTextAnchorRect(aAnkRect);
+ SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
+ SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
+ SdrTextAniKind eAniKind=GetTextAniKind();
+ SdrTextAniDirection eAniDirection=GetTextAniDirection();
+
+ SdrFitToSizeType eFit=GetFitToSize();
+ FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ FASTBOOL bContourFrame=IsContourTextFrame();
+
+ FASTBOOL bFrame=IsTextFrame();
+ ULONG nStat0=rOutliner.GetControlWord();
+ Size aNullSize;
+ if (!bContourFrame)
+ {
+ rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
+ rOutliner.SetMinAutoPaperSize(aNullSize);
+ rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
+ }
+
+ if (!bFitToSize && !bContourFrame)
+ {
+ long nAnkWdt=aAnkRect.GetWidth();
+ long nAnkHgt=aAnkRect.GetHeight();
+ if (bFrame)
+ {
+ long nWdt=nAnkWdt;
+ long nHgt=nAnkHgt;
+
+ // #101684#
+ BOOL bInEditMode = IsInEditMode();
+
+ if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
+ {
+ // Grenzenlose Papiergroesse fuer Laufschrift
+ if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
+ if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
+ }
+ rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
+ }
+
+ // #103516# New try with _BLOCK for hor and ver after completely
+ // supporting full width for vertical text.
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
+ {
+ rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
+ }
+
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
+ {
+ rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
+ }
+ }
+
+ rOutliner.SetPaperSize(aNullSize);
+ if (bContourFrame)
+ ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
+
+ // put text into the outliner, if available from the edit outliner
+ SdrText* pText = getActiveText();
+ OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
+ OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
+
+ if (pPara)
+ {
+ BOOL bHitTest = FALSE;
+ if( pModel )
+ bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
+
+ const SdrTextObj* pTestObj = rOutliner.GetTextObj();
+ if( !pTestObj || !bHitTest || pTestObj != this ||
+ pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
+ {
+ if( bHitTest ) // #i33696# take back fix #i27510#
+ {
+ rOutliner.SetTextObj( this );
+ rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ }
+
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetText(*pPara);
+ }
+ }
+ else
+ {
+ rOutliner.SetTextObj( NULL );
+ }
+
+ if (pEdtOutl && !bNoEditText && pPara)
+ delete pPara;
+
+ rOutliner.SetUpdateMode(TRUE);
+ rOutliner.SetControlWord(nStat0);
+
+ if( pText )
+ pText->CheckPortionInfo(rOutliner);
+
+ Point aTextPos(aAnkRect.TopLeft());
+ Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
+
+ // #106653#
+ // For draw objects containing text correct hor/ver alignment if text is bigger
+ // than the object itself. Without that correction, the text would always be
+ // formatted to the left edge (or top edge when vertical) of the draw object.
+ if(!IsTextFrame())
+ {
+ if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
+ {
+ // #110129#
+ // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
+ {
+ eHAdj = SDRTEXTHORZADJUST_CENTER;
+ }
+ }
+
+ if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
+ {
+ // #110129#
+ // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
+ {
+ eVAdj = SDRTEXTVERTADJUST_CENTER;
+ }
+ }
+ }
+
+ if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
+ {
+ long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
+ if (eHAdj==SDRTEXTHORZADJUST_CENTER)
+ aTextPos.X()+=nFreeWdt/2;
+ if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
+ aTextPos.X()+=nFreeWdt;
+ }
+ if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
+ {
+ long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
+ if (eVAdj==SDRTEXTVERTADJUST_CENTER)
+ aTextPos.Y()+=nFreeHgt/2;
+ if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
+ aTextPos.Y()+=nFreeHgt;
+ }
+ if (aGeo.nDrehWink!=0)
+ RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+
+ if (pAnchorRect)
+ *pAnchorRect=aAnkRect;
+
+ // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
+ rTextRect=Rectangle(aTextPos,aTextSiz);
+ if (bContourFrame)
+ rTextRect=aAnkRect;
+}
+
+OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
+{
+ OutlinerParaObject* pPara=NULL;
+ if( HasTextImpl( pEdtOutl ) )
+ {
+ sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() );
+ pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
+ }
+ return pPara;
+}
+
+void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& rTextRect, const Rectangle& rAnchorRect, Fraction& rFitXKorreg) const
+{
+ OutputDevice* pOut = rOutliner.GetRefDevice();
+ BOOL bNoStretching(FALSE);
+
+ if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ // #35762#: Checken ob CharStretching ueberhaupt moeglich
+ GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
+ UniString aTestString(sal_Unicode('J'));
+
+ if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
+ pMtf = NULL;
+
+ if(pMtf)
+ pMtf->Pause(TRUE);
+
+ Font aFontMerk(pOut->GetFont());
+ Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
+
+ aTmpFont.SetSize(Size(0,100));
+ pOut->SetFont(aTmpFont);
+ Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
+ aTmpFont.SetSize(Size(800,100));
+ pOut->SetFont(aTmpFont);
+ Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
+ pOut->SetFont(aFontMerk);
+
+ if(pMtf)
+ pMtf->Pause(FALSE);
+
+ bNoStretching = (aSize1 == aSize2);
+
+#ifdef WNT
+ // #35762# Windows vergroessert bei Size(100,500) den Font proportional
+ // Und das finden wir nicht so schoen.
+ if(aSize2.Height() >= aSize1.Height() * 2)
+ {
+ bNoStretching = TRUE;
+ }
+#endif
+ }
+ unsigned nLoopCount=0;
+ FASTBOOL bNoMoreLoop=FALSE;
+ long nXDiff0=0x7FFFFFFF;
+ long nWantWdt=rAnchorRect.Right()-rAnchorRect.Left();
+ long nIsWdt=rTextRect.Right()-rTextRect.Left();
+ if (nIsWdt==0) nIsWdt=1;
+
+ long nWantHgt=rAnchorRect.Bottom()-rAnchorRect.Top();
+ long nIsHgt=rTextRect.Bottom()-rTextRect.Top();
+ if (nIsHgt==0) nIsHgt=1;
+
+ long nXTolPl=nWantWdt/100; // Toleranz +1%
+ long nXTolMi=nWantWdt/25; // Toleranz -4%
+ long nXKorr =nWantWdt/20; // Korrekturmasstab 5%
+
+ long nX=(nWantWdt*100) /nIsWdt; // X-Stretching berechnen
+ long nY=(nWantHgt*100) /nIsHgt; // Y-Stretching berechnen
+ FASTBOOL bChkX=TRUE;
+ FASTBOOL bChkY=TRUE;
+ if (bNoStretching) { // #35762# evtl. nur proportional moeglich
+ if (nX>nY) { nX=nY; bChkX=FALSE; }
+ else { nY=nX; bChkY=FALSE; }
+ }
+
+ while (nLoopCount<5 && !bNoMoreLoop) {
+ if (nX<0) nX=-nX;
+ if (nX<1) { nX=1; bNoMoreLoop=TRUE; }
+ if (nX>65535) { nX=65535; bNoMoreLoop=TRUE; }
+
+ if (nY<0) nY=-nY;
+ if (nY<1) { nY=1; bNoMoreLoop=TRUE; }
+ if (nY>65535) { nY=65535; bNoMoreLoop=TRUE; }
+
+ // exception, there is no text yet (horizontal case)
+ if(nIsWdt <= 1)
+ {
+ nX = nY;
+ bNoMoreLoop = TRUE;
+ }
+
+ // #87877# exception, there is no text yet (vertical case)
+ if(nIsHgt <= 1)
+ {
+ nY = nX;
+ bNoMoreLoop = TRUE;
+ }
+
+ rOutliner.SetGlobalCharStretching((USHORT)nX,(USHORT)nY);
+ nLoopCount++;
+ Size aSiz(rOutliner.CalcTextSize());
+ long nXDiff=aSiz.Width()-nWantWdt;
+ rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
+ if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0/*&& Abs(nYDiff)<=nYTol*/) {
+ bNoMoreLoop=TRUE;
+ } else {
+ // Stretchingfaktoren korregieren
+ long nMul=nWantWdt;
+ long nDiv=aSiz.Width();
+ if (Abs(nXDiff)<=2*nXKorr) {
+ if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // und zwar nur um die haelfte des berechneten
+ else nMul+=(nDiv-nMul)/2; // weil die EE ja eh wieder falsch rechnet
+ }
+ nX=nX*nMul/nDiv;
+ if (bNoStretching) nY=nX;
+ }
+ nXDiff0=nXDiff;
+ }
+}
+
+void SdrTextObj::StartTextAnimation(OutputDevice* /*pOutDev*/, const Point& /*rOffset*/, long /*nExtraData*/)
+{
+ // #111096#
+ // use new text animation
+ SetTextAnimationAllowed(sal_True);
+}
+
+void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
+{
+ // #111096#
+ // use new text animation
+ SetTextAnimationAllowed(sal_False);
+}
+
+void SdrTextObj::TakeObjNameSingul(XubString& rName) const
+{
+ XubString aStr;
+
+ switch(eTextKind)
+ {
+ case OBJ_OUTLINETEXT:
+ {
+ aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
+ break;
+ }
+
+ case OBJ_TITLETEXT :
+ {
+ aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
+ break;
+ }
+
+ default:
+ {
+ if(IsLinkedText())
+ aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
+ else
+ aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
+ break;
+ }
+ }
+
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
+ {
+ // Macht bei OUTLINETEXT wohl derzeit noch etwas Probleme
+ XubString aStr2(pOutlinerParaObject->GetTextObject().GetText(0));
+ aStr2.EraseLeadingChars();
+
+ // #69446# avoid non expanded text portions in object name
+ // (second condition is new)
+ if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
+ {
+ // #76681# space between ResStr and content text
+ aStr += sal_Unicode(' ');
+
+ aStr += sal_Unicode('\'');
+
+ if(aStr2.Len() > 10)
+ {
+ aStr2.Erase(8);
+ aStr2.AppendAscii("...", 3);
+ }
+
+ aStr += aStr2;
+ aStr += sal_Unicode('\'');
+ }
+ }
+
+ rName = aStr;
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+
+}
+
+void SdrTextObj::TakeObjNamePlural(XubString& rName) const
+{
+ switch (eTextKind) {
+ case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
+ case OBJ_TITLETEXT : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT); break;
+ default: {
+ if (IsLinkedText()) {
+ rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
+ } else {
+ rName=ImpGetResStr(STR_ObjNamePluralTEXT);
+ }
+ } break;
+ } // switch
+}
+
+void SdrTextObj::operator=(const SdrObject& rObj)
+{
+ // call parent
+ SdrObject::operator=(rObj);
+
+ const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >( &rObj );
+ if (pTextObj!=NULL)
+ {
+ aRect =pTextObj->aRect;
+ aGeo =pTextObj->aGeo;
+ eTextKind =pTextObj->eTextKind;
+ bTextFrame=pTextObj->bTextFrame;
+ aTextSize=pTextObj->aTextSize;
+ bTextSizeDirty=pTextObj->bTextSizeDirty;
+
+ // #101776# Not all of the necessary parameters were copied yet.
+ bNoShear = pTextObj->bNoShear;
+ bNoRotate = pTextObj->bNoRotate;
+ bNoMirror = pTextObj->bNoMirror;
+ bDisableAutoWidthOnDragging = pTextObj->bDisableAutoWidthOnDragging;
+
+ OutlinerParaObject* pNewOutlinerParaObject = 0;
+
+ SdrText* pText = getActiveText();
+
+ if( pText && pTextObj->HasText() )
+ {
+ const Outliner* pEO=pTextObj->pEdtOutl;
+ if (pEO!=NULL)
+ {
+ pNewOutlinerParaObject = pEO->CreateParaObject();
+ }
+ else
+ {
+ pNewOutlinerParaObject = new OutlinerParaObject(*pTextObj->getActiveText()->GetOutlinerParaObject());
+ }
+ }
+
+ mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
+ ImpSetTextStyleSheetListeners();
+ }
+}
+
+basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
+{
+ Polygon aPol(aRect);
+ if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+
+ basegfx::B2DPolyPolygon aRetval;
+ aRetval.append(aPol.getB2DPolygon());
+ return aRetval;
+}
+
+basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
+{
+ basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
+
+ // und nun noch ggf. das BoundRect des Textes dazu
+ if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
+ {
+ // #80328# using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
+ // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
+ // in every case
+ SdrOutliner& rOutliner=ImpGetDrawOutliner();
+
+ Rectangle aAnchor2;
+ Rectangle aR;
+ TakeTextRect(rOutliner,aR,FALSE,&aAnchor2);
+ rOutliner.Clear();
+ SdrFitToSizeType eFit=GetFitToSize();
+ FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ if (bFitToSize) aR=aAnchor2;
+ Polygon aPol(aR);
+ if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
+
+ aRetval.append(aPol.getB2DPolygon());
+ }
+
+ return aRetval;
+}
+
+void SdrTextObj::RecalcSnapRect()
+{
+ if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
+ Polygon aPol(aRect);
+ if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ maSnapRect=aPol.GetBoundRect();
+ } else {
+ maSnapRect=aRect;
+ }
+}
+
+sal_uInt32 SdrTextObj::GetSnapPointCount() const
+{
+ return 4L;
+}
+
+Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
+{
+ Point aP;
+ switch (i) {
+ case 0: aP=aRect.TopLeft(); break;
+ case 1: aP=aRect.TopRight(); break;
+ case 2: aP=aRect.BottomLeft(); break;
+ case 3: aP=aRect.BottomRight(); break;
+ default: aP=aRect.Center(); break;
+ }
+ if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ return aP;
+}
+
+void SdrTextObj::ImpCheckMasterCachable()
+{
+ bNotMasterCachable=FALSE;
+
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+
+ if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
+ {
+ const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
+ bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
+ if( !bNotMasterCachable )
+ {
+ bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
+ if( !bNotMasterCachable )
+ {
+ bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
+ if( !bNotMasterCachable )
+ {
+ bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
+ }
+ }
+ }
+ }
+}
+
+// #101029#: Extracted from ImpGetDrawOutliner()
+void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
+{
+ rOutl.SetUpdateMode(FALSE);
+ USHORT nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
+ if ( !IsOutlText() )
+ nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
+ rOutl.Init( nOutlinerMode );
+
+ rOutl.SetGlobalCharStretching(100,100);
+ ULONG nStat=rOutl.GetControlWord();
+ nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
+ rOutl.SetControlWord(nStat);
+ Size aNullSize;
+ Size aMaxSize(100000,100000);
+ rOutl.SetMinAutoPaperSize(aNullSize);
+ rOutl.SetMaxAutoPaperSize(aMaxSize);
+ rOutl.SetPaperSize(aMaxSize);
+ rOutl.ClearPolygon();
+}
+
+SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
+{
+ SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
+
+ // #101029#: Code extracted to ImpInitDrawOutliner()
+ ImpInitDrawOutliner( rOutl );
+
+ return rOutl;
+}
+
+boost::shared_ptr< SdrOutliner > SdrTextObj::CreateDrawOutliner()
+{
+ boost::shared_ptr< SdrOutliner > xDrawOutliner( pModel->CreateDrawOutliner(this) );
+ ImpInitDrawOutliner( *(xDrawOutliner.get()) );
+ return xDrawOutliner;
+}
+
+// #101029#: Extracted from Paint()
+void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL bContourFrame,
+ SdrOutliner& rOutliner,
+ Rectangle& rTextRect,
+ Rectangle& rAnchorRect,
+ Rectangle& rPaintRect,
+ Fraction& rFitXKorreg ) const
+{
+ if (!bContourFrame)
+ {
+ // FitToSize erstmal nicht mit ContourFrame
+ SdrFitToSizeType eFit=GetFitToSize();
+ if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
+ {
+ ULONG nStat=rOutliner.GetControlWord();
+ nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
+ rOutliner.SetControlWord(nStat);
+ }
+ }
+ rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ TakeTextRect(rOutliner, rTextRect, FALSE, &rAnchorRect);
+ rPaintRect = rTextRect;
+
+ if (!bContourFrame)
+ {
+ // FitToSize erstmal nicht mit ContourFrame
+ SdrFitToSizeType eFit=GetFitToSize();
+ if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
+ {
+ ImpSetCharStretching(rOutliner,rTextRect,rAnchorRect,rFitXKorreg);
+ rPaintRect=rAnchorRect;
+ }
+ }
+}
+
+void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
+{
+ ImpInitDrawOutliner( rOutl );
+ UpdateOutlinerFormatting( rOutl, rPaintRect );
+}
+
+void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
+{
+ Rectangle aTextRect;
+ Rectangle aAnchorRect;
+ Fraction aFitXKorreg(1,1);
+
+ FASTBOOL bContourFrame=IsContourTextFrame();
+
+ ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
+
+ if( GetModel() )
+ {
+ MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
+ GetModel()->GetScaleFraction(),
+ GetModel()->GetScaleFraction());
+ rOutl.SetRefMapMode(aMapMode);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
+{
+ SdrText* pText = getActiveText();
+ if( pText )
+ return pText->GetOutlinerParaObject();
+ else
+ return 0;
+}
+
+bool SdrTextObj::HasOutlinerParaObject() const
+{
+ SdrText* pText = getActiveText();
+ if( pText && pText->GetOutlinerParaObject() )
+ return true;
+ return false;
+}
+
+void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
+{
+ NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
+}
+
+void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
+{
+ if( pText )
+ pText->SetOutlinerParaObject( pTextObject );
+
+ if( pText->GetOutlinerParaObject() )
+ {
+ SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
+ ? com::sun::star::text::WritingMode_TB_RL
+ : com::sun::star::text::WritingMode_LR_TB,
+ SDRATTR_TEXTDIRECTION);
+ GetProperties().SetObjectItemDirect(aWritingMode);
+ }
+
+ SetTextSizeDirty();
+ if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
+ { // Textrahmen anpassen!
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ if (!IsTextFrame())
+ {
+ // Das SnapRect behaelt seine Groesse bei
+ SetRectsDirty(sal_True);
+ }
+
+ // always invalidate BoundRect on change
+ SetBoundRectDirty();
+ ActionChanged();
+
+ ImpSetTextStyleSheetListeners();
+ ImpCheckMasterCachable();
+}
+
+void SdrTextObj::NbcReformatText()
+{
+ SdrText* pText = getActiveText();
+ if( pText && pText->GetOutlinerParaObject() )
+ {
+ pText->ReformatText();
+ if (bTextFrame)
+ {
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ else
+ {
+ // Das SnapRect behaelt seine Groesse bei
+ SetBoundRectDirty();
+ SetRectsDirty(sal_True);
+ }
+ SetTextSizeDirty();
+ ActionChanged();
+ // FME, AW: i22396
+ // Necessary here since we have no compare operator at the outliner
+ // para object which may detect changes regarding the combination
+ // of outliner para data and configuration (e.g., change of
+ // formatting of text numerals)
+ GetViewContact().flushViewObjectContacts(false);
+ }
+}
+
+void SdrTextObj::ReformatText()
+{
+ if(GetOutlinerParaObject())
+ {
+ Rectangle aBoundRect0;
+ if (pUserCall!=NULL)
+ aBoundRect0=GetLastBoundRect();
+
+ // #110094#-14 SendRepaintBroadcast();
+ NbcReformatText();
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+SdrObjGeoData* SdrTextObj::NewGeoData() const
+{
+ return new SdrTextObjGeoData;
+}
+
+void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ SdrAttrObj::SaveGeoData(rGeo);
+ SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
+ rTGeo.aRect =aRect;
+ rTGeo.aGeo =aGeo;
+}
+
+void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
+{ // RectsDirty wird von SdrObject gerufen
+ SdrAttrObj::RestGeoData(rGeo);
+ SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
+ aRect =rTGeo.aRect;
+ aGeo =rTGeo.aGeo;
+ SetTextSizeDirty();
+}
+
+SdrFitToSizeType SdrTextObj::GetFitToSize() const
+{
+ SdrFitToSizeType eType = SDRTEXTFIT_NONE;
+
+ if(!IsAutoGrowWidth())
+ eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
+
+ return eType;
+}
+
+void SdrTextObj::ForceOutlinerParaObject()
+{
+ SdrText* pText = getActiveText();
+ if( pText && (pText->GetOutlinerParaObject() == 0) )
+ {
+ USHORT nOutlMode = OUTLINERMODE_TEXTOBJECT;
+ if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
+ nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
+
+ pText->ForceOutlinerParaObject( nOutlMode );
+ }
+}
+
+sal_Bool SdrTextObj::IsVerticalWriting() const
+{
+ // #89459#
+ if(pEdtOutl)
+ {
+ return pEdtOutl->IsVertical();
+ }
+
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if(pOutlinerParaObject)
+ {
+ return pOutlinerParaObject->IsVertical();
+ }
+
+ return sal_False;
+}
+
+void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
+{
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if( !pOutlinerParaObject && bVertical )
+ {
+ // we only need to force a outliner para object if the default of
+ // horizontal text is changed
+ ForceOutlinerParaObject();
+ pOutlinerParaObject = GetOutlinerParaObject();
+ }
+
+ if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
+ {
+ // get item settings
+ const SfxItemSet& rSet = GetObjectItemSet();
+ sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
+ sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
+
+ // #103516# Also exchange hor/ver adjust items
+ SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
+ SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
+
+ // rescue object size
+ Rectangle aObjectRect = GetSnapRect();
+
+ // prepare ItemSet to set exchanged width and height items
+ SfxItemSet aNewSet(*rSet.GetPool(),
+ SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
+ // #103516# Expanded item ranges to also support hor and ver adjust.
+ SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
+ SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
+ 0, 0);
+
+ aNewSet.Put(rSet);
+ aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
+ aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
+
+ // #103516# Exchange horz and vert adjusts
+ switch(eVert)
+ {
+ case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
+ case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
+ case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
+ case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
+ }
+ switch(eHorz)
+ {
+ case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
+ case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
+ case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
+ case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
+ }
+
+ SetObjectItemSet(aNewSet);
+
+ pOutlinerParaObject = GetOutlinerParaObject();
+ if( pOutlinerParaObject )
+ {
+ // set ParaObject orientation accordingly
+ pOutlinerParaObject->SetVertical(bVertical);
+ }
+
+ // restore object size
+ SetSnapRect(aObjectRect);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// transformation interface for StarOfficeAPI. This implements support for
+// homogen 3x3 matrices containing the transformation of the SdrObject. At the
+// moment it contains a shearX, rotation and translation, but for setting all linear
+// transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
+// with the base geometry and returns TRUE. Otherwise it returns FALSE.
+sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
+{
+ // get turn and shear
+ double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
+ double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
+
+ // get aRect, this is the unrotated snaprect
+ Rectangle aRectangle(aRect);
+
+ // fill other values
+ basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
+ basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
+
+ // position maybe relative to anchorpos, convert
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // force MapUnit to 100th mm
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // postion
+ aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
+ aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplTwipsToMM(aScale.getX()));
+ aScale.setY(ImplTwipsToMM(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
+ }
+ }
+ }
+
+ // build matrix
+ rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ aScale,
+ basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
+ basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
+ aTranslate);
+
+ return sal_False;
+}
+
+// sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
+// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
+// to use (0,0) as upper left and will be scaled to the given size in the matrix.
+void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
+{
+ // break up matrix
+ basegfx::B2DTuple aScale;
+ basegfx::B2DTuple aTranslate;
+ double fRotate(0.0);
+ double fShearX(0.0);
+ rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
+ // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
+ if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
+ {
+ aScale.setX(fabs(aScale.getX()));
+ aScale.setY(fabs(aScale.getY()));
+ fRotate = fmod(fRotate + F_PI, F_2PI);
+ }
+
+ // reset object shear and rotations
+ aGeo.nDrehWink = 0;
+ aGeo.RecalcSinCos();
+ aGeo.nShearWink = 0;
+ aGeo.RecalcTan();
+
+ // force metric to pool metric
+ SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
+ if(eMapUnit != SFX_MAPUNIT_100TH_MM)
+ {
+ switch(eMapUnit)
+ {
+ case SFX_MAPUNIT_TWIP :
+ {
+ // position
+ aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
+ aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
+
+ // size
+ aScale.setX(ImplMMToTwips(aScale.getX()));
+ aScale.setY(ImplMMToTwips(aScale.getY()));
+
+ break;
+ }
+ default:
+ {
+ DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
+ }
+ }
+ }
+
+ // if anchor is used, make position relative to it
+ if( pModel && pModel->IsWriter() )
+ {
+ if(GetAnchorPos().X() || GetAnchorPos().Y())
+ {
+ aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
+ }
+ }
+
+ // build and set BaseRect (use scale)
+ Point aPoint = Point();
+ Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
+ Rectangle aBaseRect(aPoint, aSize);
+ SetSnapRect(aBaseRect);
+
+ // shear?
+ if(!basegfx::fTools::equalZero(fShearX))
+ {
+ GeoStat aGeoStat;
+ aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
+ aGeoStat.RecalcTan();
+ Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, FALSE);
+ }
+
+ // rotation?
+ if(!basegfx::fTools::equalZero(fRotate))
+ {
+ GeoStat aGeoStat;
+
+ // #i78696#
+ // fRotate is matematically correct, but aGeoStat.nDrehWink is
+ // mirrored -> mirror value here
+ aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
+ aGeoStat.RecalcSinCos();
+ Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
+ }
+
+ // translate?
+ if(!aTranslate.equalZero())
+ {
+ Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
+ }
+}
+
+bool SdrTextObj::IsRealyEdited() const
+{
+ return pEdtOutl && pEdtOutl->IsModified();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+// moved inlines here form hxx
+
+long SdrTextObj::GetEckenradius() const
+{
+ return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
+}
+
+long SdrTextObj::GetMinTextFrameHeight() const
+{
+ return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
+}
+
+long SdrTextObj::GetMaxTextFrameHeight() const
+{
+ return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
+}
+
+long SdrTextObj::GetMinTextFrameWidth() const
+{
+ return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
+}
+
+long SdrTextObj::GetMaxTextFrameWidth() const
+{
+ return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
+}
+
+FASTBOOL SdrTextObj::IsFontwork() const
+{
+ return (bTextFrame) ? FALSE // Default ist FALSE
+ : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
+}
+
+FASTBOOL SdrTextObj::IsHideContour() const
+{
+ return (bTextFrame) ? FALSE // Default ist: Nein, kein HideContour; HideContour nicht bei TextFrames
+ : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
+}
+
+FASTBOOL SdrTextObj::IsContourTextFrame() const
+{
+ return (bTextFrame) ? FALSE // ContourFrame nicht bei normalen TextFrames
+ : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
+}
+
+long SdrTextObj::GetTextLeftDistance() const
+{
+ return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
+}
+
+long SdrTextObj::GetTextRightDistance() const
+{
+ return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
+}
+
+long SdrTextObj::GetTextUpperDistance() const
+{
+ return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
+}
+
+long SdrTextObj::GetTextLowerDistance() const
+{
+ return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
+}
+
+SdrTextAniKind SdrTextObj::GetTextAniKind() const
+{
+ return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
+}
+
+SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
+{
+ return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+}
+
+// #111096#
+// Access to thext hidden flag
+sal_Bool SdrTextObj::GetTextHidden() const
+{
+ return mbTextHidden;
+}
+
+void SdrTextObj::NbcSetTextHidden(sal_Bool bNew)
+{
+ if(bNew != mbTextHidden)
+ {
+ mbTextHidden = bNew;
+ }
+}
+
+// #111096#
+// Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
+// painting rectangle. Rotation is excluded from the returned values.
+GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
+ Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
+{
+ GDIMetaFile* pRetval = 0L;
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+ Rectangle aTextRect;
+ Rectangle aAnchorRect;
+ Rectangle aPaintRect;
+ Fraction aFitXKorreg(1,1);
+ bool bContourFrame(IsContourTextFrame());
+
+ // get outliner set up. To avoid getting a somehow rotated MetaFile,
+ // temporarily disable object rotation.
+ sal_Int32 nAngle(aGeo.nDrehWink);
+ aGeo.nDrehWink = 0L;
+ ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
+ aGeo.nDrehWink = nAngle;
+
+ Rectangle aScrollFrameRect(aPaintRect);
+ const SfxItemSet& rSet = GetObjectItemSet();
+ SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
+
+ if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
+ {
+ aScrollFrameRect.Left() = aAnchorRect.Left();
+ aScrollFrameRect.Right() = aAnchorRect.Right();
+ }
+
+ if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
+ {
+ aScrollFrameRect.Top() = aAnchorRect.Top();
+ aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
+ }
+
+ // create the MetaFile
+ pRetval = new GDIMetaFile;
+ VirtualDevice aBlackHole;
+ aBlackHole.EnableOutput(sal_False);
+ pRetval->Record(&aBlackHole);
+ Point aPaintPos = aPaintRect.TopLeft();
+
+ rOutliner.Draw(&aBlackHole, aPaintPos);
+
+ pRetval->Stop();
+ pRetval->WindStart();
+
+ // return PaintRectanglePixel and pRetval;
+ rScrollRectangle = aScrollFrameRect;
+ rPaintRectangle = aPaintRect;
+
+ return pRetval;
+}
+
+// #111096#
+// Access to TextAnimationAllowed flag
+bool SdrTextObj::IsTextAnimationAllowed() const
+{
+ return mbTextAnimationAllowed;
+}
+
+void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
+{
+ if(mbTextAnimationAllowed != bNew)
+ {
+ mbTextAnimationAllowed = bNew;
+ ActionChanged();
+ }
+}
+
+/** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
+void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
+{
+ const sal_uInt32 nStat = pEditStatus->GetStatusWord();
+ const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
+ const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
+ if(bTextFrame && (bGrowX || bGrowY))
+ {
+ const bool bAutoGrowHgt= bTextFrame && IsAutoGrowHeight();
+ const bool bAutoGrowWdt= bTextFrame && IsAutoGrowWidth();
+
+ if ((bGrowX && bAutoGrowWdt) || (bGrowY && bAutoGrowHgt))
+ {
+ AdjustTextFrameWidthAndHeight();
+ }
+ }
+}
+
+/** returns the currently active text. */
+SdrText* SdrTextObj::getActiveText() const
+{
+ if( !mpText )
+ return getText( 0 );
+ else
+ return mpText;
+}
+
+/** returns the nth available text. */
+SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
+{
+ if( nIndex == 0 )
+ {
+ if( mpText == 0 )
+ const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
+ return mpText;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/** returns the number of texts available for this object. */
+sal_Int32 SdrTextObj::getTextCount() const
+{
+ return 1;
+}
+
+/** changes the current active text */
+void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
+{
+}
+
+/** returns the index of the text that contains the given point or -1 */
+sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
+{
+ return 0;
+}
+
+void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
+{
+ static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Konzept des TextObjekts:
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+// Attribute/Varianten:
+// - BOOL Textrahmen / beschriftetes Zeichenobjekt
+// - BOOL FontWork (wenn nicht Textrahmen und nicht ContourTextFrame)
+// - BOOL ContourTextFrame (wenn nicht Textrahmen und nicht Fontwork)
+// - long Drehwinkel (wenn nicht FontWork)
+// - long Textrahmenabstaende (wenn nicht FontWork)
+// - BOOL FitToSize (wenn nicht FontWork)
+// - BOOL AutoGrowingWidth/Height (wenn nicht FitToSize und nicht FontWork)
+// - long Min/MaxFrameWidth/Height (wenn AutoGrowingWidth/Height)
+// - enum Horizontale Textverankerung Links,Mitte,Rechts,Block,Stretch(ni)
+// - enum Vertikale Textverankerung Oben,Mitte,Unten,Block,Stretch(ni)
+// - enum Laufschrift (wenn nicht FontWork)
+//
+// Jedes abgeleitete Objekt ist entweder ein Textrahmen (bTextFrame=TRUE)
+// oder ein beschriftetes Zeichenobjekt (bTextFrame=FALSE).
+//
+// Defaultverankerung von Textrahmen:
+// SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
+// = statische Pooldefaults
+// Defaultverankerung von beschrifteten Zeichenobjekten:
+// SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
+// durch harte Attributierung von SdrAttrObj
+//
+// Jedes vom SdrTextObj abgeleitete Objekt muss ein "UnrotatedSnapRect"
+// (->TakeUnrotatedSnapRect()) liefern (Drehreferenz ist TopLeft dieses
+// Rechtecks (aGeo.nDrehWink)), welches die Grundlage der Textverankerung
+// bildet. Von diesem werden dann ringsum die Textrahmenabstaende abgezogen;
+// das Ergebnis ist der Ankerbereich (->TakeTextAnchorRect()). Innerhalb
+// dieses Bereichs wird dann in Abhaengigkeit von der horizontalen und
+// vertikalen Ausrichtung (SdrTextVertAdjust,SdrTextHorzAdjust) der Ankerpunkt
+// sowie der Ausgabebereich bestimmt. Bei beschrifteten Grafikobjekten kann
+// der Ausgabebereich durchaus groesser als der Ankerbereich werden, bei
+// Textrahmen ist er stets kleiner oder gleich (ausser bei negativen Textrahmen-
+// abstaenden).
+//
+// FitToSize hat Prioritaet vor Textverankerung und AutoGrowHeight/Width. Der
+// Ausgabebereich ist bei FitToSize immer genau der Ankerbereich. Weiterhin
+// gibt es bei FitToSize keinen automatischen Zeilenumbruch.
+//
+// ContourTextFrame:
+// - long Drehwinkel
+// - long Textrahmenabstaende spaeter vielleicht
+// - BOOL FitToSize spaeter vielleicht
+// - BOOL AutoGrowingWidth/Height viel spaeter vielleicht
+// - long Min/MaxFrameWidth/Height viel spaeter vielleicht
+// - enum Horizontale Textverankerung spaeter vielleicht, erstmal Links, Absatz zentr.
+// - enum Vertikale Textverankerung spaeter vielleicht, erstmal oben
+// - enum Laufschrift spaeter vielleicht (evtl. sogar mit korrektem Clipping)
+//
+// Bei Aenderungen zu beachten:
+// - Paint
+// - HitTest
+// - ConvertToPoly
+// - Edit
+// - Drucken,Speichern, Paint in Nachbarview waerend Edit
+// - ModelChanged (z.B. durch NachbarView oder Lineale) waerend Edit
+// - FillColorChanged waerend Edit
+// - uvm...
+//
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
new file mode 100644
index 000000000000..3675c7becac4
--- /dev/null
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -0,0 +1,1258 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include <svx/svdoutl.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <editeng/editstat.hxx>
+#include <vcl/salbtype.hxx>
+#include <svx/sdtfchim.hxx>
+#include <svl/itemset.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/animation/animationtiming.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <vcl/svapp.hxx>
+#include <editeng/eeitemid.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/svxenum.hxx>
+#include <editeng/flditem.hxx>
+#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
+#include <vcl/metaact.hxx>
+#include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
+#include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <unoapi.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <editeng/outlobj.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// helpers
+
+namespace
+{
+ drawinglayer::primitive2d::Primitive2DSequence impConvertVectorToPrimitive2DSequence(const std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rPrimitiveVector)
+ {
+ const sal_Int32 nCount(rPrimitiveVector.size());
+ drawinglayer::primitive2d::Primitive2DSequence aRetval(nCount);
+
+ for(sal_Int32 a(0L); a < nCount; a++)
+ {
+ aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(rPrimitiveVector[a]);
+ }
+
+ return aRetval;
+ }
+
+ class impTextBreakupHandler
+ {
+ private:
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > maTextPortionPrimitives;
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > maLinePrimitives;
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > maParagraphPrimitives;
+
+ SdrOutliner& mrOutliner;
+ basegfx::B2DHomMatrix maNewTransformA;
+ basegfx::B2DHomMatrix maNewTransformB;
+
+ // the visible area for contour text decomposition
+ basegfx::B2DVector maScale;
+
+ // #SJ# ClipRange for BlockText decomposition; only text portions completely
+ // inside are to be accepted, so this is different from geometric clipping
+ // (which would allow e.g. upper parts of portions to remain). Only used for
+ // BlockText (see there)
+ basegfx::B2DRange maClipRange;
+
+ DECL_LINK(decomposeContourTextPrimitive, DrawPortionInfo* );
+ DECL_LINK(decomposeBlockTextPrimitive, DrawPortionInfo* );
+ DECL_LINK(decomposeStretchTextPrimitive, DrawPortionInfo* );
+
+ DECL_LINK(decomposeContourBulletPrimitive, DrawBulletInfo* );
+ DECL_LINK(decomposeBlockBulletPrimitive, DrawBulletInfo* );
+ DECL_LINK(decomposeStretchBulletPrimitive, DrawBulletInfo* );
+
+ bool impIsUnderlineAbove(const Font& rFont) const;
+ void impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo);
+ drawinglayer::primitive2d::BasePrimitive2D* impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo) const;
+ void impFlushTextPortionPrimitivesToLinePrimitives();
+ void impFlushLinePrimitivesToParagraphPrimitives();
+ void impHandleDrawPortionInfo(const DrawPortionInfo& rInfo);
+ void impHandleDrawBulletInfo(const DrawBulletInfo& rInfo);
+
+ public:
+ impTextBreakupHandler(SdrOutliner& rOutliner)
+ : maTextPortionPrimitives(),
+ maLinePrimitives(),
+ maParagraphPrimitives(),
+ mrOutliner(rOutliner),
+ maNewTransformA(),
+ maNewTransformB(),
+ maScale(),
+ maClipRange()
+ {
+ }
+
+ void decomposeContourTextPrimitive(const basegfx::B2DHomMatrix& rNewTransformA, const basegfx::B2DHomMatrix& rNewTransformB, const basegfx::B2DVector& rScale)
+ {
+ maScale = rScale;
+ maNewTransformA = rNewTransformA;
+ maNewTransformB = rNewTransformB;
+ mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeContourTextPrimitive));
+ mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeContourBulletPrimitive));
+ mrOutliner.StripPortions();
+ mrOutliner.SetDrawPortionHdl(Link());
+ mrOutliner.SetDrawBulletHdl(Link());
+ }
+
+ void decomposeBlockTextPrimitive(
+ const basegfx::B2DHomMatrix& rNewTransformA,
+ const basegfx::B2DHomMatrix& rNewTransformB,
+ const basegfx::B2DRange& rClipRange)
+ {
+ maNewTransformA = rNewTransformA;
+ maNewTransformB = rNewTransformB;
+ maClipRange = rClipRange;
+ mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeBlockTextPrimitive));
+ mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeBlockBulletPrimitive));
+ mrOutliner.StripPortions();
+ mrOutliner.SetDrawPortionHdl(Link());
+ mrOutliner.SetDrawBulletHdl(Link());
+ }
+
+ void decomposeStretchTextPrimitive(const basegfx::B2DHomMatrix& rNewTransformA, const basegfx::B2DHomMatrix& rNewTransformB)
+ {
+ maNewTransformA = rNewTransformA;
+ maNewTransformB = rNewTransformB;
+ mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeStretchTextPrimitive));
+ mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeStretchBulletPrimitive));
+ mrOutliner.StripPortions();
+ mrOutliner.SetDrawPortionHdl(Link());
+ mrOutliner.SetDrawBulletHdl(Link());
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence getPrimitive2DSequence();
+ };
+
+ bool impTextBreakupHandler::impIsUnderlineAbove(const Font& rFont) const
+ {
+ if(!rFont.IsVertical())
+ {
+ return false;
+ }
+
+ if((LANGUAGE_JAPANESE == rFont.GetLanguage()) || (LANGUAGE_JAPANESE == rFont.GetCJKContextLanguage()))
+ {
+ // the underline is right for Japanese only
+ return true;
+ }
+
+ return false;
+ }
+
+ void impTextBreakupHandler::impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo)
+ {
+ if(rInfo.mrText.Len() && rInfo.mnTextLen)
+ {
+ basegfx::B2DVector aFontScaling;
+ drawinglayer::attribute::FontAttribute aFontAttribute(
+ drawinglayer::primitive2d::getFontAttributeFromVclFont(
+ aFontScaling,
+ rInfo.mrFont,
+ rInfo.IsRTL(),
+ false));
+ basegfx::B2DHomMatrix aNewTransform;
+
+ // add font scale to new transform
+ aNewTransform.scale(aFontScaling.getX(), aFontScaling.getY());
+
+ // look for proportional font scaling, evtl scale accordingly
+ if(100 != rInfo.mrFont.GetPropr())
+ {
+ const double fFactor(rInfo.mrFont.GetPropr() / 100.0);
+ aNewTransform.scale(fFactor, fFactor);
+ }
+
+ // apply font rotate
+ if(rInfo.mrFont.GetOrientation())
+ {
+ aNewTransform.rotate(-rInfo.mrFont.GetOrientation() * F_PI1800);
+ }
+
+ // look for escapement, evtl translate accordingly
+ if(rInfo.mrFont.GetEscapement())
+ {
+ sal_Int16 nEsc(rInfo.mrFont.GetEscapement());
+
+ if(DFLT_ESC_AUTO_SUPER == nEsc)
+ {
+ nEsc = 33;
+ }
+ else if(DFLT_ESC_AUTO_SUB == nEsc)
+ {
+ nEsc = -20;
+ }
+
+ if(nEsc > 100)
+ {
+ nEsc = 100;
+ }
+ else if(nEsc < -100)
+ {
+ nEsc = -100;
+ }
+
+ const double fEscapement(nEsc / -100.0);
+ aNewTransform.translate(0.0, fEscapement * aFontScaling.getY());
+ }
+
+ // apply transformA
+ aNewTransform *= maNewTransformA;
+
+ // apply local offset
+ aNewTransform.translate(rInfo.mrStartPos.X(), rInfo.mrStartPos.Y());
+
+ // also apply embedding object's transform
+ aNewTransform *= maNewTransformB;
+
+ // prepare DXArray content. To make it independent from font size (and such from
+ // the text transformation), scale it to unit coordinates
+ ::std::vector< double > aDXArray;
+ static bool bDisableTextArray(false);
+
+ if(!bDisableTextArray && rInfo.mpDXArray && rInfo.mnTextLen)
+ {
+ aDXArray.reserve(rInfo.mnTextLen);
+
+ for(xub_StrLen a(0); a < rInfo.mnTextLen; a++)
+ {
+ aDXArray.push_back((double)rInfo.mpDXArray[a]);
+ }
+ }
+
+ // create complex text primitive and append
+ const Color aFontColor(rInfo.mrFont.GetColor());
+ const basegfx::BColor aBFontColor(aFontColor.getBColor());
+
+ // prepare wordLineMode (for underline and strikeout)
+ // NOT for bullet texts. It is set (this may be an error by itself), but needs to be suppressed to hinder e.g. '1)'
+ // to be splitted which would not look like the original
+ const bool bWordLineMode(rInfo.mrFont.IsWordLineMode() && !rInfo.mbEndOfBullet);
+
+ // prepare new primitive
+ drawinglayer::primitive2d::BasePrimitive2D* pNewPrimitive = 0;
+ const bool bDecoratedIsNeeded(
+ UNDERLINE_NONE != rInfo.mrFont.GetOverline()
+ || UNDERLINE_NONE != rInfo.mrFont.GetUnderline()
+ || STRIKEOUT_NONE != rInfo.mrFont.GetStrikeout()
+ || EMPHASISMARK_NONE != (rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
+ || RELIEF_NONE != rInfo.mrFont.GetRelief()
+ || rInfo.mrFont.IsShadow()
+ || bWordLineMode);
+
+ if(bDecoratedIsNeeded)
+ {
+ // TextDecoratedPortionPrimitive2D needed, prepare some more data
+ // get overline and underline color. If it's on automatic (0xffffffff) use FontColor instead
+ const Color aUnderlineColor(rInfo.maTextLineColor);
+ const basegfx::BColor aBUnderlineColor((0xffffffff == aUnderlineColor.GetColor()) ? aBFontColor : aUnderlineColor.getBColor());
+ const Color aOverlineColor(rInfo.maOverlineColor);
+ const basegfx::BColor aBOverlineColor((0xffffffff == aOverlineColor.GetColor()) ? aBFontColor : aOverlineColor.getBColor());
+
+ // prepare overline and underline data
+ const drawinglayer::primitive2d::TextLine eFontOverline(
+ drawinglayer::primitive2d::mapFontUnderlineToTextLine(rInfo.mrFont.GetOverline()));
+ const drawinglayer::primitive2d::TextLine eFontUnderline(
+ drawinglayer::primitive2d::mapFontUnderlineToTextLine(rInfo.mrFont.GetUnderline()));
+
+ // check UndelineAbove
+ const bool bUnderlineAbove(
+ drawinglayer::primitive2d::TEXT_LINE_NONE != eFontUnderline && impIsUnderlineAbove(rInfo.mrFont));
+
+ // prepare strikeout data
+ const drawinglayer::primitive2d::TextStrikeout eTextStrikeout(
+ drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rInfo.mrFont.GetStrikeout()));
+
+ // prepare emphasis mark data
+ drawinglayer::primitive2d::TextEmphasisMark eTextEmphasisMark(drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE);
+
+ switch(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
+ {
+ case EMPHASISMARK_DOT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DOT; break;
+ case EMPHASISMARK_CIRCLE : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_CIRCLE; break;
+ case EMPHASISMARK_DISC : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DISC; break;
+ case EMPHASISMARK_ACCENT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_ACCENT; break;
+ }
+
+ const bool bEmphasisMarkAbove(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_POS_ABOVE);
+ const bool bEmphasisMarkBelow(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_POS_BELOW);
+
+ // prepare font relief data
+ drawinglayer::primitive2d::TextRelief eTextRelief(drawinglayer::primitive2d::TEXT_RELIEF_NONE);
+
+ switch(rInfo.mrFont.GetRelief())
+ {
+ case RELIEF_EMBOSSED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_EMBOSSED; break;
+ case RELIEF_ENGRAVED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_ENGRAVED; break;
+ default : break; // RELIEF_NONE, FontRelief_FORCE_EQUAL_SIZE
+ }
+
+ // prepare shadow/outline data
+ const bool bShadow(rInfo.mrFont.IsShadow());
+
+ // TextDecoratedPortionPrimitive2D is needed, create one
+ pNewPrimitive = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D(
+
+ // attributes for TextSimplePortionPrimitive2D
+ aNewTransform,
+ rInfo.mrText,
+ rInfo.mnTextStart,
+ rInfo.mnTextLen,
+ aDXArray,
+ aFontAttribute,
+ rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale(),
+ aBFontColor,
+
+ // attributes for TextDecoratedPortionPrimitive2D
+ aBOverlineColor,
+ aBUnderlineColor,
+ eFontOverline,
+ eFontUnderline,
+ bUnderlineAbove,
+ eTextStrikeout,
+ bWordLineMode,
+ eTextEmphasisMark,
+ bEmphasisMarkAbove,
+ bEmphasisMarkBelow,
+ eTextRelief,
+ bShadow);
+ }
+ else
+ {
+ // TextSimplePortionPrimitive2D is enough
+ pNewPrimitive = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aNewTransform,
+ rInfo.mrText,
+ rInfo.mnTextStart,
+ rInfo.mnTextLen,
+ aDXArray,
+ aFontAttribute,
+ rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale(),
+ aBFontColor);
+ }
+
+ if(rInfo.mbEndOfBullet)
+ {
+ // embed in TextHierarchyBulletPrimitive2D
+ const drawinglayer::primitive2d::Primitive2DReference aNewReference(pNewPrimitive);
+ const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(&aNewReference, 1);
+ pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(aNewSequence);
+ }
+
+ if(rInfo.mpFieldData)
+ {
+ pNewPrimitive = impCheckFieldPrimitive(pNewPrimitive, rInfo);
+ }
+
+ maTextPortionPrimitives.push_back(pNewPrimitive);
+
+ // support for WrongSpellVector. Create WrongSpellPrimitives as needed
+ if(rInfo.mpWrongSpellVector && !aDXArray.empty())
+ {
+ const sal_uInt32 nSize(rInfo.mpWrongSpellVector->size());
+ const sal_uInt32 nDXCount(aDXArray.size());
+ const basegfx::BColor aSpellColor(1.0, 0.0, 0.0); // red, hard coded
+
+ for(sal_uInt32 a(0); a < nSize; a++)
+ {
+ const EEngineData::WrongSpellClass& rCandidate = (*rInfo.mpWrongSpellVector)[a];
+
+ if(rCandidate.nStart >= rInfo.mnTextStart && rCandidate.nEnd >= rInfo.mnTextStart && rCandidate.nEnd > rCandidate.nStart)
+ {
+ const sal_uInt32 nStart(rCandidate.nStart - rInfo.mnTextStart);
+ const sal_uInt32 nEnd(rCandidate.nEnd - rInfo.mnTextStart);
+ double fStart(0.0);
+ double fEnd(0.0);
+
+ if(nStart > 0 && nStart - 1 < nDXCount)
+ {
+ fStart = aDXArray[nStart - 1];
+ }
+
+ if(nEnd > 0 && nEnd - 1 < nDXCount)
+ {
+ fEnd = aDXArray[nEnd - 1];
+ }
+
+ if(!basegfx::fTools::equal(fStart, fEnd))
+ {
+ if(rInfo.IsRTL())
+ {
+ // #i98523#
+ // When the portion is RTL, mirror the redlining using the
+ // full portion width
+ const double fTextWidth(aDXArray[aDXArray.size() - 1]);
+
+ fStart = fTextWidth - fStart;
+ fEnd = fTextWidth - fEnd;
+ }
+
+ // need to take FontScaling out of values; it's already part of
+ // aNewTransform and would be double applied
+ const double fFontScaleX(aFontScaling.getX());
+
+ if(!basegfx::fTools::equal(fFontScaleX, 1.0)
+ && !basegfx::fTools::equalZero(fFontScaleX))
+ {
+ fStart /= fFontScaleX;
+ fEnd /= fFontScaleX;
+ }
+
+ maTextPortionPrimitives.push_back(new drawinglayer::primitive2d::WrongSpellPrimitive2D(
+ aNewTransform,
+ fStart,
+ fEnd,
+ aSpellColor));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ drawinglayer::primitive2d::BasePrimitive2D* impTextBreakupHandler::impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo) const
+ {
+ if(rInfo.mpFieldData)
+ {
+ // Support for FIELD_SEQ_BEGIN, FIELD_SEQ_END. If used, create a TextHierarchyFieldPrimitive2D
+ // which holds the field type and evtl. the URL
+ const SvxURLField* pURLField = dynamic_cast< const SvxURLField* >(rInfo.mpFieldData);
+ const SvxPageField* pPageField = dynamic_cast< const SvxPageField* >(rInfo.mpFieldData);
+
+ // embed current primitive to a sequence
+ drawinglayer::primitive2d::Primitive2DSequence aSequence;
+
+ if(pPrimitive)
+ {
+ aSequence.realloc(1);
+ aSequence[0] = drawinglayer::primitive2d::Primitive2DReference(pPrimitive);
+ }
+
+ if(pURLField)
+ {
+ pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_URL, pURLField->GetURL());
+ }
+ else if(pPageField)
+ {
+ pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_PAGE, String());
+ }
+ else
+ {
+ pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_COMMON, String());
+ }
+ }
+
+ return pPrimitive;
+ }
+
+ void impTextBreakupHandler::impFlushTextPortionPrimitivesToLinePrimitives()
+ {
+ // only create a line primitive when we had content; there is no need for
+ // empty line primitives (contrary to paragraphs, see below).
+ if(maTextPortionPrimitives.size())
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aLineSequence(impConvertVectorToPrimitive2DSequence(maTextPortionPrimitives));
+ maTextPortionPrimitives.clear();
+ maLinePrimitives.push_back(new drawinglayer::primitive2d::TextHierarchyLinePrimitive2D(aLineSequence));
+ }
+ }
+
+ void impTextBreakupHandler::impFlushLinePrimitivesToParagraphPrimitives()
+ {
+ // ALWAYS create a paragraph primitive, even when no content was added. This is done to
+ // have the correct paragraph count even with empty paragraphs. Those paragraphs will
+ // have an empty sub-PrimitiveSequence.
+ drawinglayer::primitive2d::Primitive2DSequence aParagraphSequence(impConvertVectorToPrimitive2DSequence(maLinePrimitives));
+ maLinePrimitives.clear();
+ maParagraphPrimitives.push_back(new drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D(aParagraphSequence));
+ }
+
+ void impTextBreakupHandler::impHandleDrawPortionInfo(const DrawPortionInfo& rInfo)
+ {
+ impCreateTextPortionPrimitive(rInfo);
+
+ if(rInfo.mbEndOfLine || rInfo.mbEndOfParagraph)
+ {
+ impFlushTextPortionPrimitivesToLinePrimitives();
+ }
+
+ if(rInfo.mbEndOfParagraph)
+ {
+ impFlushLinePrimitivesToParagraphPrimitives();
+ }
+ }
+
+ void impTextBreakupHandler::impHandleDrawBulletInfo(const DrawBulletInfo& rInfo)
+ {
+ basegfx::B2DHomMatrix aNewTransform;
+
+ // add size to new transform
+ aNewTransform.scale(rInfo.maBulletSize.getWidth(), rInfo.maBulletSize.getHeight());
+
+ // apply transformA
+ aNewTransform *= maNewTransformA;
+
+ // apply local offset
+ aNewTransform.translate(rInfo.maBulletPosition.X(), rInfo.maBulletPosition.Y());
+
+ // also apply embedding object's transform
+ aNewTransform *= maNewTransformB;
+
+ // prepare empty GraphicAttr
+ const GraphicAttr aGraphicAttr;
+
+ // create GraphicPrimitive2D
+ const drawinglayer::primitive2d::Primitive2DReference aNewReference(new drawinglayer::primitive2d::GraphicPrimitive2D(
+ aNewTransform,
+ rInfo.maBulletGraphicObject,
+ aGraphicAttr));
+
+ // embed in TextHierarchyBulletPrimitive2D
+ const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(&aNewReference, 1);
+ drawinglayer::primitive2d::BasePrimitive2D* pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(aNewSequence);
+
+ // add to output
+ maTextPortionPrimitives.push_back(pNewPrimitive);
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeContourTextPrimitive, DrawPortionInfo*, pInfo)
+ {
+ // for contour text, ignore (clip away) all portions which are below
+ // the visible area given by maScale
+ if(pInfo && (double)pInfo->mrStartPos.Y() < maScale.getY())
+ {
+ impHandleDrawPortionInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeBlockTextPrimitive, DrawPortionInfo*, pInfo)
+ {
+ if(pInfo)
+ {
+ // #SJ# Is clipping wanted? This is text clipping; only accept a portion
+ // if it's completely in the range
+ if(!maClipRange.isEmpty())
+ {
+ // Test start position first; this allows to not get the text range at
+ // all if text is far outside
+ const basegfx::B2DPoint aStartPosition(pInfo->mrStartPos.X(), pInfo->mrStartPos.Y());
+
+ if(!maClipRange.isInside(aStartPosition))
+ {
+ return 0;
+ }
+
+ // Start position is inside. Get TextBoundRect and TopLeft next
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
+ aTextLayouterDevice.setFont(pInfo->mrFont);
+
+ const basegfx::B2DRange aTextBoundRect(
+ aTextLayouterDevice.getTextBoundRect(
+ pInfo->mrText, pInfo->mnTextStart, pInfo->mnTextLen));
+ const basegfx::B2DPoint aTopLeft(aTextBoundRect.getMinimum() + aStartPosition);
+
+ if(!maClipRange.isInside(aTopLeft))
+ {
+ return 0;
+ }
+
+ // TopLeft is inside. Get BottomRight and check
+ const basegfx::B2DPoint aBottomRight(aTextBoundRect.getMaximum() + aStartPosition);
+
+ if(!maClipRange.isInside(aBottomRight))
+ {
+ return 0;
+ }
+
+ // all inside, clip was successful
+ }
+ impHandleDrawPortionInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeStretchTextPrimitive, DrawPortionInfo*, pInfo)
+ {
+ if(pInfo)
+ {
+ impHandleDrawPortionInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeContourBulletPrimitive, DrawBulletInfo*, pInfo)
+ {
+ if(pInfo)
+ {
+ impHandleDrawBulletInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeBlockBulletPrimitive, DrawBulletInfo*, pInfo)
+ {
+ if(pInfo)
+ {
+ impHandleDrawBulletInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ IMPL_LINK(impTextBreakupHandler, decomposeStretchBulletPrimitive, DrawBulletInfo*, pInfo)
+ {
+ if(pInfo)
+ {
+ impHandleDrawBulletInfo(*pInfo);
+ }
+
+ return 0;
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence impTextBreakupHandler::getPrimitive2DSequence()
+ {
+ if(maTextPortionPrimitives.size())
+ {
+ // collect non-closed lines
+ impFlushTextPortionPrimitivesToLinePrimitives();
+ }
+
+ if(maLinePrimitives.size())
+ {
+ // collect non-closed paragraphs
+ impFlushLinePrimitivesToParagraphPrimitives();
+ }
+
+ return impConvertVectorToPrimitive2DSequence(maParagraphPrimitives);
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// primitive decompositions
+
+void SdrTextObj::impDecomposeContourTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrContourTextPrimitive2D& rSdrContourTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
+{
+ // decompose matrix to have position and size of text
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ rSdrContourTextPrimitive.getObjectTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // prepare contour polygon, force to non-mirrored for layouting
+ basegfx::B2DPolyPolygon aPolyPolygon(rSdrContourTextPrimitive.getUnitPolyPolygon());
+ aPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(fabs(aScale.getX()), fabs(aScale.getY())));
+
+ // prepare outliner
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+ const Size aNullSize;
+ rOutliner.SetPaperSize(aNullSize);
+ rOutliner.SetPolygon(aPolyPolygon);
+ rOutliner.SetUpdateMode(true);
+ rOutliner.SetText(rSdrContourTextPrimitive.getOutlinerParaObject());
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+
+ // prepare matrices to apply to newly created primitives
+ basegfx::B2DHomMatrix aNewTransformA;
+
+ // mirroring. We are now in the polygon sizes. When mirroring in X and Y,
+ // move the null point which was top left to bottom right.
+ const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
+ const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
+
+ // in-between the translations of the single primitives will take place. Afterwards,
+ // the object's transformations need to be applied
+ const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
+ fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
+
+ // now break up text primitives.
+ impTextBreakupHandler aConverter(rOutliner);
+ aConverter.decomposeContourTextPrimitive(aNewTransformA, aNewTransformB, aScale);
+
+ // cleanup outliner
+ rOutliner.Clear();
+ rOutliner.setVisualizedPage(0);
+
+ rTarget = aConverter.getPrimitive2DSequence();
+}
+
+void SdrTextObj::impDecomposeBlockTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrBlockTextPrimitive2D& rSdrBlockTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
+{
+ // decompose matrix to have position and size of text
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ rSdrBlockTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // use B2DRange aAnchorTextRange for calculations
+ basegfx::B2DRange aAnchorTextRange(aTranslate);
+ aAnchorTextRange.expand(aTranslate + aScale);
+
+ // prepare outliner
+ const bool bIsCell(rSdrBlockTextPrimitive.getCellText());
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+ SdrTextHorzAdjust eHAdj = rSdrBlockTextPrimitive.getSdrTextHorzAdjust();
+ SdrTextVertAdjust eVAdj = rSdrBlockTextPrimitive.getSdrTextVertAdjust();
+ const sal_uInt32 nOriginalControlWord(rOutliner.GetControlWord());
+ const Size aNullSize;
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+ rOutliner.SetFixedCellHeight(rSdrBlockTextPrimitive.isFixedCellHeight());
+ rOutliner.SetControlWord(nOriginalControlWord|EE_CNTRL_AUTOPAGESIZE);
+ rOutliner.SetMinAutoPaperSize(aNullSize);
+ rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
+
+ // add one to rage sizes to get back to the old Rectangle and outliner measurements
+ const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1L));
+ const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1L));
+ const bool bVerticalWritintg(rSdrBlockTextPrimitive.getOutlinerParaObject().IsVertical());
+ const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight));
+
+ if(bIsCell)
+ {
+ // cell text is formated neither like a text object nor like a object
+ // text, so use a special setup here
+ rOutliner.SetMaxAutoPaperSize(aAnchorTextSize);
+
+ // #i106214# To work with an unchangeable PaperSize (CellSize in
+ // this case) Set(Min|Max)AutoPaperSize and SetPaperSize have to be used.
+ // #i106214# This was not completely correct; to still measure the real
+ // text height to allow vertical adjust (and vice versa for VerticalWritintg)
+ // only one aspect has to be set, but the other one to zero
+ if(bVerticalWritintg)
+ {
+ // measure the horizontal text size
+ rOutliner.SetMinAutoPaperSize(Size(0, aAnchorTextSize.Height()));
+ }
+ else
+ {
+ // measure the vertical text size
+ rOutliner.SetMinAutoPaperSize(Size(aAnchorTextSize.Width(), 0));
+ }
+
+ rOutliner.SetPaperSize(aAnchorTextSize);
+ rOutliner.SetUpdateMode(true);
+ rOutliner.SetText(rSdrBlockTextPrimitive.getOutlinerParaObject());
+ }
+ else
+ {
+ // check if block text is used (only one of them can be true)
+ const bool bHorizontalIsBlock(SDRTEXTHORZADJUST_BLOCK == eHAdj && !bVerticalWritintg);
+ const bool bVerticalIsBlock(SDRTEXTVERTADJUST_BLOCK == eVAdj && bVerticalWritintg);
+
+ // set minimal paper size hor/ver if needed
+ if(bHorizontalIsBlock)
+ {
+ rOutliner.SetMinAutoPaperSize(Size(nAnchorTextWidth, 0));
+ }
+ else if(bVerticalIsBlock)
+ {
+ rOutliner.SetMinAutoPaperSize(Size(0, nAnchorTextHeight));
+ }
+
+ if((rSdrBlockTextPrimitive.getWordWrap() || IsTextFrame()) && !rSdrBlockTextPrimitive.getUnlimitedPage())
+ {
+ // #i103454# maximal paper size hor/ver needs to be limited to text
+ // frame size. If it's block text, still allow the 'other' direction
+ // to grow to get a correct real text size when using GetPaperSize().
+ // When just using aAnchorTextSize as maximum, GetPaperSize()
+ // would just return aAnchorTextSize again: this means, the wanted
+ // 'measurement' of the real size of block text would not work
+ Size aMaxAutoPaperSize(aAnchorTextSize);
+
+ if(bHorizontalIsBlock)
+ {
+ // allow to grow vertical for horizontal blocks
+ aMaxAutoPaperSize.setHeight(1000000);
+ }
+ else if(bVerticalIsBlock)
+ {
+ // allow to grow horizontal for vertical blocks
+ aMaxAutoPaperSize.setWidth(1000000);
+ }
+
+ rOutliner.SetMaxAutoPaperSize(aMaxAutoPaperSize);
+ }
+
+ rOutliner.SetPaperSize(aNullSize);
+ rOutliner.SetUpdateMode(true);
+ rOutliner.SetText(rSdrBlockTextPrimitive.getOutlinerParaObject());
+ }
+
+ rOutliner.SetControlWord(nOriginalControlWord);
+
+ // now get back the layouted text size from outliner
+ const Size aOutlinerTextSiz(rOutliner.GetPaperSize());
+ const basegfx::B2DVector aOutlinerScale(aOutlinerTextSiz.Width(), aOutlinerTextSiz.Height());
+ basegfx::B2DVector aAdjustTranslate(0.0, 0.0);
+
+ // For draw objects containing text correct hor/ver alignment if text is bigger
+ // than the object itself. Without that correction, the text would always be
+ // formatted to the left edge (or top edge when vertical) of the draw object.
+ if(!IsTextFrame() && !bIsCell)
+ {
+ if(aAnchorTextRange.getWidth() < aOutlinerScale.getX() && !bVerticalWritintg)
+ {
+ // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
+ {
+ eHAdj = SDRTEXTHORZADJUST_CENTER;
+ }
+ }
+
+ if(aAnchorTextRange.getHeight() < aOutlinerScale.getY() && bVerticalWritintg)
+ {
+ // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
+ // else the alignment is wanted.
+ if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
+ {
+ eVAdj = SDRTEXTVERTADJUST_CENTER;
+ }
+ }
+ }
+
+ // correct horizontal translation using the now known text size
+ if(SDRTEXTHORZADJUST_CENTER == eHAdj || SDRTEXTHORZADJUST_RIGHT == eHAdj)
+ {
+ const double fFree(aAnchorTextRange.getWidth() - aOutlinerScale.getX());
+
+ if(SDRTEXTHORZADJUST_CENTER == eHAdj)
+ {
+ aAdjustTranslate.setX(fFree / 2.0);
+ }
+
+ if(SDRTEXTHORZADJUST_RIGHT == eHAdj)
+ {
+ aAdjustTranslate.setX(fFree);
+ }
+ }
+
+ // correct vertical translation using the now known text size
+ if(SDRTEXTVERTADJUST_CENTER == eVAdj || SDRTEXTVERTADJUST_BOTTOM == eVAdj)
+ {
+ const double fFree(aAnchorTextRange.getHeight() - aOutlinerScale.getY());
+
+ if(SDRTEXTVERTADJUST_CENTER == eVAdj)
+ {
+ aAdjustTranslate.setY(fFree / 2.0);
+ }
+
+ if(SDRTEXTVERTADJUST_BOTTOM == eVAdj)
+ {
+ aAdjustTranslate.setY(fFree);
+ }
+ }
+
+ // prepare matrices to apply to newly created primitives. aNewTransformA
+ // will get coordinates in aOutlinerScale size and positive in X, Y.
+ // Translate relative to given primitive to get same rotation and shear
+ // as the master shape we are working on. For vertical, use the top-right
+ // corner
+ const double fStartInX(bVerticalWritintg ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX());
+ const basegfx::B2DTuple aAdjOffset(fStartInX, aAdjustTranslate.getY());
+ basegfx::B2DHomMatrix aNewTransformA(basegfx::tools::createTranslateB2DHomMatrix(aAdjOffset.getX(), aAdjOffset.getY()));
+
+ // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
+ // move the null point which was top left to bottom right.
+ const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
+ const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
+
+ // in-between the translations of the single primitives will take place. Afterwards,
+ // the object's transformations need to be applied
+ const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
+ fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
+
+ // #SJ# create ClipRange (if needed)
+ basegfx::B2DRange aClipRange;
+
+ if(rSdrBlockTextPrimitive.getClipOnBounds())
+ {
+ aClipRange.expand(-aAdjOffset);
+ aClipRange.expand(basegfx::B2DTuple(aAnchorTextSize.Width(), aAnchorTextSize.Height()) - aAdjOffset);
+ }
+
+ // now break up text primitives.
+ impTextBreakupHandler aConverter(rOutliner);
+ aConverter.decomposeBlockTextPrimitive(aNewTransformA, aNewTransformB, aClipRange);
+
+ // cleanup outliner
+ rOutliner.Clear();
+ rOutliner.setVisualizedPage(0);
+
+ rTarget = aConverter.getPrimitive2DSequence();
+}
+
+void SdrTextObj::impDecomposeStretchTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrStretchTextPrimitive2D& rSdrStretchTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
+{
+ // decompose matrix to have position and size of text
+ basegfx::B2DVector aScale, aTranslate;
+ double fRotate, fShearX;
+ rSdrStretchTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
+
+ // use non-mirrored B2DRange aAnchorTextRange for calculations
+ basegfx::B2DRange aAnchorTextRange(aTranslate);
+ aAnchorTextRange.expand(aTranslate + aScale);
+
+ // prepare outliner
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+ const sal_uInt32 nOriginalControlWord(rOutliner.GetControlWord());
+ const Size aNullSize;
+
+ rOutliner.SetControlWord(nOriginalControlWord|EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
+ rOutliner.SetFixedCellHeight(rSdrStretchTextPrimitive.isFixedCellHeight());
+ rOutliner.SetMinAutoPaperSize(aNullSize);
+ rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
+ rOutliner.SetPaperSize(aNullSize);
+ rOutliner.SetUpdateMode(true);
+ rOutliner.SetText(rSdrStretchTextPrimitive.getOutlinerParaObject());
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+
+ // now get back the layouted text size from outliner
+ const Size aOutlinerTextSiz(rOutliner.CalcTextSize());
+ const basegfx::B2DVector aOutlinerScale(
+ basegfx::fTools::equalZero(aOutlinerTextSiz.Width()) ? 1.0 : aOutlinerTextSiz.Width(),
+ basegfx::fTools::equalZero(aOutlinerTextSiz.Height()) ? 1.0 : aOutlinerTextSiz.Height());
+
+ // prepare matrices to apply to newly created primitives
+ basegfx::B2DHomMatrix aNewTransformA;
+
+ // #i101957# Check for vertical text. If used, aNewTransformA
+ // needs to translate the text initially around object width to orient
+ // it relative to the topper right instead of the topper left
+ const bool bVertical(rSdrStretchTextPrimitive.getOutlinerParaObject().IsVertical());
+
+ if(bVertical)
+ {
+ aNewTransformA.translate(aScale.getX(), 0.0);
+ }
+
+ // calculate global char stretching scale parameters. Use non-mirrored sizes
+ // to layout without mirroring
+ const double fScaleX(fabs(aScale.getX()) / aOutlinerScale.getX());
+ const double fScaleY(fabs(aScale.getY()) / aOutlinerScale.getY());
+ rOutliner.SetGlobalCharStretching((sal_Int16)FRound(fScaleX * 100.0), (sal_Int16)FRound(fScaleY * 100.0));
+
+ // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
+ // move the null point which was top left to bottom right.
+ const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
+ const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
+
+ // in-between the translations of the single primitives will take place. Afterwards,
+ // the object's transformations need to be applied
+ const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
+ bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
+ fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
+
+ // now break up text primitives.
+ impTextBreakupHandler aConverter(rOutliner);
+ aConverter.decomposeStretchTextPrimitive(aNewTransformA, aNewTransformB);
+
+ // cleanup outliner
+ rOutliner.SetControlWord(nOriginalControlWord);
+ rOutliner.Clear();
+ rOutliner.setVisualizedPage(0);
+
+ rTarget = aConverter.getPrimitive2DSequence();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// timing generators
+#define ENDLESS_LOOP (0xffffffff)
+#define ENDLESS_TIME ((double)0xffffffff)
+#define PIXEL_DPI (96.0)
+
+void SdrTextObj::impGetBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const
+{
+ if(SDRTEXTANI_BLINK == GetTextAniKind())
+ {
+ // get values
+ const SfxItemSet& rSet = GetObjectItemSet();
+ const sal_uInt32 nRepeat((sal_uInt32)((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
+ bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
+ double fDelay((double)((SdrTextAniDelayItem&)rSet.Get(SDRATTR_TEXT_ANIDELAY)).GetValue());
+
+ if(0.0 == fDelay)
+ {
+ // use default
+ fDelay = 250.0;
+ }
+
+ // prepare loop and add
+ drawinglayer::animation::AnimationEntryLoop aLoop(nRepeat ? nRepeat : ENDLESS_LOOP);
+ drawinglayer::animation::AnimationEntryFixed aStart(fDelay, 0.0);
+ aLoop.append(aStart);
+ drawinglayer::animation::AnimationEntryFixed aEnd(fDelay, 1.0);
+ aLoop.append(aEnd);
+ rAnimList.append(aLoop);
+
+ // add stopped state if loop is not endless
+ if(0L != nRepeat)
+ {
+ drawinglayer::animation::AnimationEntryFixed aStop(ENDLESS_TIME, bVisisbleWhenStopped ? 0.0 : 1.0);
+ rAnimList.append(aStop);
+ }
+ }
+}
+
+void impCreateScrollTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, bool bForward, double fTimeFullPath, double fFrequency)
+{
+ bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
+ bool bVisisbleWhenStarted(((SdrTextAniStartInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE )).GetValue());
+ const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
+
+ if(bVisisbleWhenStarted)
+ {
+ // move from center to outside
+ drawinglayer::animation::AnimationEntryLinear aInOut(fTimeFullPath * 0.5, fFrequency, 0.5, bForward ? 1.0 : 0.0);
+ rAnimList.append(aInOut);
+ }
+
+ // loop. In loop, move through
+ if(nRepeat || 0L == nRepeat)
+ {
+ drawinglayer::animation::AnimationEntryLoop aLoop(nRepeat ? nRepeat : ENDLESS_LOOP);
+ drawinglayer::animation::AnimationEntryLinear aThrough(fTimeFullPath, fFrequency, bForward ? 0.0 : 1.0, bForward ? 1.0 : 0.0);
+ aLoop.append(aThrough);
+ rAnimList.append(aLoop);
+ }
+
+ if(0L != nRepeat && bVisisbleWhenStopped)
+ {
+ // move from outside to center
+ drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, bForward ? 0.0 : 1.0, 0.5);
+ rAnimList.append(aOutIn);
+
+ // add timing for staying at the end
+ drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
+ rAnimList.append(aEnd);
+ }
+}
+
+void impCreateAlternateTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, double fRelativeTextLength, bool bForward, double fTimeFullPath, double fFrequency)
+{
+ if(basegfx::fTools::more(fRelativeTextLength, 0.5))
+ {
+ // this is the case when fTextLength > fFrameLength, text is bigger than animation frame.
+ // In that case, correct direction
+ bForward = !bForward;
+ }
+
+ const double fStartPosition(bForward ? fRelativeTextLength : 1.0 - fRelativeTextLength);
+ const double fEndPosition(bForward ? 1.0 - fRelativeTextLength : fRelativeTextLength);
+ bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
+ bool bVisisbleWhenStarted(((SdrTextAniStartInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE )).GetValue());
+ const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
+
+ if(!bVisisbleWhenStarted)
+ {
+ // move from outside to center
+ drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, bForward ? 0.0 : 1.0, 0.5);
+ rAnimList.append(aOutIn);
+ }
+
+ // loop. In loop, move out and in again. fInnerMovePath may be negative when text is bigger then frame,
+ // so use absolute value
+ const double fInnerMovePath(fabs(1.0 - (fRelativeTextLength * 2.0)));
+ const double fTimeForInnerPath(fTimeFullPath * fInnerMovePath);
+ const double fHalfInnerPath(fTimeForInnerPath * 0.5);
+ const sal_uInt32 nDoubleRepeat(nRepeat / 2L);
+
+ if(nDoubleRepeat || 0L == nRepeat)
+ {
+ // double forth and back loop
+ drawinglayer::animation::AnimationEntryLoop aLoop(nDoubleRepeat ? nDoubleRepeat : ENDLESS_LOOP);
+ drawinglayer::animation::AnimationEntryLinear aTime0(fHalfInnerPath, fFrequency, 0.5, fEndPosition);
+ aLoop.append(aTime0);
+ drawinglayer::animation::AnimationEntryLinear aTime1(fTimeForInnerPath, fFrequency, fEndPosition, fStartPosition);
+ aLoop.append(aTime1);
+ drawinglayer::animation::AnimationEntryLinear aTime2(fHalfInnerPath, fFrequency, fStartPosition, 0.5);
+ aLoop.append(aTime2);
+ rAnimList.append(aLoop);
+ }
+
+ if(nRepeat % 2L)
+ {
+ // repeat is uneven, so we need one more forth and back to center
+ drawinglayer::animation::AnimationEntryLinear aTime0(fHalfInnerPath, fFrequency, 0.5, fEndPosition);
+ rAnimList.append(aTime0);
+ drawinglayer::animation::AnimationEntryLinear aTime1(fHalfInnerPath, fFrequency, fEndPosition, 0.5);
+ rAnimList.append(aTime1);
+ }
+
+ if(0L != nRepeat)
+ {
+ if(bVisisbleWhenStopped)
+ {
+ // add timing for staying at the end
+ drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
+ rAnimList.append(aEnd);
+ }
+ else
+ {
+ // move from center to outside
+ drawinglayer::animation::AnimationEntryLinear aInOut(fTimeFullPath * 0.5, fFrequency, 0.5, bForward ? 1.0 : 0.0);
+ rAnimList.append(aInOut);
+ }
+ }
+}
+
+void impCreateSlideTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, bool bForward, double fTimeFullPath, double fFrequency)
+{
+ // move in from outside, start outside
+ const double fStartPosition(bForward ? 0.0 : 1.0);
+ const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
+
+ // move from outside to center
+ drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, fStartPosition, 0.5);
+ rAnimList.append(aOutIn);
+
+ // loop. In loop, move out and in again
+ if(nRepeat > 1L || 0L == nRepeat)
+ {
+ drawinglayer::animation::AnimationEntryLoop aLoop(nRepeat ? nRepeat - 1L : ENDLESS_LOOP);
+ drawinglayer::animation::AnimationEntryLinear aTime0(fTimeFullPath * 0.5, fFrequency, 0.5, fStartPosition);
+ aLoop.append(aTime0);
+ drawinglayer::animation::AnimationEntryLinear aTime1(fTimeFullPath * 0.5, fFrequency, fStartPosition, 0.5);
+ aLoop.append(aTime1);
+ rAnimList.append(aLoop);
+ }
+
+ // always visible when stopped, so add timing for staying at the end when not endless
+ if(0L != nRepeat)
+ {
+ drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
+ rAnimList.append(aEnd);
+ }
+}
+
+void SdrTextObj::impGetScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const
+{
+ const SdrTextAniKind eAniKind(GetTextAniKind());
+
+ if(SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind)
+ {
+ // get data. Goal is to calculate fTimeFullPath which is the time needed to
+ // move animation from (0.0) to (1.0) state
+ const SfxItemSet& rSet = GetObjectItemSet();
+ double fAnimationDelay((double)((SdrTextAniDelayItem&)rSet.Get(SDRATTR_TEXT_ANIDELAY)).GetValue());
+ double fSingleStepWidth((double)((SdrTextAniAmountItem&)rSet.Get(SDRATTR_TEXT_ANIAMOUNT)).GetValue());
+ const SdrTextAniDirection eDirection(GetTextAniDirection());
+ const bool bForward(SDRTEXTANI_RIGHT == eDirection || SDRTEXTANI_DOWN == eDirection);
+
+ if(basegfx::fTools::equalZero(fAnimationDelay))
+ {
+ // default to 1/20 second
+ fAnimationDelay = 50.0;
+ }
+
+ if(basegfx::fTools::less(fSingleStepWidth, 0.0))
+ {
+ // data is in pixels, convert to logic. Imply PIXEL_DPI dpi.
+ // It makes no sense to keep the view-transformation centered
+ // definitions, so get rid of them here.
+ fSingleStepWidth = (-fSingleStepWidth * (2540.0 / PIXEL_DPI));
+ }
+
+ if(basegfx::fTools::equalZero(fSingleStepWidth))
+ {
+ // default to 1 milimeter
+ fSingleStepWidth = 100.0;
+ }
+
+ // use the length of the full animation path and the number of steps
+ // to get the full path time
+ const double fFullPathLength(fFrameLength + fTextLength);
+ const double fNumberOfSteps(fFullPathLength / fSingleStepWidth);
+ double fTimeFullPath(fNumberOfSteps * fAnimationDelay);
+
+ if(fTimeFullPath < fAnimationDelay)
+ {
+ fTimeFullPath = fAnimationDelay;
+ }
+
+ switch(eAniKind)
+ {
+ case SDRTEXTANI_SCROLL :
+ {
+ impCreateScrollTiming(rSet, rAnimList, bForward, fTimeFullPath, fAnimationDelay);
+ break;
+ }
+ case SDRTEXTANI_ALTERNATE :
+ {
+ double fRelativeTextLength(fTextLength / (fFrameLength + fTextLength));
+ impCreateAlternateTiming(rSet, rAnimList, fRelativeTextLength, bForward, fTimeFullPath, fAnimationDelay);
+ break;
+ }
+ case SDRTEXTANI_SLIDE :
+ {
+ impCreateSlideTiming(rSet, rAnimList, bForward, fTimeFullPath, fAnimationDelay);
+ break;
+ }
+ default : break; // SDRTEXTANI_NONE, SDRTEXTANI_BLINK
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdotextpathdecomposition.cxx b/svx/source/svdraw/svdotextpathdecomposition.cxx
new file mode 100644
index 000000000000..031e8e9dd45b
--- /dev/null
+++ b/svx/source/svdraw/svdotextpathdecomposition.cxx
@@ -0,0 +1,824 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include <svx/svdoutl.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <vcl/salbtype.hxx>
+#include <svl/itemset.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <algorithm>
+#include <svx/xtextit.hxx>
+#include <svx/xftshtit.hxx>
+#include <vcl/virdev.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/CharacterIteratorMode.hdl>
+#include <editeng/unolingu.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
+#include <drawinglayer/primitive2d/textprimitive2d.hxx>
+#include <basegfx/color/bcolor.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// primitive decomposition helpers
+
+#include <basegfx/polygon/b2dlinegeometry.hxx>
+#include <drawinglayer/attribute/strokeattribute.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlndsit.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <editeng/editstat.hxx>
+#include <unoapi.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::i18n;
+
+//////////////////////////////////////////////////////////////////////////////
+// PathTextPortion helper
+
+namespace
+{
+ class impPathTextPortion
+ {
+ basegfx::B2DVector maOffset;
+ String maText;
+ xub_StrLen mnTextStart;
+ xub_StrLen mnTextLength;
+ sal_uInt16 mnParagraph;
+ xub_StrLen mnIndex;
+ SvxFont maFont;
+ ::std::vector< double > maDblDXArray; // double DXArray, font size independent -> unit coordinate system
+ ::com::sun::star::lang::Locale maLocale;
+
+ // bitfield
+ unsigned mbRTL : 1;
+
+ public:
+ impPathTextPortion(DrawPortionInfo& rInfo)
+ : maOffset(rInfo.mrStartPos.X(), rInfo.mrStartPos.Y()),
+ maText(rInfo.mrText),
+ mnTextStart(rInfo.mnTextStart),
+ mnTextLength(rInfo.mnTextLen),
+ mnParagraph(rInfo.mnPara),
+ mnIndex(rInfo.mnIndex),
+ maFont(rInfo.mrFont),
+ maDblDXArray(),
+ maLocale(rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale()),
+ mbRTL(rInfo.mrFont.IsVertical() ? false : rInfo.IsRTL())
+ {
+ if(mnTextLength && rInfo.mpDXArray)
+ {
+ maDblDXArray.reserve(mnTextLength);
+
+ for(xub_StrLen a(0); a < mnTextLength; a++)
+ {
+ maDblDXArray.push_back((double)rInfo.mpDXArray[a]);
+ }
+ }
+ }
+
+ // for ::std::sort
+ bool operator<(const impPathTextPortion& rComp) const
+ {
+ if(mnParagraph < rComp.mnParagraph)
+ {
+ return true;
+ }
+
+ if(maOffset.getX() < rComp.maOffset.getX())
+ {
+ return true;
+ }
+
+ return (maOffset.getY() < rComp.maOffset.getY());
+ }
+
+ const basegfx::B2DVector& getOffset() const { return maOffset; }
+ const String& getText() const { return maText; }
+ xub_StrLen getTextStart() const { return mnTextStart; }
+ xub_StrLen getTextLength() const { return mnTextLength; }
+ sal_uInt16 getParagraph() const { return mnParagraph; }
+ xub_StrLen getIndex() const { return mnIndex; }
+ const SvxFont& getFont() const { return maFont; }
+ bool isRTL() const { return mbRTL; }
+ const ::std::vector< double >& getDoubleDXArray() const { return maDblDXArray; }
+ const ::com::sun::star::lang::Locale& getLocale() const { return maLocale; }
+
+ xub_StrLen getPortionIndex(xub_StrLen nIndex, xub_StrLen nLength) const
+ {
+ if(mbRTL)
+ {
+ return (mnTextStart + (mnTextLength - (nIndex + nLength)));
+ }
+ else
+ {
+ return (mnTextStart + nIndex);
+ }
+ }
+
+ double getDisplayLength(xub_StrLen nIndex, xub_StrLen nLength) const
+ {
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
+ double fRetval(0.0);
+
+ if(maFont.IsVertical())
+ {
+ fRetval = aTextLayouter.getTextHeight() * (double)nLength;
+ }
+ else
+ {
+ fRetval = aTextLayouter.getTextWidth(maText, getPortionIndex(nIndex, nLength), nLength);
+ }
+
+ return fRetval;
+ }
+ };
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// TextBreakup helper
+
+namespace
+{
+ class impTextBreakupHandler
+ {
+ SdrOutliner& mrOutliner;
+ ::std::vector< impPathTextPortion > maPathTextPortions;
+
+ DECL_LINK(decompositionPathTextPrimitive, DrawPortionInfo* );
+
+ public:
+ impTextBreakupHandler(SdrOutliner& rOutliner)
+ : mrOutliner(rOutliner)
+ {
+ }
+
+ const ::std::vector< impPathTextPortion >& decompositionPathTextPrimitive()
+ {
+ // strip portions to maPathTextPortions
+ mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decompositionPathTextPrimitive));
+ mrOutliner.StripPortions();
+
+ if(maPathTextPortions.size())
+ {
+ // sort portions by paragraph, x and y
+ ::std::sort(maPathTextPortions.begin(), maPathTextPortions.end());
+ }
+
+ return maPathTextPortions;
+ }
+ };
+
+ IMPL_LINK(impTextBreakupHandler, decompositionPathTextPrimitive, DrawPortionInfo*, pInfo)
+ {
+ maPathTextPortions.push_back(impPathTextPortion(*pInfo));
+ return 0;
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// TextBreakup one poly and one paragraph helper
+
+namespace
+{
+ class impPolygonParagraphHandler
+ {
+ const drawinglayer::attribute::SdrFormTextAttribute maSdrFormTextAttribute; // FormText parameters
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& mrDecomposition; // destination primitive list
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& mrShadowDecomposition; // destination primitive list for shadow
+ Reference < com::sun::star::i18n::XBreakIterator > mxBreak; // break iterator
+
+ double getParagraphTextLength(const ::std::vector< const impPathTextPortion* >& rTextPortions)
+ {
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
+ double fRetval(0.0);
+
+ for(sal_uInt32 a(0L); a < rTextPortions.size(); a++)
+ {
+ const impPathTextPortion* pCandidate = rTextPortions[a];
+
+ if(pCandidate && pCandidate->getTextLength())
+ {
+ aTextLayouter.setFont(pCandidate->getFont());
+ fRetval += pCandidate->getDisplayLength(0L, pCandidate->getTextLength());
+ }
+ }
+
+ return fRetval;
+ }
+
+ xub_StrLen getNextGlyphLen(const impPathTextPortion* pCandidate, xub_StrLen nPosition, const ::com::sun::star::lang::Locale& rFontLocale)
+ {
+ xub_StrLen nNextGlyphLen(1);
+
+ if(mxBreak.is())
+ {
+ sal_Int32 nDone(0L);
+ nNextGlyphLen = (xub_StrLen)mxBreak->nextCharacters(pCandidate->getText(), nPosition,
+ rFontLocale, CharacterIteratorMode::SKIPCELL, 1, nDone) - nPosition;
+ }
+
+ return nNextGlyphLen;
+ }
+
+ public:
+ impPolygonParagraphHandler(
+ const drawinglayer::attribute::SdrFormTextAttribute& rSdrFormTextAttribute,
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rDecomposition,
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rShadowDecomposition)
+ : maSdrFormTextAttribute(rSdrFormTextAttribute),
+ mrDecomposition(rDecomposition),
+ mrShadowDecomposition(rShadowDecomposition)
+ {
+ // prepare BreakIterator
+ Reference < XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
+ Reference < XInterface > xInterface = xMSF->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator"));
+
+ if(xInterface.is())
+ {
+ Any x = xInterface->queryInterface(::getCppuType((const Reference< XBreakIterator >*)0));
+ x >>= mxBreak;
+ }
+ }
+
+ void HandlePair(const basegfx::B2DPolygon rPolygonCandidate, const ::std::vector< const impPathTextPortion* >& rTextPortions)
+ {
+ // prepare polygon geometry, take into account as many parameters as possible
+ basegfx::B2DPolygon aPolygonCandidate(rPolygonCandidate);
+ const double fPolyLength(basegfx::tools::getLength(aPolygonCandidate));
+ double fPolyEnd(fPolyLength);
+ double fPolyStart(0.0);
+ double fAutosizeScaleFactor(1.0);
+ bool bAutosizeScale(false);
+
+ if(maSdrFormTextAttribute.getFormTextMirror())
+ {
+ aPolygonCandidate.flip();
+ }
+
+ if(maSdrFormTextAttribute.getFormTextStart()
+ && (XFT_LEFT == maSdrFormTextAttribute.getFormTextAdjust()
+ || XFT_RIGHT == maSdrFormTextAttribute.getFormTextAdjust()))
+ {
+ if(XFT_LEFT == maSdrFormTextAttribute.getFormTextAdjust())
+ {
+ fPolyStart += maSdrFormTextAttribute.getFormTextStart();
+
+ if(fPolyStart > fPolyEnd)
+ {
+ fPolyStart = fPolyEnd;
+ }
+ }
+ else
+ {
+ fPolyEnd -= maSdrFormTextAttribute.getFormTextStart();
+
+ if(fPolyEnd < fPolyStart)
+ {
+ fPolyEnd = fPolyStart;
+ }
+ }
+ }
+
+ if(XFT_LEFT != maSdrFormTextAttribute.getFormTextAdjust())
+ {
+ // calculate total text length of this paragraph, some layout needs to be done
+ const double fParagraphTextLength(getParagraphTextLength(rTextPortions));
+
+ // check if text is too long for paragraph. If yes, handle as if left aligned (default),
+ // but still take care of XFT_AUTOSIZE in that case
+ const bool bTextTooLong(fParagraphTextLength > (fPolyEnd - fPolyStart));
+
+ if(XFT_RIGHT == maSdrFormTextAttribute.getFormTextAdjust())
+ {
+ if(!bTextTooLong)
+ {
+ // if right aligned, add difference to polygon start
+ fPolyStart += ((fPolyEnd - fPolyStart) - fParagraphTextLength);
+ }
+ }
+ else if(XFT_CENTER == maSdrFormTextAttribute.getFormTextAdjust())
+ {
+ if(!bTextTooLong)
+ {
+ // if centered, add half of difference to polygon start
+ fPolyStart += ((fPolyEnd - fPolyStart) - fParagraphTextLength) / 2.0;
+ }
+ }
+ else if(XFT_AUTOSIZE == maSdrFormTextAttribute.getFormTextAdjust())
+ {
+ // if scale, prepare scale factor between curve length and text length
+ if(0.0 != fParagraphTextLength)
+ {
+ fAutosizeScaleFactor = (fPolyEnd - fPolyStart) / fParagraphTextLength;
+ bAutosizeScale = true;
+ }
+ }
+ }
+
+ // handle text portions for this paragraph
+ for(sal_uInt32 a(0L); a < rTextPortions.size() && fPolyStart < fPolyEnd; a++)
+ {
+ const impPathTextPortion* pCandidate = rTextPortions[a];
+ basegfx::B2DVector aFontScaling;
+ const drawinglayer::attribute::FontAttribute aCandidateFontAttribute(
+ drawinglayer::primitive2d::getFontAttributeFromVclFont(
+ aFontScaling,
+ pCandidate->getFont(),
+ pCandidate->isRTL(),
+ false));
+
+ if(pCandidate && pCandidate->getTextLength())
+ {
+ drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
+ aTextLayouter.setFont(pCandidate->getFont());
+ xub_StrLen nUsedTextLength(0);
+
+ while(nUsedTextLength < pCandidate->getTextLength() && fPolyStart < fPolyEnd)
+ {
+ xub_StrLen nNextGlyphLen(getNextGlyphLen(pCandidate, pCandidate->getTextStart() + nUsedTextLength, pCandidate->getLocale()));
+
+ // prepare portion length. Takes RTL sections into account.
+ double fPortionLength(pCandidate->getDisplayLength(nUsedTextLength, nNextGlyphLen));
+
+ if(bAutosizeScale)
+ {
+ // when autosize scaling, expand portion length
+ fPortionLength *= fAutosizeScaleFactor;
+ }
+
+ // create transformation
+ basegfx::B2DHomMatrix aNewTransformA, aNewTransformB, aNewShadowTransform;
+ basegfx::B2DPoint aStartPos(basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart, fPolyLength));
+ basegfx::B2DPoint aEndPos(aStartPos);
+
+ // add font scaling
+ aNewTransformA.scale(aFontScaling.getX(), aFontScaling.getY());
+
+ // prepare scaling of text primitive
+ if(bAutosizeScale)
+ {
+ // when autosize scaling, expand text primitive scaling to it
+ aNewTransformA.scale(fAutosizeScaleFactor, fAutosizeScaleFactor);
+ }
+
+ // eventually create shadow primitives from aDecomposition and add to rDecomposition
+ const bool bShadow(XFTSHADOW_NONE != maSdrFormTextAttribute.getFormTextShadow());
+
+ if(bShadow)
+ {
+ if(XFTSHADOW_NORMAL == maSdrFormTextAttribute.getFormTextShadow())
+ {
+ aNewShadowTransform.translate(
+ maSdrFormTextAttribute.getFormTextShdwXVal(),
+ -maSdrFormTextAttribute.getFormTextShdwYVal());
+ }
+ else // XFTSHADOW_SLANT
+ {
+ double fScaleValue(maSdrFormTextAttribute.getFormTextShdwYVal() / 100.0);
+ double fShearValue(-maSdrFormTextAttribute.getFormTextShdwXVal() * F_PI1800);
+
+ aNewShadowTransform.scale(1.0, fScaleValue);
+ aNewShadowTransform.shearX(sin(fShearValue));
+ aNewShadowTransform.scale(1.0, cos(fShearValue));
+ }
+ }
+
+ switch(maSdrFormTextAttribute.getFormTextStyle())
+ {
+ case XFT_ROTATE :
+ {
+ aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
+ const basegfx::B2DVector aDirection(aEndPos - aStartPos);
+ aNewTransformB.rotate(atan2(aDirection.getY(), aDirection.getX()));
+ aNewTransformB.translate(aStartPos.getX(), aStartPos.getY());
+
+ break;
+ }
+ case XFT_UPRIGHT :
+ {
+ aNewTransformB.translate(aStartPos.getX() - (fPortionLength / 2.0), aStartPos.getY());
+
+ break;
+ }
+ case XFT_SLANTX :
+ {
+ aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
+ const basegfx::B2DVector aDirection(aEndPos - aStartPos);
+ const double fShearValue(atan2(aDirection.getY(), aDirection.getX()));
+ const double fSin(sin(fShearValue));
+ const double fCos(cos(fShearValue));
+
+ aNewTransformB.shearX(-fSin);
+
+ // Scale may lead to objects without height since fCos == 0.0 is possible.
+ // Renderers need to handle that, it's not a forbidden value and does not
+ // need to be avoided
+ aNewTransformB.scale(1.0, fCos);
+ aNewTransformB.translate(aStartPos.getX() - (fPortionLength / 2.0), aStartPos.getY());
+
+ break;
+ }
+ case XFT_SLANTY :
+ {
+ aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
+ const basegfx::B2DVector aDirection(aEndPos - aStartPos);
+ const double fShearValue(atan2(aDirection.getY(), aDirection.getX()));
+ const double fCos(cos(fShearValue));
+ const double fTan(tan(fShearValue));
+
+ // shear to 'stand' on the curve
+ aNewTransformB.shearY(fTan);
+
+ // scale in X to make as tight as needed. As with XFT_SLANT_X, this may
+ // lead to primitives without width which the renderers will handle
+ aNewTransformA.scale(fCos, 1.0);
+
+ aNewTransformB.translate(aStartPos.getX(), aStartPos.getY());
+
+ break;
+ }
+ default : break; // XFT_NONE
+ }
+
+ // distance from path?
+ if(maSdrFormTextAttribute.getFormTextDistance())
+ {
+ if(aEndPos.equal(aStartPos))
+ {
+ aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
+ }
+
+ // use back vector (aStartPos - aEndPos) here to get mirrored perpendicular as in old stuff
+ const basegfx::B2DVector aPerpendicular(
+ basegfx::getNormalizedPerpendicular(aStartPos - aEndPos) *
+ maSdrFormTextAttribute.getFormTextDistance());
+ aNewTransformB.translate(aPerpendicular.getX(), aPerpendicular.getY());
+ }
+
+ if(pCandidate->getText().Len() && nNextGlyphLen)
+ {
+ const xub_StrLen nPortionIndex(pCandidate->getPortionIndex(nUsedTextLength, nNextGlyphLen));
+ ::std::vector< double > aNewDXArray;
+
+ if(nNextGlyphLen > 1 && pCandidate->getDoubleDXArray().size())
+ {
+ // copy DXArray for portion
+ aNewDXArray.insert(
+ aNewDXArray.begin(),
+ pCandidate->getDoubleDXArray().begin() + nPortionIndex,
+ pCandidate->getDoubleDXArray().begin() + (nPortionIndex + nNextGlyphLen));
+
+ if(nPortionIndex > 0)
+ {
+ // adapt to portion start
+ double fDXOffset= *(pCandidate->getDoubleDXArray().begin() + (nPortionIndex - 1));
+ ::std::transform(
+ aNewDXArray.begin(), aNewDXArray.end(),
+ aNewDXArray.begin(), ::std::bind2nd(::std::minus<double>(), fDXOffset));
+ }
+
+ if(bAutosizeScale)
+ {
+ // when autosize scaling, adapt to DXArray, too
+ ::std::transform(
+ aNewDXArray.begin(), aNewDXArray.end(),
+ aNewDXArray.begin(), ::std::bind2nd(::std::multiplies<double>(), fAutosizeScaleFactor));
+ }
+ }
+
+ if(bShadow)
+ {
+ // shadow primitive creation
+ const Color aShadowColor(maSdrFormTextAttribute.getFormTextShdwColor());
+ const basegfx::BColor aRGBShadowColor(aShadowColor.getBColor());
+
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew =
+ new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aNewTransformB * aNewShadowTransform * aNewTransformA,
+ pCandidate->getText(),
+ nPortionIndex,
+ nNextGlyphLen,
+ aNewDXArray,
+ aCandidateFontAttribute,
+ pCandidate->getLocale(),
+ aRGBShadowColor);
+
+ mrShadowDecomposition.push_back(pNew);
+ }
+
+ {
+ // primitive creation
+ const Color aColor(pCandidate->getFont().GetColor());
+ const basegfx::BColor aRGBColor(aColor.getBColor());
+
+ drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew =
+ new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+ aNewTransformB * aNewTransformA,
+ pCandidate->getText(),
+ nPortionIndex,
+ nNextGlyphLen,
+ aNewDXArray,
+ aCandidateFontAttribute,
+ pCandidate->getLocale(),
+ aRGBColor);
+
+ mrDecomposition.push_back(pNew);
+ }
+ }
+
+ // consume from portion // no += here, xub_StrLen is USHORT and the compiler will gererate a warning here
+ nUsedTextLength = nUsedTextLength + nNextGlyphLen;
+
+ // consume from polygon
+ fPolyStart += fPortionLength;
+ }
+ }
+ }
+ }
+ };
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// primitive decomposition helpers
+
+namespace
+{
+ void impAddPolygonStrokePrimitives(
+ const basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector,
+ const basegfx::B2DHomMatrix& rTransform,
+ const drawinglayer::attribute::LineAttribute& rLineAttribute,
+ const drawinglayer::attribute::StrokeAttribute& rStrokeAttribute,
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rTarget)
+ {
+ for(basegfx::B2DPolyPolygonVector::const_iterator aPolygon(rB2DPolyPolyVector.begin()); aPolygon != rB2DPolyPolyVector.end(); aPolygon++)
+ {
+ // prepare PolyPolygons
+ basegfx::B2DPolyPolygon aB2DPolyPolygon = *aPolygon;
+ aB2DPolyPolygon.transform(rTransform);
+
+ for(sal_uInt32 a(0L); a < aB2DPolyPolygon.count(); a++)
+ {
+ // create one primitive per polygon
+ drawinglayer::primitive2d::PolygonStrokePrimitive2D* pNew =
+ new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
+ aB2DPolyPolygon.getB2DPolygon(a), rLineAttribute, rStrokeAttribute);
+ rTarget.push_back(pNew);
+ }
+ }
+ }
+
+ drawinglayer::primitive2d::Primitive2DSequence impAddPathTextOutlines(
+ const std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rSource,
+ const drawinglayer::attribute::SdrFormTextOutlineAttribute& rOutlineAttribute)
+ {
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aNewPrimitives;
+
+ for(sal_uInt32 a(0L); a < rSource.size(); a++)
+ {
+ const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pTextCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(rSource[a]);
+
+ if(pTextCandidate)
+ {
+ basegfx::B2DPolyPolygonVector aB2DPolyPolyVector;
+ basegfx::B2DHomMatrix aPolygonTransform;
+
+ // get text outlines and their object transformation
+ pTextCandidate->getTextOutlinesAndTransformation(aB2DPolyPolyVector, aPolygonTransform);
+
+ if(aB2DPolyPolyVector.size())
+ {
+ // create stroke primitives
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aStrokePrimitives;
+ impAddPolygonStrokePrimitives(
+ aB2DPolyPolyVector,
+ aPolygonTransform,
+ rOutlineAttribute.getLineAttribute(),
+ rOutlineAttribute.getStrokeAttribute(),
+ aStrokePrimitives);
+ const sal_uInt32 nStrokeCount(aStrokePrimitives.size());
+
+ if(nStrokeCount)
+ {
+ if(rOutlineAttribute.getTransparence())
+ {
+ // create UnifiedTransparencePrimitive2D
+ drawinglayer::primitive2d::Primitive2DSequence aStrokePrimitiveSequence(nStrokeCount);
+
+ for(sal_uInt32 b(0L); b < nStrokeCount; b++)
+ {
+ aStrokePrimitiveSequence[b] = drawinglayer::primitive2d::Primitive2DReference(aStrokePrimitives[b]);
+ }
+
+ drawinglayer::primitive2d::UnifiedTransparencePrimitive2D* pNew2 =
+ new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
+ aStrokePrimitiveSequence,
+ (double)rOutlineAttribute.getTransparence() / 100.0);
+ aNewPrimitives.push_back(pNew2);
+ }
+ else
+ {
+ // add polygons to rDecomposition as polygonStrokePrimitives
+ aNewPrimitives.insert(aNewPrimitives.end(), aStrokePrimitives.begin(), aStrokePrimitives.end());
+ }
+ }
+ }
+ }
+ }
+
+ const sal_uInt32 nNewCount(aNewPrimitives.size());
+
+ if(nNewCount)
+ {
+ drawinglayer::primitive2d::Primitive2DSequence aRetval(nNewCount);
+
+ for(sal_uInt32 a(0L); a < nNewCount; a++)
+ {
+ aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(aNewPrimitives[a]);
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return drawinglayer::primitive2d::Primitive2DSequence();
+ }
+ }
+} // end of anonymous namespace
+
+//////////////////////////////////////////////////////////////////////////////
+// primitive decomposition
+
+void SdrTextObj::impDecomposePathTextPrimitive(
+ drawinglayer::primitive2d::Primitive2DSequence& rTarget,
+ const drawinglayer::primitive2d::SdrPathTextPrimitive2D& rSdrPathTextPrimitive,
+ const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetvalA;
+ drawinglayer::primitive2d::Primitive2DSequence aRetvalB;
+
+ // prepare outliner
+ SdrOutliner& rOutliner = ImpGetDrawOutliner();
+ rOutliner.SetUpdateMode(true);
+ rOutliner.Clear();
+ rOutliner.SetPaperSize(Size(LONG_MAX,LONG_MAX));
+ rOutliner.SetText(rSdrPathTextPrimitive.getOutlinerParaObject());
+
+ // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
+ rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
+
+ // now break up to text portions
+ impTextBreakupHandler aConverter(rOutliner);
+ const ::std::vector< impPathTextPortion > rPathTextPortions = aConverter.decompositionPathTextPrimitive();
+
+ if(rPathTextPortions.size())
+ {
+ // get FormText and polygon values
+ const drawinglayer::attribute::SdrFormTextAttribute& rFormTextAttribute = rSdrPathTextPrimitive.getSdrFormTextAttribute();
+ const basegfx::B2DPolyPolygon& rPathPolyPolygon(rSdrPathTextPrimitive.getPathPolyPolygon());
+
+ // get loop count
+ sal_uInt32 nLoopCount(rPathPolyPolygon.count());
+
+ if(rOutliner.GetParagraphCount() < nLoopCount)
+ {
+ nLoopCount = rOutliner.GetParagraphCount();
+ }
+
+ if(nLoopCount)
+ {
+ // prepare common decomposition stuff
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aRegularDecomposition;
+ std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aShadowDecomposition;
+ impPolygonParagraphHandler aPolygonParagraphHandler(
+ rFormTextAttribute,
+ aRegularDecomposition,
+ aShadowDecomposition);
+ sal_uInt32 a;
+
+ for(a = 0L; a < nLoopCount; a++)
+ {
+ // filter text portions for this paragraph
+ ::std::vector< const impPathTextPortion* > aParagraphTextPortions;
+
+ for(sal_uInt32 b(0L); b < rPathTextPortions.size(); b++)
+ {
+ const impPathTextPortion& rCandidate = rPathTextPortions[b];
+
+ if(rCandidate.getParagraph() == a)
+ {
+ aParagraphTextPortions.push_back(&rCandidate);
+ }
+ }
+
+ // handle data pair polygon/ParagraphTextPortions
+ if(aParagraphTextPortions.size())
+ {
+ aPolygonParagraphHandler.HandlePair(rPathPolyPolygon.getB2DPolygon(a), aParagraphTextPortions);
+ }
+ }
+
+ const sal_uInt32 nShadowCount(aShadowDecomposition.size());
+ const sal_uInt32 nRegularCount(aRegularDecomposition.size());
+
+ if(nShadowCount)
+ {
+ // add shadow primitives to decomposition
+ aRetvalA.realloc(nShadowCount);
+
+ for(a = 0L; a < nShadowCount; a++)
+ {
+ aRetvalA[a] = drawinglayer::primitive2d::Primitive2DReference(aShadowDecomposition[a]);
+ }
+
+ // evtl. add shadow outlines
+ if(rFormTextAttribute.getFormTextOutline()
+ && !rFormTextAttribute.getShadowOutline().isDefault())
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence aOutlines(
+ impAddPathTextOutlines(
+ aShadowDecomposition,
+ rFormTextAttribute.getShadowOutline()));
+
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetvalA, aOutlines);
+ }
+ }
+
+ if(nRegularCount)
+ {
+ // add normal primitives to decomposition
+ aRetvalB.realloc(nRegularCount);
+
+ for(a = 0L; a < nRegularCount; a++)
+ {
+ aRetvalB[a] = drawinglayer::primitive2d::Primitive2DReference(aRegularDecomposition[a]);
+ }
+
+ // evtl. add outlines
+ if(rFormTextAttribute.getFormTextOutline()
+ && !rFormTextAttribute.getOutline().isDefault())
+ {
+ const drawinglayer::primitive2d::Primitive2DSequence aOutlines(
+ impAddPathTextOutlines(
+ aRegularDecomposition,
+ rFormTextAttribute.getOutline()));
+
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetvalB, aOutlines);
+ }
+ }
+ }
+ }
+
+ // cleanup outliner
+ rOutliner.SetDrawPortionHdl(Link());
+ rOutliner.Clear();
+ rOutliner.setVisualizedPage(0);
+
+ // concatenate all results
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aRetvalA);
+ drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aRetvalB);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdotxat.cxx b/svx/source/svdraw/svdotxat.cxx
new file mode 100644
index 000000000000..13064e890313
--- /dev/null
+++ b/svx/source/svdraw/svdotxat.cxx
@@ -0,0 +1,462 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svl/style.hxx>
+#include <svx/svdotext.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx> // fuer GetMaxObjSize und GetStyleSheetPool
+#include <svx/svdoutl.hxx>
+#include <svx/svdorect.hxx> // fuer SetDirty bei NbcAdjustTextFrameWidthAndHeight
+#include <svx/svdocapt.hxx> // fuer SetDirty bei NbcAdjustTextFrameWidthAndHeight
+#include <svx/svdetc.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/sdtfchim.hxx>
+
+
+#include <editeng/editview.hxx>
+#include <svl/smplhint.hxx>
+#include <svl/whiter.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/fhgtitem.hxx>
+
+#include <editeng/charscaleitem.hxx>
+#include <svl/style.hxx>
+#include <svl/itemiter.hxx>
+#include <editeng/lrspitem.hxx>
+#include <svl/itempool.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/postitem.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+// Attribute, StyleSheets und AutoGrow
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrTextObj::AdjustTextFrameWidthAndHeight(Rectangle& rR, FASTBOOL bHgt, FASTBOOL bWdt) const
+{
+ if (bTextFrame && pModel!=NULL && !rR.IsEmpty())
+ {
+ SdrFitToSizeType eFit=GetFitToSize();
+ FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ FASTBOOL bWdtGrow=bWdt && IsAutoGrowWidth();
+ FASTBOOL bHgtGrow=bHgt && IsAutoGrowHeight();
+ SdrTextAniKind eAniKind=GetTextAniKind();
+ SdrTextAniDirection eAniDir=GetTextAniDirection();
+ FASTBOOL bScroll=eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE;
+ FASTBOOL bHScroll=bScroll && (eAniDir==SDRTEXTANI_LEFT || eAniDir==SDRTEXTANI_RIGHT);
+ FASTBOOL bVScroll=bScroll && (eAniDir==SDRTEXTANI_UP || eAniDir==SDRTEXTANI_DOWN);
+ if (!bFitToSize && (bWdtGrow || bHgtGrow))
+ {
+ Rectangle aR0(rR);
+ long nHgt=0,nMinHgt=0,nMaxHgt=0;
+ long nWdt=0,nMinWdt=0,nMaxWdt=0;
+ Size aSiz(rR.GetSize()); aSiz.Width()--; aSiz.Height()--;
+ Size aMaxSiz(100000,100000);
+ Size aTmpSiz(pModel->GetMaxObjSize());
+ if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
+ if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
+ if (bWdtGrow)
+ {
+ nMinWdt=GetMinTextFrameWidth();
+ nMaxWdt=GetMaxTextFrameWidth();
+ if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
+ if (nMinWdt<=0) nMinWdt=1;
+ aSiz.Width()=nMaxWdt;
+ }
+ if (bHgtGrow)
+ {
+ nMinHgt=GetMinTextFrameHeight();
+ nMaxHgt=GetMaxTextFrameHeight();
+ if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
+ if (nMinHgt<=0) nMinHgt=1;
+ aSiz.Height()=nMaxHgt;
+ }
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ aSiz.Width()-=nHDist;
+ aSiz.Height()-=nVDist;
+ if (aSiz.Width()<2) aSiz.Width()=2; // Mindestgroesse 2
+ if (aSiz.Height()<2) aSiz.Height()=2; // Mindestgroesse 2
+
+ // #101684#
+ BOOL bInEditMode = IsInEditMode();
+
+ if(!bInEditMode)
+ {
+ if (bHScroll) aSiz.Width()=0x0FFFFFFF; // Laufschrift nicht umbrechen
+ if (bVScroll) aSiz.Height()=0x0FFFFFFF;
+ }
+
+ if(pEdtOutl)
+ {
+ pEdtOutl->SetMaxAutoPaperSize(aSiz);
+ if (bWdtGrow) {
+ Size aSiz2(pEdtOutl->CalcTextSize());
+ nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
+ if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
+ } else {
+ nHgt=pEdtOutl->GetTextHeight()+1; // lieber etwas Tolleranz
+ }
+ } else {
+ Outliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetPaperSize(aSiz);
+ rOutliner.SetUpdateMode(TRUE);
+ // !!! hier sollte ich wohl auch noch mal die Optimierung mit
+ // bPortionInfoChecked usw einbauen
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if ( pOutlinerParaObject != NULL )
+ {
+ rOutliner.SetText(*pOutlinerParaObject);
+ rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ }
+ if (bWdtGrow)
+ {
+ Size aSiz2(rOutliner.CalcTextSize());
+ nWdt=aSiz2.Width()+1; // lieber etwas Tolleranz
+ if (bHgtGrow) nHgt=aSiz2.Height()+1; // lieber etwas Tolleranz
+ } else {
+ nHgt=rOutliner.GetTextHeight()+1; // lieber etwas Tolleranz
+ }
+ rOutliner.Clear();
+ }
+ if (nWdt<nMinWdt) nWdt=nMinWdt;
+ if (nWdt>nMaxWdt) nWdt=nMaxWdt;
+ nWdt+=nHDist;
+ if (nWdt<1) nWdt=1; // nHDist kann auch negativ sein
+ if (nHgt<nMinHgt) nHgt=nMinHgt;
+ if (nHgt>nMaxHgt) nHgt=nMaxHgt;
+ nHgt+=nVDist;
+ if (nHgt<1) nHgt=1; // nVDist kann auch negativ sein
+ long nWdtGrow=nWdt-(rR.Right()-rR.Left());
+ long nHgtGrow=nHgt-(rR.Bottom()-rR.Top());
+ if (nWdtGrow==0) bWdtGrow=FALSE;
+ if (nHgtGrow==0) bHgtGrow=FALSE;
+ if (bWdtGrow || bHgtGrow) {
+ if (bWdtGrow) {
+ SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
+ if (eHAdj==SDRTEXTHORZADJUST_LEFT) rR.Right()+=nWdtGrow;
+ else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) rR.Left()-=nWdtGrow;
+ else {
+ long nWdtGrow2=nWdtGrow/2;
+ rR.Left()-=nWdtGrow2;
+ rR.Right()=rR.Left()+nWdt;
+ }
+ }
+ if (bHgtGrow) {
+ SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
+ if (eVAdj==SDRTEXTVERTADJUST_TOP) rR.Bottom()+=nHgtGrow;
+ else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) rR.Top()-=nHgtGrow;
+ else {
+ long nHgtGrow2=nHgtGrow/2;
+ rR.Top()-=nHgtGrow2;
+ rR.Bottom()=rR.Top()+nHgt;
+ }
+ }
+ if (aGeo.nDrehWink!=0) {
+ Point aD1(rR.TopLeft());
+ aD1-=aR0.TopLeft();
+ Point aD2(aD1);
+ RotatePoint(aD2,Point(),aGeo.nSin,aGeo.nCos);
+ aD2-=aD1;
+ rR.Move(aD2.X(),aD2.Y());
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+FASTBOOL SdrTextObj::NbcAdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
+{
+ FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aRect,bHgt,bWdt);
+ if (bRet) {
+ SetRectsDirty();
+ if (HAS_BASE(SdrRectObj,this)) { // mal wieder 'nen Hack
+ ((SdrRectObj*)this)->SetXPolyDirty();
+ }
+ if (HAS_BASE(SdrCaptionObj,this)) { // mal wieder 'nen Hack
+ ((SdrCaptionObj*)this)->ImpRecalcTail();
+ }
+ }
+ return bRet;
+}
+
+FASTBOOL SdrTextObj::AdjustTextFrameWidthAndHeight(FASTBOOL bHgt, FASTBOOL bWdt)
+{
+ Rectangle aNeuRect(aRect);
+ FASTBOOL bRet=AdjustTextFrameWidthAndHeight(aNeuRect,bHgt,bWdt);
+ if (bRet) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ aRect=aNeuRect;
+ SetRectsDirty();
+ if (HAS_BASE(SdrRectObj,this)) { // mal wieder 'nen Hack
+ ((SdrRectObj*)this)->SetXPolyDirty();
+ }
+ if (HAS_BASE(SdrCaptionObj,this)) { // mal wieder 'nen Hack
+ ((SdrCaptionObj*)this)->ImpRecalcTail();
+ }
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+ return bRet;
+}
+
+void SdrTextObj::ImpSetTextStyleSheetListeners()
+{
+ SfxStyleSheetBasePool* pStylePool=pModel!=NULL ? pModel->GetStyleSheetPool() : NULL;
+ if (pStylePool!=NULL)
+ {
+ Container aStyles(1024,64,64);
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if (pOutlinerParaObject!=NULL)
+ {
+ // Zunaechst werden alle im ParaObject enthaltenen StyleSheets
+ // im Container aStyles gesammelt. Dazu wird die Family jeweils
+ // ans Ende des StyleSheet-Namen drangehaengt.
+ const EditTextObject& rTextObj=pOutlinerParaObject->GetTextObject();
+ XubString aStyleName;
+ SfxStyleFamily eStyleFam;
+ USHORT nParaAnz=rTextObj.GetParagraphCount();
+
+ for(UINT16 nParaNum(0); nParaNum < nParaAnz; nParaNum++)
+ {
+ rTextObj.GetStyleSheet(nParaNum, aStyleName, eStyleFam);
+
+ if(aStyleName.Len())
+ {
+ XubString aFam = UniString::CreateFromInt32((UINT16)eStyleFam);
+ aFam.Expand(5);
+
+ aStyleName += sal_Unicode('|');
+ aStyleName += aFam;
+
+ BOOL bFnd(FALSE);
+ UINT32 nNum(aStyles.Count());
+
+ while(!bFnd && nNum > 0)
+ {
+ // kein StyleSheet doppelt!
+ nNum--;
+ bFnd = (aStyleName.Equals(*(XubString*)aStyles.GetObject(nNum)));
+ }
+
+ if(!bFnd)
+ {
+ aStyles.Insert(new XubString(aStyleName), CONTAINER_APPEND);
+ }
+ }
+ }
+ }
+
+ // nun die Strings im Container durch StyleSheet* ersetzten
+ ULONG nNum=aStyles.Count();
+ while (nNum>0) {
+ nNum--;
+ XubString* pName=(XubString*)aStyles.GetObject(nNum);
+
+ // UNICODE: String aFam(pName->Cut(pName->Len()-6));
+ String aFam = pName->Copy(0, pName->Len() - 6);
+
+ aFam.Erase(0,1);
+ aFam.EraseTrailingChars();
+
+ // UNICODE: USHORT nFam=USHORT(aFam);
+ UINT16 nFam = (UINT16)aFam.ToInt32();
+
+ SfxStyleFamily eFam=(SfxStyleFamily)nFam;
+ SfxStyleSheetBase* pStyleBase=pStylePool->Find(*pName,eFam);
+ SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pStyleBase);
+ delete pName;
+ if (pStyle!=NULL && pStyle!=GetStyleSheet()) {
+ aStyles.Replace(pStyle,nNum);
+ } else {
+ aStyles.Remove(nNum);
+ }
+ }
+ // jetzt alle ueberfluessigen StyleSheets entfernen
+ nNum=GetBroadcasterCount();
+ while (nNum>0) {
+ nNum--;
+ SfxBroadcaster* pBroadcast=GetBroadcasterJOE((USHORT)nNum);
+ SfxStyleSheet* pStyle=PTR_CAST(SfxStyleSheet,pBroadcast);
+ if (pStyle!=NULL && pStyle!=GetStyleSheet()) { // Sonderbehandlung fuer den StyleSheet des Objekts
+ if (aStyles.GetPos(pStyle)==CONTAINER_ENTRY_NOTFOUND) {
+ EndListening(*pStyle);
+ }
+ }
+ }
+ // und schliesslich alle in aStyles enthaltenen StyleSheets mit den vorhandenen Broadcastern mergen
+ nNum=aStyles.Count();
+ while (nNum>0) {
+ nNum--;
+ SfxStyleSheet* pStyle=(SfxStyleSheet*)aStyles.GetObject(nNum);
+ // StartListening soll selbst nachsehen, ob hier nicht evtl. schon gehorcht wird
+ StartListening(*pStyle,TRUE);
+ }
+ }
+}
+
+void SdrTextObj::NbcResizeTextAttributes(const Fraction& xFact, const Fraction& yFact)
+{
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if (pOutlinerParaObject!=NULL && xFact.IsValid() && yFact.IsValid())
+ {
+ Fraction n100(100,1);
+ long nX=long(xFact*n100);
+ long nY=long(yFact*n100);
+ if (nX<0) nX=-nX;
+ if (nX<1) nX=1;
+ if (nX>0xFFFF) nX=0xFFFF;
+ if (nY<0) nY=-nY;
+ if (nY<1) nY=1;
+ if (nY>0xFFFF) nY=0xFFFF;
+ if (nX!=100 || nY!=100)
+ {
+ // Rahmenattribute
+ const SfxItemSet& rSet = GetObjectItemSet();
+ const SvxCharScaleWidthItem& rOldWdt=(SvxCharScaleWidthItem&)rSet.Get(EE_CHAR_FONTWIDTH);
+ const SvxFontHeightItem& rOldHgt=(SvxFontHeightItem&)rSet.Get(EE_CHAR_FONTHEIGHT);
+
+ // erstmal die alten Werte holen
+ long nRelWdt=rOldWdt.GetValue();
+ long nAbsHgt=rOldHgt.GetHeight();
+ long nRelHgt=rOldHgt.GetProp();
+
+ // Relative Breite aendern
+ nRelWdt*=nX;
+ nRelWdt/=nY;
+ if (nRelWdt<0) nRelWdt=-nRelWdt; // nicht negativ
+ if (nRelWdt<=0) nRelWdt=1; // und mind. 1%
+ if (nRelWdt>0xFFFF) nRelWdt=0xFFFF;
+
+ // Absolute Hoehe aendern
+ nAbsHgt*=nY;
+ nAbsHgt/=100;
+ if (nAbsHgt<0) nAbsHgt=-nAbsHgt; // nicht negativ
+ if (nAbsHgt<=0) nAbsHgt=1; // und mind. 1
+ if (nAbsHgt>0xFFFF) nAbsHgt=0xFFFF;
+
+ // und nun attributieren
+ SetObjectItem(SvxCharScaleWidthItem( (USHORT) nRelWdt, EE_CHAR_FONTWIDTH));
+ SetObjectItem(SvxFontHeightItem(nAbsHgt,(USHORT)nRelHgt, EE_CHAR_FONTHEIGHT));
+ // Zeichen- und Absatzattribute innerhalb des OutlinerParaObjects
+ Outliner& rOutliner=ImpGetDrawOutliner();
+ rOutliner.SetPaperSize(Size(LONG_MAX,LONG_MAX));
+ rOutliner.SetText(*pOutlinerParaObject);
+ rOutliner.DoStretchChars((USHORT)nX,(USHORT)nY);
+ OutlinerParaObject* pNewPara=rOutliner.CreateParaObject();
+ NbcSetOutlinerParaObject(pNewPara);
+ rOutliner.Clear();
+ }
+ }
+}
+
+/** #103836# iterates over the paragraphs of a given SdrObject and removes all
+ hard set character attributes with the which ids contained in the
+ given vector
+*/
+void SdrTextObj::RemoveOutlinerCharacterAttribs( const std::vector<sal_uInt16>& rCharWhichIds )
+{
+ sal_Int32 nText = getTextCount();
+
+ while( --nText >= 0 )
+ {
+ SdrText* pText = getText( nText );
+ OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
+
+ if(pOutlinerParaObject)
+ {
+ Outliner* pOutliner = 0;
+
+ if( pEdtOutl || (pText == getActiveText()) )
+ pOutliner = pEdtOutl;
+
+ if(!pOutliner)
+ {
+ pOutliner = &ImpGetDrawOutliner();
+ pOutliner->SetText(*pOutlinerParaObject);
+ }
+
+ ESelection aSelAll( 0, 0, 0xffff, 0xffff );
+ std::vector<sal_uInt16>::const_iterator aIter( rCharWhichIds.begin() );
+ while( aIter != rCharWhichIds.end() )
+ {
+ pOutliner->RemoveAttribs( aSelAll, false, (*aIter++) );
+ }
+
+ if(!pEdtOutl || (pText != getActiveText()) )
+ {
+ const sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
+ OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount);
+ pOutliner->Clear();
+ NbcSetOutlinerParaObjectForText(pTemp, pText);
+ }
+ }
+ }
+}
+
+bool SdrTextObj::HasText() const
+{
+ if( pEdtOutl )
+ return HasEditText();
+
+ OutlinerParaObject* pOPO = GetOutlinerParaObject();
+
+ bool bHasText = false;
+ if( pOPO )
+ {
+ const EditTextObject& rETO = pOPO->GetTextObject();
+ USHORT nParaCount = rETO.GetParagraphCount();
+
+ if( nParaCount > 0 )
+ bHasText = (nParaCount > 1) || (rETO.GetText( 0 ).Len() != 0);
+ }
+
+ return bHasText;
+}
diff --git a/svx/source/svdraw/svdotxdr.cxx b/svx/source/svdraw/svdotxdr.cxx
new file mode 100644
index 000000000000..97da16876ac0
--- /dev/null
+++ b/svx/source/svdraw/svdotxdr.cxx
@@ -0,0 +1,285 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/svddrag.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdorect.hxx> // fuer SetXPolyDirty in MovCreate bei SolidDragging
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdoashp.hxx>
+#include <tools/bigint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+// Dragging, Handles, Create
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_uInt32 SdrTextObj::GetHdlCount() const
+{
+ return 8L;
+}
+
+SdrHdl* SdrTextObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pH=NULL;
+ Point aPnt;
+ SdrHdlKind eKind=HDL_MOVE;
+ switch (nHdlNum) {
+ case 0: aPnt=aRect.TopLeft(); eKind=HDL_UPLFT; break; // Oben links
+ case 1: aPnt=aRect.TopCenter(); eKind=HDL_UPPER; break; // Oben
+ case 2: aPnt=aRect.TopRight(); eKind=HDL_UPRGT; break; // Oben rechts
+ case 3: aPnt=aRect.LeftCenter(); eKind=HDL_LEFT ; break; // Links
+ case 4: aPnt=aRect.RightCenter(); eKind=HDL_RIGHT; break; // Rechts
+ case 5: aPnt=aRect.BottomLeft(); eKind=HDL_LWLFT; break; // Unten links
+ case 6: aPnt=aRect.BottomCenter(); eKind=HDL_LOWER; break; // Unten
+ case 7: aPnt=aRect.BottomRight(); eKind=HDL_LWRGT; break; // Unten rechts
+ }
+ if (aGeo.nShearWink!=0) ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
+ if (aGeo.nDrehWink!=0) RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+ if (eKind!=HDL_MOVE) {
+ pH=new SdrHdl(aPnt,eKind);
+ pH->SetObj((SdrObject*)this);
+ pH->SetDrehWink(aGeo.nDrehWink);
+ }
+ return pH;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrTextObj::hasSpecialDrag() const
+{
+ return true;
+}
+
+Rectangle SdrTextObj::ImpDragCalcRect(const SdrDragStat& rDrag) const
+{
+ Rectangle aTmpRect(aRect);
+ const SdrHdl* pHdl=rDrag.GetHdl();
+ SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
+ FASTBOOL bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
+ FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
+ FASTBOOL bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
+ Point aPos(rDrag.GetNow());
+ // Unrotate:
+ if (aGeo.nDrehWink!=0) RotatePoint(aPos,aTmpRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
+ // Unshear:
+ if (aGeo.nShearWink!=0) ShearPoint(aPos,aTmpRect.TopLeft(),-aGeo.nTan);
+ //
+ FASTBOOL bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT || eHdl==HDL_LWLFT);
+ FASTBOOL bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
+ FASTBOOL bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
+ FASTBOOL bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
+ if (bLft) aTmpRect.Left() =aPos.X();
+ if (bRgt) aTmpRect.Right() =aPos.X();
+ if (bTop) aTmpRect.Top() =aPos.Y();
+ if (bBtm) aTmpRect.Bottom()=aPos.Y();
+ if (bOrtho) { // Ortho
+ long nWdt0=aRect.Right() -aRect.Left();
+ long nHgt0=aRect.Bottom()-aRect.Top();
+ long nXMul=aTmpRect.Right() -aTmpRect.Left();
+ long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
+ long nXDiv=nWdt0;
+ long nYDiv=nHgt0;
+ FASTBOOL bXNeg=(nXMul<0)!=(nXDiv<0);
+ FASTBOOL bYNeg=(nYMul<0)!=(nYDiv<0);
+ nXMul=Abs(nXMul);
+ nYMul=Abs(nYMul);
+ nXDiv=Abs(nXDiv);
+ nYDiv=Abs(nYDiv);
+ Fraction aXFact(nXMul,nXDiv); // Fractions zum kuerzen
+ Fraction aYFact(nYMul,nYDiv); // und zum vergleichen
+ nXMul=aXFact.GetNumerator();
+ nYMul=aYFact.GetNumerator();
+ nXDiv=aXFact.GetDenominator();
+ nYDiv=aYFact.GetDenominator();
+ if (bEcke) { // Eckpunkthandles
+ FASTBOOL bUseX=(aXFact<aYFact) != bBigOrtho;
+ if (bUseX) {
+ long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
+ if (bYNeg) nNeed=-nNeed;
+ if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
+ if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
+ } else {
+ long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
+ if (bXNeg) nNeed=-nNeed;
+ if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
+ if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
+ }
+ } else { // Scheitelpunkthandles
+ if ((bLft || bRgt) && nXDiv!=0) {
+ long nHgt0b=aRect.Bottom()-aRect.Top();
+ long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
+ aTmpRect.Top()-=(nNeed-nHgt0b)/2;
+ aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
+ }
+ if ((bTop || bBtm) && nYDiv!=0) {
+ long nWdt0b=aRect.Right()-aRect.Left();
+ long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
+ aTmpRect.Left()-=(nNeed-nWdt0b)/2;
+ aTmpRect.Right()=aTmpRect.Left()+nNeed;
+ }
+ }
+ }
+ if (!ISA(SdrObjCustomShape)) // not justifying for CustomShapes to be able to detect if a shape has to be mirrored
+ ImpJustifyRect(aTmpRect);
+ return aTmpRect;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// drag
+
+bool SdrTextObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ Rectangle aNewRect(ImpDragCalcRect(rDrag));
+
+ if(aNewRect.TopLeft() != aRect.TopLeft() && (aGeo.nDrehWink || aGeo.nShearWink))
+ {
+ Point aNewPos(aNewRect.TopLeft());
+
+ if(aGeo.nShearWink)
+ ShearPoint(aNewPos,aRect.TopLeft(),aGeo.nTan);
+
+ if(aGeo.nDrehWink)
+ RotatePoint(aNewPos,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
+
+ aNewRect.SetPos(aNewPos);
+ }
+
+ if(aNewRect != aRect)
+ {
+ NbcSetLogicRect(aNewRect);
+ }
+
+ return true;
+}
+
+String SdrTextObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_DragRectResize,aStr);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Create
+
+FASTBOOL SdrTextObj::BegCreate(SdrDragStat& rStat)
+{
+ rStat.SetOrtho4Possible();
+ Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
+ aRect1.Justify();
+ rStat.SetActionRect(aRect1);
+ aRect = aRect1;
+ return TRUE;
+}
+
+FASTBOOL SdrTextObj::MovCreate(SdrDragStat& rStat)
+{
+ Rectangle aRect1;
+ rStat.TakeCreateRect(aRect1);
+ ImpJustifyRect(aRect1);
+ rStat.SetActionRect(aRect1);
+ aRect=aRect1; // fuer ObjName
+ SetBoundRectDirty();
+ bSnapRectDirty=TRUE;
+ if (HAS_BASE(SdrRectObj,this)) {
+ ((SdrRectObj*)this)->SetXPolyDirty();
+ }
+ return TRUE;
+}
+
+FASTBOOL SdrTextObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ rStat.TakeCreateRect(aRect);
+ ImpJustifyRect(aRect);
+ if (bTextFrame) {
+ if (IsAutoGrowHeight()) {
+ // MinTextHeight
+ long nHgt=aRect.GetHeight()-1;
+ if (nHgt==1) nHgt=0;
+ NbcSetMinTextFrameHeight(nHgt);
+ }
+ if (IsAutoGrowWidth()) {
+ // MinTextWidth
+ long nWdt=aRect.GetWidth()-1;
+ if (nWdt==1) nWdt=0;
+ NbcSetMinTextFrameWidth(nWdt);
+ }
+ // Textrahmen neu berechnen
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ SetRectsDirty();
+ if (HAS_BASE(SdrRectObj,this)) {
+ ((SdrRectObj*)this)->SetXPolyDirty();
+ }
+ return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
+}
+
+void SdrTextObj::BrkCreate(SdrDragStat& /*rStat*/)
+{
+}
+
+FASTBOOL SdrTextObj::BckCreate(SdrDragStat& /*rStat*/)
+{
+ return TRUE;
+}
+
+basegfx::B2DPolyPolygon SdrTextObj::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ Rectangle aRect1;
+ rDrag.TakeCreateRect(aRect1);
+ aRect1.Justify();
+
+ basegfx::B2DPolyPolygon aRetval;
+ const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
+ aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
+ return aRetval;
+}
+
+Pointer SdrTextObj::GetCreatePointer() const
+{
+ if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT);
+ return Pointer(POINTER_CROSS);
+}
+
diff --git a/svx/source/svdraw/svdotxed.cxx b/svx/source/svdraw/svdotxed.cxx
new file mode 100644
index 000000000000..c7715f37764c
--- /dev/null
+++ b/svx/source/svdraw/svdotxed.cxx
@@ -0,0 +1,350 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx> // fuer GetMaxObjSize
+#include <svx/svdoutl.hxx>
+#include <editeng/outliner.hxx>
+#include <editeng/editstat.hxx>
+#include <svl/itemset.hxx>
+#include <editeng/eeitem.hxx>
+#include <svx/sdtfchim.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+// TextEdit
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrTextObj::HasTextEdit() const
+{
+ // lt. Anweisung von MB duerfen gelinkte Textobjekte nun doch
+ // geaendert werden (kein automatisches Reload)
+ return TRUE;
+}
+
+sal_Bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
+{
+ if (pEdtOutl!=NULL) return sal_False; // Textedit laeuft evtl. schon an einer anderen View!
+ pEdtOutl=&rOutl;
+
+ // #101684#
+ mbInEditMode = TRUE;
+
+ USHORT nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
+ if ( !IsOutlText() )
+ nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
+ rOutl.Init( nOutlinerMode );
+ rOutl.SetRefDevice( pModel->GetRefDevice() );
+
+ SdrFitToSizeType eFit=GetFitToSize();
+ FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ FASTBOOL bContourFrame=IsContourTextFrame();
+ ImpSetTextEditParams();
+
+ if (!bContourFrame) {
+ ULONG nStat=rOutl.GetControlWord();
+ nStat|=EE_CNTRL_AUTOPAGESIZE;
+ if (bFitToSize) nStat|=EE_CNTRL_STRETCHING; else nStat&=~EE_CNTRL_STRETCHING;
+ rOutl.SetControlWord(nStat);
+ }
+
+ OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
+ if(pOutlinerParaObject!=NULL)
+ {
+ rOutl.SetText(*GetOutlinerParaObject());
+ rOutl.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
+ }
+
+ // ggf. Rahmenattribute am 1. (neuen) Absatz des Outliners setzen
+ if( !HasTextImpl( &rOutl ) )
+ {
+ // Outliner has no text so we must set some
+ // empty text so the outliner initialise itself
+ rOutl.SetText( String(), rOutl.GetParagraph( 0 ) );
+
+ if(GetStyleSheet())
+ rOutl.SetStyleSheet( 0, GetStyleSheet());
+
+ // Beim setzen der harten Attribute an den ersten Absatz muss
+ // der Parent pOutlAttr (=die Vorlage) temporaer entfernt
+ // werden, da sonst bei SetParaAttribs() auch alle in diesem
+ // Parent enthaltenen Items hart am Absatz attributiert werden.
+ // -> BugID 22467
+ const SfxItemSet& rSet = GetObjectItemSet();
+ SfxItemSet aFilteredSet(*rSet.GetPool(), EE_ITEMS_START, EE_ITEMS_END);
+ aFilteredSet.Put(rSet);
+ rOutl.SetParaAttribs(0, aFilteredSet);
+ }
+ if (bFitToSize)
+ {
+ Rectangle aAnchorRect;
+ Rectangle aTextRect;
+ TakeTextRect(rOutl, aTextRect, FALSE,
+ &aAnchorRect/* #97097# give TRUE here, not FALSE */);
+ Fraction aFitXKorreg(1,1);
+ ImpSetCharStretching(rOutl,aTextRect,aAnchorRect,aFitXKorreg);
+ }
+
+ if(pOutlinerParaObject)
+ {
+ // #78476# also repaint when animated text is put to edit mode
+ // to not make appear the text double
+ // #111096# should now repaint automatically.
+ // BOOL bIsAnimated(pPlusData && pPlusData->pAnimator);
+
+ if(aGeo.nDrehWink || IsFontwork() /*|| bIsAnimated*/)
+ {
+ // only repaint here, no real objectchange
+
+// ActionChanged();
+ BroadcastObjectChange();
+ }
+ }
+
+ rOutl.UpdateFields();
+ rOutl.ClearModifyFlag();
+
+ return sal_True;
+}
+
+void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
+{
+ SdrFitToSizeType eFit=GetFitToSize();
+ FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ Size aPaperMin,aPaperMax;
+ Rectangle aViewInit;
+ TakeTextAnchorRect(aViewInit);
+ if (aGeo.nDrehWink!=0) {
+ Point aCenter(aViewInit.Center());
+ aCenter-=aViewInit.TopLeft();
+ Point aCenter0(aCenter);
+ RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
+ aCenter-=aCenter0;
+ aViewInit.Move(aCenter.X(),aCenter.Y());
+ }
+ Size aAnkSiz(aViewInit.GetSize());
+ aAnkSiz.Width()--; aAnkSiz.Height()--; // weil GetSize() ein draufaddiert
+ Size aMaxSiz(1000000,1000000);
+ if (pModel!=NULL) {
+ Size aTmpSiz(pModel->GetMaxObjSize());
+ if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
+ if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
+ }
+
+ // #106879#
+ // Done earlier since used in else tree below
+ SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
+ SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
+
+ if(IsTextFrame())
+ {
+ long nMinWdt=GetMinTextFrameWidth();
+ long nMinHgt=GetMinTextFrameHeight();
+ long nMaxWdt=GetMaxTextFrameWidth();
+ long nMaxHgt=GetMaxTextFrameHeight();
+ if (nMinWdt<1) nMinWdt=1;
+ if (nMinHgt<1) nMinHgt=1;
+ if (!bFitToSize) {
+ if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
+ if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
+ if (!IsAutoGrowWidth() ) { nMaxWdt=aAnkSiz.Width(); nMinWdt=nMaxWdt; }
+ if (!IsAutoGrowHeight()) { nMaxHgt=aAnkSiz.Height(); nMinHgt=nMaxHgt; }
+ SdrTextAniKind eAniKind=GetTextAniKind();
+ SdrTextAniDirection eAniDirection=GetTextAniDirection();
+
+ // #101684#
+ BOOL bInEditMode = IsInEditMode();
+
+ if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
+ {
+ // Grenzenlose Papiergroesse fuer Laufschrift
+ if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
+ if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
+ }
+ aPaperMax.Width()=nMaxWdt;
+ aPaperMax.Height()=nMaxHgt;
+ } else {
+ aPaperMax=aMaxSiz;
+ }
+ aPaperMin.Width()=nMinWdt;
+ aPaperMin.Height()=nMinHgt;
+ }
+ else
+ {
+ // #106879#
+ // aPaperMin needs to be set to object's size if full width is activated
+ // for hor or ver writing respectively
+ if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
+ || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
+ {
+ aPaperMin = aAnkSiz;
+ }
+
+ aPaperMax=aMaxSiz;
+ }
+
+ if (pViewMin!=NULL) {
+ *pViewMin=aViewInit;
+
+ long nXFree=aAnkSiz.Width()-aPaperMin.Width();
+ if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
+ else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
+ else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
+
+ long nYFree=aAnkSiz.Height()-aPaperMin.Height();
+ if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
+ else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
+ else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
+ }
+
+ // Die PaperSize soll in den meisten Faellen von selbst wachsen
+ // #89459#
+ if(IsVerticalWriting())
+ aPaperMin.Width() = 0;
+ else
+ aPaperMin.Height() = 0; // #33102#
+
+ if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
+ aPaperMin.Width()=0;
+ }
+
+ // #103516# For complete ver adjust support, set paper min height to 0, here.
+ if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
+ {
+ aPaperMin.Height() = 0;
+ }
+
+ if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
+ if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
+ if (pViewInit!=NULL) *pViewInit=aViewInit;
+}
+
+void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
+{
+ if(rOutl.IsModified())
+ {
+ OutlinerParaObject* pNewText = NULL;
+
+ if(HasTextImpl( &rOutl ) )
+ {
+ // Damit der grauen Feldhintergrund wieder verschwindet
+ rOutl.UpdateFields();
+
+ sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( rOutl.GetParagraphCount() );
+ pNewText = rOutl.CreateParaObject( 0, nParaAnz );
+ }
+
+ // need to end edit mode early since SetOutlinerParaObject already
+ // uses GetCurrentBoundRect() which needs to take the text into account
+ // to work correct
+ mbInEditMode = FALSE;
+ SetOutlinerParaObject(pNewText);
+ }
+
+ pEdtOutl = NULL;
+ rOutl.Clear();
+ UINT32 nStat = rOutl.GetControlWord();
+ nStat &= ~EE_CNTRL_AUTOPAGESIZE;
+ rOutl.SetControlWord(nStat);
+
+ // #101684#
+ mbInEditMode = FALSE;
+}
+
+USHORT SdrTextObj::GetOutlinerViewAnchorMode() const
+{
+ SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
+ SdrTextVertAdjust eV=GetTextVerticalAdjust();
+ EVAnchorMode eRet=ANCHOR_TOP_LEFT;
+ if (IsContourTextFrame()) return (USHORT)eRet;
+ if (eH==SDRTEXTHORZADJUST_LEFT) {
+ if (eV==SDRTEXTVERTADJUST_TOP) {
+ eRet=ANCHOR_TOP_LEFT;
+ } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
+ eRet=ANCHOR_BOTTOM_LEFT;
+ } else {
+ eRet=ANCHOR_VCENTER_LEFT;
+ }
+ } else if (eH==SDRTEXTHORZADJUST_RIGHT) {
+ if (eV==SDRTEXTVERTADJUST_TOP) {
+ eRet=ANCHOR_TOP_RIGHT;
+ } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
+ eRet=ANCHOR_BOTTOM_RIGHT;
+ } else {
+ eRet=ANCHOR_VCENTER_RIGHT;
+ }
+ } else {
+ if (eV==SDRTEXTVERTADJUST_TOP) {
+ eRet=ANCHOR_TOP_HCENTER;
+ } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
+ eRet=ANCHOR_BOTTOM_HCENTER;
+ } else {
+ eRet=ANCHOR_VCENTER_HCENTER;
+ }
+ }
+ return (USHORT)eRet;
+}
+
+void SdrTextObj::ImpSetTextEditParams() const
+{
+ if (pEdtOutl!=NULL) {
+ FASTBOOL bUpdMerk=pEdtOutl->GetUpdateMode();
+ if (bUpdMerk) pEdtOutl->SetUpdateMode(FALSE);
+ Size aPaperMin;
+ Size aPaperMax;
+ Rectangle aEditArea;
+ TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
+ //SdrFitToSizeType eFit=GetFitToSize();
+ //FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ FASTBOOL bContourFrame=IsContourTextFrame();
+ //EVAnchorMode eAM=(EVAnchorMode)GetOutlinerViewAnchorMode();
+ //ULONG nViewAnz=pEdtOutl->GetViewCount();
+ pEdtOutl->SetMinAutoPaperSize(aPaperMin);
+ pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
+ pEdtOutl->SetPaperSize(Size());
+ if (bContourFrame) {
+ Rectangle aAnchorRect;
+ TakeTextAnchorRect(aAnchorRect);
+ ImpSetContourPolygon(*pEdtOutl,aAnchorRect, TRUE);
+ }
+ if (bUpdMerk) pEdtOutl->SetUpdateMode(TRUE);
+ }
+}
+
diff --git a/svx/source/svdraw/svdotxfl.cxx b/svx/source/svdraw/svdotxfl.cxx
new file mode 100644
index 000000000000..fe21621c1b9a
--- /dev/null
+++ b/svx/source/svdraw/svdotxfl.cxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <editeng/eeitem.hxx>
+
+#include <editeng/measfld.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdfield.hxx>
+
+static BOOL bInit = FALSE;
+
+// Do not remove this, it is still used in src536a!
+void SdrRegisterFieldClasses()
+{
+ if ( !bInit )
+ {
+ SvxFieldItem::GetClassManager().SV_CLASS_REGISTER(SdrMeasureField);
+ SvxFieldItem::GetClassManager().SV_CLASS_REGISTER(SvxHeaderField);
+ SvxFieldItem::GetClassManager().SV_CLASS_REGISTER(SvxFooterField);
+ SvxFieldItem::GetClassManager().SV_CLASS_REGISTER(SvxDateTimeField);
+ bInit = TRUE;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////// */
+
+FASTBOOL SdrTextObj::CalcFieldValue(const SvxFieldItem& /*rField*/, USHORT /*nPara*/, USHORT /*nPos*/,
+ FASTBOOL /*bEdit*/, Color*& /*rpTxtColor*/, Color*& /*rpFldColor*/, XubString& /*rRet*/) const
+{
+ return FALSE;
+}
+
diff --git a/svx/source/svdraw/svdotxln.cxx b/svx/source/svdraw/svdotxln.cxx
new file mode 100644
index 000000000000..7d176fbfe811
--- /dev/null
+++ b/svx/source/svdraw/svdotxln.cxx
@@ -0,0 +1,350 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <unotools/datetime.hxx>
+#include <svx/svdotext.hxx>
+#include "svditext.hxx"
+#include <svx/svdmodel.hxx>
+#include <editeng/editdata.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <svl/urihelper.hxx>
+
+// #90477#
+#include <tools/tenccvt.hxx>
+
+#ifndef SVX_LIGHT
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@ @@ @@@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@@@ @@ @@ @@ @@@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@@@@ @@ @@ @@ @@ @@@@@@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@@ @@ @@ @@ @@ @@@ @@ @@
+// @@@@ @@@@@ @@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@ @@ @@ @@
+//
+// ImpSdrObjTextLink zur Verbindung von SdrTextObj und LinkManager
+//
+// Einem solchen Link merke ich mir als SdrObjUserData am Objekt. Im Gegensatz
+// zum Grafik-Link werden die ObjektDaten jedoch kopiert (fuer Paint, etc.).
+// Die Information ob das Objekt ein Link ist besteht genau darin, dass dem
+// Objekt ein entsprechender UserData-Record angehaengt ist oder nicht.
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class ImpSdrObjTextLink: public ::sfx2::SvBaseLink
+{
+ SdrTextObj* pSdrObj;
+
+public:
+ ImpSdrObjTextLink( SdrTextObj* pObj1 )
+ : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ),
+ pSdrObj( pObj1 )
+ {}
+ virtual ~ImpSdrObjTextLink();
+
+ virtual void Closed();
+ virtual void DataChanged( const String& rMimeType,
+ const ::com::sun::star::uno::Any & rValue );
+
+ BOOL Connect() { return 0 != SvBaseLink::GetRealObject(); }
+};
+
+ImpSdrObjTextLink::~ImpSdrObjTextLink()
+{
+}
+
+void ImpSdrObjTextLink::Closed()
+{
+ if (pSdrObj )
+ {
+ // pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
+ ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
+ if (pData!=NULL) pData->pLink=NULL;
+ pSdrObj->ReleaseTextLink();
+ }
+ SvBaseLink::Closed();
+}
+
+
+void ImpSdrObjTextLink::DataChanged( const String& /*rMimeType*/,
+ const ::com::sun::star::uno::Any & /*rValue */)
+{
+ FASTBOOL bForceReload=FALSE;
+ SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0;
+ sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
+ if( pLinkManager )
+ {
+ ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
+ if( pData )
+ {
+ String aFile;
+ String aFilter;
+ pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter );
+
+ if( !pData->aFileName.Equals( aFile ) ||
+ !pData->aFilterName.Equals( aFilter ))
+ {
+ pData->aFileName = aFile;
+ pData->aFilterName = aFilter;
+ pSdrObj->SetChanged();
+ bForceReload = TRUE;
+ }
+ }
+ }
+ if (pSdrObj )
+ pSdrObj->ReloadLinkedText( bForceReload );
+}
+#endif // SVX_LIGHT
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@@@@@ @@@@@ @@@@@ @@@@ @@@@@@ @@@@
+// @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@@ @@@@ @@ @@ @@@@ @@@@@ @@@@@ @@ @@ @@@@@@ @@ @@@@@@
+// @@ @@ @@ @@@ @@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@@ @@ @@ @@ @@ @@ @@@@ @@@@@ @@@@@@ @@ @@ @@@@@ @@ @@ @@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData);
+
+ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1):
+ SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0),
+ pObj(pObj1),
+ pLink(NULL),
+ eCharSet(RTL_TEXTENCODING_DONTKNOW)
+{
+}
+
+ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
+{
+#ifndef SVX_LIGHT
+ delete pLink;
+#endif
+}
+
+SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const
+{
+ ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1);
+ pData->aFileName =aFileName;
+ pData->aFilterName=aFilterName;
+ pData->aFileDate0 =aFileDate0;
+ pData->eCharSet =eCharSet;
+ pData->pLink=NULL;
+ return pData;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrTextObj::SetTextLink(const String& rFileName, const String& rFilterName, rtl_TextEncoding eCharSet)
+{
+ if(eCharSet == RTL_TEXTENCODING_DONTKNOW)
+ eCharSet = gsl_getSystemTextEncoding();
+
+ ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
+ if (pData!=NULL) {
+ ReleaseTextLink();
+ }
+ pData=new ImpSdrObjTextLinkUserData(this);
+ pData->aFileName=rFileName;
+ pData->aFilterName=rFilterName;
+ pData->eCharSet=eCharSet;
+ InsertUserData(pData);
+ ImpLinkAnmeldung();
+}
+
+void SdrTextObj::ReleaseTextLink()
+{
+ ImpLinkAbmeldung();
+ USHORT nAnz=GetUserDataCount();
+ for (USHORT nNum=nAnz; nNum>0;) {
+ nNum--;
+ SdrObjUserData* pData=GetUserData(nNum);
+ if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
+ DeleteUserData(nNum);
+ }
+ }
+}
+
+FASTBOOL SdrTextObj::ReloadLinkedText( FASTBOOL bForceLoad)
+{
+ ImpSdrObjTextLinkUserData* pData = GetLinkUserData();
+ FASTBOOL bRet = TRUE;
+
+ if( pData )
+ {
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ DateTime aFileDT;
+ BOOL bExists = FALSE, bLoad = FALSE;
+
+ if( pBroker )
+ {
+ bExists = TRUE;
+
+ try
+ {
+ INetURLObject aURL( pData->aFileName );
+ DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
+
+ ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
+ ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) ) );
+ ::com::sun::star::util::DateTime aDateTime;
+
+ aAny >>= aDateTime;
+ ::utl::typeConvert( aDateTime, aFileDT );
+ }
+ catch( ... )
+ {
+ bExists = FALSE;
+ }
+ }
+
+ if( bExists )
+ {
+ if( bForceLoad )
+ bLoad = TRUE;
+ else
+ bLoad = ( aFileDT > pData->aFileDate0 );
+
+ if( bLoad )
+ {
+ bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet );
+ }
+
+ pData->aFileDate0 = aFileDT;
+ }
+ }
+
+ return bRet;
+}
+
+FASTBOOL SdrTextObj::LoadText(const String& rFileName, const String& /*rFilterName*/, rtl_TextEncoding eCharSet)
+{
+ INetURLObject aFileURL( rFileName );
+ BOOL bRet = FALSE;
+
+ if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID )
+ {
+ String aFileURLStr;
+
+ if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) )
+ aFileURL = INetURLObject( aFileURLStr );
+ else
+ aFileURL.SetSmartURL( rFileName );
+ }
+
+ DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );
+
+ SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
+
+ if( pIStm )
+ {
+ // #90477# pIStm->SetStreamCharSet( eCharSet );
+ pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet, (sal_uInt16)pIStm->GetVersion()));
+
+ char cRTF[5];
+ cRTF[4] = 0;
+ pIStm->Read(cRTF, 5);
+
+ BOOL bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';
+
+ pIStm->Seek(0);
+
+ if( !pIStm->GetError() )
+ {
+ SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< USHORT >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) );
+ bRet = TRUE;
+ }
+
+ delete pIStm;
+ }
+
+ return bRet;
+}
+
+ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const
+{
+ ImpSdrObjTextLinkUserData* pData=NULL;
+ USHORT nAnz=GetUserDataCount();
+ for (USHORT nNum=nAnz; nNum>0 && pData==NULL;) {
+ nNum--;
+ pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum);
+ if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) {
+ pData=NULL;
+ }
+ }
+ return pData;
+}
+
+void SdrTextObj::ImpLinkAnmeldung()
+{
+ ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
+ sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
+ if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // Nicht 2x Anmelden
+ pData->pLink=new ImpSdrObjTextLink(this);
+#ifdef GCC
+ pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
+ pData->aFilterName.Len() ?
+ &pData->aFilterName : (const String *)NULL,
+ (const String *)NULL);
+#else
+ pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
+ pData->aFilterName.Len() ? &pData->aFilterName : NULL,NULL);
+#endif
+ pData->pLink->Connect();
+ }
+}
+
+void SdrTextObj::ImpLinkAbmeldung()
+{
+ ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
+ sfx2::LinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
+ if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // Nicht 2x Abmelden
+ // Bei Remove wird *pLink implizit deleted
+ pLinkManager->Remove( pData->pLink );
+ pData->pLink=NULL;
+ }
+}
+
diff --git a/svx/source/svdraw/svdotxtr.cxx b/svx/source/svdraw/svdotxtr.cxx
new file mode 100644
index 000000000000..bd1564ab3f4e
--- /dev/null
+++ b/svx/source/svdraw/svdotxtr.cxx
@@ -0,0 +1,558 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdotext.hxx>
+#include "svditext.hxx"
+#include <svx/svdtrans.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdpage.hxx> // fuer Convert
+#include <svx/svdmodel.hxx> // fuer Convert
+#include <editeng/outliner.hxx>
+#include <svx/sdr/properties/itemsettools.hxx>
+#include <svx/sdr/properties/properties.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <svl/itemset.hxx>
+#include <svditer.hxx>
+#include <drawinglayer/processor2d/textaspolygonextractor2d.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
+// @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
+//
+// Transformationen
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrTextObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
+ Rectangle aSR0(GetSnapRect());
+ long nWdt0=aSR0.Right()-aSR0.Left();
+ long nHgt0=aSR0.Bottom()-aSR0.Top();
+ long nWdt1=rRect.Right()-rRect.Left();
+ long nHgt1=rRect.Bottom()-rRect.Top();
+ SdrTextObj::NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
+ SdrTextObj::NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
+ } else {
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
+ long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
+ long nTWdt1=rRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
+ long nTHgt1=rRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
+ aRect=rRect;
+ ImpJustifyRect(aRect);
+ if (bTextFrame && (pModel==NULL || !pModel->IsPasteResize())) { // #51139#
+ if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
+ if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
+ if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
+ NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
+ }
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ ImpCheckShear();
+ SetRectsDirty();
+ }
+}
+
+const Rectangle& SdrTextObj::GetLogicRect() const
+{
+ return aRect;
+}
+
+void SdrTextObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
+ long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
+ long nTWdt1=rRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
+ long nTHgt1=rRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
+ aRect=rRect;
+ ImpJustifyRect(aRect);
+ if (bTextFrame) {
+ if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
+ if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
+ if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
+ NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
+ }
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ SetRectsDirty();
+}
+
+long SdrTextObj::GetRotateAngle() const
+{
+ return aGeo.nDrehWink;
+}
+
+long SdrTextObj::GetShearAngle(FASTBOOL /*bVertical*/) const
+{
+ return aGeo.nShearWink;
+}
+
+void SdrTextObj::NbcMove(const Size& rSiz)
+{
+ MoveRect(aRect,rSiz);
+ MoveRect(aOutRect,rSiz);
+ MoveRect(maSnapRect,rSiz);
+ SetRectsDirty(sal_True);
+}
+
+void SdrTextObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ FASTBOOL bNoShearMerk=aGeo.nShearWink==0;
+ FASTBOOL bRota90Merk=bNoShearMerk && aGeo.nDrehWink % 9000 ==0;
+ long nHDist=GetTextLeftDistance()+GetTextRightDistance();
+ long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
+ long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
+ long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
+ FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
+ FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
+ if (bXMirr || bYMirr) {
+ Point aRef1(GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ }
+
+ if (aGeo.nDrehWink==0 && aGeo.nShearWink==0) {
+ ResizeRect(aRect,rRef,xFact,yFact);
+ if (bYMirr) {
+ aRect.Justify();
+ aRect.Move(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top());
+ aGeo.nDrehWink=18000;
+ aGeo.RecalcSinCos();
+ }
+ }
+ else
+ {
+ // #100663# aRect is NOT initialized for lines (polgon objects with two
+ // exceptionally handled points). Thus, after this call the text rotaion is
+ // gone. This error must be present since day one of this old drawing layer.
+ // It's astonishing that noone discovered it earlier.
+ // Polygon aPol(Rect2Poly(aRect,aGeo));
+ // Polygon aPol(Rect2Poly(GetSnapRect(), aGeo));
+
+ // #101412# go back to old method, side effects are impossible
+ // to calculate.
+ Polygon aPol(Rect2Poly(aRect,aGeo));
+
+ for(sal_uInt16 a(0); a < aPol.GetSize(); a++)
+ {
+ ResizePoint(aPol[a], rRef, xFact, yFact);
+ }
+
+ if(bXMirr != bYMirr)
+ {
+ // Polygon wenden und etwas schieben
+ Polygon aPol0(aPol);
+
+ aPol[0] = aPol0[1];
+ aPol[1] = aPol0[0];
+ aPol[2] = aPol0[3];
+ aPol[3] = aPol0[2];
+ aPol[4] = aPol0[1];
+ }
+
+ Poly2Rect(aPol, aRect, aGeo);
+ }
+
+ if (bRota90Merk) {
+ FASTBOOL bRota90=aGeo.nDrehWink % 9000 ==0;
+ if (!bRota90) { // Scheinbar Rundungsfehler: Korregieren
+ long a=NormAngle360(aGeo.nDrehWink);
+ if (a<4500) a=0;
+ else if (a<13500) a=9000;
+ else if (a<22500) a=18000;
+ else if (a<31500) a=27000;
+ else a=0;
+ aGeo.nDrehWink=a;
+ aGeo.RecalcSinCos();
+ }
+ if (bNoShearMerk!=(aGeo.nShearWink==0)) { // Shear ggf. korregieren wg. Rundungsfehler
+ aGeo.nShearWink=0;
+ aGeo.RecalcTan();
+ }
+ }
+
+ ImpJustifyRect(aRect);
+ long nTWdt1=aRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
+ long nTHgt1=aRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
+ if (bTextFrame && (pModel==NULL || !pModel->IsPasteResize())) { // #51139#
+ if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
+ if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
+ if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
+ NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
+ }
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ ImpCheckShear();
+ SetRectsDirty();
+}
+
+void SdrTextObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ SetGlueReallyAbsolute(TRUE);
+ long dx=aRect.Right()-aRect.Left();
+ long dy=aRect.Bottom()-aRect.Top();
+ Point aP(aRect.TopLeft());
+ RotatePoint(aP,rRef,sn,cs);
+ aRect.Left()=aP.X();
+ aRect.Top()=aP.Y();
+ aRect.Right()=aRect.Left()+dx;
+ aRect.Bottom()=aRect.Top()+dy;
+ if (aGeo.nDrehWink==0) {
+ aGeo.nDrehWink=NormAngle360(nWink);
+ aGeo.nSin=sn;
+ aGeo.nCos=cs;
+ } else {
+ aGeo.nDrehWink=NormAngle360(aGeo.nDrehWink+nWink);
+ aGeo.RecalcSinCos();
+ }
+ SetRectsDirty();
+ NbcRotateGluePoints(rRef,nWink,sn,cs);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+void SdrTextObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ SetGlueReallyAbsolute(TRUE);
+
+ // #75889# when this is a SdrPathObj aRect maybe not initialized
+ Polygon aPol(Rect2Poly(aRect.IsEmpty() ? GetSnapRect() : aRect, aGeo));
+
+ USHORT nPointCount=aPol.GetSize();
+ for (USHORT i=0; i<nPointCount; i++) {
+ ShearPoint(aPol[i],rRef,tn,bVShear);
+ }
+ Poly2Rect(aPol,aRect,aGeo);
+ ImpJustifyRect(aRect);
+ if (bTextFrame) {
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ ImpCheckShear();
+ SetRectsDirty();
+ NbcShearGluePoints(rRef,nWink,tn,bVShear);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+void SdrTextObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ SetGlueReallyAbsolute(TRUE);
+ FASTBOOL bNoShearMerk=aGeo.nShearWink==0;
+ FASTBOOL bRota90Merk=FALSE;
+ if (bNoShearMerk &&
+ (rRef1.X()==rRef2.X() || rRef1.Y()==rRef2.Y() ||
+ Abs(rRef1.X()-rRef2.X())==Abs(rRef1.Y()-rRef2.Y()))) {
+ bRota90Merk=aGeo.nDrehWink % 9000 ==0;
+ }
+ Polygon aPol(Rect2Poly(aRect,aGeo));
+ USHORT i;
+ USHORT nPntAnz=aPol.GetSize();
+ for (i=0; i<nPntAnz; i++) {
+ MirrorPoint(aPol[i],rRef1,rRef2);
+ }
+ // Polygon wenden und etwas schieben
+ Polygon aPol0(aPol);
+ aPol[0]=aPol0[1];
+ aPol[1]=aPol0[0];
+ aPol[2]=aPol0[3];
+ aPol[3]=aPol0[2];
+ aPol[4]=aPol0[1];
+ Poly2Rect(aPol,aRect,aGeo);
+
+ if (bRota90Merk) {
+ FASTBOOL bRota90=aGeo.nDrehWink % 9000 ==0;
+ if (bRota90Merk && !bRota90) { // Scheinbar Rundungsfehler: Korregieren
+ long a=NormAngle360(aGeo.nDrehWink);
+ if (a<4500) a=0;
+ else if (a<13500) a=9000;
+ else if (a<22500) a=18000;
+ else if (a<31500) a=27000;
+ else a=0;
+ aGeo.nDrehWink=a;
+ aGeo.RecalcSinCos();
+ }
+ }
+ if (bNoShearMerk!=(aGeo.nShearWink==0)) { // Shear ggf. korregieren wg. Rundungsfehler
+ aGeo.nShearWink=0;
+ aGeo.RecalcTan();
+ }
+
+ ImpJustifyRect(aRect);
+ if (bTextFrame) {
+ NbcAdjustTextFrameWidthAndHeight();
+ }
+ ImpCheckShear();
+ SetRectsDirty();
+ NbcMirrorGluePoints(rRef1,rRef2);
+ SetGlueReallyAbsolute(FALSE);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrTextObj::ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const
+{
+ SdrObject* pRetval = 0;
+
+ if(!ImpCanConvTextToCurve())
+ {
+ // suppress HelpTexts from PresObj's
+ return 0;
+ }
+
+ // get primitives
+ const drawinglayer::primitive2d::Primitive2DSequence xSequence(GetViewContact().getViewIndependentPrimitive2DSequence());
+
+ if(xSequence.hasElements())
+ {
+ // create an extractor with neutral ViewInformation
+ const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0);
+ drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
+
+ // extract text as polygons
+ aExtractor.process(xSequence);
+
+ // get results
+ const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
+ const sal_uInt32 nResultCount(rResult.size());
+
+ if(nResultCount)
+ {
+ // prepare own target
+ SdrObjGroup* pGroup = new SdrObjGroup();
+ SdrObjList* pObjectList = pGroup->GetSubList();
+
+ // process results
+ for(sal_uInt32 a(0); a < nResultCount; a++)
+ {
+ const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
+ basegfx::B2DPolyPolygon aPolyPolygon(rCandidate.getB2DPolyPolygon());
+
+ if(aPolyPolygon.count())
+ {
+ // take care of wanted polygon type
+ if(bToPoly)
+ {
+ if(aPolyPolygon.areControlPointsUsed())
+ {
+ aPolyPolygon = basegfx::tools::adaptiveSubdivideByAngle(aPolyPolygon);
+ }
+ }
+ else
+ {
+ if(!aPolyPolygon.areControlPointsUsed())
+ {
+ aPolyPolygon = basegfx::tools::expandToCurve(aPolyPolygon);
+ }
+ }
+
+ // create ItemSet with object attributes
+ SfxItemSet aAttributeSet(GetObjectItemSet());
+ SdrPathObj* pPathObj = 0;
+
+ // always clear objectshadow; this is included in the extraction
+ aAttributeSet.Put(SdrShadowItem(false));
+
+ if(rCandidate.getIsFilled())
+ {
+ // set needed items
+ aAttributeSet.Put(XFillColorItem(String(), Color(rCandidate.getBColor())));
+ aAttributeSet.Put(XLineStyleItem(XLINE_NONE));
+ aAttributeSet.Put(XFillStyleItem(XFILL_SOLID));
+
+ // create filled SdrPathObj
+ pPathObj = new SdrPathObj(OBJ_PATHFILL, aPolyPolygon);
+ }
+ else
+ {
+ // set needed items
+ aAttributeSet.Put(XLineColorItem(String(), Color(rCandidate.getBColor())));
+ aAttributeSet.Put(XLineStyleItem(XLINE_SOLID));
+ aAttributeSet.Put(XLineWidthItem(0));
+ aAttributeSet.Put(XFillStyleItem(XFILL_NONE));
+
+ // create line SdrPathObj
+ pPathObj = new SdrPathObj(OBJ_PATHLINE, aPolyPolygon);
+ }
+
+ // copy basic information from original
+ pPathObj->ImpSetAnchorPos(GetAnchorPos());
+ pPathObj->NbcSetLayer(GetLayer());
+
+ if(GetModel())
+ {
+ pPathObj->SetModel(GetModel());
+ pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
+ }
+
+ // apply prepared ItemSet and add to target
+ pPathObj->SetMergedItemSet(aAttributeSet);
+ pObjectList->InsertObject(pPathObj);
+ }
+ }
+
+ // postprocess; if no result and/or only one object, simplify
+ if(!pObjectList->GetObjCount())
+ {
+ delete pGroup;
+ }
+ else if(1 == pObjectList->GetObjCount())
+ {
+ pRetval = pObjectList->RemoveObject(0);
+ delete pGroup;
+ }
+ else
+ {
+ pRetval = pGroup;
+ }
+ }
+ }
+
+ return pRetval;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+SdrObject* SdrTextObj::DoConvertToPolyObj(BOOL bBezier) const
+{
+ return ImpConvertContainedTextToSdrPathObjs(!bBezier);
+}
+
+bool SdrTextObj::ImpCanConvTextToCurve() const
+{
+ return !IsOutlText();
+}
+
+SdrObject* SdrTextObj::ImpConvertMakeObj(const basegfx::B2DPolyPolygon& rPolyPolygon, sal_Bool bClosed, sal_Bool bBezier, sal_Bool bNoSetAttr) const
+{
+ SdrObjKind ePathKind = bClosed ? OBJ_PATHFILL : OBJ_PATHLINE;
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon);
+
+ // #i37011#
+ if(!bBezier)
+ {
+ aB2DPolyPolygon = basegfx::tools::adaptiveSubdivideByAngle(aB2DPolyPolygon);
+ ePathKind = bClosed ? OBJ_POLY : OBJ_PLIN;
+ }
+
+ SdrPathObj* pPathObj = new SdrPathObj(ePathKind, aB2DPolyPolygon);
+
+ if(bBezier)
+ {
+ // create bezier curves
+ pPathObj->SetPathPoly(basegfx::tools::expandToCurve(pPathObj->GetPathPoly()));
+ }
+
+ if(pPathObj)
+ {
+ pPathObj->ImpSetAnchorPos(aAnchor);
+ pPathObj->NbcSetLayer(SdrLayerID(GetLayer()));
+
+ if(pModel)
+ {
+ pPathObj->SetModel(pModel);
+
+ if(!bNoSetAttr)
+ {
+ sdr::properties::ItemChangeBroadcaster aC(*pPathObj);
+
+ pPathObj->ClearMergedItem();
+ pPathObj->SetMergedItemSet(GetObjectItemSet());
+ pPathObj->GetProperties().BroadcastItemChange(aC);
+ pPathObj->NbcSetStyleSheet(GetStyleSheet(), sal_True);
+ }
+ }
+ }
+
+ return pPathObj;
+}
+
+SdrObject* SdrTextObj::ImpConvertAddText(SdrObject* pObj, FASTBOOL bBezier) const
+{
+ if(!ImpCanConvTextToCurve())
+ {
+ return pObj;
+ }
+
+ SdrObject* pText = ImpConvertContainedTextToSdrPathObjs(!bBezier);
+
+ if(!pText)
+ {
+ return pObj;
+ }
+
+ if(!pObj)
+ {
+ return pText;
+ }
+
+ if(pText->IsGroupObject())
+ {
+ // is already group object, add partial shape in front
+ SdrObjList* pOL=pText->GetSubList();
+ pOL->InsertObject(pObj,0);
+
+ return pText;
+ }
+ else
+ {
+ // not yet a group, create one and add partial and new shapes
+ SdrObjGroup* pGrp=new SdrObjGroup;
+ SdrObjList* pOL=pGrp->GetSubList();
+ pOL->InsertObject(pObj);
+ pOL->InsertObject(pText);
+
+ return pGrp;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdouno.cxx b/svx/source/svdraw/svdouno.cxx
new file mode 100644
index 000000000000..b98e5ba5c1c6
--- /dev/null
+++ b/svx/source/svdraw/svdouno.cxx
@@ -0,0 +1,665 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/sdr/contact/viewcontactofunocontrol.hxx>
+#include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/io/XPersistObject.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XActiveDataSink.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XObjectOutputStream.hpp>
+#include <com/sun/star/io/XObjectInputStream.hpp>
+#include <com/sun/star/util/XCloneable.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/types.hxx>
+#include <vcl/pdfextoutdevdata.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdmodel.hxx>
+#include "svdglob.hxx" // Stringcache
+#include "svdstr.hrc" // Objektname
+#include <svx/svdetc.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdorect.hxx>
+#include "svdviter.hxx"
+#include <rtl/ref.hxx>
+#include <set>
+#include <memory>
+#include <svx/sdrpagewindow.hxx>
+#include <sdrpaintwindow.hxx>
+#include <tools/diagnose_ex.h>
+#include <svx/svdograf.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::sdr::contact;
+
+//************************************************************
+// Defines
+//************************************************************
+
+//************************************************************
+// Hilfsklasse SdrControlEventListenerImpl
+//************************************************************
+#include <com/sun/star/lang/XEventListener.hpp>
+
+#include <cppuhelper/implbase1.hxx>
+
+// =============================================================================
+class SdrControlEventListenerImpl : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
+{
+protected:
+ SdrUnoObj* pObj;
+
+public:
+ SdrControlEventListenerImpl(SdrUnoObj* _pObj)
+ : pObj(_pObj)
+ {}
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
+
+ void StopListening(const uno::Reference< lang::XComponent >& xComp);
+ void StartListening(const uno::Reference< lang::XComponent >& xComp);
+};
+
+// XEventListener
+void SAL_CALL SdrControlEventListenerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (pObj)
+ {
+ pObj->xUnoControlModel = NULL;
+ }
+}
+
+void SdrControlEventListenerImpl::StopListening(const uno::Reference< lang::XComponent >& xComp)
+{
+ if (xComp.is())
+ xComp->removeEventListener(this);
+}
+
+void SdrControlEventListenerImpl::StartListening(const uno::Reference< lang::XComponent >& xComp)
+{
+ if (xComp.is())
+ xComp->addEventListener(this);
+}
+
+// =============================================================================
+struct SAL_DLLPRIVATE SdrUnoObjDataHolder
+{
+ mutable ::rtl::Reference< SdrControlEventListenerImpl >
+ pEventListener;
+};
+
+// =============================================================================
+namespace
+{
+ void lcl_ensureControlVisibility( SdrView* _pView, const SdrUnoObj* _pObject, bool _bVisible )
+ {
+ OSL_PRECOND( _pObject, "lcl_ensureControlVisibility: no object -> no survival!" );
+
+ SdrPageView* pPageView = _pView ? _pView->GetSdrPageView() : NULL;
+ DBG_ASSERT( pPageView, "lcl_ensureControlVisibility: no view found!" );
+ if ( !pPageView )
+ return;
+
+ ViewContact& rUnoControlContact( _pObject->GetViewContact() );
+
+ for ( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); ++i )
+ {
+ const SdrPageWindow* pPageWindow = pPageView->GetPageWindow( i );
+ DBG_ASSERT( pPageWindow, "lcl_ensureControlVisibility: invalid PageViewWindow!" );
+ if ( !pPageWindow )
+ continue;
+
+ if ( !pPageWindow->HasObjectContact() )
+ continue;
+
+ ObjectContact& rPageViewContact( pPageWindow->GetObjectContact() );
+ const ViewObjectContact& rViewObjectContact( rUnoControlContact.GetViewObjectContact( rPageViewContact ) );
+ const ViewObjectContactOfUnoControl* pUnoControlContact = dynamic_cast< const ViewObjectContactOfUnoControl* >( &rViewObjectContact );
+ DBG_ASSERT( pUnoControlContact, "lcl_ensureControlVisibility: wrong ViewObjectContact type!" );
+ if ( !pUnoControlContact )
+ continue;
+
+ pUnoControlContact->ensureControlVisibility( _bVisible );
+ }
+ }
+}
+
+//************************************************************
+// SdrUnoObj
+//************************************************************
+
+TYPEINIT1(SdrUnoObj, SdrRectObj);
+
+SdrUnoObj::SdrUnoObj(const String& rModelName, BOOL _bOwnUnoControlModel)
+: m_pImpl( new SdrUnoObjDataHolder ),
+ bOwnUnoControlModel( _bOwnUnoControlModel )
+{
+ bIsUnoObj = TRUE;
+
+ m_pImpl->pEventListener = new SdrControlEventListenerImpl(this);
+
+ // nur ein owner darf eigenstaendig erzeugen
+ if (rModelName.Len())
+ CreateUnoControlModel(rModelName);
+}
+
+SdrUnoObj::SdrUnoObj(const String& rModelName,
+ const uno::Reference< lang::XMultiServiceFactory >& rxSFac,
+ BOOL _bOwnUnoControlModel)
+: m_pImpl( new SdrUnoObjDataHolder ),
+ bOwnUnoControlModel( _bOwnUnoControlModel )
+{
+ bIsUnoObj = TRUE;
+
+ m_pImpl->pEventListener = new SdrControlEventListenerImpl(this);
+
+ // nur ein owner darf eigenstaendig erzeugen
+ if (rModelName.Len())
+ CreateUnoControlModel(rModelName,rxSFac);
+}
+
+SdrUnoObj::~SdrUnoObj()
+{
+ try
+ {
+ // clean up the control model
+ uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
+ if (xComp.is())
+ {
+ // is the control model owned by it's environment?
+ uno::Reference< container::XChild > xContent(xUnoControlModel, uno::UNO_QUERY);
+ if (xContent.is() && !xContent->getParent().is())
+ xComp->dispose();
+ else
+ m_pImpl->pEventListener->StopListening(xComp);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ OSL_ENSURE( sal_False, "SdrUnoObj::~SdrUnoObj: caught an exception!" );
+ }
+ delete m_pImpl;
+}
+
+void SdrUnoObj::SetModel(SdrModel* pNewModel)
+{
+ SdrRectObj::SetModel(pNewModel);
+}
+
+void SdrUnoObj::SetPage(SdrPage* pNewPage)
+{
+ SdrRectObj::SetPage(pNewPage);
+}
+
+void SdrUnoObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bRotateFreeAllowed = FALSE;
+ rInfo.bRotate90Allowed = FALSE;
+ rInfo.bMirrorFreeAllowed = FALSE;
+ rInfo.bMirror45Allowed = FALSE;
+ rInfo.bMirror90Allowed = FALSE;
+ rInfo.bTransparenceAllowed = FALSE;
+ rInfo.bGradientAllowed = FALSE;
+ rInfo.bShearAllowed = FALSE;
+ rInfo.bEdgeRadiusAllowed = FALSE;
+ rInfo.bNoOrthoDesired = FALSE;
+ rInfo.bCanConvToPath = FALSE;
+ rInfo.bCanConvToPoly = FALSE;
+ rInfo.bCanConvToPathLineToArea = FALSE;
+ rInfo.bCanConvToPolyLineToArea = FALSE;
+ rInfo.bCanConvToContour = FALSE;
+}
+
+UINT16 SdrUnoObj::GetObjIdentifier() const
+{
+ return UINT16(OBJ_UNO);
+}
+
+void SdrUnoObj::SetContextWritingMode( const sal_Int16 _nContextWritingMode )
+{
+ try
+ {
+ uno::Reference< beans::XPropertySet > xModelProperties( GetUnoControlModel(), uno::UNO_QUERY_THROW );
+ xModelProperties->setPropertyValue(
+ ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "ContextWritingMode" ) ),
+ uno::makeAny( _nContextWritingMode )
+ );
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+}
+
+// ----------------------------------------------------------------------------
+namespace
+{
+ /** helper class to restore graphics at <awt::XView> object after <SdrUnoObj::Paint>
+
+ OD 08.05.2003 #109432#
+ Restoration of graphics necessary to assure that paint on a window
+
+ @author OD
+ */
+ class RestoreXViewGraphics
+ {
+ private:
+ uno::Reference< awt::XView > m_rXView;
+ uno::Reference< awt::XGraphics > m_rXGraphics;
+
+ public:
+ RestoreXViewGraphics( const uno::Reference< awt::XView >& _rXView )
+ {
+ m_rXView = _rXView;
+ m_rXGraphics = m_rXView->getGraphics();
+ }
+ ~RestoreXViewGraphics()
+ {
+ m_rXView->setGraphics( m_rXGraphics );
+ }
+ };
+}
+
+void SdrUnoObj::TakeObjNameSingul(XubString& rName) const
+{
+ rName = ImpGetResStr(STR_ObjNameSingulUno);
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrUnoObj::TakeObjNamePlural(XubString& rName) const
+{
+ rName = ImpGetResStr(STR_ObjNamePluralUno);
+}
+
+void SdrUnoObj::operator = (const SdrObject& rObj)
+{
+ SdrRectObj::operator = (rObj);
+
+ // release the reference to the current control model
+ SetUnoControlModel(uno::Reference< awt::XControlModel >());
+
+ aUnoControlModelTypeName = ((SdrUnoObj&) rObj).aUnoControlModelTypeName;
+ aUnoControlTypeName = ((SdrUnoObj&) rObj).aUnoControlTypeName;
+
+ // copy the uno control model
+ uno::Reference< awt::XControlModel > xCtrl( ((SdrUnoObj&) rObj).GetUnoControlModel(), uno::UNO_QUERY );
+ uno::Reference< util::XCloneable > xClone( xCtrl, uno::UNO_QUERY );
+
+ if ( xClone.is() )
+ {
+ // copy the model by cloning
+ uno::Reference< awt::XControlModel > xNewModel( xClone->createClone(), uno::UNO_QUERY );
+ DBG_ASSERT( xNewModel.is(), "SdrUnoObj::operator =, no control model!");
+ xUnoControlModel = xNewModel;
+ }
+ else
+ {
+ // copy the model by streaming
+ uno::Reference< io::XPersistObject > xObj( xCtrl, uno::UNO_QUERY );
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+
+ if ( xObj.is() && xFactory.is() )
+ {
+ // creating a pipe
+ uno::Reference< io::XOutputStream > xOutPipe(xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.Pipe")), uno::UNO_QUERY);
+ uno::Reference< io::XInputStream > xInPipe(xOutPipe, uno::UNO_QUERY);
+
+ // creating the mark streams
+ uno::Reference< io::XInputStream > xMarkIn(xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.MarkableInputStream")), uno::UNO_QUERY);
+ uno::Reference< io::XActiveDataSink > xMarkSink(xMarkIn, uno::UNO_QUERY);
+
+ uno::Reference< io::XOutputStream > xMarkOut(xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.MarkableOutputStream")), uno::UNO_QUERY);
+ uno::Reference< io::XActiveDataSource > xMarkSource(xMarkOut, uno::UNO_QUERY);
+
+ // connect mark and sink
+ uno::Reference< io::XActiveDataSink > xSink(xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.ObjectInputStream")), uno::UNO_QUERY);
+
+ // connect mark and source
+ uno::Reference< io::XActiveDataSource > xSource(xFactory->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.ObjectOutputStream")), uno::UNO_QUERY);
+
+ uno::Reference< io::XObjectOutputStream > xOutStrm(xSource, uno::UNO_QUERY);
+ uno::Reference< io::XObjectInputStream > xInStrm(xSink, uno::UNO_QUERY);
+
+ if (xMarkSink.is() && xMarkSource.is() && xSink.is() && xSource.is())
+ {
+ xMarkSink->setInputStream(xInPipe);
+ xMarkSource->setOutputStream(xOutPipe);
+ xSink->setInputStream(xMarkIn);
+ xSource->setOutputStream(xMarkOut);
+
+ // write the object to source
+ xOutStrm->writeObject(xObj);
+ xOutStrm->closeOutput();
+ // read the object
+ uno::Reference< awt::XControlModel > xModel(xInStrm->readObject(), uno::UNO_QUERY);
+ xInStrm->closeInput();
+
+ DBG_ASSERT(xModel.is(), "SdrUnoObj::operator =, keine Model erzeugt");
+
+ xUnoControlModel = xModel;
+ }
+ }
+ }
+
+ // get service name of the control from the control model
+ uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ uno::Any aValue( xSet->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl")) );
+ ::rtl::OUString aStr;
+
+ if( aValue >>= aStr )
+ aUnoControlTypeName = String(aStr);
+ }
+
+ uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
+ if (xComp.is())
+ m_pImpl->pEventListener->StartListening(xComp);
+}
+
+void SdrUnoObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ SdrRectObj::NbcResize(rRef,xFact,yFact);
+
+ if (aGeo.nShearWink!=0 || aGeo.nDrehWink!=0)
+ {
+ // kleine Korrekturen
+ if (aGeo.nDrehWink>=9000 && aGeo.nDrehWink<27000)
+ {
+ aRect.Move(aRect.Left()-aRect.Right(),aRect.Top()-aRect.Bottom());
+ }
+
+ aGeo.nDrehWink = 0;
+ aGeo.nShearWink = 0;
+ aGeo.nSin = 0.0;
+ aGeo.nCos = 1.0;
+ aGeo.nTan = 0.0;
+ SetRectsDirty();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+bool SdrUnoObj::hasSpecialDrag() const
+{
+ // no special drag; we have no rounding rect and
+ // do want frame handles
+ return false;
+}
+
+bool SdrUnoObj::supportsFullDrag() const
+{
+ // overloaded to have the possibility to enable/disable in debug and
+ // to ckeck some things out. Current solution is working, so default is
+ // enabled
+ static bool bDoSupportFullDrag(true);
+
+ return bDoSupportFullDrag;
+}
+
+SdrObject* SdrUnoObj::getFullDragClone() const
+{
+ SdrObject* pRetval = 0;
+ static bool bHandleSpecial(false);
+
+ if(bHandleSpecial)
+ {
+ // special handling for SdrUnoObj (FormControl). Create a SdrGrafObj
+ // for drag containing the graphical representation. This does not work too
+ // well, so the default is to simply clone
+ pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect());
+ }
+ else
+ {
+ // call parent (simply clone)
+ pRetval = SdrRectObj::getFullDragClone();
+ }
+
+ return pRetval;
+}
+
+// -----------------------------------------------------------------------------
+void SdrUnoObj::NbcSetLayer( SdrLayerID _nLayer )
+{
+ if ( GetLayer() == _nLayer )
+ { // redundant call -> not interested in doing anything here
+ SdrRectObj::NbcSetLayer( _nLayer );
+ return;
+ }
+
+ // we need some special handling here in case we're moved from an invisible layer
+ // to a visible one, or vice versa
+ // (relative to a layer. Remember that the visibility of a layer is a view attribute
+ // - the same layer can be visible in one view, and invisible in another view, at the
+ // same time)
+ // 2003-06-03 - #110592# - fs@openoffice.org
+
+ // collect all views in which our old layer is visible
+ ::std::set< SdrView* > aPreviouslyVisible;
+
+ {
+ SdrViewIter aIter( this );
+ for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
+ aPreviouslyVisible.insert( pView );
+ }
+
+ SdrRectObj::NbcSetLayer( _nLayer );
+
+ // collect all views in which our new layer is visible
+ ::std::set< SdrView* > aNewlyVisible;
+
+ {
+ SdrViewIter aIter( this );
+ for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
+ {
+ ::std::set< SdrView* >::const_iterator aPrevPos = aPreviouslyVisible.find( pView );
+ if ( aPreviouslyVisible.end() != aPrevPos )
+ { // in pView, we were visible _before_ the layer change, and are
+ // visible _after_ the layer change, too
+ // -> we're not interested in this view at all
+ aPreviouslyVisible.erase( aPrevPos );
+ }
+ else
+ {
+ // in pView, we were visible _before_ the layer change, and are
+ // _not_ visible after the layer change
+ // => remember this view, as our visibility there changed
+ aNewlyVisible.insert( pView );
+ }
+ }
+ }
+
+ // now aPreviouslyVisible contains all views where we became invisible
+ ::std::set< SdrView* >::const_iterator aLoopViews;
+ for ( aLoopViews = aPreviouslyVisible.begin();
+ aLoopViews != aPreviouslyVisible.end();
+ ++aLoopViews
+ )
+ {
+ lcl_ensureControlVisibility( *aLoopViews, this, false );
+ }
+
+ // and aNewlyVisible all views where we became visible
+ for ( aLoopViews = aNewlyVisible.begin();
+ aLoopViews != aNewlyVisible.end();
+ ++aLoopViews
+ )
+ {
+ lcl_ensureControlVisibility( *aLoopViews, this, true );
+ }
+}
+
+void SdrUnoObj::CreateUnoControlModel(const String& rModelName)
+{
+ DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
+
+ aUnoControlModelTypeName = rModelName;
+
+ uno::Reference< awt::XControlModel > xModel;
+ uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ if (aUnoControlModelTypeName.Len() && xFactory.is() )
+ {
+ xModel = uno::Reference< awt::XControlModel >(xFactory->createInstance(
+ aUnoControlModelTypeName), uno::UNO_QUERY);
+
+ if (xModel.is())
+ SetChanged();
+ }
+
+ SetUnoControlModel(xModel);
+}
+
+void SdrUnoObj::CreateUnoControlModel(const String& rModelName,
+ const uno::Reference< lang::XMultiServiceFactory >& rxSFac)
+{
+ DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
+
+ aUnoControlModelTypeName = rModelName;
+
+ uno::Reference< awt::XControlModel > xModel;
+ if (aUnoControlModelTypeName.Len() && rxSFac.is() )
+ {
+ xModel = uno::Reference< awt::XControlModel >(rxSFac->createInstance(
+ aUnoControlModelTypeName), uno::UNO_QUERY);
+
+ if (xModel.is())
+ SetChanged();
+ }
+
+ SetUnoControlModel(xModel);
+}
+
+void SdrUnoObj::SetUnoControlModel( const uno::Reference< awt::XControlModel >& xModel)
+{
+ if (xUnoControlModel.is())
+ {
+ uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
+ if (xComp.is())
+ m_pImpl->pEventListener->StopListening(xComp);
+ }
+
+ xUnoControlModel = xModel;
+
+ // control model muss servicename des controls enthalten
+ if (xUnoControlModel.is())
+ {
+ uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ uno::Any aValue( xSet->getPropertyValue(String("DefaultControl", gsl_getSystemTextEncoding())) );
+ ::rtl::OUString aStr;
+ if( aValue >>= aStr )
+ aUnoControlTypeName = String(aStr);
+ }
+
+ uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
+ if (xComp.is())
+ m_pImpl->pEventListener->StartListening(xComp);
+ }
+
+ // invalidate all ViewObject contacts
+ ViewContactOfUnoControl* pVC = NULL;
+ if ( impl_getViewContact( pVC ) )
+ {
+ // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This
+ // is always allowed since they will be re-created on demand (and with the changed model)
+ GetViewContact().flushViewObjectContacts(true);
+ }
+}
+
+//------------------------------------------------------------------------
+uno::Reference< awt::XControl > SdrUnoObj::GetUnoControl(const SdrView& _rView, const OutputDevice& _rOut) const
+{
+ uno::Reference< awt::XControl > xControl;
+
+ SdrPageView* pPageView = _rView.GetSdrPageView();
+ OSL_ENSURE( GetPage() == pPageView->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" );
+ if ( GetPage() != pPageView->GetPage() )
+ return NULL;
+
+ SdrPageWindow* pPageWindow = pPageView ? pPageView->FindPageWindow( _rOut ) : NULL;
+ OSL_ENSURE( pPageWindow, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
+ if ( !pPageWindow )
+ return NULL;
+
+ ViewObjectContact& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow->GetObjectContact() ) );
+ ViewObjectContactOfUnoControl* pUnoContact = dynamic_cast< ViewObjectContactOfUnoControl* >( &rViewObjectContact );
+ OSL_ENSURE( pUnoContact, "SdrUnoObj::GetUnoControl: wrong contact type!" );
+ if ( pUnoContact )
+ xControl = pUnoContact->getControl();
+
+ return xControl;
+}
+
+//------------------------------------------------------------------------
+uno::Reference< awt::XControl > SdrUnoObj::GetTemporaryControlForWindow(
+ const Window& _rWindow, uno::Reference< awt::XControlContainer >& _inout_ControlContainer ) const
+{
+ uno::Reference< awt::XControl > xControl;
+
+ ViewContactOfUnoControl* pVC = NULL;
+ if ( impl_getViewContact( pVC ) )
+ xControl = pVC->getTemporaryControlForWindow( _rWindow, _inout_ControlContainer );
+
+ return xControl;
+}
+
+//------------------------------------------------------------------------
+bool SdrUnoObj::impl_getViewContact( ViewContactOfUnoControl*& _out_rpContact ) const
+{
+ ViewContact& rViewContact( GetViewContact() );
+ _out_rpContact = dynamic_cast< ViewContactOfUnoControl* >( &rViewContact );
+ DBG_ASSERT( _out_rpContact, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" );
+ return ( _out_rpContact != NULL );
+}
+
+//------------------------------------------------------------------------
+::sdr::contact::ViewContact* SdrUnoObj::CreateObjectSpecificViewContact()
+{
+ return new ::sdr::contact::ViewContactOfUnoControl( *this );
+}
+
+// -----------------------------------------------------------------------------
+// eof
diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx
new file mode 100644
index 000000000000..79e74a3382b8
--- /dev/null
+++ b/svx/source/svdraw/svdoutl.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/svdoutl.hxx>
+#include <editeng/outliner.hxx>
+#include <svx/svdotext.hxx>
+#include <editeng/editstat.hxx>
+#include <svx/svdmodel.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/itempool.hxx>
+
+DBG_NAME(SdrOutliner)
+/*************************************************************************
+|*
+|* Ctor
+|*
+\************************************************************************/
+SdrOutliner::SdrOutliner( SfxItemPool* pItemPool, USHORT nMode )
+: Outliner( pItemPool, nMode ),
+ //mpPaintInfoRec( NULL )
+ mpVisualizedPage(0)
+{
+ DBG_CTOR(SdrOutliner,NULL);
+}
+
+
+/*************************************************************************
+|*
+|* Dtor
+|*
+\************************************************************************/
+SdrOutliner::~SdrOutliner()
+{
+ DBG_DTOR(SdrOutliner,NULL);
+}
+
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+void SdrOutliner::SetTextObj( const SdrTextObj* pObj )
+{
+ if( pObj && pObj != mpTextObj.get() )
+ {
+ SetUpdateMode(FALSE);
+ USHORT nOutlinerMode2 = OUTLINERMODE_OUTLINEOBJECT;
+ if ( !pObj->IsOutlText() )
+ nOutlinerMode2 = OUTLINERMODE_TEXTOBJECT;
+ Init( nOutlinerMode2 );
+
+ SetGlobalCharStretching(100,100);
+
+ ULONG nStat = GetControlWord();
+ nStat &= ~( EE_CNTRL_STRETCHING | EE_CNTRL_AUTOPAGESIZE );
+ SetControlWord(nStat);
+
+ Size aNullSize;
+ Size aMaxSize( 100000,100000 );
+ SetMinAutoPaperSize( aNullSize );
+ SetMaxAutoPaperSize( aMaxSize );
+ SetPaperSize( aMaxSize );
+ ClearPolygon();
+ }
+
+ mpTextObj.reset( const_cast< SdrTextObj* >(pObj) );
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+void SdrOutliner::SetTextObjNoInit( const SdrTextObj* pObj )
+{
+ mpTextObj.reset( const_cast< SdrTextObj* >(pObj) );
+}
+
+/*************************************************************************
+|*
+|*
+|*
+\************************************************************************/
+XubString SdrOutliner::CalcFieldValue(const SvxFieldItem& rField, USHORT nPara, USHORT nPos,
+ Color*& rpTxtColor, Color*& rpFldColor)
+{
+ FASTBOOL bOk = FALSE;
+ XubString aRet;
+
+ if(mpTextObj.is())
+ bOk = static_cast< SdrTextObj* >( mpTextObj.get())->CalcFieldValue(rField, nPara, nPos, FALSE, rpTxtColor, rpFldColor, aRet);
+
+ if (!bOk)
+ aRet = Outliner::CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor);
+
+ return aRet;
+}
+
+const SdrTextObj* SdrOutliner::GetTextObj() const
+{
+ if( mpTextObj.is() )
+ return static_cast< SdrTextObj* >( mpTextObj.get() );
+ else
+ return 0;
+}
diff --git a/svx/source/svdraw/svdoutlinercache.cxx b/svx/source/svdraw/svdoutlinercache.cxx
new file mode 100644
index 000000000000..429b459d3271
--- /dev/null
+++ b/svx/source/svdraw/svdoutlinercache.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+
+#include "svdoutlinercache.hxx"
+#include <svx/svdoutl.hxx>
+#include <svx/svdmodel.hxx>
+
+extern SdrOutliner* SdrMakeOutliner( USHORT nOutlinerMode, SdrModel* pModel );
+
+SdrOutlinerCache::SdrOutlinerCache( SdrModel* pModel )
+: mpModel( pModel ),
+ mpModeOutline( NULL ),
+ mpModeText( NULL )
+{
+}
+
+SdrOutliner* SdrOutlinerCache::createOutliner( sal_uInt16 nOutlinerMode )
+{
+ SdrOutliner* pOutliner = NULL;
+
+ if( (OUTLINERMODE_OUTLINEOBJECT == nOutlinerMode) && mpModeOutline )
+ {
+ pOutliner = mpModeOutline;
+ mpModeOutline = NULL;
+ }
+ else if( (OUTLINERMODE_TEXTOBJECT == nOutlinerMode) && mpModeText )
+ {
+ pOutliner = mpModeText;
+ mpModeText = NULL;
+ }
+ else
+ {
+ pOutliner = SdrMakeOutliner( nOutlinerMode, mpModel );
+ Outliner& aDrawOutliner = mpModel->GetDrawOutliner();
+ pOutliner->SetCalcFieldValueHdl( aDrawOutliner.GetCalcFieldValueHdl() );
+ }
+
+ return pOutliner;
+}
+
+SdrOutlinerCache::~SdrOutlinerCache()
+{
+ if( mpModeOutline )
+ {
+ delete mpModeOutline;
+ mpModeOutline = NULL;
+ }
+
+ if( mpModeText )
+ {
+ delete mpModeText;
+ mpModeText = NULL;
+ }
+}
+
+void SdrOutlinerCache::disposeOutliner( SdrOutliner* pOutliner )
+{
+ if( pOutliner )
+ {
+ USHORT nOutlMode = pOutliner->GetOutlinerMode();
+
+ if( (OUTLINERMODE_OUTLINEOBJECT == nOutlMode) && (NULL == mpModeOutline) )
+ {
+ mpModeOutline = pOutliner;
+ pOutliner->Clear();
+ pOutliner->SetVertical( false );
+
+ // #101088# Deregister on outliner, might be reused from outliner cache
+ pOutliner->SetNotifyHdl( Link() );
+ }
+ else if( (OUTLINERMODE_TEXTOBJECT == nOutlMode) && (NULL == mpModeText) )
+ {
+ mpModeText = pOutliner;
+ pOutliner->Clear();
+ pOutliner->SetVertical( false );
+
+ // #101088# Deregister on outliner, might be reused from outliner cache
+ pOutliner->SetNotifyHdl( Link() );
+ }
+ else
+ {
+ delete pOutliner;
+ }
+ }
+}
+
+
diff --git a/svx/source/svdraw/svdovirt.cxx b/svx/source/svdraw/svdovirt.cxx
new file mode 100644
index 000000000000..c97af7abc37c
--- /dev/null
+++ b/svx/source/svdraw/svdovirt.cxx
@@ -0,0 +1,659 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdovirt.hxx>
+#include <svx/xpool.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdhdl.hxx>
+#include <svx/sdr/contact/viewcontactofvirtobj.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svddrgv.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sdr::properties::BaseProperties& SdrVirtObj::GetProperties() const
+{
+ return rRefObj.GetProperties();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// AW, OD 2004-05-03 #i27224#
+sdr::contact::ViewContact* SdrVirtObj::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfVirtObj(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrVirtObj,SdrObject);
+
+SdrVirtObj::SdrVirtObj(SdrObject& rNewObj):
+ rRefObj(rNewObj)
+{
+ bVirtObj=TRUE; // Ja, ich bin ein virtuelles Objekt
+ rRefObj.AddReference(*this);
+ bClosedObj=rRefObj.IsClosedObj();
+}
+
+SdrVirtObj::SdrVirtObj(SdrObject& rNewObj, const Point& rAnchorPos):
+ rRefObj(rNewObj)
+{
+ aAnchor=rAnchorPos;
+ bVirtObj=TRUE; // Ja, ich bin ein virtuelles Objekt
+ rRefObj.AddReference(*this);
+ bClosedObj=rRefObj.IsClosedObj();
+}
+
+SdrVirtObj::~SdrVirtObj()
+{
+ rRefObj.DelReference(*this);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const SdrObject& SdrVirtObj::GetReferencedObj() const
+{
+ return rRefObj;
+}
+
+SdrObject& SdrVirtObj::ReferencedObj()
+{
+ return rRefObj;
+}
+
+void __EXPORT SdrVirtObj::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/)
+{
+ bClosedObj=rRefObj.IsClosedObj();
+ SetRectsDirty(); // hier noch Optimieren.
+
+ // Only a repaint here, rRefObj may have changed and broadcasts
+ ActionChanged();
+ // BroadcastObjectChange();
+}
+
+void SdrVirtObj::NbcSetAnchorPos(const Point& rAnchorPos)
+{
+ aAnchor=rAnchorPos;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrVirtObj::SetModel(SdrModel* pNewModel)
+{
+ SdrObject::SetModel(pNewModel);
+ rRefObj.SetModel(pNewModel);
+}
+
+void SdrVirtObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rRefObj.TakeObjInfo(rInfo);
+}
+
+UINT32 SdrVirtObj::GetObjInventor() const
+{
+ return rRefObj.GetObjInventor();
+}
+
+UINT16 SdrVirtObj::GetObjIdentifier() const
+{
+ return rRefObj.GetObjIdentifier();
+}
+
+SdrObjList* SdrVirtObj::GetSubList() const
+{
+ return rRefObj.GetSubList();
+}
+
+const Rectangle& SdrVirtObj::GetCurrentBoundRect() const
+{
+ ((SdrVirtObj*)this)->aOutRect=rRefObj.GetCurrentBoundRect(); // Hier noch optimieren
+ ((SdrVirtObj*)this)->aOutRect+=aAnchor;
+ return aOutRect;
+}
+
+const Rectangle& SdrVirtObj::GetLastBoundRect() const
+{
+ ((SdrVirtObj*)this)->aOutRect=rRefObj.GetLastBoundRect(); // Hier noch optimieren
+ ((SdrVirtObj*)this)->aOutRect+=aAnchor;
+ return aOutRect;
+}
+
+void SdrVirtObj::RecalcBoundRect()
+{
+ aOutRect=rRefObj.GetCurrentBoundRect();
+ aOutRect+=aAnchor;
+}
+
+void SdrVirtObj::SetChanged()
+{
+ SdrObject::SetChanged();
+}
+
+SdrObject* SdrVirtObj::Clone() const
+{
+ SdrObject* pObj=new SdrVirtObj(((SdrVirtObj*)this)->rRefObj); // Nur eine weitere Referenz
+ return pObj;
+}
+
+void SdrVirtObj::operator=(const SdrObject& rObj)
+{ // ???anderes Objekt referenzieren???
+ SdrObject::operator=(rObj);
+ aAnchor=((SdrVirtObj&)rObj).aAnchor;
+}
+
+void SdrVirtObj::TakeObjNameSingul(XubString& rName) const
+{
+ rRefObj.TakeObjNameSingul(rName);
+ rName.Insert(sal_Unicode('['), 0);
+ rName += sal_Unicode(']');
+
+ String aName( GetName() );
+ if(aName.Len())
+ {
+ rName += sal_Unicode(' ');
+ rName += sal_Unicode('\'');
+ rName += aName;
+ rName += sal_Unicode('\'');
+ }
+}
+
+void SdrVirtObj::TakeObjNamePlural(XubString& rName) const
+{
+ rRefObj.TakeObjNamePlural(rName);
+ rName.Insert(sal_Unicode('['), 0);
+ rName += sal_Unicode(']');
+}
+
+void operator +=(PolyPolygon& rPoly, const Point& rOfs)
+{
+ if (rOfs.X()!=0 || rOfs.Y()!=0) {
+ USHORT i,j;
+ for (j=0; j<rPoly.Count(); j++) {
+ Polygon aP1(rPoly.GetObject(j));
+ for (i=0; i<aP1.GetSize(); i++) {
+ aP1[i]+=rOfs;
+ }
+ rPoly.Replace(aP1,j);
+ }
+ }
+}
+
+basegfx::B2DPolyPolygon SdrVirtObj::TakeXorPoly() const
+{
+ basegfx::B2DPolyPolygon aPolyPolygon(rRefObj.TakeXorPoly());
+
+ if(aAnchor.X() || aAnchor.Y())
+ {
+ aPolyPolygon.transform(basegfx::tools::createTranslateB2DHomMatrix(aAnchor.X(), aAnchor.Y()));
+ }
+
+ return aPolyPolygon;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_uInt32 SdrVirtObj::GetHdlCount() const
+{
+ return rRefObj.GetHdlCount();
+}
+
+SdrHdl* SdrVirtObj::GetHdl(sal_uInt32 nHdlNum) const
+{
+ SdrHdl* pHdl=rRefObj.GetHdl(nHdlNum);
+
+ // #i73248#
+ // GetHdl() at SdrObject is not guaranteed to return an object
+ if(pHdl)
+ {
+ Point aP(pHdl->GetPos()+aAnchor);
+ pHdl->SetPos(aP);
+ }
+
+ return pHdl;
+}
+
+sal_uInt32 SdrVirtObj::GetPlusHdlCount(const SdrHdl& rHdl) const
+{
+ return rRefObj.GetPlusHdlCount(rHdl);
+}
+
+SdrHdl* SdrVirtObj::GetPlusHdl(const SdrHdl& rHdl, sal_uInt32 nPlNum) const
+{
+ SdrHdl* pHdl=rRefObj.GetPlusHdl(rHdl,nPlNum);
+ pHdl->SetPos(pHdl->GetPos() + aAnchor);
+ return pHdl;
+}
+
+void SdrVirtObj::AddToHdlList(SdrHdlList& rHdlList) const
+{
+ // #i73248#
+ // SdrObject::AddToHdlList(rHdlList) is not a good thing to call
+ // since at SdrPathObj, only AddToHdlList may be used and the call
+ // will instead use the standard implementation which uses GetHdlCount()
+ // and GetHdl instead. This is not wrong, but may be much less effective
+ // and may not be prepared to GetHdl returning NULL
+
+ // get handles using AddToHdlList from ref object
+ SdrHdlList aLocalList(0);
+ rRefObj.AddToHdlList(aLocalList);
+ const sal_uInt32 nHdlCount(aLocalList.GetHdlCount());
+
+ if(nHdlCount)
+ {
+ // translate handles and add them to dest list. They are temporarily part of
+ // two lists then
+ const Point aOffset(GetOffset());
+
+ for(sal_uInt32 a(0L); a < nHdlCount; a++)
+ {
+ SdrHdl* pCandidate = aLocalList.GetHdl(a);
+ pCandidate->SetPos(pCandidate->GetPos() + aOffset);
+ rHdlList.AddHdl(pCandidate);
+ }
+
+ // remove them from source list, else they will be deleted when
+ // source list is deleted
+ while(aLocalList.GetHdlCount())
+ {
+ aLocalList.RemoveHdl(aLocalList.GetHdlCount() - 1L);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool SdrVirtObj::hasSpecialDrag() const
+{
+ return rRefObj.hasSpecialDrag();
+}
+
+bool SdrVirtObj::supportsFullDrag() const
+{
+ return false;
+}
+
+SdrObject* SdrVirtObj::getFullDragClone() const
+{
+ static bool bSpecialHandling(false);
+ SdrObject* pRetval = 0;
+
+ if(bSpecialHandling)
+ {
+ // special handling for VirtObj. Do not create another
+ // reference to rRefObj, this would allow to change that
+ // one on drag. Instead, create a SdrGrafObj for drag containing
+ // the graphical representation
+ pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect());
+ }
+ else
+ {
+ SdrObject& rReferencedObject = ((SdrVirtObj*)this)->ReferencedObj();
+ pRetval = new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), &rReferencedObject), GetLogicRect());
+ }
+
+ return pRetval;
+}
+
+bool SdrVirtObj::beginSpecialDrag(SdrDragStat& rDrag) const
+{
+ return rRefObj.beginSpecialDrag(rDrag);
+}
+
+bool SdrVirtObj::applySpecialDrag(SdrDragStat& rDrag)
+{
+ return rRefObj.applySpecialDrag(rDrag);
+}
+
+basegfx::B2DPolyPolygon SdrVirtObj::getSpecialDragPoly(const SdrDragStat& rDrag) const
+{
+ return rRefObj.getSpecialDragPoly(rDrag);
+ // Offset handlen !!!!!! fehlt noch !!!!!!!
+}
+
+String SdrVirtObj::getSpecialDragComment(const SdrDragStat& rDrag) const
+{
+ return rRefObj.getSpecialDragComment(rDrag);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrVirtObj::BegCreate(SdrDragStat& rStat)
+{
+ return rRefObj.BegCreate(rStat);
+}
+
+FASTBOOL SdrVirtObj::MovCreate(SdrDragStat& rStat)
+{
+ return rRefObj.MovCreate(rStat);
+}
+
+FASTBOOL SdrVirtObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
+{
+ return rRefObj.EndCreate(rStat,eCmd);
+}
+
+FASTBOOL SdrVirtObj::BckCreate(SdrDragStat& rStat)
+{
+ return rRefObj.BckCreate(rStat);
+}
+
+void SdrVirtObj::BrkCreate(SdrDragStat& rStat)
+{
+ rRefObj.BrkCreate(rStat);
+}
+
+basegfx::B2DPolyPolygon SdrVirtObj::TakeCreatePoly(const SdrDragStat& rDrag) const
+{
+ return rRefObj.TakeCreatePoly(rDrag);
+ // Offset handlen !!!!!! fehlt noch !!!!!!!
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrVirtObj::NbcMove(const Size& rSiz)
+{
+ MovePoint(aAnchor,rSiz);
+ SetRectsDirty();
+}
+
+void SdrVirtObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ rRefObj.NbcResize(rRef-aAnchor,xFact,yFact);
+ SetRectsDirty();
+}
+
+void SdrVirtObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ rRefObj.NbcRotate(rRef-aAnchor,nWink,sn,cs);
+ SetRectsDirty();
+}
+
+void SdrVirtObj::NbcMirror(const Point& rRef1, const Point& rRef2)
+{
+ rRefObj.NbcMirror(rRef1-aAnchor,rRef2-aAnchor);
+ SetRectsDirty();
+}
+
+void SdrVirtObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ rRefObj.NbcShear(rRef-aAnchor,nWink,tn,bVShear);
+ SetRectsDirty();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrVirtObj::Move(const Size& rSiz)
+{
+ if (rSiz.Width()!=0 || rSiz.Height()!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ // #110094#-14 SendRepaintBroadcast();
+ NbcMove(rSiz);
+ SetChanged();
+ BroadcastObjectChange();
+ SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
+ }
+}
+
+void SdrVirtObj::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ rRefObj.Resize(rRef-aAnchor,xFact,yFact);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrVirtObj::Rotate(const Point& rRef, long nWink, double sn, double cs)
+{
+ if (nWink!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ rRefObj.Rotate(rRef-aAnchor,nWink,sn,cs);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrVirtObj::Mirror(const Point& rRef1, const Point& rRef2)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ rRefObj.Mirror(rRef1-aAnchor,rRef2-aAnchor);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrVirtObj::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
+{
+ if (nWink!=0) {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ rRefObj.Shear(rRef-aAnchor,nWink,tn,bVShear);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrVirtObj::RecalcSnapRect()
+{
+ aSnapRect=rRefObj.GetSnapRect();
+ aSnapRect+=aAnchor;
+}
+
+const Rectangle& SdrVirtObj::GetSnapRect() const
+{
+ ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetSnapRect();
+ ((SdrVirtObj*)this)->aSnapRect+=aAnchor;
+ return aSnapRect;
+}
+
+void SdrVirtObj::SetSnapRect(const Rectangle& rRect)
+{
+ {
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ Rectangle aR(rRect);
+ aR-=aAnchor;
+ rRefObj.SetSnapRect(aR);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+ }
+}
+
+void SdrVirtObj::NbcSetSnapRect(const Rectangle& rRect)
+{
+ Rectangle aR(rRect);
+ aR-=aAnchor;
+ SetRectsDirty();
+ rRefObj.NbcSetSnapRect(aR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+const Rectangle& SdrVirtObj::GetLogicRect() const
+{
+ ((SdrVirtObj*)this)->aSnapRect=rRefObj.GetLogicRect(); // !!! Missbrauch von aSnapRect !!!
+ ((SdrVirtObj*)this)->aSnapRect+=aAnchor; // Wenns mal Aerger gibt, muss ein weiteres Rectangle Member her (oder Heap)
+ return aSnapRect;
+}
+
+void SdrVirtObj::SetLogicRect(const Rectangle& rRect)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ Rectangle aR(rRect);
+ aR-=aAnchor;
+ rRefObj.SetLogicRect(aR);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+void SdrVirtObj::NbcSetLogicRect(const Rectangle& rRect)
+{
+ Rectangle aR(rRect);
+ aR-=aAnchor;
+ SetRectsDirty();
+ rRefObj.NbcSetLogicRect(aR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+long SdrVirtObj::GetRotateAngle() const
+{
+ return rRefObj.GetRotateAngle();
+}
+
+long SdrVirtObj::GetShearAngle(FASTBOOL bVertical) const
+{
+ return rRefObj.GetShearAngle(bVertical);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_uInt32 SdrVirtObj::GetSnapPointCount() const
+{
+ return rRefObj.GetSnapPointCount();
+}
+
+Point SdrVirtObj::GetSnapPoint(sal_uInt32 i) const
+{
+ Point aP(rRefObj.GetSnapPoint(i));
+ aP+=aAnchor;
+ return aP;
+}
+
+sal_Bool SdrVirtObj::IsPolyObj() const
+{
+ return rRefObj.IsPolyObj();
+}
+
+sal_uInt32 SdrVirtObj::GetPointCount() const
+{
+ return rRefObj.GetPointCount();
+}
+
+Point SdrVirtObj::GetPoint(sal_uInt32 i) const
+{
+ return Point(rRefObj.GetPoint(i) + aAnchor);
+}
+
+void SdrVirtObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
+{
+ Point aP(rPnt);
+ aP-=aAnchor;
+ rRefObj.SetPoint(aP,i);
+ SetRectsDirty();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObjGeoData* SdrVirtObj::NewGeoData() const
+{
+ return rRefObj.NewGeoData();
+}
+
+void SdrVirtObj::SaveGeoData(SdrObjGeoData& rGeo) const
+{
+ rRefObj.SaveGeoData(rGeo);
+}
+
+void SdrVirtObj::RestGeoData(const SdrObjGeoData& rGeo)
+{
+ rRefObj.RestGeoData(rGeo);
+ SetRectsDirty();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrObjGeoData* SdrVirtObj::GetGeoData() const
+{
+ return rRefObj.GetGeoData();
+}
+
+void SdrVirtObj::SetGeoData(const SdrObjGeoData& rGeo)
+{
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
+ rRefObj.SetGeoData(rGeo);
+ SetRectsDirty();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrVirtObj::NbcReformatText()
+{
+ rRefObj.NbcReformatText();
+}
+
+void SdrVirtObj::ReformatText()
+{
+ rRefObj.ReformatText();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+FASTBOOL SdrVirtObj::HasMacro() const
+{
+ return rRefObj.HasMacro();
+}
+
+SdrObject* SdrVirtObj::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
+{
+ return rRefObj.CheckMacroHit(rRec); // Todo: Positionsversatz
+}
+
+Pointer SdrVirtObj::GetMacroPointer(const SdrObjMacroHitRec& rRec) const
+{
+ return rRefObj.GetMacroPointer(rRec); // Todo: Positionsversatz
+}
+
+void SdrVirtObj::PaintMacro(OutputDevice& rOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const
+{
+ rRefObj.PaintMacro(rOut,rDirtyRect,rRec); // Todo: Positionsversatz
+}
+
+FASTBOOL SdrVirtObj::DoMacro(const SdrObjMacroHitRec& rRec)
+{
+ return rRefObj.DoMacro(rRec); // Todo: Positionsversatz
+}
+
+XubString SdrVirtObj::GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const
+{
+ return rRefObj.GetMacroPopupComment(rRec); // Todo: Positionsversatz
+}
+
+const Point SdrVirtObj::GetOffset() const
+{
+ // #i73248# default offset of SdrVirtObj is aAnchor
+ return aAnchor;
+}
+
+// eof
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
new file mode 100644
index 000000000000..8da0b248f38b
--- /dev/null
+++ b/svx/source/svdraw/svdpage.cxx
@@ -0,0 +1,2020 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdpage.hxx>
+
+// HACK
+#include <sot/storage.hxx>
+#include <sot/clsids.hxx>
+#include <sot/storage.hxx>
+#include <svx/svdview.hxx>
+#include <string.h>
+#ifndef _STRING_H
+#define _STRING_H
+#endif
+#include <vcl/svapp.hxx>
+
+#include <tools/diagnose_ex.h>
+
+#include <svx/svdetc.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdograf.hxx> // fuer SwapInAll()
+#include <svx/svdoedge.hxx> // Zum kopieren der Konnektoren
+#include <svx/svdoole2.hxx> // Sonderbehandlung OLE beim SdrExchangeFormat
+#include "svditer.hxx"
+#include <svx/svdmodel.hxx>
+#include <svx/svdlayer.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/polysc3d.hxx>
+
+#include <svx/fmdpage.hxx>
+
+#include <sfx2/objsh.hxx>
+#include <vcl/salbtype.hxx> // FRound
+#include <svx/sdr/contact/viewcontactofsdrpage.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <algorithm>
+#include <svl/smplhint.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+void DumpObjectList (const ::std::vector<SdrObjectWeakRef>& rContainer)
+{
+ ::std::vector<SdrObjectWeakRef>::const_iterator iObject (rContainer.begin());
+ ::std::vector<SdrObjectWeakRef>::const_iterator iEnd (rContainer.end());
+ for (int nIndex=0 ; iObject!=iEnd; ++iObject,++nIndex)
+ {
+ const SdrObject* pObject = iObject->get();
+ OSL_TRACE("%d : %x, %s", nIndex,
+ pObject,
+ ::rtl::OUStringToOString(pObject->GetName(),RTL_TEXTENCODING_UTF8).getStr());
+ }
+}
+}
+
+
+class SdrObjList::WeakSdrObjectContainerType
+ : public ::std::vector<SdrObjectWeakRef>
+{
+public:
+ WeakSdrObjectContainerType (const sal_Int32 nInitialSize)
+ : ::std::vector<SdrObjectWeakRef>(nInitialSize) {};
+};
+
+
+
+static const sal_Int32 InitialObjectContainerCapacity (64);
+DBG_NAME(SdrObjList)
+
+TYPEINIT0(SdrObjList);
+
+SdrObjList::SdrObjList(SdrModel* pNewModel, SdrPage* pNewPage, SdrObjList* pNewUpList):
+ maList(),
+ mpNavigationOrder(),
+ mbIsNavigationOrderDirty(false)
+{
+ DBG_CTOR(SdrObjList,NULL);
+ maList.reserve(InitialObjectContainerCapacity);
+ pModel=pNewModel;
+ pPage=pNewPage;
+ pUpList=pNewUpList;
+ bObjOrdNumsDirty=FALSE;
+ bRectsDirty=FALSE;
+ pOwnerObj=NULL;
+ eListKind=SDROBJLIST_UNKNOWN;
+}
+
+SdrObjList::SdrObjList(const SdrObjList& rSrcList):
+ maList(),
+ mpNavigationOrder(),
+ mbIsNavigationOrderDirty(false)
+{
+ DBG_CTOR(SdrObjList,NULL);
+ maList.reserve(InitialObjectContainerCapacity);
+ pModel=NULL;
+ pPage=NULL;
+ pUpList=NULL;
+ bObjOrdNumsDirty=FALSE;
+ bRectsDirty=FALSE;
+ pOwnerObj=NULL;
+ eListKind=SDROBJLIST_UNKNOWN;
+ *this=rSrcList;
+}
+
+SdrObjList::~SdrObjList()
+{
+ DBG_DTOR(SdrObjList,NULL);
+
+ // #111111#
+ // To avoid that the Clear() method will broadcast changes when in destruction
+ // which would call virtual methos (not allowed in destructor), the model is set
+ // to NULL here.
+ pModel = 0L;
+
+ Clear(); // Containerinhalt loeschen!
+}
+
+void SdrObjList::operator=(const SdrObjList& rSrcList)
+{
+ Clear();
+ eListKind=rSrcList.eListKind;
+ CopyObjects(rSrcList);
+}
+
+void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
+{
+ Clear();
+ bObjOrdNumsDirty=FALSE;
+ bRectsDirty =FALSE;
+ ULONG nCloneErrCnt=0;
+ ULONG nAnz=rSrcList.GetObjCount();
+ SdrInsertReason aReason(SDRREASON_COPY);
+ ULONG no;
+ for (no=0; no<nAnz; no++) {
+ SdrObject* pSO=rSrcList.GetObj(no);
+
+ // #116235#
+ //SdrObject* pDO=pSO->Clone(pPage,pModel);
+ SdrObject* pDO = pSO->Clone();
+ pDO->SetModel(pModel);
+ pDO->SetPage(pPage);
+
+ if (pDO!=NULL) {
+ NbcInsertObject(pDO,CONTAINER_APPEND,&aReason);
+ } else {
+ nCloneErrCnt++;
+ }
+ }
+ // und nun zu den Konnektoren
+ // Die neuen Objekte werden auf die der rSrcList abgebildet
+ // und so die Objektverbindungen hergestellt.
+ // Aehnliche Implementation an folgenden Stellen:
+ // void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
+ // SdrModel* SdrExchangeView::GetMarkedObjModel() const
+ // FASTBOOL SdrExchangeView::Paste(const SdrModel& rMod,...)
+ // void SdrEditView::CopyMarked()
+ if (nCloneErrCnt==0) {
+ for (no=0; no<nAnz; no++) {
+ const SdrObject* pSrcOb=rSrcList.GetObj(no);
+ SdrEdgeObj* pSrcEdge=PTR_CAST(SdrEdgeObj,pSrcOb);
+ if (pSrcEdge!=NULL) {
+ SdrObject* pSrcNode1=pSrcEdge->GetConnectedNode(TRUE);
+ SdrObject* pSrcNode2=pSrcEdge->GetConnectedNode(FALSE);
+ if (pSrcNode1!=NULL && pSrcNode1->GetObjList()!=pSrcEdge->GetObjList()) pSrcNode1=NULL; // Listenuebergreifend
+ if (pSrcNode2!=NULL && pSrcNode2->GetObjList()!=pSrcEdge->GetObjList()) pSrcNode2=NULL; // ist (noch) nicht
+ if (pSrcNode1!=NULL || pSrcNode2!=NULL) {
+ SdrObject* pEdgeObjTmp=GetObj(no);
+ SdrEdgeObj* pDstEdge=PTR_CAST(SdrEdgeObj,pEdgeObjTmp);
+ if (pDstEdge!=NULL) {
+ if (pSrcNode1!=NULL) {
+ ULONG nDstNode1=pSrcNode1->GetOrdNum();
+ SdrObject* pDstNode1=GetObj(nDstNode1);
+ if (pDstNode1!=NULL) { // Sonst grober Fehler!
+ pDstEdge->ConnectToNode(TRUE,pDstNode1);
+ } else {
+ DBG_ERROR("SdrObjList::operator=(): pDstNode1==NULL!");
+ }
+ }
+ if (pSrcNode2!=NULL) {
+ ULONG nDstNode2=pSrcNode2->GetOrdNum();
+ SdrObject* pDstNode2=GetObj(nDstNode2);
+ if (pDstNode2!=NULL) { // Node war sonst wohl nicht markiert
+ pDstEdge->ConnectToNode(FALSE,pDstNode2);
+ } else {
+ DBG_ERROR("SdrObjList::operator=(): pDstNode2==NULL!");
+ }
+ }
+ } else {
+ DBG_ERROR("SdrObjList::operator=(): pDstEdge==NULL!");
+ }
+ }
+ }
+ }
+ } else {
+#ifdef DBG_UTIL
+ ByteString aStr("SdrObjList::operator=(): Fehler beim Clonen ");
+
+ if(nCloneErrCnt == 1)
+ {
+ aStr += "eines Zeichenobjekts.";
+ }
+ else
+ {
+ aStr += "von ";
+ aStr += ByteString::CreateFromInt32( nCloneErrCnt );
+ aStr += " Zeichenobjekten.";
+ }
+
+ aStr += " Objektverbindungen werden nicht mitkopiert.";
+
+ DBG_ERROR(aStr.GetBuffer());
+#endif
+ }
+}
+
+void SdrObjList::Clear()
+{
+ sal_Bool bObjectsRemoved(sal_False);
+
+ while( ! maList.empty())
+ {
+ // remove last object from list
+ SdrObject* pObj = maList.back();
+ RemoveObjectFromContainer(maList.size()-1);
+
+ // flushViewObjectContacts() is done since SdrObject::Free is not guaranteed
+ // to delete the object and thus refresh visualisations
+ pObj->GetViewContact().flushViewObjectContacts(true);
+
+ bObjectsRemoved = sal_True;
+
+ // sent remove hint (after removal, see RemoveObject())
+ if(pModel)
+ {
+ SdrHint aHint(*pObj);
+ aHint.SetKind(HINT_OBJREMOVED);
+ aHint.SetPage(pPage);
+ pModel->Broadcast(aHint);
+ }
+
+ // delete the object itself
+ SdrObject::Free( pObj );
+ }
+
+ if(pModel && bObjectsRemoved)
+ {
+ pModel->SetChanged();
+ }
+}
+
+SdrPage* SdrObjList::GetPage() const
+{
+ return pPage;
+}
+
+void SdrObjList::SetPage(SdrPage* pNewPage)
+{
+ if (pPage!=pNewPage) {
+ pPage=pNewPage;
+ ULONG nAnz=GetObjCount();
+ for (ULONG no=0; no<nAnz; no++) {
+ SdrObject* pObj=GetObj(no);
+ pObj->SetPage(pPage);
+ }
+ }
+}
+
+SdrModel* SdrObjList::GetModel() const
+{
+ return pModel;
+}
+
+void SdrObjList::SetModel(SdrModel* pNewModel)
+{
+ if (pModel!=pNewModel) {
+ pModel=pNewModel;
+ ULONG nAnz=GetObjCount();
+ for (ULONG i=0; i<nAnz; i++) {
+ SdrObject* pObj=GetObj(i);
+ pObj->SetModel(pModel);
+ }
+ }
+}
+
+void SdrObjList::RecalcObjOrdNums()
+{
+ ULONG nAnz=GetObjCount();
+ for (ULONG no=0; no<nAnz; no++) {
+ SdrObject* pObj=GetObj(no);
+ pObj->SetOrdNum(no);
+ }
+ bObjOrdNumsDirty=FALSE;
+}
+
+void SdrObjList::RecalcRects()
+{
+ aOutRect=Rectangle();
+ aSnapRect=aOutRect;
+ ULONG nAnz=GetObjCount();
+ ULONG i;
+ for (i=0; i<nAnz; i++) {
+ SdrObject* pObj=GetObj(i);
+ if (i==0) {
+ aOutRect=pObj->GetCurrentBoundRect();
+ aSnapRect=pObj->GetSnapRect();
+ } else {
+ aOutRect.Union(pObj->GetCurrentBoundRect());
+ aSnapRect.Union(pObj->GetSnapRect());
+ }
+ }
+}
+
+void SdrObjList::SetRectsDirty()
+{
+ bRectsDirty=TRUE;
+ if (pUpList!=NULL) pUpList->SetRectsDirty();
+}
+
+void SdrObjList::impChildInserted(SdrObject& rChild) const
+{
+ sdr::contact::ViewContact* pParent = rChild.GetViewContact().GetParentContact();
+
+ if(pParent)
+ {
+ pParent->ActionChildInserted(rChild.GetViewContact());
+ }
+}
+
+void SdrObjList::NbcInsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* /*pReason*/)
+{
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::NbcInsertObject(NULL)");
+ if (pObj!=NULL) {
+ DBG_ASSERT(!pObj->IsInserted(),"ZObjekt hat bereits Inserted-Status");
+ ULONG nAnz=GetObjCount();
+ if (nPos>nAnz) nPos=nAnz;
+ InsertObjectIntoContainer(*pObj,nPos);
+
+ if (nPos<nAnz) bObjOrdNumsDirty=TRUE;
+ pObj->SetOrdNum(nPos);
+ pObj->SetObjList(this);
+ pObj->SetPage(pPage);
+
+ // #110094# Inform the parent about change to allow invalidations at
+ // evtl. existing parent visualisations
+ impChildInserted(*pObj);
+
+ if (!bRectsDirty) {
+ aOutRect.Union(pObj->GetCurrentBoundRect());
+ aSnapRect.Union(pObj->GetSnapRect());
+ }
+ pObj->SetInserted(TRUE); // Ruft u.a. den UserCall
+ }
+}
+
+void SdrObjList::InsertObject(SdrObject* pObj, ULONG nPos, const SdrInsertReason* pReason)
+{
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::InsertObject(NULL)");
+
+ if(pObj)
+ {
+ // #69055# if anchor is used, reset it before grouping
+ if(GetOwnerObj())
+ {
+ const Point& rAnchorPos = pObj->GetAnchorPos();
+ if(rAnchorPos.X() || rAnchorPos.Y())
+ pObj->NbcSetAnchorPos(Point());
+ }
+
+ // do insert to new group
+ NbcInsertObject(pObj, nPos, pReason);
+
+ // Falls das Objekt in eine Gruppe eingefuegt wird
+ // und nicht mit seinen Bruedern ueberlappt, muss es
+ // einen eigenen Redraw bekommen
+ if(pOwnerObj)
+ {
+ // only repaint here
+ pOwnerObj->ActionChanged();
+ }
+
+ if(pModel)
+ {
+ // Hier muss ein anderer Broadcast her!
+ // Repaint ab Objekt Nummer ... (Achtung: GroupObj)
+ if(pObj->GetPage())
+ {
+ SdrHint aHint(*pObj);
+
+ aHint.SetKind(HINT_OBJINSERTED);
+ pModel->Broadcast(aHint);
+ }
+
+ pModel->SetChanged();
+ }
+ }
+}
+
+SdrObject* SdrObjList::NbcRemoveObject(ULONG nObjNum)
+{
+ if (nObjNum >= maList.size())
+ {
+ OSL_ASSERT(nObjNum<maList.size());
+ return NULL;
+ }
+
+ ULONG nAnz=GetObjCount();
+ SdrObject* pObj=maList[nObjNum];
+ RemoveObjectFromContainer(nObjNum);
+
+ // flushViewObjectContacts() clears the VOC's and those invalidate
+ pObj->GetViewContact().flushViewObjectContacts(true);
+
+ DBG_ASSERT(pObj!=NULL,"Object zum Removen nicht gefunden");
+ if (pObj!=NULL) {
+ DBG_ASSERT(pObj->IsInserted(),"ZObjekt hat keinen Inserted-Status");
+ pObj->SetInserted(FALSE); // Ruft u.a. den UserCall
+ pObj->SetObjList(NULL);
+ pObj->SetPage(NULL);
+ if (!bObjOrdNumsDirty) { // Optimierung fuer den Fall, dass das letzte Obj rausgenommen wird
+ if (nObjNum!=ULONG(nAnz-1)) {
+ bObjOrdNumsDirty=TRUE;
+ }
+ }
+ SetRectsDirty();
+ }
+ return pObj;
+}
+
+SdrObject* SdrObjList::RemoveObject(ULONG nObjNum)
+{
+ if (nObjNum >= maList.size())
+ {
+ OSL_ASSERT(nObjNum<maList.size());
+ return NULL;
+ }
+
+ ULONG nAnz=GetObjCount();
+ SdrObject* pObj=maList[nObjNum];
+ RemoveObjectFromContainer(nObjNum);
+
+ DBG_ASSERT(pObj!=NULL,"Object zum Removen nicht gefunden");
+ if(pObj)
+ {
+ // flushViewObjectContacts() clears the VOC's and those invalidate
+ pObj->GetViewContact().flushViewObjectContacts(true);
+
+ DBG_ASSERT(pObj->IsInserted(),"ZObjekt hat keinen Inserted-Status");
+ if (pModel!=NULL) {
+ // Hier muss ein anderer Broadcast her!
+ if (pObj->GetPage()!=NULL) {
+ SdrHint aHint(*pObj);
+ aHint.SetKind(HINT_OBJREMOVED);
+ pModel->Broadcast(aHint);
+ }
+ pModel->SetChanged();
+ }
+ pObj->SetInserted(FALSE); // Ruft u.a. den UserCall
+ pObj->SetObjList(NULL);
+ pObj->SetPage(NULL);
+ if (!bObjOrdNumsDirty) { // Optimierung fuer den Fall, dass das letzte Obj rausgenommen wird
+ if (nObjNum!=ULONG(nAnz-1)) {
+ bObjOrdNumsDirty=TRUE;
+ }
+ }
+ SetRectsDirty();
+
+ if(pOwnerObj && !GetObjCount())
+ {
+ // empty group created; it needs to be repainted since it's
+ // visualisation changes
+ pOwnerObj->ActionChanged();
+ }
+ }
+ return pObj;
+}
+
+SdrObject* SdrObjList::NbcReplaceObject(SdrObject* pNewObj, ULONG nObjNum)
+{
+ if (nObjNum >= maList.size() || pNewObj == NULL)
+ {
+ OSL_ASSERT(nObjNum<maList.size());
+ OSL_ASSERT(pNewObj!=NULL);
+ return NULL;
+ }
+
+ SdrObject* pObj=maList[nObjNum];
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::ReplaceObject: Object zum Removen nicht gefunden");
+ if (pObj!=NULL) {
+ DBG_ASSERT(pObj->IsInserted(),"SdrObjList::ReplaceObject: ZObjekt hat keinen Inserted-Status");
+ pObj->SetInserted(FALSE);
+ pObj->SetObjList(NULL);
+ pObj->SetPage(NULL);
+ ReplaceObjectInContainer(*pNewObj,nObjNum);
+
+ // flushViewObjectContacts() clears the VOC's and those invalidate
+ pObj->GetViewContact().flushViewObjectContacts(true);
+
+ pNewObj->SetOrdNum(nObjNum);
+ pNewObj->SetObjList(this);
+ pNewObj->SetPage(pPage);
+
+ // #110094# Inform the parent about change to allow invalidations at
+ // evtl. existing parent visualisations
+ impChildInserted(*pNewObj);
+
+ pNewObj->SetInserted(TRUE);
+ SetRectsDirty();
+ }
+ return pObj;
+}
+
+SdrObject* SdrObjList::ReplaceObject(SdrObject* pNewObj, ULONG nObjNum)
+{
+ if (nObjNum >= maList.size())
+ {
+ OSL_ASSERT(nObjNum<maList.size());
+ return NULL;
+ }
+ if (pNewObj == NULL)
+ {
+ OSL_ASSERT(pNewObj!=NULL);
+ return NULL;
+ }
+
+ SdrObject* pObj=maList[nObjNum];
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::ReplaceObject: Object zum Removen nicht gefunden");
+ if (pObj!=NULL) {
+ DBG_ASSERT(pObj->IsInserted(),"SdrObjList::ReplaceObject: ZObjekt hat keinen Inserted-Status");
+ if (pModel!=NULL) {
+ // Hier muss ein anderer Broadcast her!
+ if (pObj->GetPage()!=NULL) {
+ SdrHint aHint(*pObj);
+ aHint.SetKind(HINT_OBJREMOVED);
+ pModel->Broadcast(aHint);
+ }
+ }
+ pObj->SetInserted(FALSE);
+ pObj->SetObjList(NULL);
+ pObj->SetPage(NULL);
+ ReplaceObjectInContainer(*pNewObj,nObjNum);
+
+ // flushViewObjectContacts() clears the VOC's and those invalidate
+ pObj->GetViewContact().flushViewObjectContacts(true);
+
+ pNewObj->SetOrdNum(nObjNum);
+ pNewObj->SetObjList(this);
+ pNewObj->SetPage(pPage);
+
+ // #110094# Inform the parent about change to allow invalidations at
+ // evtl. existing parent visualisations
+ impChildInserted(*pNewObj);
+
+ pNewObj->SetInserted(TRUE);
+ if (pModel!=NULL) {
+ // Hier muss ein anderer Broadcast her!
+ if (pNewObj->GetPage()!=NULL) {
+ SdrHint aHint(*pNewObj);
+ aHint.SetKind(HINT_OBJINSERTED);
+ pModel->Broadcast(aHint);
+ }
+ pModel->SetChanged();
+ }
+ SetRectsDirty();
+ }
+ return pObj;
+}
+
+SdrObject* SdrObjList::NbcSetObjectOrdNum(ULONG nOldObjNum, ULONG nNewObjNum)
+{
+ if (nOldObjNum >= maList.size() || nNewObjNum >= maList.size())
+ {
+ OSL_ASSERT(nOldObjNum<maList.size());
+ OSL_ASSERT(nNewObjNum<maList.size());
+ return NULL;
+ }
+
+ SdrObject* pObj=maList[nOldObjNum];
+ if (nOldObjNum==nNewObjNum) return pObj;
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::NbcSetObjectOrdNum: Object nicht gefunden");
+ if (pObj!=NULL) {
+ DBG_ASSERT(pObj->IsInserted(),"SdrObjList::NbcSetObjectOrdNum: ZObjekt hat keinen Inserted-Status");
+ RemoveObjectFromContainer(nOldObjNum);
+
+ InsertObjectIntoContainer(*pObj,nNewObjNum);
+
+ // #110094# No need to delete visualisation data since same object
+ // gets inserted again. Also a single ActionChanged is enough
+ pObj->ActionChanged();
+
+ pObj->SetOrdNum(nNewObjNum);
+ bObjOrdNumsDirty=TRUE;
+ }
+ return pObj;
+}
+
+SdrObject* SdrObjList::SetObjectOrdNum(ULONG nOldObjNum, ULONG nNewObjNum)
+{
+ if (nOldObjNum >= maList.size() || nNewObjNum >= maList.size())
+ {
+ OSL_ASSERT(nOldObjNum<maList.size());
+ OSL_ASSERT(nNewObjNum<maList.size());
+ return NULL;
+ }
+
+ SdrObject* pObj=maList[nOldObjNum];
+ if (nOldObjNum==nNewObjNum) return pObj;
+ DBG_ASSERT(pObj!=NULL,"SdrObjList::SetObjectOrdNum: Object nicht gefunden");
+ if (pObj!=NULL) {
+ DBG_ASSERT(pObj->IsInserted(),"SdrObjList::SetObjectOrdNum: ZObjekt hat keinen Inserted-Status");
+ RemoveObjectFromContainer(nOldObjNum);
+ InsertObjectIntoContainer(*pObj,nNewObjNum);
+
+ // #110094#No need to delete visualisation data since same object
+ // gets inserted again. Also a single ActionChanged is enough
+ pObj->ActionChanged();
+
+ pObj->SetOrdNum(nNewObjNum);
+ bObjOrdNumsDirty=TRUE;
+ if (pModel!=NULL)
+ {
+ // Hier muss ein anderer Broadcast her!
+ if (pObj->GetPage()!=NULL) pModel->Broadcast(SdrHint(*pObj));
+ pModel->SetChanged();
+ }
+ }
+ return pObj;
+}
+
+const Rectangle& SdrObjList::GetAllObjSnapRect() const
+{
+ if (bRectsDirty) {
+ ((SdrObjList*)this)->RecalcRects();
+ ((SdrObjList*)this)->bRectsDirty=FALSE;
+ }
+ return aSnapRect;
+}
+
+const Rectangle& SdrObjList::GetAllObjBoundRect() const
+{
+ // #i106183# for deep group hierarchies like in chart2, the invalidates
+ // through the hierarchy are not correct; use a 2nd hint for the needed
+ // recalculation. Future versions will have no bool flag at all, but
+ // just aOutRect in empty state to representate an invalid state, thus
+ // it's a step in the right direction.
+ if (bRectsDirty || aOutRect.IsEmpty())
+ {
+ ((SdrObjList*)this)->RecalcRects();
+ ((SdrObjList*)this)->bRectsDirty=FALSE;
+ }
+ return aOutRect;
+}
+
+void SdrObjList::NbcReformatAllTextObjects()
+{
+ ULONG nAnz=GetObjCount();
+ ULONG nNum=0;
+
+ Printer* pPrinter = NULL;
+
+ if (pModel)
+ {
+ if (pModel->GetRefDevice() && pModel->GetRefDevice()->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ // Kein RefDevice oder RefDevice kein Printer
+ pPrinter = (Printer*) pModel->GetRefDevice();
+ }
+ }
+
+ while (nNum<nAnz)
+ {
+ SdrObject* pObj = GetObj(nNum);
+ if (pPrinter &&
+ pObj->GetObjInventor() == SdrInventor &&
+ pObj->GetObjIdentifier() == OBJ_OLE2 &&
+ !( (SdrOle2Obj*) pObj )->IsEmpty() )
+ {
+ //const SvInPlaceObjectRef& xObjRef = ((SdrOle2Obj*) pObj)->GetObjRef();
+ //TODO/LATER: PrinterChangeNotification needed
+ //if( xObjRef.Is() && ( xObjRef->GetMiscStatus() & SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE ) )
+ // xObjRef->OnDocumentPrinterChanged(pPrinter);
+ }
+
+ pObj->NbcReformatText();
+ nAnz=GetObjCount(); // ReformatText may delete an object
+ nNum++;
+ }
+
+}
+
+void SdrObjList::ReformatAllTextObjects()
+{
+ NbcReformatAllTextObjects();
+}
+
+/** steps over all available objects and reformats all
+ edge objects that are connected to other objects so that
+ they may reposition itselfs.
+ #103122#
+*/
+void SdrObjList::ReformatAllEdgeObjects()
+{
+ const sal_uInt32 nCount=GetObjCount();
+ sal_uInt32 nObj;
+
+ for( nObj = 0; nObj < nCount; nObj++ )
+ {
+ SdrObject* pObj = GetObj(nObj);
+ if( pObj->ISA(SdrEdgeObj) )
+ static_cast<SdrEdgeObj*>(pObj)->Reformat();
+ }
+}
+
+void SdrObjList::BurnInStyleSheetAttributes()
+{
+ for(sal_uInt32 a(0L); a < GetObjCount(); a++)
+ {
+ GetObj(a)->BurnInStyleSheetAttributes();
+ }
+}
+
+ULONG SdrObjList::GetObjCount() const
+{
+ return maList.size();
+}
+
+
+
+
+SdrObject* SdrObjList::GetObj(ULONG nNum) const
+{
+ if (nNum >= maList.size())
+ {
+ OSL_ASSERT(nNum<maList.size());
+ return NULL;
+ }
+ else
+ return maList[nNum];
+}
+
+
+
+
+FASTBOOL SdrObjList::IsReadOnly() const
+{
+ FASTBOOL bRet=FALSE;
+ if (pPage!=NULL && pPage!=this) bRet=pPage->IsReadOnly();
+ return bRet;
+}
+
+ULONG SdrObjList::CountAllObjects() const
+{
+ ULONG nCnt=GetObjCount();
+ ULONG nAnz=nCnt;
+ for (USHORT nNum=0; nNum<nAnz; nNum++) {
+ SdrObjList* pSubOL=GetObj(nNum)->GetSubList();
+ if (pSubOL!=NULL) {
+ nCnt+=pSubOL->CountAllObjects();
+ }
+ }
+ return nCnt;
+}
+
+void SdrObjList::ForceSwapInObjects() const
+{
+ ULONG nObjAnz=GetObjCount();
+ for (ULONG nObjNum=nObjAnz; nObjNum>0;) {
+ SdrObject* pObj=GetObj(--nObjNum);
+ SdrGrafObj* pGrafObj=PTR_CAST(SdrGrafObj,pObj);
+ if (pGrafObj!=NULL) {
+ pGrafObj->ForceSwapIn();
+ }
+ SdrObjList* pOL=pObj->GetSubList();
+ if (pOL!=NULL) {
+ pOL->ForceSwapInObjects();
+ }
+ }
+}
+
+void SdrObjList::ForceSwapOutObjects() const
+{
+ ULONG nObjAnz=GetObjCount();
+ for (ULONG nObjNum=nObjAnz; nObjNum>0;) {
+ SdrObject* pObj=GetObj(--nObjNum);
+ SdrGrafObj* pGrafObj=PTR_CAST(SdrGrafObj,pObj);
+ if (pGrafObj!=NULL) {
+ pGrafObj->ForceSwapOut();
+ }
+ SdrObjList* pOL=pObj->GetSubList();
+ if (pOL!=NULL) {
+ pOL->ForceSwapOutObjects();
+ }
+ }
+}
+
+void SdrObjList::FlattenGroups()
+{
+ sal_Int32 nObj = GetObjCount();
+ sal_Int32 i;
+ for( i=nObj-1; i>=0; --i)
+ UnGroupObj(i);
+}
+
+void SdrObjList::UnGroupObj( ULONG nObjNum )
+{
+ // if the given object is no group, this method is a noop
+ SdrObject* pUngroupObj = GetObj( nObjNum );
+ if( pUngroupObj )
+ {
+ SdrObjList* pSrcLst = pUngroupObj->GetSubList();
+ //sal_Int32 nCount( 0 );
+ if( pUngroupObj->ISA( SdrObjGroup ) && pSrcLst )
+ {
+ SdrObjGroup* pUngroupGroup = static_cast< SdrObjGroup* > (pUngroupObj);
+
+ // ungroup recursively (has to be head recursion,
+ // otherwise our indices will get trashed when doing it in
+ // the loop)
+ pSrcLst->FlattenGroups();
+
+ // the position at which we insert the members of rUngroupGroup
+ sal_Int32 nInsertPos( pUngroupGroup->GetOrdNum() );
+
+ SdrObject* pObj;
+ sal_Int32 i, nAnz = pSrcLst->GetObjCount();
+ for( i=0; i<nAnz; ++i )
+ {
+ pObj = pSrcLst->RemoveObject(0);
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pUngroupGroup);
+ InsertObject(pObj, nInsertPos, &aReason);
+ ++nInsertPos;
+ }
+
+ RemoveObject(nInsertPos);
+ }
+ }
+#ifdef DBG_UTIL
+ else
+ DBG_ERROR("SdrObjList::UnGroupObj: object index invalid");
+#endif
+}
+
+
+
+
+bool SdrObjList::HasObjectNavigationOrder (void) const
+{
+ return mpNavigationOrder.get() != NULL;
+}
+
+
+
+
+void SdrObjList::SetObjectNavigationPosition (
+ SdrObject& rObject,
+ const sal_uInt32 nNewPosition)
+{
+ // When the navigation order container has not yet been created then
+ // create one now. It is initialized with the z-order taken from
+ // maList.
+ if (mpNavigationOrder.get() == NULL)
+ {
+ mpNavigationOrder.reset(new WeakSdrObjectContainerType(maList.size()));
+ ::std::copy(
+ maList.begin(),
+ maList.end(),
+ mpNavigationOrder->begin());
+ }
+ OSL_ASSERT(mpNavigationOrder.get()!=NULL);
+ OSL_ASSERT( mpNavigationOrder->size() == maList.size());
+
+ SdrObjectWeakRef aReference (&rObject);
+
+ // Look up the object whose navigation position is to be changed.
+ WeakSdrObjectContainerType::iterator iObject (::std::find(
+ mpNavigationOrder->begin(),
+ mpNavigationOrder->end(),
+ aReference));
+ if (iObject == mpNavigationOrder->end())
+ {
+ // The given object is not a member of the navigation order.
+ return;
+ }
+
+ // Move the object to its new position.
+ const sal_uInt32 nOldPosition = ::std::distance(mpNavigationOrder->begin(), iObject);
+ if (nOldPosition != nNewPosition)
+ {
+ mpNavigationOrder->erase(iObject);
+ sal_uInt32 nInsertPosition (nNewPosition);
+ // Adapt insertion position for the just erased object.
+ if (nNewPosition >= nOldPosition)
+ nInsertPosition -= 1;
+ if (nInsertPosition >= mpNavigationOrder->size())
+ mpNavigationOrder->push_back(aReference);
+ else
+ mpNavigationOrder->insert(mpNavigationOrder->begin()+nInsertPosition, aReference);
+
+ mbIsNavigationOrderDirty = true;
+
+ // The navigation order is written out to file so mark the model as modified.
+ if (pModel != NULL)
+ pModel->SetChanged();
+ }
+}
+
+
+
+
+SdrObject* SdrObjList::GetObjectForNavigationPosition (const sal_uInt32 nNavigationPosition) const
+{
+ if (HasObjectNavigationOrder())
+ {
+ // There is a user defined navigation order. Make sure the object
+ // index is correct and look up the object in mpNavigationOrder.
+ if (nNavigationPosition >= mpNavigationOrder->size())
+ {
+ OSL_ASSERT(nNavigationPosition < mpNavigationOrder->size());
+ }
+ else
+ return (*mpNavigationOrder)[nNavigationPosition].get();
+ }
+ else
+ {
+ // There is no user defined navigation order. Use the z-order
+ // instead.
+ if (nNavigationPosition >= maList.size())
+ {
+ OSL_ASSERT(nNavigationPosition < maList.size());
+ }
+ else
+ return maList[nNavigationPosition];
+ }
+ return NULL;
+}
+
+
+
+
+void SdrObjList::ClearObjectNavigationOrder (void)
+{
+ mpNavigationOrder.reset();
+ mbIsNavigationOrderDirty = true;
+}
+
+
+
+
+bool SdrObjList::RecalcNavigationPositions (void)
+{
+ bool bUpToDate (false);
+
+ if (mbIsNavigationOrderDirty)
+ {
+ if (mpNavigationOrder.get() != NULL)
+ {
+ mbIsNavigationOrderDirty = false;
+
+ WeakSdrObjectContainerType::iterator iObject;
+ WeakSdrObjectContainerType::const_iterator iEnd (mpNavigationOrder->end());
+ sal_uInt32 nIndex (0);
+ for (iObject=mpNavigationOrder->begin(); iObject!=iEnd; ++iObject,++nIndex)
+ (*iObject)->SetNavigationPosition(nIndex);
+
+ bUpToDate = true;
+ }
+ }
+
+ return mpNavigationOrder.get() != NULL;
+}
+
+
+
+
+void SdrObjList::SetNavigationOrder (const uno::Reference<container::XIndexAccess>& rxOrder)
+{
+ if (rxOrder.is())
+ {
+ const sal_Int32 nCount = rxOrder->getCount();
+ if ((sal_uInt32)nCount != maList.size())
+ return;
+
+ if (mpNavigationOrder.get() == NULL)
+ mpNavigationOrder.reset(new WeakSdrObjectContainerType(nCount));
+
+ for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
+ {
+ uno::Reference<uno::XInterface> xShape (rxOrder->getByIndex(nIndex), uno::UNO_QUERY);
+ SdrObject* pObject = SdrObject::getSdrObjectFromXShape(xShape);
+ if (pObject == NULL)
+ break;
+ (*mpNavigationOrder)[nIndex] = pObject;
+ }
+
+ mbIsNavigationOrderDirty = true;
+ }
+ else
+ ClearObjectNavigationOrder();
+}
+
+
+
+
+void SdrObjList::InsertObjectIntoContainer (
+ SdrObject& rObject,
+ const sal_uInt32 nInsertPosition)
+{
+ OSL_ASSERT(nInsertPosition<=maList.size());
+
+ // Update the navigation positions.
+ if (HasObjectNavigationOrder())
+ {
+ // The new object does not have a user defined position so append it
+ // to the list.
+ rObject.SetNavigationPosition(mpNavigationOrder->size());
+ mpNavigationOrder->push_back(&rObject);
+ }
+
+ // Insert object into object list. Because the insert() method requires
+ // a valid iterator as insertion position, we have to use push_back() to
+ // insert at the end of the list.
+ if (nInsertPosition >= maList.size())
+ maList.push_back(&rObject);
+ else
+ maList.insert(maList.begin()+nInsertPosition, &rObject);
+ bObjOrdNumsDirty=TRUE;
+}
+
+
+
+
+void SdrObjList::ReplaceObjectInContainer (
+ SdrObject& rNewObject,
+ const sal_uInt32 nObjectPosition)
+{
+ if (nObjectPosition >= maList.size())
+ {
+ OSL_ASSERT(nObjectPosition<maList.size());
+ return;
+ }
+
+ // Update the navigation positions.
+ if (HasObjectNavigationOrder())
+ {
+ // A user defined position of the object that is to be replaced is
+ // not transferred to the new object so erase the former and append
+ // the later object from/to the navigation order.
+ OSL_ASSERT(nObjectPosition < maList.size());
+ SdrObjectWeakRef aReference (maList[nObjectPosition]);
+ WeakSdrObjectContainerType::iterator iObject (::std::find(
+ mpNavigationOrder->begin(),
+ mpNavigationOrder->end(),
+ aReference));
+ if (iObject != mpNavigationOrder->end())
+ mpNavigationOrder->erase(iObject);
+
+ mpNavigationOrder->push_back(&rNewObject);
+
+ mbIsNavigationOrderDirty = true;
+ }
+
+ maList[nObjectPosition] = &rNewObject;
+ bObjOrdNumsDirty=TRUE;
+}
+
+
+
+
+void SdrObjList::RemoveObjectFromContainer (
+ const sal_uInt32 nObjectPosition)
+{
+ if (nObjectPosition >= maList.size())
+ {
+ OSL_ASSERT(nObjectPosition<maList.size());
+ return;
+ }
+
+ // Update the navigation positions.
+ if (HasObjectNavigationOrder())
+ {
+ SdrObjectWeakRef aReference (maList[nObjectPosition]);
+ WeakSdrObjectContainerType::iterator iObject (::std::find(
+ mpNavigationOrder->begin(),
+ mpNavigationOrder->end(),
+ aReference));
+ if (iObject != mpNavigationOrder->end())
+ mpNavigationOrder->erase(iObject);
+ mbIsNavigationOrderDirty = true;
+ }
+
+ maList.erase(maList.begin()+nObjectPosition);
+ bObjOrdNumsDirty=TRUE;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPageGridFrameList::Clear()
+{
+ USHORT nAnz=GetCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ delete GetObject(i);
+ }
+ aList.Clear();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #111111# PageUser section
+
+void SdrPage::AddPageUser(sdr::PageUser& rNewUser)
+{
+ maPageUsers.push_back(&rNewUser);
+}
+
+void SdrPage::RemovePageUser(sdr::PageUser& rOldUser)
+{
+ const ::sdr::PageUserVector::iterator aFindResult = ::std::find(maPageUsers.begin(), maPageUsers.end(), &rOldUser);
+ if(aFindResult != maPageUsers.end())
+ {
+ maPageUsers.erase(aFindResult);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// #110094# DrawContact section
+
+sdr::contact::ViewContact* SdrPage::CreateObjectSpecificViewContact()
+{
+ return new sdr::contact::ViewContactOfSdrPage(*this);
+}
+
+sdr::contact::ViewContact& SdrPage::GetViewContact() const
+{
+ if(!mpViewContact)
+ {
+ const_cast< SdrPage* >(this)->mpViewContact =
+ const_cast< SdrPage* >(this)->CreateObjectSpecificViewContact();
+ }
+
+ return *mpViewContact;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPageProperties::ImpRemoveStyleSheet()
+{
+ if(mpStyleSheet)
+ {
+ EndListening(*mpStyleSheet);
+ mpProperties->SetParent(0);
+ mpStyleSheet = 0;
+ }
+}
+
+void SdrPageProperties::ImpAddStyleSheet(SfxStyleSheet& rNewStyleSheet)
+{
+ if(mpStyleSheet != &rNewStyleSheet)
+ {
+ ImpRemoveStyleSheet();
+ mpStyleSheet = &rNewStyleSheet;
+ StartListening(rNewStyleSheet);
+ mpProperties->SetParent(&rNewStyleSheet.GetItemSet());
+ }
+}
+
+void ImpPageChange(SdrPage& rSdrPage)
+{
+ rSdrPage.ActionChanged();
+
+ if(rSdrPage.GetModel())
+ {
+ rSdrPage.GetModel()->SetChanged(true);
+ SdrHint aHint(HINT_PAGEORDERCHG);
+ aHint.SetPage(&rSdrPage);
+ rSdrPage.GetModel()->Broadcast(aHint);
+ }
+}
+
+SdrPageProperties::SdrPageProperties(SdrPage& rSdrPage)
+: SfxListener(),
+ mpSdrPage(&rSdrPage),
+ mpStyleSheet(0),
+ mpProperties(new SfxItemSet(mpSdrPage->GetModel()->GetItemPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST))
+{
+ if(!rSdrPage.IsMasterPage())
+ {
+ mpProperties->Put(XFillStyleItem(XFILL_NONE));
+ }
+}
+
+SdrPageProperties::~SdrPageProperties()
+{
+ ImpRemoveStyleSheet();
+ delete mpProperties;
+}
+
+void SdrPageProperties::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint)
+{
+ const SfxSimpleHint* pSimpleHint = dynamic_cast< const SfxSimpleHint* >(&rHint);
+
+ if(pSimpleHint)
+ {
+ switch(pSimpleHint->GetId())
+ {
+ case SFX_HINT_DATACHANGED :
+ {
+ // notify change, broadcast
+ ImpPageChange(*mpSdrPage);
+ break;
+ }
+ case SFX_HINT_DYING :
+ {
+ // Style needs to be forgotten
+ ImpRemoveStyleSheet();
+ break;
+ }
+ }
+ }
+}
+
+const SfxItemSet& SdrPageProperties::GetItemSet() const
+{
+ return *mpProperties;
+}
+
+void SdrPageProperties::PutItemSet(const SfxItemSet& rSet)
+{
+ OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
+ mpProperties->Put(rSet);
+ ImpPageChange(*mpSdrPage);
+}
+
+void SdrPageProperties::PutItem(const SfxPoolItem& rItem)
+{
+ OSL_ENSURE(!mpSdrPage->IsMasterPage(), "Item set at MasterPage Attributes (!)");
+ mpProperties->Put(rItem);
+ ImpPageChange(*mpSdrPage);
+}
+
+void SdrPageProperties::ClearItem(const sal_uInt16 nWhich)
+{
+ mpProperties->ClearItem(nWhich);
+ ImpPageChange(*mpSdrPage);
+}
+
+void SdrPageProperties::SetStyleSheet(SfxStyleSheet* pStyleSheet)
+{
+ if(pStyleSheet)
+ {
+ ImpAddStyleSheet(*pStyleSheet);
+ }
+ else
+ {
+ ImpRemoveStyleSheet();
+ }
+
+ ImpPageChange(*mpSdrPage);
+}
+
+SfxStyleSheet* SdrPageProperties::GetStyleSheet() const
+{
+ return mpStyleSheet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrPage,SdrObjList);
+DBG_NAME(SdrPage)
+SdrPage::SdrPage(SdrModel& rNewModel, bool bMasterPage)
+: SdrObjList(&rNewModel, this),
+ mpViewContact(0L),
+ nWdt(10L),
+ nHgt(10L),
+ nBordLft(0L),
+ nBordUpp(0L),
+ nBordRgt(0L),
+ nBordLwr(0L),
+ pLayerAdmin(new SdrLayerAdmin(&rNewModel.GetLayerAdmin())),
+ mpSdrPageProperties(0),
+ mpMasterPageDescriptor(0L),
+ nPageNum(0L),
+ mbMaster(bMasterPage),
+ mbInserted(false),
+ mbObjectsNotPersistent(false),
+ mbSwappingLocked(false),
+ mbPageBorderOnlyLeftRight(false)
+{
+ DBG_CTOR(SdrPage,NULL);
+ aPrefVisiLayers.SetAll();
+ eListKind = (bMasterPage) ? SDROBJLIST_MASTERPAGE : SDROBJLIST_DRAWPAGE;
+
+ mpSdrPageProperties = new SdrPageProperties(*this);
+}
+
+SdrPage::SdrPage(const SdrPage& rSrcPage)
+: SdrObjList(rSrcPage.pModel, this),
+ tools::WeakBase< SdrPage >(),
+ mpViewContact(0L),
+ nWdt(rSrcPage.nWdt),
+ nHgt(rSrcPage.nHgt),
+ nBordLft(rSrcPage.nBordLft),
+ nBordUpp(rSrcPage.nBordUpp),
+ nBordRgt(rSrcPage.nBordRgt),
+ nBordLwr(rSrcPage.nBordLwr),
+ pLayerAdmin(new SdrLayerAdmin(rSrcPage.pModel->GetLayerAdmin())),
+ mpSdrPageProperties(0),
+ mpMasterPageDescriptor(0L),
+ nPageNum(rSrcPage.nPageNum),
+ mbMaster(rSrcPage.mbMaster),
+ mbInserted(false),
+ mbObjectsNotPersistent(rSrcPage.mbObjectsNotPersistent),
+ mbSwappingLocked(rSrcPage.mbSwappingLocked),
+ mbPageBorderOnlyLeftRight(rSrcPage.mbPageBorderOnlyLeftRight)
+{
+ DBG_CTOR(SdrPage,NULL);
+ aPrefVisiLayers.SetAll();
+ eListKind = (mbMaster) ? SDROBJLIST_MASTERPAGE : SDROBJLIST_DRAWPAGE;
+
+ // copy things from source
+ // Warning: this leads to slicing (see issue 93186) and has to be
+ // removed as soon as possible.
+ *this = rSrcPage;
+ OSL_ENSURE(mpSdrPageProperties,
+ "SdrPage::SdrPage: operator= did not create needed SdrPageProperties (!)");
+
+ // be careful and correct eListKind, a member of SdrObjList which
+ // will be changed by the SdrOIbjList::operator= before...
+ eListKind = (mbMaster) ? SDROBJLIST_MASTERPAGE : SDROBJLIST_DRAWPAGE;
+
+ // The previous assignment to *this may have resulted in a call to
+ // createUnoPage at a partially initialized (sliced) SdrPage object.
+ // Due to the vtable being not yet fully set-up at this stage,
+ // createUnoPage() may have been called at the wrong class.
+ // To force a call to the right createUnoPage() at a later time when the
+ // new object is full constructed mxUnoPage is disposed now.
+ uno::Reference<lang::XComponent> xComponent (mxUnoPage, uno::UNO_QUERY);
+ if (xComponent.is())
+ {
+ mxUnoPage = NULL;
+ xComponent->dispose();
+ }
+}
+
+SdrPage::~SdrPage()
+{
+ if( mxUnoPage.is() ) try
+ {
+ uno::Reference< lang::XComponent > xPageComponent( mxUnoPage, uno::UNO_QUERY_THROW );
+ mxUnoPage.clear();
+ xPageComponent->dispose();
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ // #111111#
+ // tell all the registered PageUsers that the page is in destruction
+ // This causes some (all?) PageUsers to remove themselves from the list
+ // of page users. Therefore we have to use a copy of the list for the
+ // iteration.
+ ::sdr::PageUserVector aListCopy (maPageUsers.begin(), maPageUsers.end());
+ for(::sdr::PageUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); aIterator++)
+ {
+ sdr::PageUser* pPageUser = *aIterator;
+ DBG_ASSERT(pPageUser, "SdrPage::~SdrPage: corrupt PageUser list (!)");
+ pPageUser->PageInDestruction(*this);
+ }
+
+ // #111111#
+ // Clear the vector. This means that user do not need to call RemovePageUser()
+ // when they get called from PageInDestruction().
+ maPageUsers.clear();
+
+ delete pLayerAdmin;
+
+ TRG_ClearMasterPage();
+
+ // #110094#
+ if(mpViewContact)
+ {
+ delete mpViewContact;
+ mpViewContact = 0L;
+ }
+
+ {
+ delete mpSdrPageProperties;
+ mpSdrPageProperties = 0;
+ }
+
+ DBG_DTOR(SdrPage,NULL);
+}
+
+void SdrPage::operator=(const SdrPage& rSrcPage)
+{
+ if(mpViewContact)
+ {
+ delete mpViewContact;
+ mpViewContact = 0L;
+ }
+
+ // Joe also sets some parameters for the class this one
+ // is derived from. SdrObjList does the same bad handling of
+ // copy constructor and operator=, so i better let it stand here.
+ pPage = this;
+
+ // copy all the local parameters to make this instance
+ // a valid copy od source page before copying and inserting
+ // the contained objects
+ mbMaster = rSrcPage.mbMaster;
+ mbSwappingLocked = rSrcPage.mbSwappingLocked;
+ mbPageBorderOnlyLeftRight = rSrcPage.mbPageBorderOnlyLeftRight;
+ aPrefVisiLayers = rSrcPage.aPrefVisiLayers;
+ nWdt = rSrcPage.nWdt;
+ nHgt = rSrcPage.nHgt;
+ nBordLft = rSrcPage.nBordLft;
+ nBordUpp = rSrcPage.nBordUpp;
+ nBordRgt = rSrcPage.nBordRgt;
+ nBordLwr = rSrcPage.nBordLwr;
+ nPageNum = rSrcPage.nPageNum;
+
+ if(rSrcPage.TRG_HasMasterPage())
+ {
+ TRG_SetMasterPage(rSrcPage.TRG_GetMasterPage());
+ TRG_SetMasterPageVisibleLayers(rSrcPage.TRG_GetMasterPageVisibleLayers());
+ }
+ else
+ {
+ TRG_ClearMasterPage();
+ }
+ //aMasters = rSrcPage.aMasters;
+
+ mbObjectsNotPersistent = rSrcPage.mbObjectsNotPersistent;
+
+ {
+ // #i111122# delete SdrPageProperties when model is different
+ if(mpSdrPageProperties && GetModel() != rSrcPage.GetModel())
+ {
+ delete mpSdrPageProperties;
+ mpSdrPageProperties = 0;
+ }
+
+ if(!mpSdrPageProperties)
+ {
+ mpSdrPageProperties = new SdrPageProperties(*this);
+ }
+ else
+ {
+ mpSdrPageProperties->ClearItem(0);
+ }
+
+ if(!IsMasterPage())
+ {
+ mpSdrPageProperties->PutItemSet(rSrcPage.getSdrPageProperties().GetItemSet());
+ }
+
+ mpSdrPageProperties->SetStyleSheet(rSrcPage.getSdrPageProperties().GetStyleSheet());
+ }
+
+ // Now copy the contained obejcts (by cloning them)
+ SdrObjList::operator=(rSrcPage);
+}
+
+SdrPage* SdrPage::Clone() const
+{
+ return Clone(NULL);
+}
+
+SdrPage* SdrPage::Clone(SdrModel* pNewModel) const
+{
+ if (pNewModel==NULL) pNewModel=pModel;
+ SdrPage* pPage2=new SdrPage(*pNewModel);
+ *pPage2=*this;
+ return pPage2;
+}
+
+void SdrPage::SetSize(const Size& aSiz)
+{
+ bool bChanged(false);
+
+ if(aSiz.Width() != nWdt)
+ {
+ nWdt = aSiz.Width();
+ bChanged = true;
+ }
+
+ if(aSiz.Height() != nHgt)
+ {
+ nHgt = aSiz.Height();
+ bChanged = true;
+ }
+
+ if(bChanged)
+ {
+ SetChanged();
+ }
+}
+
+Size SdrPage::GetSize() const
+{
+ return Size(nWdt,nHgt);
+}
+
+INT32 SdrPage::GetWdt() const
+{
+ return nWdt;
+}
+
+void SdrPage::SetOrientation(Orientation eOri)
+{
+ // Quadratisch ist und bleibt immer Portrait
+ Size aSiz(GetSize());
+ if (aSiz.Width()!=aSiz.Height()) {
+ if ((eOri==ORIENTATION_PORTRAIT) == (aSiz.Width()>aSiz.Height())) {
+ SetSize(Size(aSiz.Height(),aSiz.Width()));
+ }
+ }
+}
+
+Orientation SdrPage::GetOrientation() const
+{
+ // Quadratisch ist Portrait
+ Orientation eRet=ORIENTATION_PORTRAIT;
+ Size aSiz(GetSize());
+ if (aSiz.Width()>aSiz.Height()) eRet=ORIENTATION_LANDSCAPE;
+ return eRet;
+}
+
+INT32 SdrPage::GetHgt() const
+{
+ return nHgt;
+}
+
+void SdrPage::SetBorder(INT32 nLft, INT32 nUpp, INT32 nRgt, INT32 nLwr)
+{
+ bool bChanged(false);
+
+ if(nBordLft != nLft)
+ {
+ nBordLft = nLft;
+ bChanged = true;
+ }
+
+ if(nBordUpp != nUpp)
+ {
+ nBordUpp = nUpp;
+ bChanged = true;
+ }
+
+ if(nBordRgt != nRgt)
+ {
+ nBordRgt = nRgt;
+ bChanged = true;
+ }
+
+ if(nBordLwr != nLwr)
+ {
+ nBordLwr = nLwr;
+ bChanged = true;
+ }
+
+ if(bChanged)
+ {
+ SetChanged();
+ }
+}
+
+void SdrPage::SetLftBorder(INT32 nBorder)
+{
+ if(nBordLft != nBorder)
+ {
+ nBordLft = nBorder;
+ SetChanged();
+ }
+}
+
+void SdrPage::SetUppBorder(INT32 nBorder)
+{
+ if(nBordUpp != nBorder)
+ {
+ nBordUpp = nBorder;
+ SetChanged();
+ }
+}
+
+void SdrPage::SetRgtBorder(INT32 nBorder)
+{
+ if(nBordRgt != nBorder)
+ {
+ nBordRgt=nBorder;
+ SetChanged();
+ }
+}
+
+void SdrPage::SetLwrBorder(INT32 nBorder)
+{
+ if(nBordLwr != nBorder)
+ {
+ nBordLwr=nBorder;
+ SetChanged();
+ }
+}
+
+INT32 SdrPage::GetLftBorder() const
+{
+ return nBordLft;
+}
+
+INT32 SdrPage::GetUppBorder() const
+{
+ return nBordUpp;
+}
+
+INT32 SdrPage::GetRgtBorder() const
+{
+ return nBordRgt;
+}
+
+INT32 SdrPage::GetLwrBorder() const
+{
+ return nBordLwr;
+}
+
+void SdrPage::SetModel(SdrModel* pNewModel)
+{
+ SdrModel* pOldModel=pModel;
+ SdrObjList::SetModel(pNewModel);
+ if (pNewModel!=pOldModel)
+ {
+ if (pNewModel!=NULL) {
+ pLayerAdmin->SetParent(&pNewModel->GetLayerAdmin());
+ } else {
+ pLayerAdmin->SetParent(NULL);
+ }
+ pLayerAdmin->SetModel(pNewModel);
+
+ // create new SdrPageProperties with new model (due to SfxItemSet there)
+ // and copy ItemSet and StyleSheet
+ SdrPageProperties *pNew = new SdrPageProperties(*this);
+
+ if(!IsMasterPage())
+ {
+ pNew->PutItemSet(getSdrPageProperties().GetItemSet());
+ }
+
+ pNew->SetStyleSheet(getSdrPageProperties().GetStyleSheet());
+
+ delete mpSdrPageProperties;
+ mpSdrPageProperties = pNew;
+ }
+
+ // update listeners at possible api wrapper object
+ if( pOldModel != pNewModel )
+ {
+ if( mxUnoPage.is() )
+ {
+ SvxDrawPage* pPage2 = SvxDrawPage::getImplementation( mxUnoPage );
+ if( pPage2 )
+ pPage2->ChangeModel( pNewModel );
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// #i68775# React on PageNum changes (from Model in most cases)
+void SdrPage::SetPageNum(sal_uInt16 nNew)
+{
+ if(nNew != nPageNum)
+ {
+ // change
+ nPageNum = nNew;
+
+ // notify visualisations, also notifies e.g. buffered MasterPages
+ ActionChanged();
+ }
+}
+
+USHORT SdrPage::GetPageNum() const
+{
+ if (!mbInserted)
+ return 0;
+
+ if (mbMaster) {
+ if (pModel && pModel->IsMPgNumsDirty())
+ ((SdrModel*)pModel)->RecalcPageNums(TRUE);
+ } else {
+ if (pModel && pModel->IsPagNumsDirty())
+ ((SdrModel*)pModel)->RecalcPageNums(FALSE);
+ }
+ return nPageNum;
+}
+
+void SdrPage::SetChanged()
+{
+ // #110094#-11
+ // For test purposes, use the new ViewContact for change
+ // notification now.
+ ActionChanged();
+
+ if( pModel )
+ {
+ pModel->SetChanged();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// MasterPage interface
+
+void SdrPage::TRG_SetMasterPage(SdrPage& rNew)
+{
+ if(mpMasterPageDescriptor && &(mpMasterPageDescriptor->GetUsedPage()) == &rNew)
+ return;
+
+ if(mpMasterPageDescriptor)
+ TRG_ClearMasterPage();
+
+ mpMasterPageDescriptor = new ::sdr::MasterPageDescriptor(*this, rNew);
+ GetViewContact().ActionChanged();
+}
+
+void SdrPage::TRG_ClearMasterPage()
+{
+ if(mpMasterPageDescriptor)
+ {
+ SetChanged();
+
+ // the flushViewObjectContacts() will do needed invalidates by deleting the involved VOCs
+ mpMasterPageDescriptor->GetUsedPage().GetViewContact().flushViewObjectContacts(true);
+
+ delete mpMasterPageDescriptor;
+ mpMasterPageDescriptor = 0L;
+ }
+}
+
+SdrPage& SdrPage::TRG_GetMasterPage() const
+{
+ DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPage(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
+ return mpMasterPageDescriptor->GetUsedPage();
+}
+
+const SetOfByte& SdrPage::TRG_GetMasterPageVisibleLayers() const
+{
+ DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
+ return mpMasterPageDescriptor->GetVisibleLayers();
+}
+
+void SdrPage::TRG_SetMasterPageVisibleLayers(const SetOfByte& rNew)
+{
+ DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_SetMasterPageVisibleLayers(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
+ mpMasterPageDescriptor->SetVisibleLayers(rNew);
+}
+
+sdr::contact::ViewContact& SdrPage::TRG_GetMasterPageDescriptorViewContact() const
+{
+ DBG_ASSERT(mpMasterPageDescriptor != 0L, "TRG_GetMasterPageDescriptorViewContact(): No MasterPage available. Use TRG_HasMasterPage() before access (!)");
+ return mpMasterPageDescriptor->GetViewContact();
+}
+
+// #115423# used from SdrModel::RemoveMasterPage
+void SdrPage::TRG_ImpMasterPageRemoved(const SdrPage& rRemovedPage)
+{
+ if(TRG_HasMasterPage())
+ {
+ if(&TRG_GetMasterPage() == &rRemovedPage)
+ {
+ TRG_ClearMasterPage();
+ }
+ }
+}
+
+const SdrPageGridFrameList* SdrPage::GetGridFrameList(const SdrPageView* /*pPV*/, const Rectangle* /*pRect*/) const
+{
+ return NULL;
+}
+
+XubString SdrPage::GetLayoutName() const
+{
+ // Die wollte Dieter haben.
+ return String();
+}
+
+void SdrPage::SetInserted( bool bIns )
+{
+ if( mbInserted != bIns )
+ {
+ mbInserted = bIns;
+
+ SdrObjListIter aIter( *this, IM_FLAT );
+ while ( aIter.IsMore() )
+ {
+ SdrObject* pObj = aIter.Next();
+ if ( pObj->ISA(SdrOle2Obj) )
+ {
+ if( mbInserted )
+ ( (SdrOle2Obj*) pObj)->Connect();
+ else
+ ( (SdrOle2Obj*) pObj)->Disconnect();
+ }
+ }
+ }
+}
+
+
+uno::Reference< uno::XInterface > SdrPage::getUnoPage()
+{
+ // try weak reference first
+ if( !mxUnoPage.is() )
+ {
+ // create one
+ mxUnoPage = createUnoPage();
+ }
+
+ return mxUnoPage;
+}
+
+uno::Reference< uno::XInterface > SdrPage::createUnoPage()
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xInt =
+ static_cast<cppu::OWeakObject*>( new SvxFmDrawPage( this ) );
+ return xInt;
+}
+
+SfxStyleSheet* SdrPage::GetTextStyleSheetForObject( SdrObject* pObj ) const
+{
+ return pObj->GetStyleSheet();
+}
+
+FASTBOOL SdrPage::HasTransparentObjects( BOOL bCheckForAlphaChannel ) const
+{
+ FASTBOOL bRet = FALSE;
+
+ for( ULONG n = 0, nCount = GetObjCount(); ( n < nCount ) && !bRet; n++ )
+ if( GetObj( n )->IsTransparent( bCheckForAlphaChannel ) )
+ bRet = TRUE;
+
+ return bRet;
+}
+
+/** returns an averaged background color of this page */
+// #i75566# GetBackgroundColor -> GetPageBackgroundColor and bScreenDisplay hint value
+Color SdrPage::GetPageBackgroundColor( SdrPageView* pView, bool bScreenDisplay ) const
+{
+ Color aColor;
+
+ if(bScreenDisplay && (!pView || pView->GetApplicationDocumentColor() == COL_AUTO))
+ {
+ svtools::ColorConfig aColorConfig;
+ aColor = aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor;
+ }
+ else
+ {
+ aColor = pView->GetApplicationDocumentColor();
+ }
+
+ const SfxItemSet* pBackgroundFill = &getSdrPageProperties().GetItemSet();
+
+ if(!IsMasterPage() && TRG_HasMasterPage())
+ {
+ if(XFILL_NONE == ((const XFillStyleItem&)pBackgroundFill->Get(XATTR_FILLSTYLE)).GetValue())
+ {
+ pBackgroundFill = &TRG_GetMasterPage().getSdrPageProperties().GetItemSet();
+ }
+ }
+
+ GetDraftFillColor(*pBackgroundFill, aColor);
+
+ return aColor;
+}
+
+/** *deprecated, use GetBackgroundColor with SdrPageView */
+Color SdrPage::GetPageBackgroundColor() const
+// #i75566# GetBackgroundColor -> GetPageBackgroundColor
+{
+ return GetPageBackgroundColor( NULL, true );
+}
+
+/** this method returns true if the object from the ViewObjectContact should
+ be visible on this page while rendering.
+ bEdit selects if visibility test is for an editing view or a final render,
+ like printing.
+*/
+bool SdrPage::checkVisibility(
+ const sdr::contact::ViewObjectContact& /*rOriginal*/,
+ const sdr::contact::DisplayInfo& /*rDisplayInfo*/,
+ bool /*bEdit*/)
+{
+ // this will be handled in the application if needed
+ return true;
+}
+
+// #110094# DrawContact support: Methods for handling Page changes
+void SdrPage::ActionChanged() const
+{
+ // Do necessary ViewContact actions
+ GetViewContact().ActionChanged();
+
+ // #i48535# also handle MasterPage change
+ if(TRG_HasMasterPage())
+ {
+ TRG_GetMasterPageDescriptorViewContact().ActionChanged();
+ }
+}
+
+// NYI: Dummy implementations for declarations in svdpage.hxx
+Bitmap SdrPage::GetBitmap(const SetOfByte& /*rVisibleLayers*/, FASTBOOL /*bTrimBorders*/) const
+{
+ DBG_ASSERT(0, "SdrPage::GetBitmap(): not yet implemented.");
+ return Bitmap();
+}
+GDIMetaFile SdrPage::GetMetaFile(const SetOfByte& /*rVisibleLayers*/, FASTBOOL /*bTrimBorders*/)
+{
+ DBG_ASSERT(0, "SdrPage::GetMetaFile(): not yet implemented.");
+ return GDIMetaFile();
+}
+
+bool SdrPage::isHandoutMasterPage() const
+{
+ return mbMaster && GetModel() && GetModel()->GetMasterPageCount()
+ && GetModel()->GetMasterPage(0) == this;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// sdr::Comment interface
+
+const sdr::Comment& SdrPage::GetCommentByIndex(sal_uInt32 nIndex)
+{
+ DBG_ASSERT(nIndex < maComments.size(), "SdrPage::GetCommentByIndex: Access out of range (!)");
+ return maComments[nIndex];
+}
+
+void SdrPage::AddComment(const sdr::Comment& rNew)
+{
+ maComments.push_back(rNew);
+ ::std::sort(maComments.begin(), maComments.end());
+}
+
+void SdrPage::ReplaceCommentByIndex(sal_uInt32 nIndex, const sdr::Comment& rNew)
+{
+ DBG_ASSERT(nIndex < maComments.size(), "SdrPage::GetCommentByIndex: Access out of range (!)");
+
+ if(maComments[nIndex] != rNew)
+ {
+ maComments[nIndex] = rNew;
+ ::std::sort(maComments.begin(), maComments.end());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// use new redirector instead of pPaintProc
+
+StandardCheckVisisbilityRedirector::StandardCheckVisisbilityRedirector()
+: ViewObjectContactRedirector()
+{
+}
+
+StandardCheckVisisbilityRedirector::~StandardCheckVisisbilityRedirector()
+{
+}
+
+drawinglayer::primitive2d::Primitive2DSequence StandardCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence(
+ const sdr::contact::ViewObjectContact& rOriginal,
+ const sdr::contact::DisplayInfo& rDisplayInfo)
+{
+ SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
+
+ if(pObject)
+ {
+ if(pObject->GetPage())
+ {
+ if(pObject->GetPage()->checkVisibility(rOriginal, rDisplayInfo, false))
+ {
+ return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
+ }
+ }
+
+ return drawinglayer::primitive2d::Primitive2DSequence();
+ }
+ else
+ {
+ // not an object, maybe a page
+ return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
new file mode 100644
index 000000000000..bad1401c2305
--- /dev/null
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -0,0 +1,1122 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <svx/svdpagv.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/xpoly.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+
+#include <svx/svdedxv.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdpagv.hxx>
+#include <editeng/outliner.hxx>
+#include <svx/svdetc.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdouno.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+#include "svditer.hxx"
+#include <svx/svdogrp.hxx>
+#include <svx/svdtypes.hxx>
+
+#include <svx/svdotext.hxx> // fuer PaintOutlinerView
+#include <svx/svdoole2.hxx>
+
+// #110094#
+#include <svx/sdr/contact/objectcontactofpageview.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/sdr/contact/viewobjectcontactredirector.hxx>
+#include <svx/fmview.hxx>
+
+// for search on vector
+#include <algorithm>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+#include <svx/sdrpagewindow.hxx>
+#include <sdrpaintwindow.hxx>
+
+TYPEINIT1(SdrPageView, SfxListener);
+DBG_NAME(SdrPageView);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// interface to SdrPageWindow
+
+SdrPageWindow* SdrPageView::FindPageWindow(SdrPaintWindow& rPaintWindow) const
+{
+ for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
+ {
+ if(&((*a)->GetPaintWindow()) == &rPaintWindow)
+ {
+ return *a;
+ }
+ }
+
+ return 0L;
+}
+
+const SdrPageWindow* SdrPageView::FindPatchedPageWindow( const OutputDevice& _rOutDev ) const
+{
+ for ( SdrPageWindowVector::const_iterator loop = maPageWindows.begin();
+ loop != maPageWindows.end();
+ ++loop
+ )
+ {
+ const SdrPageWindow& rPageWindow( *(*loop) );
+ const SdrPaintWindow& rPaintWindow( rPageWindow.GetOriginalPaintWindow() ? *rPageWindow.GetOriginalPaintWindow() : rPageWindow.GetPaintWindow() );
+ if ( &rPaintWindow.GetOutputDevice() == &_rOutDev )
+ {
+ return &rPageWindow;
+ }
+ }
+
+ return NULL;
+}
+
+SdrPageWindow* SdrPageView::FindPageWindow(const OutputDevice& rOutDev) const
+{
+ for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
+ {
+ if(&((*a)->GetPaintWindow().GetOutputDevice()) == &rOutDev)
+ {
+ return *a;
+ }
+ }
+
+ return 0L;
+}
+
+SdrPageWindow* SdrPageView::GetPageWindow(sal_uInt32 nIndex) const
+{
+ // #126416#
+ if(nIndex < maPageWindows.size())
+ {
+ return maPageWindows[nIndex];
+ }
+
+ return 0L;
+}
+
+void SdrPageView::ClearPageWindows()
+{
+ // #126416#
+ for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
+ {
+ delete *a;
+ }
+
+ maPageWindows.clear();
+}
+
+void SdrPageView::AppendPageWindow(SdrPageWindow& rNew)
+{
+ maPageWindows.push_back(&rNew);
+}
+
+SdrPageWindow* SdrPageView::RemovePageWindow(sal_uInt32 nPos)
+{
+ if(nPos < maPageWindows.size())
+ {
+ SdrPageWindowVector::iterator aAccess = maPageWindows.begin() + nPos;
+ // #114376# remember return value
+ SdrPageWindow* pErasedSdrPageWindow = *aAccess;
+ maPageWindows.erase(aAccess);
+ return pErasedSdrPageWindow;
+ }
+
+ return 0L;
+}
+
+SdrPageWindow* SdrPageView::RemovePageWindow(SdrPageWindow& rOld)
+{
+ const SdrPageWindowVector::iterator aFindResult = ::std::find(maPageWindows.begin(), maPageWindows.end(), &rOld);
+
+ if(aFindResult != maPageWindows.end())
+ {
+ // #114376# remember return value
+ SdrPageWindow* pSdrPageWindow = *aFindResult;
+ maPageWindows.erase(aFindResult);
+ return pSdrPageWindow;
+ }
+
+ return 0L;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+SdrPageView::SdrPageView(SdrPage* pPage1, SdrView& rNewView)
+: mrView(rNewView),
+ // #103911# col_auto color lets the view takes the default SvxColorConfig entry
+ maDocumentColor( COL_AUTO ),
+ maBackgroundColor(COL_AUTO ), // #i48367# also react on autocolor
+ mpPreparedPageWindow(0) // #i72752#
+{
+ DBG_CTOR(SdrPageView,NULL);
+ mpPage = pPage1;
+
+ if(mpPage)
+ {
+ aPgOrg.X()=mpPage->GetLftBorder();
+ aPgOrg.Y()=mpPage->GetUppBorder();
+ }
+ mbHasMarked = sal_False;
+ aLayerVisi.SetAll();
+ aLayerPrn.SetAll();
+
+ mbVisible = sal_False;
+ pAktList = NULL;
+ pAktGroup = NULL;
+ SetAktGroupAndList(NULL, mpPage);
+
+ StartListening(*rNewView.GetModel());
+
+ for(sal_uInt32 a(0L); a < rNewView.PaintWindowCount(); a++)
+ {
+ AddPaintWindowToPageView(*rNewView.GetPaintWindow(a));
+ }
+}
+
+SdrPageView::~SdrPageView()
+{
+ DBG_DTOR(SdrPageView,NULL);
+
+ // cleanup window vector
+ ClearPageWindows();
+}
+
+SdrPageWindow& SdrPageView::CreateNewPageWindowEntry(SdrPaintWindow& rPaintWindow)
+{
+ // MIB 3.7.08: Das WinRec muss sofort in die Liste eingetragen werden,
+ // weil sich das InsertControlContainer darauf verlaesst
+ //SdrPageViewWinRec* pRec = new SdrPageViewWinRec( *this, pOut );
+ //pWinList->Insert(pRec);
+ SdrPageWindow& rWindow = *(new SdrPageWindow(*this, rPaintWindow));
+ AppendPageWindow(rWindow);
+
+ return rWindow;
+}
+
+void SdrPageView::AddPaintWindowToPageView(SdrPaintWindow& rPaintWindow)
+{
+ if(!FindPageWindow(rPaintWindow))
+ {
+ CreateNewPageWindowEntry(rPaintWindow);
+ }
+}
+
+void SdrPageView::RemovePaintWindowFromPageView(SdrPaintWindow& rPaintWindow)
+{
+ SdrPageWindow* pCandidate = FindPageWindow(rPaintWindow);
+
+ if(pCandidate)
+ {
+ pCandidate = RemovePageWindow(*pCandidate);
+
+ if(pCandidate)
+ {
+ delete pCandidate;
+ }
+ }
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageView::GetControlContainer( const OutputDevice& _rDevice ) const
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xReturn;
+ const SdrPageWindow* pCandidate = FindPatchedPageWindow( _rDevice );
+
+ if ( pCandidate )
+ xReturn = pCandidate->GetControlContainer( true );
+
+ return xReturn;
+}
+
+void __EXPORT SdrPageView::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/)
+{
+ // not really interested in
+}
+
+void SdrPageView::ModelHasChanged()
+{
+ if (GetAktGroup()!=NULL) CheckAktGroup();
+}
+
+sal_Bool SdrPageView::IsReadOnly() const
+{
+ return (0L == GetPage() || GetView().GetModel()->IsReadOnly() || GetPage()->IsReadOnly() || GetObjList()->IsReadOnly());
+}
+
+void SdrPageView::Show()
+{
+ if(!IsVisible())
+ {
+ mbVisible = sal_True;
+ InvalidateAllWin();
+
+ for(sal_uInt32 a(0L); a < GetView().PaintWindowCount(); a++)
+ {
+ AddPaintWindowToPageView(*GetView().GetPaintWindow(a));
+ }
+ }
+}
+
+void SdrPageView::Hide()
+{
+ if(IsVisible())
+ {
+ InvalidateAllWin();
+ mbVisible = sal_False;
+ ClearPageWindows();
+ }
+}
+
+Rectangle SdrPageView::GetPageRect() const
+{
+ if (GetPage()==NULL) return Rectangle();
+ return Rectangle(Point(),Size(GetPage()->GetWdt()+1,GetPage()->GetHgt()+1));
+}
+
+void SdrPageView::InvalidateAllWin()
+{
+ if(IsVisible() && GetPage())
+ {
+ Rectangle aRect(Point(0,0),Size(GetPage()->GetWdt()+1,GetPage()->GetHgt()+1));
+ aRect.Union(GetPage()->GetAllObjBoundRect());
+ GetView().InvalidateAllWin(aRect);
+ }
+}
+
+void SdrPageView::InvalidateAllWin(const Rectangle& rRect, sal_Bool bPlus1Pix)
+{
+ if(IsVisible())
+ {
+ GetView().InvalidateAllWin(rRect, bPlus1Pix);
+ }
+}
+
+void SdrPageView::PaintOutlinerView(OutputDevice* pOut, const Rectangle& rRect) const
+{
+ if (GetView().pTextEditOutliner==NULL) return;
+ //const SdrObject* pTextObjTmp=GetView().GetTextEditObject();
+ //const SdrTextObj* pText=PTR_CAST(SdrTextObj,pTextObjTmp);
+ //FASTBOOL bTextFrame=pText!=NULL && pText->IsTextFrame();
+ ULONG nViewAnz=GetView().pTextEditOutliner->GetViewCount();
+ for (ULONG i=0; i<nViewAnz; i++) {
+ OutlinerView* pOLV=GetView().pTextEditOutliner->GetView(i);
+ if (pOLV->GetWindow()==pOut) {
+ GetView().ImpPaintOutlinerView(*pOLV, rRect);
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPageView::PrePaint()
+{
+ const sal_uInt32 nCount(PageWindowCount());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ SdrPageWindow* pCandidate = GetPageWindow(a);
+
+ if(pCandidate)
+ {
+ pCandidate->PrePaint();
+ }
+ }
+}
+
+void SdrPageView::CompleteRedraw(SdrPaintWindow& rPaintWindow, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector) const
+{
+ if(GetPage())
+ {
+ SdrPageWindow* pPageWindow = FindPageWindow(rPaintWindow);
+ sal_Bool bIsTempTarget(sal_False);
+
+ if(!pPageWindow)
+ {
+ // create temp PageWindow
+ pPageWindow = new SdrPageWindow(*((SdrPageView*)this), rPaintWindow);
+ bIsTempTarget = sal_True;
+ }
+
+ // do the redraw
+ pPageWindow->PrepareRedraw(rReg);
+ pPageWindow->RedrawAll(pRedirector);
+
+ // get rid of temp PageWindow
+ if(bIsTempTarget)
+ {
+ delete pPageWindow;
+ pPageWindow = 0L;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i74769# use SdrPaintWindow directly
+
+void SdrPageView::setPreparedPageWindow(SdrPageWindow* pKnownTarget)
+{
+ // #i72752# remember prepared SdrPageWindow
+ mpPreparedPageWindow = pKnownTarget;
+}
+
+void SdrPageView::DrawLayer(SdrLayerID nID, OutputDevice* pGivenTarget, sdr::contact::ViewObjectContactRedirector* pRedirector) const
+{
+ if(GetPage())
+ {
+ if(pGivenTarget)
+ {
+ const SdrPageWindow* pKnownTarget = FindPageWindow(*pGivenTarget);
+
+ if(pKnownTarget)
+ {
+ // paint known target
+ pKnownTarget->RedrawLayer(&nID, pRedirector);
+ }
+ else
+ {
+ // #i72752# DrawLayer() uses a OutputDevice different from BeginDrawLayer. This happens
+ // e.g. when SW paints a single text line in text edit mode. Try to use it
+ SdrPageWindow* pPreparedTarget = mpPreparedPageWindow;
+
+ if(pPreparedTarget)
+ {
+ // if we have a prepared target, do not use a new SdrPageWindow since this
+ // works but is expensive. Just use a temporary PaintWindow
+ SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
+
+ // Copy existing paint region to use the same as prepared in BeginDrawLayer
+ SdrPaintWindow& rExistingPaintWindow = pPreparedTarget->GetPaintWindow();
+ const Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
+ aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
+
+ // patch the ExistingPageWindow
+ pPreparedTarget->patchPaintWindow(aTemporaryPaintWindow);
+
+ // redraw the layer
+ pPreparedTarget->RedrawLayer(&nID, pRedirector);
+
+ // restore the ExistingPageWindow
+ pPreparedTarget->unpatchPaintWindow();
+ }
+ else
+ {
+ OSL_ENSURE(false, "SdrPageView::DrawLayer: Creating temporary SdrPageWindow (ObjectContact), this should never be needed (!)");
+
+ // None of the known OutputDevices is the target of this paint, use
+ // a temporary SdrPageWindow for this Redraw.
+ SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
+ SdrPageWindow aTemporaryPageWindow(*((SdrPageView*)this), aTemporaryPaintWindow);
+
+ // #i72752#
+ // Copy existing paint region if other PageWindows exist, this was created by
+ // PrepareRedraw() from BeginDrawLayer(). Needs to be used e.g. when suddenly SW
+ // paints into an unknown device other than the view was created for (e.g. VirtualDevice)
+ if(PageWindowCount())
+ {
+ SdrPageWindow* pExistingPageWindow = GetPageWindow(0L);
+ SdrPaintWindow& rExistingPaintWindow = pExistingPageWindow->GetPaintWindow();
+ const Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
+ aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
+ }
+
+ aTemporaryPageWindow.RedrawLayer(&nID, pRedirector);
+ }
+ }
+ }
+ else
+ {
+ // paint in all known windows
+ for(sal_uInt32 a(0L); a < PageWindowCount(); a++)
+ {
+ SdrPageWindow* pTarget = GetPageWindow(a);
+ pTarget->RedrawLayer(&nID, pRedirector);
+ }
+ }
+ }
+}
+
+void SdrPageView::SetDesignMode( bool _bDesignMode ) const
+{
+ for ( sal_uInt32 i = 0L; i < PageWindowCount(); ++i )
+ {
+ const SdrPageWindow& rPageViewWindow = *GetPageWindow(i);
+ rPageViewWindow.SetDesignMode( _bDesignMode );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef OS2
+#define RGBCOLOR(r,g,b) ((ULONG)(((BYTE)(b) | ((USHORT)(g)<<8)) | (((ULONG)(BYTE)(r))<<16)))
+#endif
+
+void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, const Rectangle& rRect, Color aColor)
+{
+ if (GetPage()==NULL)
+ return;
+
+ long nx1=GetView().aGridBig.Width();
+ long nx2=GetView().aGridFin.Width();
+ long ny1=GetView().aGridBig.Height();
+ long ny2=GetView().aGridFin.Height();
+
+ if (nx1==0) nx1=nx2;
+ if (nx2==0) nx2=nx1;
+ if (ny1==0) ny1=ny2;
+ if (ny2==0) ny2=ny1;
+ if (nx1==0) { nx1=ny1; nx2=ny2; }
+ if (ny1==0) { ny1=nx1; ny2=nx2; }
+ if (nx1<0) nx1=-nx1;
+ if (nx2<0) nx2=-nx2;
+ if (ny1<0) ny1=-ny1;
+ if (ny2<0) ny2=-ny2;
+
+ if (nx1!=0)
+ {
+ // no more global output size, use window size instead to decide grid sizes
+ long nScreenWdt = rOut.GetOutputSizePixel().Width();
+ // old: long nScreenWdt=System::GetDesktopRectPixel().GetWidth();
+
+ // Grid bei kleinen Zoomstufen etwas erweitern
+ //Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
+ long nMinDotPix=2;
+ long nMinLinPix=4;
+
+ if (nScreenWdt>=1600)
+ {
+ nMinDotPix=4;
+ nMinLinPix=8;
+ }
+ else if (nScreenWdt>=1024)
+ {
+ nMinDotPix=3;
+ nMinLinPix=6;
+ }
+ else
+ { // z.B. 640x480
+ nMinDotPix=2;
+ nMinLinPix=4;
+ }
+ Size aMinDotDist(rOut.PixelToLogic(Size(nMinDotPix,nMinDotPix)));
+ //Size a3PixSiz(rOut.PixelToLogic(Size(2,2)));
+ Size aMinLinDist(rOut.PixelToLogic(Size(nMinLinPix,nMinLinPix)));
+ FASTBOOL bHoriSolid=nx2<aMinDotDist.Width();
+ FASTBOOL bVertSolid=ny2<aMinDotDist.Height();
+ // Linienabstand vergroessern (mind. 4 Pixel)
+ // Vergroesserung: *2 *5 *10 *20 *50 *100 ...
+ int nTgl=0;
+ long nVal0=nx1;
+ while (nx1<aMinLinDist.Width())
+ {
+ long a=nx1;
+
+ if (nTgl==0) nx1*=2;
+ if (nTgl==1) nx1=nVal0*5; // => nx1*=2.5
+ if (nTgl==2) nx1*=2;
+
+ nVal0=a;
+ nTgl++; if (nTgl>=3) nTgl=0;
+ }
+ nTgl=0;
+ nVal0=ny1;
+ while (ny1<aMinLinDist.Height())
+ {
+ long a=ny1;
+
+ if (nTgl==0) ny1*=2;
+ if (nTgl==1) ny1=nVal0*5; // => ny1*=2.5
+ if (nTgl==2) ny1*=2;
+
+ nVal0=a;
+ nTgl++;
+
+ if (nTgl>=3) nTgl=0;
+ }
+ // Keine Zwischenpunkte, wenn...
+ //if (nx2<a2PixSiz.Width()) nx2=nx1;
+ //if (ny2<a2PixSiz.Height()) ny2=ny1;
+
+ FASTBOOL bHoriFine=nx2<nx1;
+ FASTBOOL bVertFine=ny2<ny1;
+ FASTBOOL bHoriLines=bHoriSolid || bHoriFine || !bVertFine;
+ FASTBOOL bVertLines=bVertSolid || bVertFine;
+
+ Color aColorMerk( rOut.GetLineColor() );
+ rOut.SetLineColor( aColor );
+
+ bool bMap0=rOut.IsMapModeEnabled();
+#ifdef WIN // SetPixel-Profiling fuer Windows
+ COLORREF aWinColRef=PALETTERGB(aColor.GetRed()>>8,aColor.GetGreen()>>8,aColor.GetBlue()>>8);
+ HDC aWinhDC=Sysdepen::GethDC(rOut);
+#endif
+
+ long nWrX=0;//aWriterPageOffset.X();
+ long nWrY=0;//aWriterPageOffset.Y();
+ Point aOrg(aPgOrg);
+ long x1=GetPage()->GetLftBorder()+1+nWrX;
+ long x2=GetPage()->GetWdt()-GetPage()->GetRgtBorder()-1+nWrY;
+ long y1=GetPage()->GetUppBorder()+1+nWrX;
+ long y2=GetPage()->GetHgt()-GetPage()->GetLwrBorder()-1+nWrY;
+ const SdrPageGridFrameList* pFrames=GetPage()->GetGridFrameList(this,NULL);
+ //USHORT nBufSiz=1024; // 4k Buffer = max. 512 Punkte
+ // #90353# long* pBuf = NULL;
+ USHORT nGridPaintAnz=1;
+ if (pFrames!=NULL) nGridPaintAnz=pFrames->GetCount();
+ for (USHORT nGridPaintNum=0; nGridPaintNum<nGridPaintAnz; nGridPaintNum++) {
+ if (pFrames!=NULL) {
+ const SdrPageGridFrame& rGF=(*pFrames)[nGridPaintNum];
+ nWrX=rGF.GetPaperRect().Left();
+ nWrY=rGF.GetPaperRect().Top();
+ x1=rGF.GetUserArea().Left();
+ x2=rGF.GetUserArea().Right();
+ y1=rGF.GetUserArea().Top();
+ y2=rGF.GetUserArea().Bottom();
+ aOrg=rGF.GetUserArea().TopLeft();
+ aOrg-=rGF.GetPaperRect().TopLeft();
+ }
+ if (!rRect.IsEmpty()) {
+ Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
+ long nX1Pix=a1PixSiz.Width(); // 1 Pixel Toleranz drauf
+ long nY1Pix=a1PixSiz.Height();
+ if (x1<rRect.Left() -nX1Pix) x1=rRect.Left() -nX1Pix;
+ if (x2>rRect.Right() +nX1Pix) x2=rRect.Right() +nX1Pix;
+ if (y1<rRect.Top() -nY1Pix) y1=rRect.Top() -nY1Pix;
+ if (y2>rRect.Bottom()+nY1Pix) y2=rRect.Bottom()+nY1Pix;
+ }
+ Point aPnt;
+
+ long xBigOrg=aOrg.X()+nWrX;
+ while (xBigOrg>=x1) xBigOrg-=nx1;
+ while (xBigOrg<x1) xBigOrg+=nx1;
+ long xFinOrg=xBigOrg;
+ while (xFinOrg>=x1) xFinOrg-=nx2;
+ while (xFinOrg<x1) xFinOrg+=nx2;
+
+ long yBigOrg=aOrg.Y()+nWrY;
+ while (yBigOrg>=y1) yBigOrg-=ny1;
+ while (yBigOrg<y1) yBigOrg+=ny1;
+ long yFinOrg=yBigOrg;
+ while (yFinOrg>=y1) yFinOrg-=ny2;
+ while (yFinOrg<y1) yFinOrg+=ny2;
+
+ if( x1 <= x2 && y1 <= y2 )
+ {
+ if( bHoriLines )
+ {
+ ULONG nGridFlags = ( bHoriSolid ? GRID_HORZLINES : GRID_DOTS );
+ UINT16 nSteps = sal_uInt16(nx1 / nx2);
+ UINT32 nRestPerStepMul1000 = nSteps ? ( ((nx1 * 1000L)/ nSteps) - (nx2 * 1000L) ) : 0;
+ UINT32 nStepOffset = 0;
+ UINT16 nPointOffset = 0;
+
+ for(UINT16 a=0;a<nSteps;a++)
+ {
+ // Zeichnen
+ rOut.DrawGrid(
+ Rectangle( xFinOrg + (a * nx2) + nPointOffset, yBigOrg, x2, y2 ),
+ Size( nx1, ny1 ), nGridFlags );
+
+ // Schritt machen
+ nStepOffset += nRestPerStepMul1000;
+ while(nStepOffset >= 1000)
+ {
+ nStepOffset -= 1000;
+ nPointOffset++;
+ }
+ }
+ }
+
+ if( bVertLines )
+ {
+ ULONG nGridFlags = ( bVertSolid ? GRID_VERTLINES : GRID_DOTS );
+ UINT16 nSteps = sal_uInt16(ny1 / ny2);
+ UINT32 nRestPerStepMul1000 = nSteps ? ( ((ny1 * 1000L)/ nSteps) - (ny2 * 1000L) ) : 0;
+ UINT32 nStepOffset = 0;
+ UINT16 nPointOffset = 0;
+
+ for(UINT16 a=0;a<nSteps;a++)
+ {
+ // Zeichnen
+ rOut.DrawGrid(
+ Rectangle( xBigOrg, yFinOrg + (a * ny2) + nPointOffset, x2, y2 ),
+ Size( nx1, ny1 ), nGridFlags );
+
+ // Schritt machen
+ nStepOffset += nRestPerStepMul1000;
+ while(nStepOffset >= 1000)
+ {
+ nStepOffset -= 1000;
+ nPointOffset++;
+ }
+ }
+
+ // rOut.DrawGrid( Rectangle( xo + xBigOrg, yo + yFinOrg, x2, y2 ), Size( nx1, ny2 ), nGridFlags );
+ }
+ }
+ }
+
+ rOut.EnableMapMode(bMap0);
+ rOut.SetLineColor(aColorMerk);
+ }
+}
+
+void SdrPageView::AdjHdl()
+{
+ GetView().AdjustMarkHdl();
+}
+
+void SdrPageView::SetLayer(const XubString& rName, SetOfByte& rBS, sal_Bool bJa)
+{
+ if(!GetPage())
+ return;
+
+ SdrLayerID nID = GetPage()->GetLayerAdmin().GetLayerID(rName, sal_True);
+
+ if(SDRLAYER_NOTFOUND != nID)
+ rBS.Set(nID, bJa);
+}
+
+sal_Bool SdrPageView::IsLayer(const XubString& rName, const SetOfByte& rBS) const
+{
+ if(!GetPage())
+ return sal_False;
+
+ sal_Bool bRet(sal_False);
+
+ if(rName.Len())
+ {
+ SdrLayerID nId = GetPage()->GetLayerAdmin().GetLayerID(rName, sal_True);
+
+ if(SDRLAYER_NOTFOUND != nId)
+ {
+ bRet = rBS.IsSet(nId);
+ }
+ }
+
+ return bRet;
+}
+
+void SdrPageView::SetAllLayers(SetOfByte& rB, sal_Bool bJa)
+{
+ if(bJa)
+ {
+ rB.SetAll();
+ rB.Clear(SDRLAYER_NOTFOUND);
+ }
+ else
+ {
+ rB.ClearAll();
+ }
+}
+
+sal_Bool SdrPageView::IsObjMarkable(SdrObject* pObj) const
+{
+ if(pObj)
+ {
+ // Vom Markieren ausgeschlossen?
+ if(pObj->IsMarkProtect())
+ {
+ return sal_False;
+ }
+
+ // only visible are markable
+ if( !pObj->IsVisible() )
+ {
+ return sal_False;
+ }
+
+ // #112440#
+ if(pObj->ISA(SdrObjGroup))
+ {
+ // If object is a Group object, visibility depends evtl. on
+ // multiple layers. If one object is markable, Group is markable.
+ SdrObjList* pObjList = ((SdrObjGroup*)pObj)->GetSubList();
+
+ if(pObjList && pObjList->GetObjCount())
+ {
+ sal_Bool bGroupIsMarkable(sal_False);
+
+ for(sal_uInt32 a(0L); !bGroupIsMarkable && a < pObjList->GetObjCount(); a++)
+ {
+ SdrObject* pCandidate = pObjList->GetObj(a);
+
+ // call recursively
+ if(IsObjMarkable(pCandidate))
+ {
+ bGroupIsMarkable = sal_True;
+ }
+ }
+
+ return bGroupIsMarkable;
+ }
+ else
+ {
+ // #i43302#
+ // Allow empty groups to be selected to be able to delete them
+ return sal_True;
+ }
+ }
+ else
+ {
+ // Der Layer muss sichtbar und darf nicht gesperrt sein
+ SdrLayerID nL = pObj->GetLayer();
+ return (aLayerVisi.IsSet(BYTE(nL)) && !aLayerLock.IsSet(BYTE(nL)));
+ }
+ }
+
+ return sal_False;
+}
+
+void SdrPageView::SetPageOrigin(const Point& rOrg)
+{
+ if (rOrg!=aPgOrg) {
+ aPgOrg=rOrg;
+ if (GetView().IsGridVisible()) {
+ InvalidateAllWin();
+ }
+ }
+}
+
+void SdrPageView::ImpInvalidateHelpLineArea(USHORT nNum) const
+{
+ if (GetView().IsHlplVisible() && nNum<aHelpLines.GetCount()) {
+ const SdrHelpLine& rHL=aHelpLines[nNum];
+
+ for(sal_uInt32 a(0L); a < GetView().PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = GetView().GetPaintWindow(a);
+
+ if(pCandidate->OutputToWindow())
+ {
+ OutputDevice& rOutDev = pCandidate->GetOutputDevice();
+ Rectangle aR(rHL.GetBoundRect(rOutDev));
+ Size aSiz(rOutDev.PixelToLogic(Size(1,1)));
+ aR.Left() -= aSiz.Width();
+ aR.Right() += aSiz.Width();
+ aR.Top() -= aSiz.Height();
+ aR.Bottom() += aSiz.Height();
+ ((SdrView&)GetView()).InvalidateOneWin((Window&)rOutDev, aR);
+ }
+ }
+ }
+}
+
+void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL)
+{
+ aHelpLines=rHLL;
+ InvalidateAllWin();
+}
+
+void SdrPageView::SetHelpLine(USHORT nNum, const SdrHelpLine& rNewHelpLine)
+{
+ if (nNum<aHelpLines.GetCount() && aHelpLines[nNum]!=rNewHelpLine) {
+ FASTBOOL bNeedRedraw=TRUE;
+ if (aHelpLines[nNum].GetKind()==rNewHelpLine.GetKind()) {
+ switch (rNewHelpLine.GetKind()) {
+ case SDRHELPLINE_VERTICAL : if (aHelpLines[nNum].GetPos().X()==rNewHelpLine.GetPos().X()) bNeedRedraw=FALSE; break;
+ case SDRHELPLINE_HORIZONTAL: if (aHelpLines[nNum].GetPos().Y()==rNewHelpLine.GetPos().Y()) bNeedRedraw=FALSE; break;
+ default: break;
+ } // switch
+ }
+ if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
+ aHelpLines[nNum]=rNewHelpLine;
+ if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
+ }
+}
+
+void SdrPageView::DeleteHelpLine(USHORT nNum)
+{
+ if (nNum<aHelpLines.GetCount()) {
+ ImpInvalidateHelpLineArea(nNum);
+ aHelpLines.Delete(nNum);
+ }
+}
+
+void SdrPageView::InsertHelpLine(const SdrHelpLine& rHL, USHORT nNum)
+{
+ if (nNum>aHelpLines.GetCount()) nNum=aHelpLines.GetCount();
+ aHelpLines.Insert(rHL,nNum);
+ if (GetView().IsHlplVisible()) {
+ if (GetView().IsHlplFront()) {
+ // Hier optimieren ...
+ ImpInvalidateHelpLineArea(nNum);
+ } else {
+ ImpInvalidateHelpLineArea(nNum);
+ }
+ }
+}
+
+// Betretene Gruppe und Liste setzen
+void SdrPageView::SetAktGroupAndList(SdrObject* pNewGroup, SdrObjList* pNewList)
+{
+ if(pAktGroup != pNewGroup)
+ {
+ pAktGroup = pNewGroup;
+ }
+ if(pAktList != pNewList)
+ {
+ pAktList = pNewList;
+ }
+}
+
+sal_Bool SdrPageView::EnterGroup(SdrObject* pObj)
+{
+ sal_Bool bRet(sal_False);
+
+ if(pObj && pObj->IsGroupObject())
+ {
+ sal_Bool bGlueInvalidate(GetView().ImpIsGlueVisible());
+
+ if(bGlueInvalidate)
+ {
+ GetView().GlueInvalidate();
+ }
+
+ // deselect all
+ GetView().UnmarkAll();
+
+ // set current group and list
+ SdrObjList* pNewObjList = pObj->GetSubList();
+ SetAktGroupAndList(pObj, pNewObjList);
+
+ // select contained object if only one object is contained,
+ // else select nothing and let the user decide what to do next
+ if(pNewObjList && pNewObjList->GetObjCount() == 1)
+ {
+ SdrObject* pFirstObject = pNewObjList->GetObj(0L);
+
+ if(GetView().GetSdrPageView())
+ {
+ GetView().MarkObj(pFirstObject, GetView().GetSdrPageView());
+ }
+ }
+
+ // build new handles
+ GetView().AdjustMarkHdl();
+
+ // invalidate only when view wants to visualize group entering
+ if(GetView().DoVisualizeEnteredGroup())
+ {
+ InvalidateAllWin();
+ }
+
+ if (bGlueInvalidate)
+ {
+ GetView().GlueInvalidate();
+ }
+
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+void SdrPageView::LeaveOneGroup()
+{
+ if(GetAktGroup())
+ {
+ BOOL bGlueInvalidate = (GetView().ImpIsGlueVisible());
+
+ if(bGlueInvalidate)
+ GetView().GlueInvalidate();
+
+ SdrObject* pLastGroup = GetAktGroup();
+ SdrObject* pParentGroup = GetAktGroup()->GetUpGroup();
+ SdrObjList* pParentList = GetPage();
+
+ if(pParentGroup)
+ pParentList = pParentGroup->GetSubList();
+
+ // Alles deselektieren
+ GetView().UnmarkAll();
+
+ // Zuweisungen, pAktGroup und pAktList muessen gesetzt sein
+ SetAktGroupAndList(pParentGroup, pParentList);
+
+ // gerade verlassene Gruppe selektieren
+ if(pLastGroup)
+ if(GetView().GetSdrPageView())
+ GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
+
+ GetView().AdjustMarkHdl();
+
+ // invalidate only when view wants to visualize group entering
+ if(GetView().DoVisualizeEnteredGroup())
+ InvalidateAllWin();
+
+ if(bGlueInvalidate)
+ GetView().GlueInvalidate();
+ }
+}
+
+void SdrPageView::LeaveAllGroup()
+{
+ if(GetAktGroup())
+ {
+ BOOL bGlueInvalidate = (GetView().ImpIsGlueVisible());
+
+ if(bGlueInvalidate)
+ GetView().GlueInvalidate();
+
+ SdrObject* pLastGroup = GetAktGroup();
+
+ // Alles deselektieren
+ GetView().UnmarkAll();
+
+ // Zuweisungen, pAktGroup und pAktList muessen gesetzt sein
+ SetAktGroupAndList(NULL, GetPage());
+
+ // Oberste letzte Gruppe finden und selektieren
+ if(pLastGroup)
+ {
+ while(pLastGroup->GetUpGroup())
+ pLastGroup = pLastGroup->GetUpGroup();
+
+ if(GetView().GetSdrPageView())
+ GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
+ }
+
+ GetView().AdjustMarkHdl();
+
+ // invalidate only when view wants to visualize group entering
+ if(GetView().DoVisualizeEnteredGroup())
+ InvalidateAllWin();
+
+ if(bGlueInvalidate)
+ GetView().GlueInvalidate();
+ }
+}
+
+USHORT SdrPageView::GetEnteredLevel() const
+{
+ USHORT nAnz=0;
+ SdrObject* pGrp=GetAktGroup();
+ while (pGrp!=NULL) {
+ nAnz++;
+ pGrp=pGrp->GetUpGroup();
+ }
+ return nAnz;
+}
+
+XubString SdrPageView::GetActualGroupName() const
+{
+ if(GetAktGroup())
+ {
+ XubString aStr(GetAktGroup()->GetName());
+
+ if(!aStr.Len())
+ aStr += sal_Unicode('?');
+
+ return aStr;
+ }
+ else
+ return String();
+}
+
+XubString SdrPageView::GetActualPathName(sal_Unicode cSep) const
+{
+ XubString aStr;
+ BOOL bNamFnd(FALSE);
+ SdrObject* pGrp = GetAktGroup();
+
+ while(pGrp)
+ {
+ XubString aStr1(pGrp->GetName());
+
+ if(!aStr1.Len())
+ aStr1 += sal_Unicode('?');
+ else
+ bNamFnd = TRUE;
+
+ aStr += aStr1;
+ pGrp = pGrp->GetUpGroup();
+
+ if(pGrp)
+ aStr += cSep;
+ }
+
+ if(!bNamFnd && GetAktGroup())
+ {
+ aStr = String();
+ aStr += sal_Unicode('(');
+ aStr += String::CreateFromInt32( GetEnteredLevel() );
+ aStr += sal_Unicode(')');
+ }
+
+ return aStr;
+}
+
+void SdrPageView::CheckAktGroup()
+{
+ SdrObject* pGrp=GetAktGroup();
+ while (pGrp!=NULL &&
+ (!pGrp->IsInserted() || pGrp->GetObjList()==NULL ||
+ pGrp->GetPage()==NULL || pGrp->GetModel()==NULL)) { // irgendwas daneben?
+ pGrp=pGrp->GetUpGroup();
+ }
+ if (pGrp!=GetAktGroup()) {
+ if (pGrp!=NULL) EnterGroup(pGrp);
+ else LeaveAllGroup();
+ }
+}
+
+// #103834# Set background color for svx at SdrPageViews
+void SdrPageView::SetApplicationBackgroundColor(Color aBackgroundColor)
+{
+ maBackgroundColor = aBackgroundColor;
+}
+
+// #109585#
+Color SdrPageView::GetApplicationBackgroundColor() const
+{
+ return maBackgroundColor;
+}
+
+// #103911# Set document color for svx at SdrPageViews
+void SdrPageView::SetApplicationDocumentColor(Color aDocumentColor)
+{
+ maDocumentColor = aDocumentColor;
+}
+
+Color SdrPageView::GetApplicationDocumentColor() const
+{
+ return maDocumentColor;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// eof
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
new file mode 100755
index 000000000000..998c687608fc
--- /dev/null
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -0,0 +1,1540 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <com/sun/star/awt/XWindow.hpp>
+#include <svx/svdpntv.hxx>
+#include <vcl/msgbox.hxx>
+#include <sdrpaintwindow.hxx>
+#include <svtools/grfmgr.hxx>
+#include <svx/svdmodel.hxx>
+
+#ifdef DBG_UTIL
+#include <svdibrow.hxx>
+#endif
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svl/smplhint.hxx>
+
+#include <svx/svdpntv.hxx>
+#include <editeng/editdata.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdglue.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdattrx.hxx>
+#include "svdibrow.hxx"
+#include "svditer.hxx"
+#include <svx/svdouno.hxx>
+#include <svx/sdr/overlay/overlayobjectlist.hxx>
+#include <svx/sdr/overlay/overlayrollingrectangle.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/svdglue.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sxlayitm.hxx>
+#include <svl/itemiter.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/whiter.hxx>
+#include <svl/style.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/svdouno.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+
+// #i38135#
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/animation/objectanimator.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #114409#-3 Migrate Encirclement
+class ImplEncirclementOverlay
+{
+ // The OverlayObjects
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+ // The remembered second position in logical coodinates
+ basegfx::B2DPoint maSecondPosition;
+
+public:
+ ImplEncirclementOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos);
+ ~ImplEncirclementOverlay();
+
+ void SetSecondPosition(const basegfx::B2DPoint& rNewPosition);
+};
+
+ImplEncirclementOverlay::ImplEncirclementOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos)
+: maSecondPosition(rStartPos)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ ::sdr::overlay::OverlayRollingRectangleStriped* aNew = new ::sdr::overlay::OverlayRollingRectangleStriped(
+ rStartPos, rStartPos, false);
+ pTargetOverlay->add(*aNew);
+ maObjects.append(*aNew);
+ }
+ }
+}
+
+ImplEncirclementOverlay::~ImplEncirclementOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+void ImplEncirclementOverlay::SetSecondPosition(const basegfx::B2DPoint& rNewPosition)
+{
+ if(rNewPosition != maSecondPosition)
+ {
+ // apply to OverlayObjects
+ for(sal_uInt32 a(0L); a < maObjects.count(); a++)
+ {
+ ::sdr::overlay::OverlayRollingRectangleStriped& rCandidate = (::sdr::overlay::OverlayRollingRectangleStriped&)maObjects.getOverlayObject(a);
+ rCandidate.setSecondPosition(rNewPosition);
+ }
+
+ // remember new position
+ maSecondPosition = rNewPosition;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// interface to SdrPaintWindow
+
+SdrPaintWindow* SdrPaintView::FindPaintWindow(const OutputDevice& rOut) const
+{
+ for(SdrPaintWindowVector::const_iterator a = maPaintWindows.begin(); a != maPaintWindows.end(); a++)
+ {
+ if(&((*a)->GetOutputDevice()) == &rOut)
+ {
+ return *a;
+ }
+ }
+
+ return 0L;
+}
+
+SdrPaintWindow* SdrPaintView::GetPaintWindow(sal_uInt32 nIndex) const
+{
+ if(nIndex < maPaintWindows.size())
+ {
+ return maPaintWindows[nIndex];
+ }
+
+ return 0L;
+}
+
+void SdrPaintView::AppendPaintWindow(SdrPaintWindow& rNew)
+{
+ maPaintWindows.push_back(&rNew);
+}
+
+SdrPaintWindow* SdrPaintView::RemovePaintWindow(SdrPaintWindow& rOld)
+{
+ SdrPaintWindow* pRetval = 0L;
+ const SdrPaintWindowVector::iterator aFindResult = ::std::find(maPaintWindows.begin(), maPaintWindows.end(), &rOld);
+
+ if(aFindResult != maPaintWindows.end())
+ {
+ // remember return value, aFindResult is no longer valid after deletion
+ pRetval = *aFindResult;
+ maPaintWindows.erase(aFindResult);
+ }
+
+ return pRetval;
+}
+
+OutputDevice* SdrPaintView::GetFirstOutputDevice() const
+{
+ if(PaintWindowCount())
+ {
+ return &(GetPaintWindow(0)->GetOutputDevice());
+ }
+
+ return 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1( SvxViewHint, SfxHint );
+
+SvxViewHint::SvxViewHint (HintType eHintType)
+ : meHintType(eHintType)
+{
+}
+
+SvxViewHint::HintType SvxViewHint::GetHintType (void) const
+{
+ return meHintType;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT2(SdrPaintView,SfxListener,SfxRepeatTarget);
+
+DBG_NAME(SdrPaintView);
+
+void SdrPaintView::ImpClearVars()
+{
+#ifdef DBG_UTIL
+ pItemBrowser=NULL;
+#endif
+ bPageVisible=TRUE;
+ bPageBorderVisible=TRUE;
+ bBordVisible=TRUE;
+ bGridVisible=TRUE;
+ bGridFront =FALSE;
+ bHlplVisible=TRUE;
+ bHlplFront =TRUE;
+ bGlueVisible=FALSE;
+ bGlueVisible2=FALSE;
+ bGlueVisible3=FALSE;
+ bGlueVisible4=FALSE;
+ bSwapAsynchron=FALSE;
+ bPrintPreview=FALSE;
+ mbPreviewRenderer=FALSE;
+
+ eAnimationMode = SDR_ANIMATION_ANIMATE;
+ bAnimationPause = FALSE;
+
+ nHitTolPix=2;
+ nMinMovPix=3;
+ nHitTolLog=0;
+ nMinMovLog=0;
+ pActualOutDev=NULL;
+ pDragWin=NULL;
+ bRestoreColors=TRUE;
+ pDefaultStyleSheet=NULL;
+ bSomeObjChgdFlag=FALSE;
+ nGraphicManagerDrawMode = GRFMGR_DRAW_STANDARD;
+ aComeBackTimer.SetTimeout(1);
+ aComeBackTimer.SetTimeoutHdl(LINK(this,SdrPaintView,ImpComeBackHdl));
+ String aNam; // System::GetUserName() just return an empty string
+
+ if (pMod)
+ SetDefaultStyleSheet(pMod->GetDefaultStyleSheet(), TRUE);
+
+ aNam.ToUpperAscii();
+
+ maGridColor = Color( COL_BLACK );
+ BrkEncirclement();
+}
+
+SdrPaintView::SdrPaintView(SdrModel* pModel1, OutputDevice* pOut)
+: mpEncirclementOverlay(0L),
+ mpPageView(0L),
+ aDefaultAttr(pModel1->GetItemPool()),
+ mbBufferedOutputAllowed(false),
+ mbBufferedOverlayAllowed(false),
+ mbPagePaintingAllowed(true),
+ mbHideOle(false),
+ mbHideChart(false),
+ mbHideDraw(false),
+ mbHideFormControl(false)
+{
+ DBG_CTOR(SdrPaintView,NULL);
+ pMod=pModel1;
+ ImpClearVars();
+
+ if(pOut)
+ {
+ AddWindowToPaintView(pOut);
+ }
+
+ // Flag zur Visualisierung von Gruppen
+ bVisualizeEnteredGroup = TRUE;
+
+ maColorConfig.AddListener(this);
+ onChangeColorConfig();
+}
+
+SdrPaintView::~SdrPaintView()
+{
+ DBG_DTOR(SdrPaintView,NULL);
+ if (pDefaultStyleSheet)
+ EndListening(*pDefaultStyleSheet);
+
+ maColorConfig.RemoveListener(this);
+ ClearPageView();
+
+#ifdef DBG_UTIL
+ if(pItemBrowser)
+ {
+ delete pItemBrowser;
+ }
+#endif
+
+ // delete existing SdrPaintWindows
+ while(maPaintWindows.size())
+ {
+ delete maPaintWindows.back();
+ maPaintWindows.pop_back();
+ }
+
+ // #114409#-3 Migrate HelpLine
+ BrkEncirclement();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void __EXPORT SdrPaintView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
+{
+ //If the stylesheet has been destroyed
+ if (&rBC == pDefaultStyleSheet)
+ {
+ if (rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
+ pDefaultStyleSheet = NULL;
+ return;
+ }
+
+ BOOL bObjChg=!bSomeObjChgdFlag; // TRUE= auswerten fuer ComeBack-Timer
+ if (bObjChg) {
+ SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
+ if (pSdrHint!=NULL) {
+ SdrHintKind eKind=pSdrHint->GetKind();
+ if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED) {
+ if (bObjChg) {
+ bSomeObjChgdFlag=TRUE;
+ aComeBackTimer.Start();
+ }
+ }
+ if (eKind==HINT_PAGEORDERCHG) {
+ const SdrPage* pPg=pSdrHint->GetPage();
+
+ if(pPg && !pPg->IsInserted())
+ {
+ if(mpPageView && mpPageView->GetPage() == pPg)
+ {
+ HideSdrPage();
+ }
+ }
+ }
+ }
+ }
+}
+
+void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster* , sal_uInt32 )
+{
+ onChangeColorConfig();
+ InvalidateAllWin();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+IMPL_LINK_INLINE_START(SdrPaintView,ImpComeBackHdl,Timer*,EMPTYARG)
+{
+ if (bSomeObjChgdFlag) {
+ bSomeObjChgdFlag=FALSE;
+ ModelHasChanged();
+ }
+ return 0;
+}
+IMPL_LINK_INLINE_END(SdrPaintView,ImpComeBackHdl,Timer*,pTimer)
+
+void SdrPaintView::FlushComeBackTimer() const
+{
+ if (bSomeObjChgdFlag) {
+ // casting auf nonconst
+ ((SdrPaintView*)this)->ImpComeBackHdl(&((SdrPaintView*)this)->aComeBackTimer);
+ ((SdrPaintView*)this)->aComeBackTimer.Stop();
+ }
+}
+
+void SdrPaintView::ModelHasChanged()
+{
+ // Auch alle PageViews benachrichtigen
+ if(mpPageView && !mpPageView->GetPage()->IsInserted())
+ {
+ HideSdrPage();
+ }
+
+ // test mpPageView here again, HideSdrPage() may have invalidated it.
+ if(mpPageView)
+ {
+ mpPageView->ModelHasChanged();
+ }
+
+#ifdef DBG_UTIL
+ if(pItemBrowser)
+ {
+ pItemBrowser->SetDirty();
+ }
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrPaintView::IsAction() const
+{
+ return IsEncirclement();
+}
+
+void SdrPaintView::MovAction(const Point& rPnt)
+{
+ if (IsEncirclement())
+ {
+ MovEncirclement(rPnt);
+ }
+}
+
+void SdrPaintView::EndAction()
+{
+ if(IsEncirclement())
+ {
+ EndEncirclement();
+ }
+}
+
+void SdrPaintView::BckAction()
+{
+ BrkEncirclement();
+}
+
+void SdrPaintView::BrkAction()
+{
+ BrkEncirclement();
+}
+
+void SdrPaintView::TakeActionRect(Rectangle& rRect) const
+{
+ if(IsEncirclement())
+ {
+ rRect = Rectangle(aDragStat.GetStart(),aDragStat.GetNow());
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// info about TextEdit. Default is sal_False.
+bool SdrPaintView::IsTextEdit() const
+{
+ return false;
+}
+
+// info about TextEditPageView. Default is 0L.
+SdrPageView* SdrPaintView::GetTextEditPageView() const
+{
+ return 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+USHORT SdrPaintView::ImpGetMinMovLogic(short nMinMov, const OutputDevice* pOut) const
+{
+ if (nMinMov>=0) return USHORT(nMinMov);
+ if (pOut==NULL)
+ {
+ pOut = GetFirstOutputDevice();
+ }
+ if (pOut!=NULL) {
+ return short(-pOut->PixelToLogic(Size(nMinMov,0)).Width());
+ } else {
+ return 0;
+ }
+}
+
+USHORT SdrPaintView::ImpGetHitTolLogic(short nHitTol, const OutputDevice* pOut) const
+{
+ if (nHitTol>=0) return USHORT(nHitTol);
+ if (pOut==NULL)
+ {
+ pOut = GetFirstOutputDevice();
+ }
+ if (pOut!=NULL) {
+ return short(-pOut->PixelToLogic(Size(nHitTol,0)).Width());
+ } else {
+ return 0;
+ }
+}
+
+void SdrPaintView::TheresNewMapMode()
+{
+ if (pActualOutDev!=NULL) {
+ nHitTolLog=(USHORT)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nHitTolPix,0)).Width();
+ nMinMovLog=(USHORT)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nMinMovPix,0)).Width();
+ }
+}
+
+void SdrPaintView::SetActualWin(const OutputDevice* pWin)
+{
+ pActualOutDev=pWin;
+ TheresNewMapMode();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPaintView::BegEncirclement(const Point& rPnt)
+{
+ BrkAction();
+
+ DBG_ASSERT(0L == mpEncirclementOverlay, "SdrSnapView::BegSetPageOrg: There exists a ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpEncirclementOverlay = new ImplEncirclementOverlay(*this, aStartPos);
+
+ aDragStat.Reset(rPnt);
+ aDragStat.SetMinMove(ImpGetMinMovLogic(-2,0L));
+ aDragStat.NextPoint();
+}
+
+void SdrPaintView::MovEncirclement(const Point& rPnt)
+{
+ if(IsEncirclement() && aDragStat.CheckMinMoved(rPnt))
+ {
+ aDragStat.NextMove(rPnt);
+
+ DBG_ASSERT(mpEncirclementOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aNewPos(rPnt.X(), rPnt.Y());
+ mpEncirclementOverlay->SetSecondPosition(aNewPos);
+ }
+}
+
+Rectangle SdrPaintView::EndEncirclement(sal_Bool bNoJustify)
+{
+ Rectangle aRetval;
+
+ if(IsEncirclement())
+ {
+ if(aDragStat.IsMinMoved())
+ {
+ aRetval = Rectangle(aDragStat.GetStart(), aDragStat.GetNow());
+
+ if(!bNoJustify)
+ {
+ aRetval.Justify();
+ }
+ }
+
+ // cleanup
+ BrkEncirclement();
+ }
+
+ return aRetval;
+}
+
+void SdrPaintView::BrkEncirclement()
+{
+ if(IsEncirclement())
+ {
+ DBG_ASSERT(mpEncirclementOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ delete mpEncirclementOverlay;
+ mpEncirclementOverlay = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPaintView::ClearPageView()
+{
+ BrkAction();
+
+ if(mpPageView)
+ {
+ InvalidateAllWin();
+ delete mpPageView;
+ mpPageView = 0L;
+ }
+}
+
+SdrPageView* SdrPaintView::ShowSdrPage(SdrPage* pPage)
+{
+ if(pPage && (!mpPageView || mpPageView->GetPage() != pPage))
+ {
+ if(mpPageView)
+ {
+ InvalidateAllWin();
+ delete mpPageView;
+ }
+
+ mpPageView = new SdrPageView(pPage, *((SdrView*)this));
+ mpPageView->Show();
+ }
+
+ return mpPageView;
+}
+
+void SdrPaintView::HideSdrPage()
+{
+ if(mpPageView)
+ {
+ mpPageView->Hide();
+ delete mpPageView;
+ mpPageView = 0L;
+ }
+}
+
+void SdrPaintView::AddWindowToPaintView(OutputDevice* pNewWin)
+{
+ DBG_ASSERT(pNewWin, "SdrPaintView::AddWindowToPaintView: No OutputDevice(!)");
+ SdrPaintWindow* pNewPaintWindow = new SdrPaintWindow(*this, *pNewWin);
+ AppendPaintWindow(*pNewPaintWindow);
+
+ if(mpPageView)
+ {
+ mpPageView->AddPaintWindowToPageView(*pNewPaintWindow);
+ }
+
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL)
+ pItemBrowser->ForceParent();
+#endif
+}
+
+void SdrPaintView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
+{
+ DBG_ASSERT(pOldWin, "SdrPaintView::DeleteWindowFromPaintView: No OutputDevice(!)");
+ SdrPaintWindow* pCandidate = FindPaintWindow(*pOldWin);
+
+ if(pCandidate)
+ {
+ if(mpPageView)
+ {
+ mpPageView->RemovePaintWindowFromPageView(*pCandidate);
+ }
+
+ RemovePaintWindow(*pCandidate);
+ delete pCandidate;
+ }
+
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL)
+ pItemBrowser->ForceParent();
+#endif
+}
+
+void SdrPaintView::SetLayerVisible(const XubString& rName, BOOL bShow)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetLayerVisible(rName,bShow);
+ }
+
+ InvalidateAllWin();
+}
+
+bool SdrPaintView::IsLayerVisible(const XubString& rName) const
+{
+ if(mpPageView)
+ {
+ return mpPageView->IsLayerVisible(rName);
+ }
+
+ return false;
+}
+
+void SdrPaintView::SetAllLayersVisible(BOOL bShow)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetAllLayersVisible(bShow);
+ }
+
+ InvalidateAllWin();
+}
+
+void SdrPaintView::SetLayerLocked(const XubString& rName, BOOL bLock)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetLayerLocked(rName,bLock);
+ }
+}
+
+bool SdrPaintView::IsLayerLocked(const XubString& rName) const
+{
+ if(mpPageView)
+ {
+ return mpPageView->IsLayerLocked(rName);
+ }
+
+ return false;
+}
+
+void SdrPaintView::SetAllLayersLocked(BOOL bLock)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetAllLayersLocked(bLock);
+ }
+}
+
+void SdrPaintView::SetLayerPrintable(const XubString& rName, BOOL bPrn)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetLayerPrintable(rName,bPrn);
+ }
+}
+
+bool SdrPaintView::IsLayerPrintable(const XubString& rName) const
+{
+ if(mpPageView)
+ {
+ return mpPageView->IsLayerPrintable(rName);
+ }
+
+ return false;
+}
+
+void SdrPaintView::SetAllLayersPrintable(BOOL bPrn)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetAllLayersPrintable(bPrn);
+ }
+}
+
+void SdrPaintView::PrePaint()
+{
+ if(mpPageView)
+ {
+ mpPageView->PrePaint();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #define SVX_REPAINT_TIMER_TEST
+
+void SdrPaintView::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector)
+{
+#ifdef SVX_REPAINT_TIMER_TEST
+#define REMEMBERED_TIMES_COUNT (10)
+ static bool bDoTimerTest(false);
+ static bool bTimesInited(false);
+ static sal_uInt32 nRepeatCount(10L);
+ static double fLastTimes[REMEMBERED_TIMES_COUNT];
+ const sal_uInt32 nStartTime(Time::GetSystemTicks());
+ sal_uInt32 count(1L);
+ sal_uInt32 a;
+
+ if(bDoTimerTest)
+ {
+ count = nRepeatCount;
+ }
+
+ for(a = 0L; a < count; a++)
+ {
+#endif // SVX_REPAINT_TIMER_TEST
+
+ // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
+ // rReg may be made more granular (fine) with using it. Normally, rReg
+ // does come from Window::Paint() anyways and thus is based on a single
+ // rectangle which was derived from exactly that repaint region
+ Region aOptimizedRepaintRegion(rReg);
+
+ if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType())
+ {
+ Window* pWindow = (Window*)pOut;
+
+ if(pWindow->IsInPaint())
+ {
+ if(!pWindow->GetPaintRegion().IsEmpty())
+ {
+ aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
+
+#ifdef DBG_UTIL
+ // #i74769# test-paint repaint region
+ static bool bDoPaintForVisualControl(false);
+ if(bDoPaintForVisualControl)
+ {
+ RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
+ Rectangle aRegionRectangle;
+
+ while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
+ {
+ pWindow->SetLineColor(COL_LIGHTGREEN);
+ pWindow->SetFillColor();
+ pWindow->DrawRect(aRegionRectangle);
+ }
+
+ aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
+ }
+#endif
+ }
+ }
+ }
+
+ SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut);
+ OSL_ENSURE(pPaintWindow, "SdrPaintView::CompleteRedraw: No OutDev (!)");
+
+ DoCompleteRedraw(*pPaintWindow, aOptimizedRepaintRegion, pRedirector);
+ EndCompleteRedraw(*pPaintWindow, true);
+
+#ifdef SVX_REPAINT_TIMER_TEST
+ }
+
+ if(bDoTimerTest)
+ {
+ const sal_uInt32 nStopTime(Time::GetSystemTicks());
+ const sal_uInt32 nNeededTime(nStopTime - nStartTime);
+ const double fTimePerPaint((double)nNeededTime / (double)nRepeatCount);
+
+ if(!bTimesInited)
+ {
+ for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
+ {
+ fLastTimes[a] = fTimePerPaint;
+ }
+
+ bTimesInited = true;
+ }
+ else
+ {
+ for(a = 1L; a < REMEMBERED_TIMES_COUNT; a++)
+ {
+ fLastTimes[a - 1L] = fLastTimes[a];
+ }
+
+ fLastTimes[REMEMBERED_TIMES_COUNT - 1L] = fTimePerPaint;
+ }
+
+ double fAddedTimes(0.0);
+
+ for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
+ {
+ fAddedTimes += fLastTimes[a];
+ }
+
+ const double fAverageTimePerPaint(fAddedTimes / (double)REMEMBERED_TIMES_COUNT);
+
+ fprintf(stderr, "-----------(start result)----------\n");
+ fprintf(stderr, "StartTime : %u, StopTime: %u, NeededTime: %u, TimePerPaint: %f\n", nStartTime, nStopTime, nNeededTime, fTimePerPaint);
+ fprintf(stderr, "Remembered times: ");
+
+ for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
+ {
+ fprintf(stderr, "%d: %f ", a, fLastTimes[a]);
+ }
+
+ fprintf(stderr, "\n");
+ fprintf(stderr, "AverageTimePerPaint: %f\n", fAverageTimePerPaint);
+ fprintf(stderr, "-----------(stop result)----------\n");
+ }
+#endif // SVX_REPAINT_TIMER_TEST
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i72889#
+
+SdrPaintWindow* SdrPaintView::BeginCompleteRedraw(OutputDevice* pOut)
+{
+ OSL_ENSURE(pOut, "SdrPaintView::BeginCompleteRedraw: No OutDev (!)");
+ SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
+
+ if(pPaintWindow)
+ {
+ // draw preprocessing, only for known devices
+ // prepare PreRendering
+ pPaintWindow->PreparePreRenderDevice();
+ }
+ else
+ {
+ // None of the known OutputDevices is the target of this paint, use
+ // a temporary SdrPaintWindow for this Redraw.
+ pPaintWindow = new SdrPaintWindow(*this, *pOut);
+ pPaintWindow->setTemporaryTarget(true);
+ }
+
+ return pPaintWindow;
+}
+
+void SdrPaintView::DoCompleteRedraw(SdrPaintWindow& rPaintWindow, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector)
+{
+ // redraw all PageViews with the target. This may expand the RedrawRegion
+ // at the PaintWindow, plus taking care of FormLayer expansion
+ if(mpPageView)
+ {
+ mpPageView->CompleteRedraw(rPaintWindow, rReg, pRedirector);
+ }
+}
+
+void SdrPaintView::EndCompleteRedraw(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer)
+{
+ if(rPaintWindow.getTemporaryTarget())
+ {
+ // get rid of temp target again
+ delete (&rPaintWindow);
+ }
+ else
+ {
+ // draw postprocessing, only for known devices
+ // it is necessary to always paint FormLayer
+ if(bPaintFormLayer)
+ {
+ ImpFormLayerDrawing(rPaintWindow);
+ }
+
+ // look for active TextEdit. As long as this cannot be painted to a VDev,
+ // it cannot get part of buffering. In that case, output evtl. prerender
+ // early and paint text edit to window.
+ const bool bTextEditActive(IsTextEdit() && GetTextEditPageView());
+
+ if(bTextEditActive)
+ {
+ // output PreRendering and destroy it so that it is not used for FormLayer
+ // or overlay
+ rPaintWindow.OutputPreRenderDevice(rPaintWindow.GetRedrawRegion());
+
+ // draw old text edit stuff before overlay to have it as part of the background
+ // ATM. This will be changed to have the text editing on the overlay, bit it
+ // is not an easy thing to do, see BegTextEdit and the OutlinerView stuff used...
+ if(bTextEditActive)
+ {
+ ImpTextEditDrawing(rPaintWindow);
+ }
+
+ // draw Overlay directly to window. This will save the contents of the window
+ // in the RedrawRegion to the overlay background buffer, too.
+ // This may lead to problems when reading from the screen is slow from the
+ // graphics driver/graphiccard combination.
+ rPaintWindow.DrawOverlay(rPaintWindow.GetRedrawRegion(), false);
+ }
+ else
+ {
+ // draw Overlay, also to PreRender device if exists
+ rPaintWindow.DrawOverlay(rPaintWindow.GetRedrawRegion(), true);
+
+ // output PreRendering
+ rPaintWindow.OutputPreRenderDevice(rPaintWindow.GetRedrawRegion());
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPaintWindow* SdrPaintView::BeginDrawLayers(OutputDevice* pOut, const Region& rReg, bool bDisableIntersect)
+{
+ // #i74769# use BeginCompleteRedraw() as common base
+ SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut);
+ OSL_ENSURE(pPaintWindow, "SdrPaintView::BeginDrawLayers: No SdrPaintWindow (!)");
+
+ if(mpPageView)
+ {
+ SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(*pPaintWindow);
+
+ if(pKnownTarget)
+ {
+ // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
+ // rReg may be made more granular (fine) with using it. Normally, rReg
+ // does come from Window::Paint() anyways and thus is based on a single
+ // rectangle which was derived from exactly that repaint region
+ Region aOptimizedRepaintRegion(rReg);
+
+ // #i76114# Intersecting the region with the Window's paint region is disabled
+ // for print preview in Calc, because the intersection can be empty (if the paint
+ // region is outside of the table area of the page), and then no clip region
+ // would be set.
+ if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType() && !bDisableIntersect)
+ {
+ Window* pWindow = (Window*)pOut;
+
+ if(pWindow->IsInPaint())
+ {
+ if(!pWindow->GetPaintRegion().IsEmpty())
+ {
+ aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
+
+#ifdef DBG_UTIL
+ // #i74769# test-paint repaint region
+ static bool bDoPaintForVisualControl(false);
+ if(bDoPaintForVisualControl)
+ {
+ RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
+ Rectangle aRegionRectangle;
+
+ while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
+ {
+ pWindow->SetLineColor(COL_LIGHTGREEN);
+ pWindow->SetFillColor();
+ pWindow->DrawRect(aRegionRectangle);
+ }
+
+ aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
+ }
+#endif
+ }
+ }
+ }
+
+ // prepare redraw
+ pKnownTarget->PrepareRedraw(aOptimizedRepaintRegion);
+
+ // remember prepared SdrPageWindow
+ mpPageView->setPreparedPageWindow(pKnownTarget);
+ }
+ }
+
+ return pPaintWindow;
+}
+
+void SdrPaintView::EndDrawLayers(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer)
+{
+ // #i74769# use EndCompleteRedraw() as common base
+ EndCompleteRedraw(rPaintWindow, bPaintFormLayer);
+
+ if(mpPageView)
+ {
+ // forget prepared SdrPageWindow
+ mpPageView->setPreparedPageWindow(0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPaintView::ImpTextEditDrawing(SdrPaintWindow& rPaintWindow) const
+{
+ // draw old text edit stuff
+ if(IsTextEdit())
+ {
+ SdrPageView* pPageView = GetTextEditPageView();
+
+ if(pPageView)
+ {
+ // paint TextEdit directly to the destination OutDev
+ const Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
+ const Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
+ pPageView->PaintOutlinerView(&rPaintWindow.GetOutputDevice(), aCheckRect);
+ }
+ }
+}
+
+void SdrPaintView::ImpFormLayerDrawing(SdrPaintWindow& rPaintWindow) const
+{
+ if(mpPageView)
+ {
+ SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(rPaintWindow);
+
+ if(pKnownTarget)
+ {
+ const SdrModel& rModel = *(GetModel());
+ const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
+ const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
+
+ // BUFFERED use GetTargetOutputDevice() now, it may be targeted to VDevs, too
+ // need to set PreparedPageWindow to make DrawLayer use the correct ObjectContact
+ mpPageView->setPreparedPageWindow(pKnownTarget);
+ mpPageView->DrawLayer(nControlLayerId, &rPaintWindow.GetTargetOutputDevice());
+ mpPageView->setPreparedPageWindow(0);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrPaintView::KeyInput(const KeyEvent& /*rKEvt*/, Window* /*pWin*/)
+{
+ return FALSE;
+}
+
+void SdrPaintView::GlueInvalidate() const
+{
+ const sal_uInt32 nWindowCount(PaintWindowCount());
+
+ for(sal_uInt32 nWinNum(0L); nWinNum < nWindowCount; nWinNum++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(nWinNum);
+
+ if(pPaintWindow->OutputToWindow())
+ {
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+
+ if(mpPageView)
+ {
+ const SdrObjList* pOL=mpPageView->GetObjList();
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
+ const SdrObject* pObj=pOL->GetObj(nObjNum);
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=NULL && pGPL->GetCount()!=0) {
+ pGPL->Invalidate((Window&)rOutDev, pObj);
+ }
+ }
+ }
+ }
+ }
+}
+
+void SdrPaintView::InvalidateAllWin()
+{
+ const sal_uInt32 nWindowCount(PaintWindowCount());
+
+ for(sal_uInt32 a(0L); a < nWindowCount; a++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
+
+ if(pPaintWindow->OutputToWindow())
+ {
+ InvalidateOneWin((Window&)pPaintWindow->GetOutputDevice());
+ }
+ }
+}
+
+void SdrPaintView::InvalidateAllWin(const Rectangle& rRect, BOOL bPlus1Pix)
+{
+ const sal_uInt32 nWindowCount(PaintWindowCount());
+
+ for(sal_uInt32 a(0L); a < nWindowCount; a++)
+ {
+ SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
+
+ if(pPaintWindow->OutputToWindow())
+ {
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+ Rectangle aRect(rRect);
+
+ if(bPlus1Pix)
+ {
+ Size aPixSiz(1,1);
+ Size aSiz(rOutDev.PixelToLogic(aPixSiz));
+ aRect.Left ()-=aSiz.Width();
+ aRect.Top ()-=aSiz.Height();
+ aRect.Right ()+=aSiz.Width();
+ aRect.Bottom()+=aSiz.Height();
+ }
+
+ Point aOrg(rOutDev.GetMapMode().GetOrigin());
+ aOrg.X()=-aOrg.X(); aOrg.Y()=-aOrg.Y();
+ Rectangle aOutRect(aOrg, rOutDev.GetOutputSize());
+
+ if (aRect.IsOver(aOutRect))
+ {
+ InvalidateOneWin((Window&)rOutDev, aRect);
+ }
+ }
+ }
+}
+
+void SdrPaintView::InvalidateOneWin(Window& rWin)
+{
+ // #111096#
+ // do not erase background, that causes flicker (!)
+ rWin.Invalidate(INVALIDATE_NOERASE);
+}
+
+void SdrPaintView::InvalidateOneWin(Window& rWin, const Rectangle& rRect)
+{
+ // #111096#
+ // do not erase background, that causes flicker (!)
+ rWin.Invalidate(rRect, INVALIDATE_NOERASE);
+}
+
+void SdrPaintView::LeaveOneGroup()
+{
+ if(mpPageView)
+ {
+ mpPageView->LeaveOneGroup();
+ }
+}
+
+void SdrPaintView::LeaveAllGroup()
+{
+ if(mpPageView)
+ {
+ mpPageView->LeaveAllGroup();
+ }
+}
+
+bool SdrPaintView::IsGroupEntered() const
+{
+ if(mpPageView)
+ {
+ return (mpPageView->GetEnteredLevel() != 0);
+ }
+
+ return false;
+}
+
+void SdrPaintView::SetNotPersistDefaultAttr(const SfxItemSet& rAttr, BOOL /*bReplaceAll*/)
+{
+ // bReplaceAll hat hier keinerlei Wirkung
+ BOOL bMeasure=ISA(SdrView) && ((SdrView*)this)->IsMeasureTool();
+ const SfxPoolItem *pPoolItem=NULL;
+ if (rAttr.GetItemState(SDRATTR_LAYERID,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ SdrLayerID nLayerId=((const SdrLayerIdItem*)pPoolItem)->GetValue();
+ const SdrLayer* pLayer=pMod->GetLayerAdmin().GetLayerPerID(nLayerId);
+ if (pLayer!=NULL) {
+ if (bMeasure) aMeasureLayer=pLayer->GetName();
+ else aAktLayer=pLayer->GetName();
+ }
+ }
+ if (rAttr.GetItemState(SDRATTR_LAYERNAME,TRUE,&pPoolItem)==SFX_ITEM_SET) {
+ if (bMeasure) aMeasureLayer=((const SdrLayerNameItem*)pPoolItem)->GetValue();
+ else aAktLayer=((const SdrLayerNameItem*)pPoolItem)->GetValue();
+ }
+}
+
+void SdrPaintView::MergeNotPersistDefaultAttr(SfxItemSet& rAttr, BOOL /*bOnlyHardAttr*/) const
+{
+ // bOnlyHardAttr hat hier keinerlei Wirkung
+ BOOL bMeasure=ISA(SdrView) && ((SdrView*)this)->IsMeasureTool();
+ const XubString& aNam=bMeasure?aMeasureLayer:aAktLayer;
+ rAttr.Put(SdrLayerNameItem(aNam));
+ SdrLayerID nLayer=pMod->GetLayerAdmin().GetLayerID(aNam,TRUE);
+ if (nLayer!=SDRLAYER_NOTFOUND) {
+ rAttr.Put(SdrLayerIdItem(nLayer));
+ }
+}
+
+void SdrPaintView::SetDefaultAttr(const SfxItemSet& rAttr, BOOL bReplaceAll)
+{
+#ifdef DBG_UTIL
+ {
+ BOOL bHasEEFeatureItems=FALSE;
+ SfxItemIter aIter(rAttr);
+ const SfxPoolItem* pItem=aIter.FirstItem();
+ while (!bHasEEFeatureItems && pItem!=NULL) {
+ if (!IsInvalidItem(pItem)) {
+ USHORT nW=pItem->Which();
+ if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=TRUE;
+ }
+ pItem=aIter.NextItem();
+ }
+
+ if(bHasEEFeatureItems)
+ {
+ String aMessage;
+ aMessage.AppendAscii("SdrPaintView::SetDefaultAttr(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten.");
+ InfoBox(NULL, aMessage).Execute();
+ }
+ }
+#endif
+ if (bReplaceAll) aDefaultAttr.Set(rAttr);
+ else aDefaultAttr.Put(rAttr,FALSE); // FALSE= InvalidItems nicht als Default, sondern als "Loecher" betrachten
+ SetNotPersistDefaultAttr(rAttr,bReplaceAll);
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+}
+
+void SdrPaintView::SetDefaultStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ if (pDefaultStyleSheet)
+ EndListening(*pDefaultStyleSheet);
+ pDefaultStyleSheet=pStyleSheet;
+ if (pDefaultStyleSheet)
+ StartListening(*pDefaultStyleSheet);
+
+ if (pStyleSheet!=NULL && !bDontRemoveHardAttr) {
+ SfxWhichIter aIter(pStyleSheet->GetItemSet());
+ USHORT nWhich=aIter.FirstWhich();
+ while (nWhich!=0) {
+ if (pStyleSheet->GetItemSet().GetItemState(nWhich,TRUE)==SFX_ITEM_SET) {
+ aDefaultAttr.ClearItem(nWhich);
+ }
+ nWhich=aIter.NextWhich();
+ }
+ }
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+}
+
+/* new interface src537 */
+BOOL SdrPaintView::GetAttributes(SfxItemSet& rTargetSet, BOOL bOnlyHardAttr) const
+{
+ if(bOnlyHardAttr || !pDefaultStyleSheet)
+ {
+ rTargetSet.Put(aDefaultAttr, FALSE);
+ }
+ else
+ {
+ // sonst DefStyleSheet dazumergen
+ rTargetSet.Put(pDefaultStyleSheet->GetItemSet(), FALSE);
+ rTargetSet.Put(aDefaultAttr, FALSE);
+ }
+ MergeNotPersistDefaultAttr(rTargetSet, bOnlyHardAttr);
+ return TRUE;
+}
+
+BOOL SdrPaintView::SetAttributes(const SfxItemSet& rSet, BOOL bReplaceAll)
+{
+ SetDefaultAttr(rSet,bReplaceAll);
+ return TRUE;
+}
+
+SfxStyleSheet* SdrPaintView::GetStyleSheet() const // SfxStyleSheet* SdrPaintView::GetStyleSheet(BOOL& rOk) const
+{
+ //rOk=TRUE;
+ return GetDefaultStyleSheet();
+}
+
+BOOL SdrPaintView::SetStyleSheet(SfxStyleSheet* pStyleSheet, BOOL bDontRemoveHardAttr)
+{
+ SetDefaultStyleSheet(pStyleSheet,bDontRemoveHardAttr);
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef DBG_UTIL
+void SdrPaintView::ShowItemBrowser(BOOL bShow)
+{
+ if (bShow) {
+ if (pItemBrowser==NULL) {
+ pItemBrowser=new SdrItemBrowser(*(SdrView*)this);
+ pItemBrowser->SetFloatingMode(TRUE);
+ }
+ pItemBrowser->Show();
+ pItemBrowser->GrabFocus();
+ } else {
+ if (pItemBrowser!=NULL) {
+ pItemBrowser->Hide();
+ delete pItemBrowser;
+ pItemBrowser=NULL;
+ }
+ }
+}
+#endif
+
+void SdrPaintView::MakeVisible(const Rectangle& rRect, Window& rWin)
+{
+ MapMode aMap(rWin.GetMapMode());
+ Size aActualSize(rWin.GetOutputSize());
+
+ if( aActualSize.Height() > 0 && aActualSize.Width() > 0 )
+ {
+ Size aNewSize(rRect.GetSize());
+ BOOL bNewScale=FALSE;
+ BOOL bNeedMoreX=aNewSize.Width()>aActualSize.Width();
+ BOOL bNeedMoreY=aNewSize.Height()>aActualSize.Height();
+ if (bNeedMoreX || bNeedMoreY)
+ {
+ bNewScale=TRUE;
+ // Neuen MapMode (Size+Org) setzen und dabei alles invalidieren
+ Fraction aXFact(aNewSize.Width(),aActualSize.Width());
+ Fraction aYFact(aNewSize.Height(),aActualSize.Height());
+ if (aYFact>aXFact) aXFact=aYFact;
+ aXFact*=aMap.GetScaleX();
+ aXFact.ReduceInaccurate(10); // Um Ueberlaeufe und BigInt-Mapping zu vermeiden
+ aMap.SetScaleX(aXFact);
+ aMap.SetScaleY(aYFact);
+ rWin.SetMapMode(aMap);
+ aActualSize=rWin.GetOutputSize();
+ }
+ Point aOrg(aMap.GetOrigin());
+ long dx=0,dy=0;
+ long l=-aOrg.X();
+ long r=-aOrg.X()+aActualSize.Width()-1;
+ long o=-aOrg.Y();
+ long u=-aOrg.Y()+aActualSize.Height()-1;
+ if (l>rRect.Left()) dx=rRect.Left()-l;
+ else if (r<rRect.Right()) dx=rRect.Right()-r;
+ if (o>rRect.Top()) dy=rRect.Top()-o;
+ else if (u<rRect.Bottom()) dy=rRect.Bottom()-u;
+ aMap.SetOrigin(Point(aOrg.X()-dx,aOrg.Y()-dy));
+ if (!bNewScale) {
+ if (dx!=0 || dy!=0) {
+ rWin.Scroll(-dx,-dy);
+ rWin.SetMapMode(aMap);
+ rWin.Update();
+ }
+ } else {
+ rWin.SetMapMode(aMap);
+ InvalidateOneWin(rWin);
+ }
+ }
+}
+
+void SdrPaintView::DoConnect(SdrOle2Obj* /*pOleObj*/)
+{
+}
+
+void SdrPaintView::SetAnimationEnabled( BOOL bEnable )
+{
+ SetAnimationMode( bEnable ? SDR_ANIMATION_ANIMATE : SDR_ANIMATION_DISABLE );
+}
+
+void SdrPaintView::SetAnimationPause( bool bSet )
+{
+ if((bool)bAnimationPause != bSet)
+ {
+ bAnimationPause = bSet;
+
+ if(mpPageView)
+ {
+ for(sal_uInt32 b(0L); b < mpPageView->PageWindowCount(); b++)
+ {
+ const SdrPageWindow& rPageWindow = *(mpPageView->GetPageWindow(b));
+ sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact();
+ sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator();
+
+ if(rAnimator.IsPaused() != bSet)
+ {
+ rAnimator.SetPaused(bSet);
+ }
+ }
+ }
+ }
+}
+
+void SdrPaintView::SetAnimationMode( const SdrAnimationMode eMode )
+{
+ eAnimationMode = eMode;
+}
+
+void SdrPaintView::VisAreaChanged(const OutputDevice* pOut)
+{
+ if(mpPageView)
+ {
+ if (pOut)
+ {
+ SdrPageWindow* pWindow = mpPageView->FindPageWindow(*((OutputDevice*)pOut));
+
+ if(pWindow)
+ {
+ VisAreaChanged(*pWindow);
+ }
+ }
+ else
+ {
+ for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++)
+ {
+ VisAreaChanged(*mpPageView->GetPageWindow(a));
+ }
+ }
+ }
+}
+
+void SdrPaintView::VisAreaChanged(const SdrPageWindow& /*rWindow*/)
+{
+ // notify SfxListener
+ Broadcast(SvxViewHint(SvxViewHint::SVX_HINT_VIEWCHANGED));
+}
+
+const svtools::ColorConfig& SdrPaintView::getColorConfig() const
+{
+ return maColorConfig;
+}
+
+void SdrPaintView::onChangeColorConfig()
+{
+ SetGridColor( Color( maColorConfig.GetColorValue( svtools::DRAWGRID ).nColor ) );
+}
+
+void SdrPaintView::SetGridColor( Color aColor )
+{
+ maGridColor = aColor;
+}
+
+Color SdrPaintView::GetGridColor() const
+{
+ return maGridColor;
+}
+
+// #103834# Set background color for svx at SdrPageViews
+void SdrPaintView::SetApplicationBackgroundColor(Color aBackgroundColor)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetApplicationBackgroundColor(aBackgroundColor);
+ }
+}
+
+// #103911# Set document color for svx at SdrPageViews
+void SdrPaintView::SetApplicationDocumentColor(Color aDocumentColor)
+{
+ if(mpPageView)
+ {
+ mpPageView->SetApplicationDocumentColor(aDocumentColor);
+ }
+}
+
+// #114898#
+bool SdrPaintView::IsBufferedOutputAllowed() const
+{
+ return (mbBufferedOutputAllowed && maDrawinglayerOpt.IsPaintBuffer());
+}
+
+// #114898#
+void SdrPaintView::SetBufferedOutputAllowed(bool bNew)
+{
+ if(bNew != (bool)mbBufferedOutputAllowed)
+ {
+ mbBufferedOutputAllowed = bNew;
+ }
+}
+
+bool SdrPaintView::IsBufferedOverlayAllowed() const
+{
+ return (mbBufferedOverlayAllowed && maDrawinglayerOpt.IsOverlayBuffer());
+}
+
+void SdrPaintView::SetBufferedOverlayAllowed(bool bNew)
+{
+ if(bNew != (bool)mbBufferedOverlayAllowed)
+ {
+ mbBufferedOverlayAllowed = bNew;
+ }
+}
+
+sal_Bool SdrPaintView::IsPagePaintingAllowed() const
+{
+ return mbPagePaintingAllowed;
+}
+
+void SdrPaintView::SetPagePaintingAllowed(bool bNew)
+{
+ if(bNew != (bool)mbPagePaintingAllowed)
+ {
+ mbPagePaintingAllowed = bNew;
+ }
+}
+
+// #i38135# Sets the timer for Object animations and restarts.
+void SdrPaintView::SetAnimationTimer(sal_uInt32 nTime)
+{
+ if(mpPageView)
+ {
+ // first, reset all timers at all windows to 0L
+ for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++)
+ {
+ const SdrPageWindow& rPageWindow = *mpPageView->GetPageWindow(a);
+ sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact();
+ sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator();
+ rAnimator.SetTime(nTime);
+ }
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/svdpoev.cxx b/svx/source/svdraw/svdpoev.cxx
new file mode 100644
index 000000000000..27e2884bb90c
--- /dev/null
+++ b/svx/source/svdraw/svdpoev.cxx
@@ -0,0 +1,745 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdpoev.hxx>
+#include <math.h>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdundo.hxx>
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/svdtrans.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <vcl/salbtype.hxx> // FRound
+
+#include <svx/polypolygoneditor.hxx>
+
+using namespace sdr;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPolyEditView::ImpResetPolyPossibilityFlags()
+{
+ eMarkedPointsSmooth=SDRPATHSMOOTH_DONTCARE;
+ eMarkedSegmentsKind=SDRPATHSEGMENT_DONTCARE;
+ bSetMarkedPointsSmoothPossible=FALSE;
+ bSetMarkedSegmentsKindPossible=FALSE;
+}
+
+void SdrPolyEditView::ImpClearVars()
+{
+ ImpResetPolyPossibilityFlags();
+}
+
+SdrPolyEditView::SdrPolyEditView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrEditView(pModel1,pOut)
+{
+ ImpClearVars();
+}
+
+SdrPolyEditView::~SdrPolyEditView()
+{
+}
+
+void SdrPolyEditView::ImpCheckPolyPossibilities()
+{
+ ImpResetPolyPossibilityFlags();
+ const ULONG nMarkAnz(GetMarkedObjectCount());
+
+ if(nMarkAnz && !ImpIsFrameHandles())
+ {
+ bool b1stSmooth(true);
+ bool b1stSegm(true);
+ bool bCurve(false);
+ bool bSmoothFuz(false);
+ bool bSegmFuz(false);
+ basegfx::B2VectorContinuity eSmooth = basegfx::CONTINUITY_NONE;
+
+ for(ULONG nMarkNum(0L); nMarkNum < nMarkAnz; 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();
+ SdrUShortCont* pPts = pM->GetMarkedPoints();
+ SdrPathObj* pPath = PTR_CAST(SdrPathObj,pObj);
+
+ if(pPath && pPts)
+ {
+ const sal_uInt32 nMarkedPntAnz(pPts->GetCount());
+
+ if(nMarkedPntAnz)
+ {
+ bool bClosed(pPath->IsClosed());
+ bSetMarkedPointsSmoothPossible = true;
+
+ if(bClosed)
+ {
+ bSetMarkedSegmentsKindPossible = true;
+ }
+
+ for(sal_uInt32 nMarkedPntNum(0L); nMarkedPntNum < nMarkedPntAnz; nMarkedPntNum++)
+ {
+ sal_uInt32 nNum(pPts->GetObject(nMarkedPntNum));
+ 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::CONTINUITY_NONE == eSmooth)
+ {
+ eMarkedPointsSmooth = SDRPATHSMOOTH_ANGULAR;
+ }
+
+ if(basegfx::CONTINUITY_C1 == eSmooth)
+ {
+ eMarkedPointsSmooth = SDRPATHSMOOTH_ASYMMETRIC;
+ }
+
+ if(basegfx::CONTINUITY_C2 == eSmooth)
+ {
+ eMarkedPointsSmooth = SDRPATHSMOOTH_SYMMETRIC;
+ }
+ }
+
+ if(!b1stSegm && !bSegmFuz)
+ {
+ eMarkedSegmentsKind = (bCurve) ? SDRPATHSEGMENT_CURVE : SDRPATHSEGMENT_LINE;
+ }
+ }
+ }
+}
+
+void SdrPolyEditView::SetMarkedPointsSmooth(SdrPathSmoothKind eKind)
+{
+ basegfx::B2VectorContinuity eFlags;
+
+ if(SDRPATHSMOOTH_ANGULAR == eKind)
+ {
+ eFlags = basegfx::CONTINUITY_NONE;
+ }
+ else if(SDRPATHSMOOTH_ASYMMETRIC == eKind)
+ {
+ eFlags = basegfx::CONTINUITY_C1;
+ }
+ else if(SDRPATHSMOOTH_SYMMETRIC == eKind)
+ {
+ eFlags = basegfx::CONTINUITY_C2;
+ }
+ else
+ {
+ return;
+ }
+
+ if(HasMarkedPoints())
+ {
+ SortMarkedObjects();
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditSetPointsSmooth), GetDescriptionOfMarkedPoints());
+ ULONG nMarkAnz(GetMarkedObjectCount());
+
+ for(ULONG nMarkNum(nMarkAnz); nMarkNum > 0L;)
+ {
+ nMarkNum--;
+ SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
+ SdrUShortCont* pPts = pM->GetMarkedPoints();
+ SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
+
+ if(pPts && pPath)
+ {
+ PolyPolygonEditor aEditor( pPath->GetPathPoly(), pPath->IsClosed() );
+ if(aEditor.SetPointsSmooth( eFlags, pPts->getContainer() ) )
+ {
+ 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());
+ ULONG nMarkAnz(GetMarkedObjectCount());
+
+ for(ULONG nMarkNum(nMarkAnz); nMarkNum > 0L;)
+ {
+ nMarkNum--;
+ SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
+ SdrUShortCont* pPts = pM->GetMarkedPoints();
+ SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
+
+ if(pPts && pPath)
+ {
+ PolyPolygonEditor aEditor( pPath->GetPathPoly(), pPath->IsClosed() );
+ if(aEditor.SetSegmentsKind( eKind, pPts->getContainer()) )
+ {
+ 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();
+ ULONG nMarkAnz=GetMarkedObjectCount();
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ {
+ // Description
+ BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_DELETE);
+ }
+
+ for (ULONG nMarkNum=nMarkAnz; nMarkNum>0;)
+ {
+ nMarkNum--;
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrUShortCont* pPts=pM->GetMarkedPoints();
+ SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() );
+
+ if( pPath && pPts )
+ {
+ PolyPolygonEditor aEditor( pPath ->GetPathPoly(), pPath->IsClosed() );
+ if( aEditor.DeletePoints( pPts->getContainer() ) )
+ {
+ 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();
+ sal_uInt32 nMarkAnz(GetMarkedObjectCount());
+
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditRipUp), GetDescriptionOfMarkedPoints());
+
+ for(sal_uInt32 nMarkNum(nMarkAnz); nMarkNum > 0L;)
+ {
+ nMarkNum--;
+ SdrMark* pM = GetSdrMarkByIndex(nMarkNum);
+ SdrUShortCont* pPts = pM->GetMarkedPoints();
+ SdrPathObj* pObj = PTR_CAST(SdrPathObj, pM->GetMarkedSdrObj());
+
+ if(pPts && pObj)
+ {
+ pPts->ForceSort();
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+ sal_Bool bKorregFlag(sal_False);
+ sal_Bool bInsAny(sal_False);
+ sal_uInt32 nMarkPtsAnz(pPts->GetCount());
+ sal_uInt32 nMax(pObj->GetHdlCount());
+
+ for(sal_uInt32 i(nMarkPtsAnz); i > 0L;)
+ {
+ i--;
+ sal_uInt32 nNewPt0Idx(0L);
+ SdrObject* pNeuObj = pObj->RipPoint(pPts->GetObject(i), nNewPt0Idx);
+
+ if(pNeuObj)
+ {
+ bInsAny = sal_True;
+ SdrInsertReason aReason(SDRREASON_VIEWCALL, pObj);
+ pM->GetPageView()->GetObjList()->InsertObject(pNeuObj, pObj->GetOrdNum() + 1, &aReason);
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj));
+ MarkObj(pNeuObj, pM->GetPageView(), FALSE, TRUE);
+ }
+
+ if(nNewPt0Idx)
+ {
+ // Korrektur notwendig?
+ DBG_ASSERT(bKorregFlag==FALSE,"Mehrfache Indexkorrektur bei SdrPolyEditView::RipUp()");
+ if(!bKorregFlag)
+ {
+ bKorregFlag = sal_True;
+
+ for(sal_uInt32 nBla(0L); nBla < nMarkPtsAnz; nBla++)
+ {
+ sal_uInt32 nPntNum(pPts->GetObject(nBla));
+ nPntNum += nNewPt0Idx;
+
+ if(nPntNum >= nMax)
+ {
+ nPntNum -= nMax;
+ }
+
+ pPts->Replace((sal_uInt16)nPntNum, nBla);
+ }
+
+ i = nMarkPtsAnz; // ... und nochmal von vorn
+ }
+ }
+ }
+ }
+ }
+
+ UnmarkAllPoints();
+ if( bUndo )
+ EndUndo();
+ MarkListHasChanged();
+ }
+}
+
+bool SdrPolyEditView::IsRipUpAtMarkedPointsPossible() const
+{
+ bool bRetval(false);
+ const sal_uInt32 nMarkCount(GetMarkedObjectCount());
+
+ for(sal_uInt32 a(0); a < nMarkCount; a++)
+ {
+ const SdrMark* pMark = GetSdrMarkByIndex(a);
+ const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj());
+
+ if(pMarkedPathObject)
+ {
+ const SdrUShortCont* pSelectedPoints = pMark->GetMarkedPoints();
+
+ if(pSelectedPoints && pSelectedPoints->GetCount())
+ {
+ 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 Polygon aPathPolygon(rPathPolyPolygon.getB2DPolygon(0));
+ const sal_uInt16 nPointCount(aPathPolygon.GetSize());
+
+ if(nPointCount >= 3)
+ {
+ bRetval = pMarkedPathObject->IsClosedObj(); // #i76617# aPathPolygon.isClosed();
+
+ for(sal_uInt32 b(0); !bRetval && b < pSelectedPoints->GetCount(); b++)
+ {
+ const sal_uInt16 nMarkedPointNum(pSelectedPoints->GetObject(b));
+
+ bRetval = (nMarkedPointNum > 0 && nMarkedPointNum < nPointCount - 1);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return bRetval;
+}
+
+bool SdrPolyEditView::IsOpenCloseMarkedObjectsPossible() const
+{
+ bool bRetval(false);
+ const sal_uInt32 nMarkCount(GetMarkedObjectCount());
+
+ for(sal_uInt32 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 PolyPolygon aPathPolyPolygon(pMarkedPathObject->GetPathPoly());
+ const sal_uInt16 nPolygonCount(aPathPolyPolygon.Count());
+
+ for(sal_uInt16 b(0); !bRetval && b < nPolygonCount; b++)
+ {
+ const 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 sal_uInt32 nMarkCount(GetMarkedObjectCount());
+
+ for(sal_uInt32 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 SDROBJCLOSED_DONTCARE;
+ }
+ else if(bOpen)
+ {
+ return SDROBJCLOSED_OPEN;
+ }
+ else
+ {
+ return SDROBJCLOSED_CLOSED;
+ }
+}
+
+void SdrPolyEditView::ShutMarkedObjects()
+{
+ CloseMarkedObjects();
+}
+
+void SdrPolyEditView::CloseMarkedObjects(BOOL bToggle, BOOL bOpen) // , long nOpenDistance)
+{
+ if (AreObjectsMarked())
+ {
+ const bool bUndo = IsUndoEnabled();
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_EditShut),GetDescriptionOfMarkedPoints());
+
+ bool bChg=false;
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pO=pM->GetMarkedSdrObj();
+ BOOL bClosed=pO->IsClosedObj();
+ if (pO->IsPolyObj() && (bClosed==bOpen) || bToggle)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
+
+ SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( pO );
+ if(pPathObj)
+ pPathObj->ToggleClosed();
+ bChg=true;
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+
+ if (bChg)
+ {
+ UnmarkAllPoints();
+ MarkListHasChanged();
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPolyEditView::ImpCopyMarkedPoints()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrPolyEditView::ImpTransformMarkedPoints(PPolyTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
+{
+ const bool bUndo = IsUndoEnabled();
+
+ ULONG nMarkAnz=GetMarkedObjectCount();
+ for (ULONG nm=0; nm<nMarkAnz; nm++)
+ {
+ SdrMark* pM=GetSdrMarkByIndex(nm);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrUShortCont* pPts=pM->GetMarkedPoints();
+ ULONG nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
+ SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
+ if (nPtAnz!=0 && pPath!=NULL)
+ {
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
+
+ basegfx::B2DPolyPolygon aXPP(pPath->GetPathPoly());
+
+ for(sal_uInt32 nPtNum(0L); nPtNum < nPtAnz; nPtNum++)
+ {
+ sal_uInt32 nPt(pPts->GetObject(nPtNum));
+ 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,p5);
+ 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*/, const void* /*p5*/)
+{
+ MovePoint(rPt,*(const Size*)p1);
+ if (pC1!=NULL) MovePoint(*pC1,*(const Size*)p1);
+ if (pC2!=NULL) MovePoint(*pC2,*(const Size*)p1);
+}
+
+void SdrPolyEditView::MoveMarkedPoints(const Size& rSiz, bool bCopy)
+{
+ bCopy=FALSE; // noch nicht implementiert
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditMove));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_MOVE);
+ if (bCopy) ImpCopyMarkedPoints();
+ 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*/, const void* /*p5*/)
+{
+ ResizePoint(rPt,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
+ if (pC1!=NULL) ResizePoint(*pC1,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
+ if (pC2!=NULL) ResizePoint(*pC2,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
+}
+
+void SdrPolyEditView::ResizeMarkedPoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
+{
+ bCopy=FALSE; // noch nicht implementiert
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditResize));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_RESIZE);
+ if (bCopy) ImpCopyMarkedPoints();
+ 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, const void* /*p5*/)
+{
+ RotatePoint(rPt,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
+ if (pC1!=NULL) RotatePoint(*pC1,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
+ if (pC2!=NULL) RotatePoint(*pC2,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
+}
+
+void SdrPolyEditView::RotateMarkedPoints(const Point& rRef, long nWink, bool bCopy)
+{
+ bCopy=FALSE; // noch nicht implementiert
+ ForceUndirtyMrkPnt();
+ XubString aStr(ImpGetResStr(STR_EditResize));
+ if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
+ BegUndo(aStr,GetDescriptionOfMarkedPoints(),SDRREPFUNC_OBJ_ROTATE);
+ if (bCopy) ImpCopyMarkedPoints();
+ double nSin=sin(nWink*nPi180);
+ double nCos=cos(nWink*nPi180);
+ ImpTransformMarkedPoints(ImpRotate,&rRef,&nWink,&nSin,&nCos);
+ EndUndo();
+ AdjustMarkHdl();
+}
+
+// eof
diff --git a/svx/source/svdraw/svdsnpv.cxx b/svx/source/svdraw/svdsnpv.cxx
new file mode 100644
index 000000000000..1a8f735887cf
--- /dev/null
+++ b/svx/source/svdraw/svdsnpv.cxx
@@ -0,0 +1,730 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdsnpv.hxx>
+#include <math.h>
+
+#include <svx/svdetc.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdpage.hxx>
+#include "svditer.hxx"
+#include <svx/sdr/overlay/overlayobjectlist.hxx>
+#include <svx/sdr/overlay/overlaycrosshair.hxx>
+#include <svx/sdr/overlay/overlayhelpline.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <sdrpaintwindow.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #114409#-1 Migrate PageOrigin
+class ImplPageOriginOverlay
+{
+ // The OverlayObjects
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+ // The current position in logical coodinates
+ basegfx::B2DPoint maPosition;
+
+public:
+ ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos);
+ ~ImplPageOriginOverlay();
+
+ void SetPosition(const basegfx::B2DPoint& rNewPosition);
+};
+
+ImplPageOriginOverlay::ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos)
+: maPosition(rStartPos)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ ::sdr::overlay::OverlayCrosshairStriped* aNew = new ::sdr::overlay::OverlayCrosshairStriped(
+ maPosition);
+ pTargetOverlay->add(*aNew);
+ maObjects.append(*aNew);
+ }
+ }
+}
+
+ImplPageOriginOverlay::~ImplPageOriginOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+void ImplPageOriginOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
+{
+ if(rNewPosition != maPosition)
+ {
+ // apply to OverlayObjects
+ for(sal_uInt32 a(0); a < maObjects.count(); a++)
+ {
+ sdr::overlay::OverlayCrosshairStriped* pCandidate =
+ static_cast< sdr::overlay::OverlayCrosshairStriped* >(&maObjects.getOverlayObject(a));
+
+ if(pCandidate)
+ {
+ pCandidate->setBasePosition(rNewPosition);
+ }
+ }
+
+ // remember new position
+ maPosition = rNewPosition;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #114409#-2 Migrate HelpLine
+class ImplHelpLineOverlay
+{
+ // The OverlayObjects
+ ::sdr::overlay::OverlayObjectList maObjects;
+
+ // The current position in logical coodinates
+ basegfx::B2DPoint maPosition;
+
+ // HelpLine specific stuff
+ SdrPageView* mpPageView;
+ sal_uInt16 mnHelpLineNumber;
+ SdrHelpLineKind meHelpLineKind;
+
+public:
+ ImplHelpLineOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
+ SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind);
+ ~ImplHelpLineOverlay();
+
+ void SetPosition(const basegfx::B2DPoint& rNewPosition);
+
+ // access to HelpLine specific stuff
+ SdrPageView* GetPageView() const { return mpPageView; }
+ sal_uInt16 GetHelpLineNumber() const { return mnHelpLineNumber; }
+ SdrHelpLineKind GetHelpLineKind() const { return meHelpLineKind; }
+};
+
+ImplHelpLineOverlay::ImplHelpLineOverlay(
+ const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
+ SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind)
+: maPosition(rStartPos),
+ mpPageView(pPageView),
+ mnHelpLineNumber(nHelpLineNumber),
+ meHelpLineKind(eKind)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ ::sdr::overlay::OverlayHelplineStriped* aNew = new ::sdr::overlay::OverlayHelplineStriped(
+ maPosition, meHelpLineKind);
+ pTargetOverlay->add(*aNew);
+ maObjects.append(*aNew);
+ }
+ }
+}
+
+ImplHelpLineOverlay::~ImplHelpLineOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+void ImplHelpLineOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
+{
+ if(rNewPosition != maPosition)
+ {
+ // apply to OverlayObjects
+ // apply to OverlayObjects
+ for(sal_uInt32 a(0); a < maObjects.count(); a++)
+ {
+ sdr::overlay::OverlayHelplineStriped* pCandidate =
+ static_cast< sdr::overlay::OverlayHelplineStriped* >(&maObjects.getOverlayObject(a));
+
+ if(pCandidate)
+ {
+ pCandidate->setBasePosition(rNewPosition);
+ }
+ }
+
+ // remember new position
+ maPosition = rNewPosition;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@ @@ @@@@ @@@@@ @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
+// @@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@ @@@@ @@@@@@@
+// @@ @@ @@@ @@ @@ @@ @@@ @@ @@ @@@@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
+// @@@@ @@ @@ @@ @@ @@ @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrSnapView::ClearVars()
+{
+ nMagnSizPix=4;
+ bSnapEnab=TRUE;
+ bGridSnap=TRUE;
+ bSnapTo1Pix=TRUE;
+ bBordSnap=TRUE;
+ bHlplSnap=TRUE;
+ bOFrmSnap=TRUE;
+ bOPntSnap=FALSE;
+ bOConSnap=TRUE;
+ bMoveMFrmSnap=TRUE;
+ bMoveOFrmSnap=TRUE;
+ bMoveOPntSnap=TRUE;
+ bMoveOConSnap=TRUE;
+ bMoveSnapOnlyTopLeft=FALSE;
+ bOrtho=FALSE;
+ bBigOrtho=TRUE;
+ nSnapAngle=1500;
+ bAngleSnapEnab=FALSE;
+ bMoveOnlyDragging=FALSE;
+ bSlantButShear=FALSE;
+ bCrookNoContortion=FALSE;
+ eCrookMode=SDRCROOK_ROTATE;
+ bHlplFixed=FALSE;
+ bEliminatePolyPoints=FALSE;
+ nEliminatePolyPointLimitAngle=0;
+
+ // #114409#-1 Migrate PageOrigin
+ BrkSetPageOrg();
+
+ // #114409#-2 Migrate HelpLine
+ BrkDragHelpLine();
+}
+
+SdrSnapView::SdrSnapView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrPaintView(pModel1,pOut),
+ // #114409#-1 Migrate PageOrigin
+ mpPageOriginOverlay(0L),
+ // #114409#-2 Migrate HelpLine
+ mpHelpLineOverlay(0L)
+{
+ ClearVars();
+}
+
+// #114409#-1 Migrate PageOrigin
+SdrSnapView::~SdrSnapView()
+{
+ // #114409#-1 Migrate PageOrigin
+ BrkSetPageOrg();
+
+ // #114409#-2 Migrate HelpLine
+ BrkDragHelpLine();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrSnapView::IsAction() const
+{
+ return IsSetPageOrg() || IsDragHelpLine() || SdrPaintView::IsAction();
+}
+
+void SdrSnapView::MovAction(const Point& rPnt)
+{
+ SdrPaintView::MovAction(rPnt);
+ if (IsSetPageOrg()) {
+ MovSetPageOrg(rPnt);
+ }
+ if (IsDragHelpLine()) {
+ MovDragHelpLine(rPnt);
+ }
+}
+
+void SdrSnapView::EndAction()
+{
+ if (IsSetPageOrg()) {
+ EndSetPageOrg();
+ }
+ if (IsDragHelpLine()) {
+ EndDragHelpLine();
+ }
+ SdrPaintView::EndAction();
+}
+
+void SdrSnapView::BckAction()
+{
+ BrkSetPageOrg();
+ BrkDragHelpLine();
+ SdrPaintView::BckAction();
+}
+
+void SdrSnapView::BrkAction()
+{
+ BrkSetPageOrg();
+ BrkDragHelpLine();
+ SdrPaintView::BrkAction();
+}
+
+void SdrSnapView::TakeActionRect(Rectangle& rRect) const
+{
+ if (IsSetPageOrg() || IsDragHelpLine()) {
+ rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow());
+ } else {
+ SdrPaintView::TakeActionRect(rRect);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Point SdrSnapView::GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const
+{
+ Point aPt(rPnt);
+ SnapPos(aPt,pPV);
+ return aPt;
+}
+
+#define NOT_SNAPPED 0x7FFFFFFF
+USHORT SdrSnapView::SnapPos(Point& rPnt, const SdrPageView* pPV) const
+{
+ if (!bSnapEnab) return SDRSNAP_NOTSNAPPED;
+ BOOL bPVOfs=FALSE;
+ long x=rPnt.X();
+ long y=rPnt.Y();
+ if (pPV==NULL) {
+ bPVOfs=TRUE;
+ pPV=GetSdrPageView();
+ if (pPV==NULL) return SDRSNAP_NOTSNAPPED;
+ }
+
+ long dx=NOT_SNAPPED;
+ long dy=NOT_SNAPPED;
+ long dx1,dy1;
+ long mx=aMagnSiz.Width();
+ long my=aMagnSiz.Height();
+ if (bHlplVisible && bHlplSnap && !IsDragHelpLine())
+ {
+ const SdrHelpLineList& rHLL=pPV->GetHelpLines();
+ USHORT nAnz=rHLL.GetCount();
+ for (USHORT i=nAnz; i>0;) {
+ i--;
+ const SdrHelpLine& rHL=rHLL[i];
+ const Point& rPos=rHL.GetPos();
+ switch (rHL.GetKind()) {
+ case SDRHELPLINE_VERTICAL: {
+ long a=x-rPos.X();
+ if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; }
+ } break;
+ case SDRHELPLINE_HORIZONTAL: {
+ long b=y-rPos.Y();
+ if (Abs(b)<=my) { dy1=-b; if (Abs(dy1)<Abs(dy)) dy=dy1; }
+ } break;
+ case SDRHELPLINE_POINT: {
+ long a=x-rPos.X();
+ long b=y-rPos.Y();
+ if (Abs(a)<=mx && Abs(b)<=my) {
+ dx1=-a; dy1=-b;
+ if (Abs(dx1)<Abs(dx) && Abs(dy1)<Abs(dy)) { dx=dx1; dy=dy1; }
+ }
+ } break;
+ } // switch
+ }
+ }
+ if (bBordVisible && bBordSnap) {
+ SdrPage* pPage=pPV->GetPage();
+ long xs=pPage->GetWdt();
+ long ys=pPage->GetHgt();
+ long lft=pPage->GetLftBorder();
+ long rgt=pPage->GetRgtBorder();
+ long upp=pPage->GetUppBorder();
+ long lwr=pPage->GetLwrBorder();
+ long a;
+ a=x- lft ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // linker Rand
+ a=x-(xs-rgt); if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // rechter Rand
+ a=x ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // linke Papierkante
+ a=x- xs ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // rechte Papierkante
+ a=y- upp ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // linker Rand
+ a=y-(ys-lwr); if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // rechter Rand
+ a=y ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // linke Papierkante
+ a=y- ys ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // rechte Papierkante
+ }
+ if (bOFrmSnap || bOPntSnap /*|| (bConnVisible && bOConSnap)*/) {
+ ULONG nMaxPointSnapCount=200;
+ ULONG nMaxFrameSnapCount=200;
+
+ // #97981# go back to IM_DEEPNOGROUPS runthrough for snap to object comparisons
+ SdrObjListIter aIter(*pPV->GetPage(),/*IM_FLAT*/IM_DEEPNOGROUPS,TRUE);
+
+ while (aIter.IsMore() && (nMaxPointSnapCount>0 || nMaxFrameSnapCount>0)) {
+ SdrObject* pO=aIter.Next();
+ Rectangle aRect(pO->GetCurrentBoundRect());
+ aRect.Left ()-=mx;
+ aRect.Right ()+=mx;
+ aRect.Top ()-=my;
+ aRect.Bottom()+=my;
+ if (aRect.IsInside(rPnt)) {
+ if (bOPntSnap && nMaxPointSnapCount>0)
+ {
+ sal_uInt32 nAnz(pO->GetSnapPointCount());
+ for (sal_uInt32 i(0L); i < nAnz && nMaxPointSnapCount > 0L; i++)
+ {
+ Point aP(pO->GetSnapPoint(i));
+ dx1=x-aP.X();
+ dy1=y-aP.Y();
+ if (Abs(dx1)<=mx && Abs(dy1)<=my && Abs(dx1)<Abs(dx) && Abs(dy1)<Abs(dy)) {
+ dx=-dx1;
+ dy=-dy1;
+ }
+ nMaxPointSnapCount--;
+ }
+ }
+ if (bOFrmSnap && nMaxFrameSnapCount>0) {
+ Rectangle aLog(pO->GetSnapRect());
+ Rectangle aR1(aLog);
+ aR1.Left ()-=mx;
+ aR1.Right ()+=mx;
+ aR1.Top ()-=my;
+ aR1.Bottom()+=my;
+ if (aR1.IsInside(rPnt)) {
+ if (Abs(x-aLog.Left ())<=mx) { dx1=-(x-aLog.Left ()); if (Abs(dx1)<Abs(dx)) dx=dx1; }
+ if (Abs(x-aLog.Right ())<=mx) { dx1=-(x-aLog.Right ()); if (Abs(dx1)<Abs(dx)) dx=dx1; }
+ if (Abs(y-aLog.Top ())<=my) { dy1=-(y-aLog.Top ()); if (Abs(dy1)<Abs(dy)) dy=dy1; }
+ if (Abs(y-aLog.Bottom())<=my) { dy1=-(y-aLog.Bottom()); if (Abs(dy1)<Abs(dy)) dy=dy1; }
+ }
+ nMaxFrameSnapCount--;
+ }
+ }
+ }
+ }
+ if(bGridSnap)
+ {
+ double fSnapWidth = aSnapWdtX;
+ if(dx == NOT_SNAPPED && fSnapWidth != 0.0)
+ {
+ double fx = (double)x;
+
+ // round statt trunc
+ if(fx - (double)pPV->GetPageOrigin().X() >= 0.0)
+ fx += fSnapWidth / 2.0;
+ else
+ fx -= fSnapWidth / 2.0;
+
+ x = (long)((fx - (double)pPV->GetPageOrigin().X()) / fSnapWidth);
+ x = (long)((double)x * fSnapWidth + (double)pPV->GetPageOrigin().X());
+ dx = 0;
+ }
+ fSnapWidth = aSnapWdtY;
+ if(dy == NOT_SNAPPED && fSnapWidth)
+ {
+ double fy = (double)y;
+
+ // round statt trunc
+ if(fy - (double)pPV->GetPageOrigin().Y() >= 0.0)
+ fy += fSnapWidth / 2.0;
+ else
+ fy -= fSnapWidth / 2.0;
+
+ y = (long)((fy - (double)pPV->GetPageOrigin().Y()) / fSnapWidth);
+ y = (long)((double)y * fSnapWidth + (double)pPV->GetPageOrigin().Y());
+ dy = 0;
+ }
+ }
+ BOOL bRet=SDRSNAP_NOTSNAPPED;
+ if (dx==NOT_SNAPPED) dx=0; else bRet|=SDRSNAP_XSNAPPED;
+ if (dy==NOT_SNAPPED) dy=0; else bRet|=SDRSNAP_YSNAPPED;
+ rPnt.X()=x+dx;
+ rPnt.Y()=y+dy;
+ return bRet;
+}
+
+void SdrSnapView::CheckSnap(const Point& rPt, const SdrPageView* pPV, long& nBestXSnap, long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const
+{
+ Point aPt(rPt);
+ USHORT nRet=SnapPos(aPt,pPV);
+ aPt-=rPt;
+ if ((nRet & SDRSNAP_XSNAPPED) !=0) {
+ if (bXSnapped) {
+ if (Abs(aPt.X())<Abs(nBestXSnap)) {
+ nBestXSnap=aPt.X();
+ }
+ } else {
+ nBestXSnap=aPt.X();
+ bXSnapped=TRUE;
+ }
+ }
+ if ((nRet & SDRSNAP_YSNAPPED) !=0) {
+ if (bYSnapped) {
+ if (Abs(aPt.Y())<Abs(nBestYSnap)) {
+ nBestYSnap=aPt.Y();
+ }
+ } else {
+ nBestYSnap=aPt.Y();
+ bYSnapped=TRUE;
+ }
+ }
+}
+
+USHORT SdrSnapView::SnapRect(const Rectangle& rRect, const SdrPageView* pPV, long& rDX, long& rDY) const
+{
+ long nBestXSnap=0;
+ long nBestYSnap=0;
+ bool bXSnapped=FALSE;
+ bool bYSnapped=FALSE;
+ CheckSnap(rRect.TopLeft() ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ if (!bMoveSnapOnlyTopLeft) {
+ CheckSnap(rRect.TopRight() ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ CheckSnap(rRect.BottomLeft() ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ CheckSnap(rRect.BottomRight(),pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
+ }
+ rDX=nBestXSnap;
+ rDY=nBestYSnap;
+ USHORT nRet=0;
+ if (bXSnapped) nRet+=SDRSNAP_XSNAPPED;
+ if (bYSnapped) nRet+=SDRSNAP_YSNAPPED;
+ return nRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrSnapView::BegSetPageOrg(const Point& rPnt)
+{
+ BrkAction();
+
+ DBG_ASSERT(0L == mpPageOriginOverlay, "SdrSnapView::BegSetPageOrg: There exists a ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpPageOriginOverlay = new ImplPageOriginOverlay(*this, aStartPos);
+ aDragStat.Reset(GetSnapPos(rPnt,NULL));
+
+ return sal_True;
+}
+
+void SdrSnapView::MovSetPageOrg(const Point& rPnt)
+{
+ if(IsSetPageOrg())
+ {
+ aDragStat.NextMove(GetSnapPos(rPnt,NULL));
+ DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ basegfx::B2DPoint aNewPos(aDragStat.GetNow().X(), aDragStat.GetNow().Y());
+ mpPageOriginOverlay->SetPosition(aNewPos);
+ }
+}
+
+sal_Bool SdrSnapView::EndSetPageOrg()
+{
+ sal_Bool bRet(sal_False);
+
+ if(IsSetPageOrg())
+ {
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ Point aPnt(aDragStat.GetNow());
+ pPV->SetPageOrigin(aPnt);
+ bRet = sal_True;
+ }
+
+ // cleanup
+ BrkSetPageOrg();
+ }
+
+ return bRet;
+}
+
+void SdrSnapView::BrkSetPageOrg()
+{
+ if(IsSetPageOrg())
+ {
+ DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
+ delete mpPageOriginOverlay;
+ mpPageOriginOverlay = 0L;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrSnapView::PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, USHORT& rnHelpLineNum, SdrPageView*& rpPV) const
+{
+ rpPV=NULL;
+ nTol=ImpGetHitTolLogic(nTol,&rOut);
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ Point aPnt(rPnt);
+ USHORT nIndex=pPV->GetHelpLines().HitTest(aPnt,USHORT(nTol),rOut);
+ if (nIndex!=SDRHELPLINE_NOTFOUND) {
+ rpPV=pPV;
+ rnHelpLineNum=nIndex;
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+// start HelpLine drag for new HelpLine
+sal_Bool SdrSnapView::BegDragHelpLine(USHORT nHelpLineNum, SdrPageView* pPV)
+{
+ sal_Bool bRet(sal_False);
+
+ if(!bHlplFixed)
+ {
+ BrkAction();
+
+ if(pPV && nHelpLineNum < pPV->GetHelpLines().GetCount())
+ {
+ const SdrHelpLineList& rHelpLines = pPV->GetHelpLines();
+ const SdrHelpLine& rHelpLine = rHelpLines[nHelpLineNum];
+ Point aHelpLinePos = rHelpLine.GetPos(); // + pPV->GetOffset();
+ basegfx::B2DPoint aStartPos(aHelpLinePos.X(), aHelpLinePos.Y());
+
+ DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)");
+ mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, pPV, nHelpLineNum, rHelpLine.GetKind());
+
+ aDragStat.Reset(GetSnapPos(aHelpLinePos, pPV));
+ aDragStat.SetMinMove(ImpGetMinMovLogic(-3, 0L));
+
+ bRet = sal_True;
+ }
+ }
+
+ return bRet;
+}
+
+// start HelpLine drag with existing HelpLine
+sal_Bool SdrSnapView::BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind)
+{
+ sal_Bool bRet(sal_False);
+
+ BrkAction();
+
+ if(GetSdrPageView())
+ {
+ DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)");
+ basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
+ mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, 0L, 0, eNewKind);
+ aDragStat.Reset(GetSnapPos(rPnt, 0L));
+ bRet = sal_True;
+ }
+
+ return bRet;
+}
+
+Pointer SdrSnapView::GetDraggedHelpLinePointer() const
+{
+ if(IsDragHelpLine())
+ {
+ switch(mpHelpLineOverlay->GetHelpLineKind())
+ {
+ case SDRHELPLINE_VERTICAL : return Pointer(POINTER_ESIZE);
+ case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE);
+ default : return Pointer(POINTER_MOVE);
+ }
+ }
+
+ return Pointer(POINTER_MOVE);
+}
+
+void SdrSnapView::MovDragHelpLine(const Point& rPnt)
+{
+ if(IsDragHelpLine() && aDragStat.CheckMinMoved(rPnt))
+ {
+ Point aPnt(GetSnapPos(rPnt, 0L));
+
+ if(aPnt != aDragStat.GetNow())
+ {
+ aDragStat.NextMove(aPnt);
+ DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::MovDragHelpLine: no ImplHelpLineOverlay (!)");
+ basegfx::B2DPoint aNewPos(aDragStat.GetNow().X(), aDragStat.GetNow().Y());
+ mpHelpLineOverlay->SetPosition(aNewPos);
+ }
+ }
+}
+
+sal_Bool SdrSnapView::EndDragHelpLine()
+{
+ sal_Bool bRet(sal_False);
+
+ if(IsDragHelpLine())
+ {
+ if(aDragStat.IsMinMoved())
+ {
+ SdrPageView* pPageView = mpHelpLineOverlay->GetPageView();
+
+ if(pPageView)
+ {
+ // moved existing one
+ Point aPnt(aDragStat.GetNow());
+ const SdrHelpLineList& rHelpLines = pPageView->GetHelpLines();
+ SdrHelpLine aChangedHelpLine = rHelpLines[mpHelpLineOverlay->GetHelpLineNumber()];
+ aChangedHelpLine.SetPos(aPnt);
+ pPageView->SetHelpLine(mpHelpLineOverlay->GetHelpLineNumber(), aChangedHelpLine);
+
+ bRet = sal_True;
+ }
+ else
+ {
+ // create new one
+ pPageView = GetSdrPageView();
+
+ if(pPageView)
+ {
+ Point aPnt(aDragStat.GetNow());
+ SdrHelpLine aNewHelpLine(mpHelpLineOverlay->GetHelpLineKind(), aPnt);
+ pPageView->InsertHelpLine(aNewHelpLine);
+
+ bRet = sal_True;
+ }
+ }
+ }
+
+ // cleanup
+ BrkDragHelpLine();
+ }
+
+ return bRet;
+}
+
+void SdrSnapView::BrkDragHelpLine()
+{
+ if(IsDragHelpLine())
+ {
+ DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::EndDragHelpLine: no ImplHelpLineOverlay (!)");
+ delete mpHelpLineOverlay;
+ mpHelpLineOverlay = 0L;
+ }
+}
+
+// eof
diff --git a/svx/source/svdraw/svdstr.src b/svx/source/svdraw/svdstr.src
new file mode 100644
index 000000000000..1317a0e1328d
--- /dev/null
+++ b/svx/source/svdraw/svdstr.src
@@ -0,0 +1,2935 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+/* StarView resource file */
+
+#include "svdstr.hrc"
+ // Ab hier gecachte Strings
+String STR_ObjNameSingulNONE
+{
+ Text [ en-US ] = "draw object" ;
+};
+String STR_ObjNamePluralNONE
+{
+ Text [ en-US ] = "draw objects" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulGRUP
+{
+ Text [ en-US ] = "group object" ;
+};
+String STR_ObjNamePluralGRUP
+{
+ Text [ en-US ] = "group objects" ;
+};
+String STR_ObjNameSingulGRUPEMPTY
+{
+ Text [ en-US ] = "blank group object" ;
+};
+String STR_ObjNamePluralGRUPEMPTY
+{
+ Text [ en-US ] = "Blank group objects" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulLINE
+{
+ Text [ en-US ] = "Line" ;
+};
+String STR_ObjNameSingulLINE_Hori
+{
+ Text [ en-US ] = "horizontal line" ;
+};
+String STR_ObjNameSingulLINE_Vert
+{
+ Text [ en-US ] = "Vertical line" ;
+};
+String STR_ObjNameSingulLINE_Diag
+{
+ Text [ en-US ] = "diagonal line" ;
+};
+String STR_ObjNamePluralLINE
+{
+ Text [ en-US ] = "Lines" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulRECT
+{
+ Text [ en-US ] = "Rectangle" ;
+};
+String STR_ObjNamePluralRECT
+{
+ Text [ en-US ] = "Rectangles" ;
+};
+String STR_ObjNameSingulQUAD
+{
+ Text [ en-US ] = "Square" ;
+};
+String STR_ObjNamePluralQUAD
+{
+ Text [ en-US ] = "Squares" ;
+};
+String STR_ObjNameSingulPARAL
+{
+ Text [ en-US ] = "Parallelogram" ;
+};
+String STR_ObjNamePluralPARAL
+{
+ Text [ en-US ] = "Parallelograms" ;
+};
+String STR_ObjNameSingulRAUTE
+{
+ Text [ en-US ] = "Rhombus" ;
+};
+String STR_ObjNamePluralRAUTE
+{
+ Text [ en-US ] = "Rhombuses" ;
+};
+String STR_ObjNameSingulRECTRND
+{
+ Text [ en-US ] = "Rounded rectangle" ;
+};
+String STR_ObjNamePluralRECTRND
+{
+ Text [ en-US ] = "Rounded Rectangles" ;
+};
+String STR_ObjNameSingulQUADRND
+{
+ Text [ en-US ] = "rounded square" ;
+};
+String STR_ObjNamePluralQUADRND
+{
+ Text [ en-US ] = "Rounded Squares" ;
+};
+String STR_ObjNameSingulPARALRND
+{
+ Text [ en-US ] = "Rounded Parallelogram" ;
+};
+String STR_ObjNamePluralPARALRND
+{
+ Text [ en-US ] = "Rounded parallelograms" ;
+};
+String STR_ObjNameSingulRAUTERND
+{
+ Text [ en-US ] = "rounded rhombus" ;
+};
+String STR_ObjNamePluralRAUTERND
+{
+ Text [ en-US ] = "Rounded rhombuses" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulCIRC
+{
+ Text [ en-US ] = "Circle" ;
+};
+String STR_ObjNamePluralCIRC
+{
+ Text [ en-US ] = "Circles" ;
+};
+String STR_ObjNameSingulSECT
+{
+ Text [ en-US ] = "Circle sector" ;
+};
+String STR_ObjNamePluralSECT
+{
+ Text [ en-US ] = "Circle sectors" ;
+};
+String STR_ObjNameSingulCARC
+{
+ Text [ en-US ] = "Arc" ;
+};
+String STR_ObjNamePluralCARC
+{
+ Text [ en-US ] = "Arcs" ;
+};
+String STR_ObjNameSingulCCUT
+{
+ Text [ en-US ] = "Circle segment" ;
+};
+String STR_ObjNamePluralCCUT
+{
+ Text [ en-US ] = "Circle segments" ;
+};
+String STR_ObjNameSingulCIRCE
+{
+ Text [ en-US ] = "Ellipse" ;
+};
+String STR_ObjNamePluralCIRCE
+{
+ Text [ en-US ] = "Ellipses" ;
+};
+String STR_ObjNameSingulSECTE
+{
+ Text [ en-US ] = "Ellipse Pie" ;
+};
+String STR_ObjNamePluralSECTE
+{
+ Text [ en-US ] = "Ellipse Pies" ;
+};
+String STR_ObjNameSingulCARCE
+{
+ Text [ en-US ] = "Elliptical arc" ;
+};
+String STR_ObjNamePluralCARCE
+{
+ Text [ en-US ] = "Elliptical arcs" ;
+};
+String STR_ObjNameSingulCCUTE
+{
+ Text [ en-US ] = "Ellipse Segment" ;
+};
+String STR_ObjNamePluralCCUTE
+{
+ Text [ en-US ] = "Ellipse Segments" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulPOLY
+{
+ Text [ en-US ] = "Polygon" ;
+};
+String STR_ObjNameSingulPOLY_PntAnz
+{
+ Text [ en-US ] = "Polygon %2 corners" ;
+};
+String STR_ObjNamePluralPOLY
+{
+ Text [ en-US ] = "Polygons" ;
+};
+String STR_ObjNameSingulPLIN
+{
+ Text [ en-US ] = "Polyline" ;
+};
+String STR_ObjNameSingulPLIN_PntAnz
+{
+ Text [ en-US ] = "Polyline with %2 corners" ;
+};
+String STR_ObjNamePluralPLIN
+{
+ Text [ en-US ] = "Polylines" ;
+};
+String STR_ObjNameSingulPATHLINE
+{
+ Text [ en-US ] = "Bézier curve" ;
+};
+String STR_ObjNamePluralPATHLINE
+{
+ Text [ en-US ] = "Bézier curves" ;
+};
+String STR_ObjNameSingulPATHFILL
+{
+ Text [ en-US ] = "Bézier curve" ;
+};
+String STR_ObjNamePluralPATHFILL
+{
+ Text [ en-US ] = "Bézier curves" ;
+};
+String STR_ObjNameSingulFREELINE
+{
+ Text [ en-US ] = "Freeform Line" ;
+};
+String STR_ObjNamePluralFREELINE
+{
+ Text [ en-US ] = "Freeform Lines" ;
+};
+String STR_ObjNameSingulFREEFILL
+{
+ Text [ en-US ] = "Freeform Line" ;
+};
+String STR_ObjNamePluralFREEFILL
+{
+ Text [ en-US ] = "Freeform Lines" ;
+};
+String STR_ObjNameSingulCOMBLINE
+{
+ Text [ en-US ] = "Curve" ;
+};
+String STR_ObjNamePluralCOMBLINE
+{
+ Text [ en-US ] = "Curve objects" ;
+};
+String STR_ObjNameSingulCOMBFILL
+{
+ Text [ en-US ] = "Curve" ;
+};
+String STR_ObjNamePluralCOMBFILL
+{
+ Text [ en-US ] = "Curve objects" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulNATSPLN
+{
+ Text [ en-US ] = "Natural Spline" ;
+};
+String STR_ObjNamePluralNATSPLN
+{
+ Text [ en-US ] = "Natural Splines" ;
+};
+String STR_ObjNameSingulPERSPLN
+{
+ Text [ en-US ] = "Periodic Spline" ;
+};
+String STR_ObjNamePluralPERSPLN
+{
+ Text [ en-US ] = "Periodic Splines" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulTEXT
+{
+ Text [ en-US ] = "Text Frame" ;
+};
+String STR_ObjNamePluralTEXT
+{
+ Text [ en-US ] = "Text Frame" ;
+};
+String STR_ObjNameSingulTEXTLNK
+{
+ Text [ en-US ] = "Linked text frame" ;
+};
+String STR_ObjNamePluralTEXTLNK
+{
+ Text [ en-US ] = "Linked text frames" ;
+};
+ //String STR_ObjNameSingulXTXT {
+ // Text="Textfortsetzungsrahmen";
+ // Text[ENGLISH]="drawobject";
+ // Text[norwegian]="Tegneobjekt";
+ // Text[italian]="Disegna oggetto";
+ // Text[portuguese_brazilian]="Desenhar objeto";
+ // Text[portuguese]="Desenhar objecto";
+ // Text[finnish]="Piirto-objekti";
+ // Text[danish]="Tegneobjekt";
+ // Text[french]="Drawobject";
+ // Text[swedish]="Ritobjekt";
+ // Text[dutch]="Tekenobject";
+ // Text[spanish]="Objeto de dibujo";
+ // Text[english_us]="drawobject";
+ //};
+ //String STR_ObjNamePluralXTXT {
+ // Text="Textfortsetzungsrahmen";
+ // Text[ENGLISH]="drawobjects";
+ // Text[norwegian]="Tegneobjektr";
+ // Text[italian]="Disegna oggetti";
+ // Text[portuguese_brazilian]="Desenhar objetos";
+ // Text[portuguese]="Desenhar objectos";
+ // Text[finnish]="Piirto-objektit";
+ // Text[danish]="Tegneobjekter";
+ // Text[french]="Drawobjects";
+ // Text[swedish]="Ritobjekt";
+ // Text[dutch]="Tekenobjecten";
+ // Text[spanish]="Objetos de dibujo";
+ // Text[english_us]="drawobjects";
+ //};
+String STR_ObjNameSingulFITTEXT
+{
+ Text [ en-US ] = "Fit-to-size text object" ;
+};
+String STR_ObjNamePluralFITTEXT
+{
+ Text [ en-US ] = "Fit-to-size text objects" ;
+};
+String STR_ObjNameSingulFITALLTEXT
+{
+ Text [ en-US ] = "Fit-to-size text object" ;
+};
+String STR_ObjNamePluralFITALLTEXT
+{
+ Text [ en-US ] = "Fit-to-size text objects" ;
+};
+String STR_ObjNameSingulTITLETEXT
+{
+ Text [ en-US ] = "Title text" ;
+};
+String STR_ObjNamePluralTITLETEXT
+{
+ Text [ en-US ] = "Title texts" ;
+};
+String STR_ObjNameSingulOUTLINETEXT
+{
+ Text [ en-US ] = "Outline Text" ;
+};
+String STR_ObjNamePluralOUTLINETEXT
+{
+ Text [ en-US ] = "Outline Texts" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulGRAF
+{
+ Text [ en-US ] = "graphic" ;
+};
+String STR_ObjNamePluralGRAF
+{
+ Text [ en-US ] = "graphics" ;
+};
+String STR_ObjNameSingulGRAFLNK
+{
+ Text [ en-US ] = "Linked graphic" ;
+};
+String STR_ObjNamePluralGRAFLNK
+{
+ Text [ en-US ] = "Linked graphics" ;
+};
+String STR_ObjNameSingulGRAFNONE
+{
+ Text [ en-US ] = "Blank graphic object" ;
+};
+String STR_ObjNamePluralGRAFNONE
+{
+ Text [ en-US ] = "Blank graphic objects" ;
+};
+String STR_ObjNameSingulGRAFNONELNK
+{
+ Text [ en-US ] = "Blank linked graphic" ;
+};
+String STR_ObjNamePluralGRAFNONELNK
+{
+ Text [ en-US ] = "Blank linked graphics" ;
+};
+String STR_ObjNameSingulGRAFMTF
+{
+ Text [ en-US ] = "Metafile" ;
+};
+String STR_ObjNamePluralGRAFMTF
+{
+ Text [ en-US ] = "Metafiles" ;
+};
+String STR_ObjNameSingulGRAFMTFLNK
+{
+ Text [ en-US ] = "Linked Metafile" ;
+};
+String STR_ObjNamePluralGRAFMTFLNK
+{
+ Text [ en-US ] = "Linked Metafiles" ;
+};
+String STR_ObjNameSingulGRAFBMP
+{
+ Text [ en-US ] = "Bitmap" ;
+};
+String STR_ObjNameSingulGRAFBMPTRANS
+{
+ Text [ en-US ] = "Bitmap with transparency" ;
+};
+String STR_ObjNameSingulGRAFBMPLNK
+{
+ Text [ en-US ] = "Linked Bitmap" ;
+};
+String STR_ObjNameSingulGRAFBMPTRANSLNK
+{
+ Text [ en-US ] = "Linked bitmap with transparency" ;
+};
+String STR_ObjNamePluralGRAFBMP
+{
+ Text [ en-US ] = "Bitmaps" ;
+};
+String STR_ObjNamePluralGRAFBMPTRANS
+{
+ Text [ en-US ] = "Bitmaps with transparency" ;
+};
+String STR_ObjNamePluralGRAFBMPLNK
+{
+ Text [ en-US ] = "Linked bitmaps" ;
+};
+String STR_ObjNamePluralGRAFBMPTRANSLNK
+{
+ Text [ en-US ] = "Linked bitmaps with transparency" ;
+};
+String STR_ObjNameSingulCUSTOMSHAPE
+{
+ Text [ en-US ] = "Shape";
+};
+String STR_ObjNamePluralCUSTOMSHAPE
+{
+ Text [ en-US ] = "Shapes";
+};
+String STR_ObjNameSingulGRAFMAC
+{
+ Text [ en-US ] = "Mac graphic" ;
+};
+String STR_ObjNamePluralGRAFMAC
+{
+ Text [ en-US ] = "Mac graphics" ;
+};
+String STR_ObjNameSingulGRAFMACLNK
+{
+ Text [ en-US ] = "Linked Mac graphic" ;
+};
+String STR_ObjNamePluralGRAFMACLNK
+{
+ Text [ en-US ] = "Linked Mac graphics" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulOLE2
+{
+ Text [ en-US ] = "embedded object (OLE)" ;
+};
+String STR_ObjNamePluralOLE2
+{
+ Text [ en-US ] = "Embedded objects (OLE)" ;
+};
+String STR_ObjNameSingulUno
+{
+ Text [ en-US ] = "Control";
+};
+String STR_ObjNamePluralUno
+{
+ Text [ en-US ] = "Controls";
+};
+String STR_ObjNameSingulOLE2LNK
+{
+ Text [ en-US ] = "linked embedded object (OLE)" ;
+};
+String STR_ObjNamePluralOLE2LNK
+{
+ Text [ en-US ] = "Linked embedded objects (OLE)" ;
+};
+String STR_ObjOLE2NamePrefix
+{
+ Text [ en-US ] = "Object" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulFrame
+{
+ Text [ en-US ] = "Frame" ;
+};
+String STR_ObjNamePluralFrame
+{
+ Text [ en-US ] = "Frames" ;
+};
+String STR_ObjFrameNamePrefix
+{
+ Text [ en-US ] = "Frame" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulEDGE
+{
+ Text [ en-US ] = "Object Connectors" ;
+};
+String STR_ObjNamePluralEDGE
+{
+ Text [ en-US ] = "Object Connectors" ;
+};
+String STR_ObjNameSingulCAPTION
+{
+ Text [ en-US ] = "Callout" ;
+};
+String STR_ObjNamePluralCAPTION
+{
+ Text [ en-US ] = "Callouts" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ObjNameSingulPAGE
+{
+ Text [ en-US ] = "Preview object" ;
+};
+String STR_ObjNamePluralPAGE
+{
+ Text [ en-US ] = "Preview objects" ;
+};
+String STR_ObjNameSingulMEASURE
+{
+ Text [ en-US ] = "Dimension line" ;
+};
+String STR_ObjNamePluralMEASURE
+{
+ Text [ en-US ] = "Dimensioning objects" ;
+};
+String STR_ObjNamePlural
+{
+ Text [ en-US ] = "draw objects" ;
+};
+String STR_ObjNameNoObj
+{
+ Text [ en-US ] = "No draw object" ;
+};
+String STR_ObjNameAnd
+{
+ Text [ en-US ] = "and" ;
+};
+String STR_ObjNameSingulPlural
+{
+ Text [ en-US ] = "draw object(s)" ;
+};
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Neu ab 537: Namen fuer 3D-Objekte
+String STR_ObjNameSingulCube3d
+{
+ Text [ en-US ] = "3D cube";
+};
+
+String STR_ObjNamePluralCube3d
+{
+ Text [ en-US ] = "3D cubes";
+};
+
+String STR_ObjNameSingulExtrude3d
+{
+ Text [ en-US ] = "Extrusion object";
+};
+
+String STR_ObjNamePluralExtrude3d
+{
+ Text [ en-US ] = "Extrusion objects";
+};
+
+String STR_ObjNameSingulLabel3d
+{
+ Text [ en-US ] = "3D text";
+};
+
+String STR_ObjNamePluralLabel3d
+{
+ Text [ en-US ] = "3D texts";
+};
+
+String STR_ObjNameSingulLathe3d
+{
+ Text [ en-US ] = "rotation object";
+};
+
+String STR_ObjNamePluralLathe3d
+{
+ Text [ en-US ] = "rotation objects";
+};
+
+String STR_ObjNameSingulObj3d
+{
+ Text [ en-US ] = "3D object";
+};
+
+String STR_ObjNamePluralObj3d
+{
+ Text [ en-US ] = "3D objects";
+};
+
+String STR_ObjNamePluralPoly3d
+{
+ Text [ en-US ] = "3D polygons";
+};
+
+String STR_ObjNameSingulScene3d
+{
+ Text [ en-US ] = "3D scene";
+};
+
+String STR_ObjNamePluralScene3d
+{
+ Text [ en-US ] = "3D scenes";
+};
+
+String STR_ObjNameSingulSphere3d
+{
+ Text [ en-US ] = "sphere";
+};
+
+String STR_ObjNamePluralSphere3d
+{
+ Text [ en-US ] = "spheres";
+};
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+
+String STR_EditWithCopy
+{
+ Text [ en-US ] = "with copy" ;
+};
+String STR_EditPosSize
+{
+ Text [ en-US ] = "Set position and size for %1" ;
+};
+String STR_EditDelete
+{
+ Text [ en-US ] = "Delete %1" ;
+};
+String STR_EditMovToTop
+{
+ Text [ en-US ] = "Move %1 forward" ;
+};
+String STR_EditMovToBtm
+{
+ Text [ en-US ] = "Move %1 further back" ;
+};
+String STR_EditPutToTop
+{
+ Text [ en-US ] = "Move %1 to front" ;
+};
+String STR_EditPutToBtm
+{
+ Text [ en-US ] = "Move %1 to back" ;
+};
+String STR_EditRevOrder
+{
+ Text [ en-US ] = "Reverse order of %1" ;
+};
+String STR_EditMove
+{
+ Text [ en-US ] = "Move %1" ;
+};
+String STR_EditResize
+{
+ Text [ en-US ] = "Resize %1" ;
+};
+String STR_EditRotate
+{
+ Text [ en-US ] = "Rotate %1" ;
+};
+String STR_EditMirrorHori
+{
+ Text [ en-US ] = "Flip %1 horizontal" ;
+};
+String STR_EditMirrorVert
+{
+ Text [ en-US ] = "Flip %1 vertical" ;
+};
+String STR_EditMirrorDiag
+{
+ Text [ en-US ] = "Flip %1 diagonal" ;
+};
+String STR_EditMirrorFree
+{
+ Text [ en-US ] = "Flip %1 freehand" ;
+};
+String STR_EditShear
+{
+ Text [ en-US ] = "Distort %1 (slant)" ;
+};
+String STR_EditCrook
+{
+ Text [ en-US ] = "Arrange %1 in circle" ;
+};
+String STR_EditCrookContortion
+{
+ Text [ en-US ] = "Curve %1 in circle" ;
+};
+String STR_EditDistort
+{
+ Text [ en-US ] = "Distort %1" ;
+};
+String STR_EditRipUp
+{
+ Text [ en-US ] = "Undo %1" ;
+};
+String STR_EditSetPointsSmooth
+{
+ Text [ en-US ] = "Modify bézier properties of %1" ;
+};
+String STR_EditSetSegmentsKind
+{
+ Text [ en-US ] = "Modify bézier properties of %1" ;
+};
+String STR_EditShut
+{
+ Text [ en-US ] = "Close %1" ;
+};
+String STR_EditSetGlueEscDir
+{
+ Text [ en-US ] = "Set exit direction for %1" ;
+};
+String STR_EditSetGluePercent
+{
+ Text [ en-US ] = "Set relative attribute at %1" ;
+};
+String STR_EditSetGlueAlign
+{
+ Text [ en-US ] = "Set reference point for %1" ;
+};
+String STR_EditGroup
+{
+ Text [ en-US ] = "Group %1" ;
+};
+String STR_EditUngroup
+{
+ Text [ en-US ] = "Ungroup %1" ;
+};
+String STR_EditSetAttributes
+{
+ Text [ en-US ] = "Apply attributes to %1" ;
+};
+String STR_EditSetStylesheet
+{
+ Text [ en-US ] = "Apply Styles to %1" ;
+};
+String STR_EditDelStylesheet
+{
+ Text [ en-US ] = "Remove Style from %1" ;
+};
+String STR_EditConvToPoly
+{
+ Text [ en-US ] = "Convert %1 to polygon" ;
+};
+String STR_EditConvToPolys
+{
+ Text [ en-US ] = "Convert %1 to polygons" ;
+};
+String STR_EditConvToCurve
+{
+ Text [ en-US ] = "Convert %1 to curve" ;
+};
+String STR_EditConvToCurves
+{
+ Text [ en-US ] = "Convert %1 to curves" ;
+};
+String STR_EditConvToContour
+{
+ Text [ en-US ] = "Convert %1 to contour";
+};
+String STR_EditConvToContours
+{
+ Text [ en-US ] = "Convert %1 to contours";
+};
+String STR_EditAlign
+{
+ Text [ en-US ] = "Align %1" ;
+};
+String STR_EditAlignVTop
+{
+ Text [ en-US ] = "Align %1 to top" ;
+};
+String STR_EditAlignVBottom
+{
+ Text [ en-US ] = "Align %1 to bottom" ;
+};
+String STR_EditAlignVCenter
+{
+ Text [ en-US ] = "Horizontally center %1" ;
+};
+String STR_EditAlignHLeft
+{
+ Text [ en-US ] = "Align %1 to left" ;
+};
+String STR_EditAlignHRight
+{
+ Text [ en-US ] = "Align %1 to right" ;
+};
+String STR_EditAlignHCenter
+{
+ Text [ en-US ] = "Vertically center %1" ;
+};
+String STR_EditAlignCenter
+{
+ Text [ en-US ] = "Center %1" ;
+};
+String STR_EditTransform
+{
+ Text [ en-US ] = "Transform %1" ;
+};
+String STR_EditCombine_PolyPoly
+{
+ Text [ en-US ] = "Combine %1" ;
+};
+String STR_EditMergeMergePoly
+{
+ Text [ en-US ] = "Merge %1";
+};
+String STR_EditMergeSubstractPoly
+{
+ Text [ en-US ] = "Subtract %1";
+};
+String STR_EditMergeIntersectPoly
+{
+ Text [ en-US ] = "Intersect %1";
+};
+String STR_DistributeMarkedObjects
+{
+ Text [ en-US ] = "Distribute selected objects";
+};
+String STR_EditCombine_OnePoly
+{
+ Text [ en-US ] = "Combine %1" ;
+};
+String STR_EditDismantle_Polys
+{
+ Text [ en-US ] = "Split %1" ;
+};
+String STR_EditDismantle_Lines
+{
+ Text [ en-US ] = "Split %1" ;
+};
+String STR_EditImportMtf
+{
+ Text [ en-US ] = "Split %1" ;
+};
+String STR_EditImportSGV
+{
+ Text = "StarDraw Dos Zeichnung importieren" ;
+};
+String STR_EditImportHPGL
+{
+ Text = "HPGL importieren" ;
+};
+String STR_EditImportDXF
+{
+ Text = "DXF importieren" ;
+};
+String STR_ExchangePaste
+{
+ Text [ en-US ] = "Insert object(s)" ;
+};
+String STR_ExchangeClpCut
+{
+ Text [ en-US ] = "Cut %1" ;
+};
+String STR_ExchangeClpPaste
+{
+ Text [ en-US ] = "Paste Clipboard" ;
+};
+String STR_ExchangeDD
+{
+ Text [ en-US ] = "Drag and Drop %1" ;
+};
+String STR_ExchangeDDPaste
+{
+ Text [ en-US ] = "Insert Drag and Drop" ;
+};
+String STR_DragInsertPoint
+{
+ Text [ en-US ] = "Insert point to %1" ;
+};
+String STR_DragInsertGluePoint
+{
+ Text [ en-US ] = "Insert glue point to %1" ;
+};
+String STR_DragMethMovHdl
+{
+ Text [ en-US ] = "Move reference-point" ;
+};
+String STR_DragMethObjOwn
+{
+ Text [ en-US ] = "Geometrically change %1" ;
+};
+String STR_DragMethMove
+{
+ Text [ en-US ] = "Move %1" ;
+};
+String STR_DragMethResize
+{
+ Text [ en-US ] = "Resize %1" ;
+};
+String STR_DragMethRotate
+{
+ Text [ en-US ] = "Rotate %1" ;
+};
+String STR_DragMethMirrorHori
+{
+ Text [ en-US ] = "Flip %1 horizontal" ;
+};
+String STR_DragMethMirrorVert
+{
+ Text [ en-US ] = "Flip %1 vertical" ;
+};
+String STR_DragMethMirrorDiag
+{
+ Text [ en-US ] = "Flip %1 diagonal" ;
+};
+String STR_DragMethMirrorFree
+{
+ Text [ en-US ] = "Flip %1 freehand" ;
+};
+String STR_DragMethGradient
+{
+ Text [ en-US ] = "Interactive gradient for %1";
+};
+String STR_DragMethTransparence
+{
+ Text [ en-US ] = "Interactive transparency for %1";
+};
+String STR_DragMethShear
+{
+ Text [ en-US ] = "Distort %1 (slant)" ;
+};
+String STR_DragMethCrook
+{
+ Text [ en-US ] = "Arrange %1 in circle" ;
+};
+String STR_DragMethCrookContortion
+{
+ Text [ en-US ] = "Curve %1 in circle" ;
+};
+String STR_DragMethDistort
+{
+ Text [ en-US ] = "Distort %1" ;
+};
+String STR_DragMethCrop
+{
+ Text [ en-US ] = "Crop %O" ;
+};
+
+String STR_DragRectEckRad
+{
+ Text [ en-US ] = "Alter radius by %1" ;
+};
+String STR_DragPathObj
+{
+ Text [ en-US ] = "Change %1" ;
+};
+String STR_DragRectResize
+{
+ Text [ en-US ] = "Resize %1" ;
+};
+String STR_DragCaptFram
+{
+ Text [ en-US ] = "Move %1" ;
+};
+String STR_DragCaptTail
+{
+ Text [ en-US ] = "Move end point of %1" ;
+};
+String STR_DragCircAngle
+{
+ Text [ en-US ] = "Adjust angle by %1" ;
+};
+String STR_DragEdgeTail
+{
+ Text [ en-US ] = "Change %1" ;
+};
+String STR_ViewTextEdit
+{
+ Text [ en-US ] = "TextEdit: Paragraph %1, Row %2, Column %3" ;
+};
+String STR_ViewMarked
+{
+ Text [ en-US ] = "%1 selected" ;
+};
+String STR_ViewMarkedPoint
+{
+ Text [ en-US ] = "Point from %1" ;
+};
+String STR_ViewMarkedPoints
+{
+ Text [ en-US ] = "%2 points from %1" ;
+};
+String STR_ViewMarkedGluePoint
+{
+ Text [ en-US ] = "Glue point from %1" ;
+};
+String STR_ViewMarkedGluePoints
+{
+ Text [ en-US ] = "%2 glue points from %1" ;
+};
+String STR_ViewMarkObjs
+{
+ Text [ en-US ] = "Mark objects" ;
+};
+String STR_ViewMarkMoreObjs
+{
+ Text [ en-US ] = "Mark additional objects" ;
+};
+String STR_ViewMarkPoints
+{
+ Text [ en-US ] = "Mark points" ;
+};
+String STR_ViewMarkMorePoints
+{
+ Text [ en-US ] = "Mark additional points" ;
+};
+String STR_ViewMarkGluePoints
+{
+ Text [ en-US ] = "Mark glue points" ;
+};
+String STR_ViewMarkMoreGluePoints
+{
+ Text [ en-US ] = "Mark additional glue points" ;
+};
+String STR_ViewCreateObj
+{
+ Text [ en-US ] = "Create %1" ;
+};
+String STR_UndoInsertObj
+{
+ Text [ en-US ] = "Insert %1" ;
+};
+String STR_UndoCopyObj
+{
+ Text [ en-US ] = "Copy %1" ;
+};
+String STR_UndoObjOrdNum
+{
+ Text [ en-US ] = "Change object order of %1" ;
+};
+String STR_UndoObjSetText
+{
+ Text [ en-US ] = "Edit text of %1" ;
+};
+String STR_UndoNewPage
+{
+ Text [ en-US ] = "Insert page" ;
+};
+String STR_UndoDelPage
+{
+ Text [ en-US ] = "Delete page" ;
+};
+String STR_UndoCopPage
+{
+ Text [ en-US ] = "Copy page" ;
+};
+String STR_UndoMovPage
+{
+ Text [ en-US ] = "Change order of pages" ;
+};
+String STR_UndoNewPageMasterDscr
+{
+ Text [ en-US ] = "Assign background page" ;
+};
+String STR_UndoDelPageMasterDscr
+{
+ Text [ en-US ] = "Clear background page assignment" ;
+};
+String STR_UndoMovPageMasterDscr
+{
+ Text [ en-US ] = "Move background page assignment" ;
+};
+String STR_UndoChgPageMasterDscr
+{
+ Text [ en-US ] = "Change background page assignment" ;
+};
+String STR_UndoMergeModel
+{
+ Text [ en-US ] = "Insert document" ;
+};
+String STR_UndoNewLayer
+{
+ Text [ en-US ] = "Insert Layer" ;
+};
+String STR_UndoDelLayer
+{
+ Text [ en-US ] = "Delete layer" ;
+};
+String STR_UndoMovLayer
+{
+ Text [ en-US ] = "Change order of layers" ;
+};
+// --> OD 2009-07-09 #i73249#
+String STR_UndoObjName
+{
+ Text [ en-US ] = "Change object name of %1 to" ;
+};
+String STR_UndoObjTitle
+{
+ Text [ en-US ] = "Change object title of %1" ;
+};
+String STR_UndoObjDescription
+{
+ Text [ en-US ] = "Change object description of %1" ;
+};
+// <--
+String STR_StandardLayerName
+{
+ Text [ en-US ] = "Standard" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValON
+{
+ Text [ en-US ] = "on" ;
+};
+String STR_ItemValOFF
+{
+ Text [ en-US ] = "off" ;
+};
+String STR_ItemValYES
+{
+ Text [ en-US ] = "yes" ;
+};
+String STR_ItemValNO
+{
+ Text [ en-US ] = "No" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValCAPTIONTYPE1
+{
+ Text [ en-US ] = "Type 1" ;
+};
+String STR_ItemValCAPTIONTYPE2
+{
+ Text [ en-US ] = "Type 2" ;
+};
+String STR_ItemValCAPTIONTYPE3
+{
+ Text [ en-US ] = "Type 3" ;
+};
+String STR_ItemValCAPTIONTYPE4
+{
+ Text [ en-US ] = "Type 4" ;
+};
+String STR_ItemValCAPTIONESCHORI
+{
+ Text [ en-US ] = "Horizontal" ;
+};
+String STR_ItemValCAPTIONESCVERT
+{
+ Text [ en-US ] = "Vertical" ;
+};
+String STR_ItemValCAPTIONESCBESTFIT
+{
+ Text [ en-US ] = "Automatic" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValFITTOSIZENONE
+{
+ Text [ en-US ] = "Off" ;
+};
+String STR_ItemValFITTOSIZEPROP
+{
+ Text [ en-US ] = "Proportional" ;
+};
+String STR_ItemValFITTOSIZEALLLINES
+{
+ Text [ en-US ] = "Fit to size (all rows separately) " ;
+};
+String STR_ItemValFITTOSIZERESIZEAT
+{
+ Text [ en-US ] = "Use hard attributes" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValTEXTVADJTOP
+{
+ Text [ en-US ] = "Top" ;
+};
+String STR_ItemValTEXTVADJCENTER
+{
+ Text [ en-US ] = "Center" ;
+};
+String STR_ItemValTEXTVADJBOTTOM
+{
+ Text [ en-US ] = "Bottom" ;
+};
+String STR_ItemValTEXTVADJBLOCK
+{
+ Text [ en-US ] = "Use entire height" ;
+};
+String STR_ItemValTEXTVADJSTRETCH
+{
+ Text [ en-US ] = "Stretched" ;
+};
+String STR_ItemValTEXTHADJLEFT
+{
+ Text [ en-US ] = "Left" ;
+};
+String STR_ItemValTEXTHADJCENTER
+{
+ Text [ en-US ] = "Center" ;
+};
+String STR_ItemValTEXTHADJRIGHT
+{
+ Text [ en-US ] = "Right" ;
+};
+String STR_ItemValTEXTHADJBLOCK
+{
+ Text [ en-US ] = "Use entire width" ;
+};
+String STR_ItemValTEXTHADJSTRETCH
+{
+ Text [ en-US ] = "Stretched" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValTEXTANI_NONE
+{
+ Text [ en-US ] = "off" ;
+};
+String STR_ItemValTEXTANI_BLINK
+{
+ Text [ en-US ] = "flash" ;
+};
+String STR_ItemValTEXTANI_SCROLL
+{
+ Text [ en-US ] = "Scroll Through" ;
+};
+String STR_ItemValTEXTANI_ALTERNATE
+{
+ Text [ en-US ] = "alternating" ;
+};
+String STR_ItemValTEXTANI_SLIDE
+{
+ Text [ en-US ] = "Scroll In" ;
+};
+String STR_ItemValTEXTANI_LEFT
+{
+ Text [ en-US ] = "left" ;
+};
+String STR_ItemValTEXTANI_UP
+{
+ Text [ en-US ] = "up" ;
+};
+String STR_ItemValTEXTANI_RIGHT
+{
+ Text [ en-US ] = "right" ;
+};
+String STR_ItemValTEXTANI_DOWN
+{
+ Text [ en-US ] = "down" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValEDGE_ORTHOLINES
+{
+ Text [ en-US ] = "Standard Connector" ;
+};
+String STR_ItemValEDGE_THREELINES
+{
+ Text [ en-US ] = "Line Connector" ;
+};
+String STR_ItemValEDGE_ONELINE
+{
+ Text [ en-US ] = "Straight Connector" ;
+};
+String STR_ItemValEDGE_BEZIER
+{
+ Text [ en-US ] = "Curved Connector" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValMEASURE_STD
+{
+ Text [ en-US ] = "Standard" ;
+};
+String STR_ItemValMEASURE_RADIUS
+{
+ Text [ en-US ] = "Radius" ;
+};
+String STR_ItemValMEASURE_TEXTHAUTO
+{
+ Text [ en-US ] = "automatic" ;
+};
+String STR_ItemValMEASURE_TEXTLEFTOUTSIDE
+{
+ Text [ en-US ] = "left outside" ;
+};
+String STR_ItemValMEASURE_TEXTINSIDE
+{
+ Text [ en-US ] = "inside (centered)" ;
+};
+String STR_ItemValMEASURE_TEXTRIGHTOUTSID
+{
+ Text [ en-US ] = "right outside" ;
+};
+String STR_ItemValMEASURE_TEXTVAUTO
+{
+ Text [ en-US ] = "automatic" ;
+};
+String STR_ItemValMEASURE_ABOVE
+{
+ Text [ en-US ] = "on the line" ;
+};
+String STR_ItemValMEASURETEXT_BREAKEDLINE
+{
+ Text [ en-US ] = "broken line" ;
+};
+String STR_ItemValMEASURE_BELOW
+{
+ Text [ en-US ] = "below the line" ;
+};
+String STR_ItemValMEASURETEXT_VERTICALCEN
+{
+ Text [ en-US ] = "centered" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemValCIRC_FULL
+{
+ Text [ en-US ] = "full circle" ;
+};
+String STR_ItemValCIRC_SECT
+{
+ Text [ en-US ] = "Circle Pie" ;
+};
+String STR_ItemValCIRC_CUT
+{
+ Text [ en-US ] = "Circle segment" ;
+};
+String STR_ItemValCIRC_ARC
+{
+ Text [ en-US ] = "Arc" ;
+};
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+String STR_ItemNam_SHADOW
+{
+ Text [ en-US ] = "Shadow" ;
+};
+String STR_ItemNam_SHADOWCOLOR
+{
+ Text [ en-US ] = "Shadow color" ;
+};
+String STR_ItemNam_SHADOWXDIST
+{
+ Text [ en-US ] = "Horizontal shadow outline" ;
+};
+String STR_ItemNam_SHADOWYDIST
+{
+ Text [ en-US ] = "Vertical shadow outline" ;
+};
+String STR_ItemNam_SHADOWTRANSPARENCE
+{
+ Text [ en-US ] = "Shadow transparency" ;
+};
+String STR_ItemNam_SHADOW3D
+{
+ Text [ en-US ] = "3D shadow" ;
+};
+String STR_ItemNam_SHADOWPERSP
+{
+ Text [ en-US ] = "Perspective shadow" ;
+};
+String STR_ItemNam_CAPTIONTYPE
+{
+ Text [ en-US ] = "Callout type" ;
+};
+String STR_ItemNam_CAPTIONFIXEDANGLE
+{
+ Text [ en-US ] = "Given angle" ;
+};
+String STR_ItemNam_CAPTIONANGLE
+{
+ Text [ en-US ] = "Angle" ;
+};
+String STR_ItemNam_CAPTIONGAP
+{
+ Text [ en-US ] = "Gap" ;
+};
+String STR_ItemNam_CAPTIONESCDIR
+{
+ Text [ en-US ] = "Exit direction" ;
+};
+String STR_ItemNam_CAPTIONESCISREL
+{
+ Text [ en-US ] = "Relative exit position" ;
+};
+String STR_ItemNam_CAPTIONESCREL
+{
+ Text [ en-US ] = "Exit Position" ;
+};
+String STR_ItemNam_CAPTIONESCABS
+{
+ Text [ en-US ] = "Exit Position" ;
+};
+String STR_ItemNam_CAPTIONLINELEN
+{
+ Text [ en-US ] = "Line length" ;
+};
+String STR_ItemNam_CAPTIONFITLINELEN
+{
+ Text [ en-US ] = "Auto line length" ;
+};
+String STR_ItemNam_ECKENRADIUS
+{
+ Text [ en-US ] = "Corner radius" ;
+};
+String STR_ItemNam_TEXT_LEFTDIST
+{
+ Text [ en-US ] = "Left border spacing" ;
+};
+String STR_ItemNam_TEXT_RIGHTDIST
+{
+ Text [ en-US ] = "Right border spacing" ;
+};
+String STR_ItemNam_TEXT_UPPERDIST
+{
+ Text [ en-US ] = "Upper border spacing" ;
+};
+String STR_ItemNam_TEXT_LOWERDIST
+{
+ Text [ en-US ] = "Lower border spacing" ;
+};
+String STR_ItemNam_TEXT_AUTOGROWHEIGHT
+{
+ Text [ en-US ] = "AutoFit frame height" ;
+};
+String STR_ItemNam_TEXT_MINFRAMEHEIGHT
+{
+ Text [ en-US ] = "Min. frame height" ;
+};
+String STR_ItemNam_TEXT_MAXFRAMEHEIGHT
+{
+ Text [ en-US ] = "Max. frame height" ;
+};
+String STR_ItemNam_TEXT_AUTOGROWWIDTH
+{
+ Text [ en-US ] = "AutoFit frame width" ;
+};
+String STR_ItemNam_TEXT_MINFRAMEWIDTH
+{
+ Text [ en-US ] = "Min. frame width" ;
+};
+String STR_ItemNam_TEXT_MAXFRAMEWIDTH
+{
+ Text [ en-US ] = "Max. frame width" ;
+};
+String STR_ItemNam_TEXT_VERTADJUST
+{
+ Text [ en-US ] = "Vertical text anchor" ;
+};
+String STR_ItemNam_TEXT_HORZADJUST
+{
+ Text [ en-US ] = "Horizontal text anchor" ;
+};
+String STR_ItemNam_TEXT_FITTOSIZE
+{
+ Text [ en-US ] = "Fit text to frame" ;
+};
+
+String STR_ItemNam_GRAFRED
+{
+ Text [ en-US ] = "Red";
+};
+String STR_ItemNam_GRAFGREEN
+{
+ Text [ en-US ] = "Green";
+};
+String STR_ItemNam_GRAFBLUE
+{
+ Text [ en-US ] = "Blue";
+};
+String STR_ItemNam_GRAFLUMINANCE
+{
+ Text [ en-US ] = "Brightness";
+};
+String STR_ItemNam_GRAFCONTRAST
+{
+ Text [ en-US ] = "Contrast";
+};
+String STR_ItemNam_GRAFGAMMA
+{
+ Text [ en-US ] = "Gamma";
+};
+String STR_ItemNam_GRAFTRANSPARENCE
+{
+ Text [ en-US ] = "Transparency";
+};
+String STR_ItemNam_GRAFINVERT
+{
+ Text [ en-US ] = "Invert";
+};
+String STR_ItemNam_GRAFMODE
+{
+ Text [ en-US ] = "Graphics mode";
+};
+String STR_ItemNam_GRAFRESERVE2 { Text = "" ; };
+String STR_ItemNam_GRAFRESERVE3 { Text = "" ; };
+String STR_ItemNam_GRAFRESERVE4 { Text = "" ; };
+String STR_ItemNam_GRAFRESERVE5 { Text = "" ; };
+String STR_ItemNam_GRAFRESERVE6 { Text = "" ; };
+
+String STR_ItemNam_RESERVE19 { Text = "" ; };
+String STR_ItemNamSET_MISC
+{
+ Text [ en-US ] = "Various attributes" ;
+};
+String STR_ItemNam_OBJMOVEPROTECT
+{
+ Text [ en-US ] = "Position protected" ;
+};
+String STR_ItemNam_OBJSIZEPROTECT
+{
+ Text [ en-US ] = "Size Protection" ;
+};
+String STR_ItemNam_OBJPRINTABLE
+{
+ Text [ en-US ] = "Don't print" ;
+};
+String STR_ItemNam_LAYERID
+{
+ Text [ en-US ] = "Layer Indicator" ;
+};
+String STR_ItemNam_LAYERNAME
+{
+ Text [ en-US ] = "Le~vel" ;
+};
+String STR_ItemNam_OBJECTNAME
+{
+ Text [ en-US ] = "Object name" ;
+};
+String STR_ItemNam_STARTANGLE
+{
+ Text [ en-US ] = "Start angle" ;
+};
+String STR_ItemNam_ENDANGLE
+{
+ Text [ en-US ] = "Final angle" ;
+};
+String STR_ItemNam_POSITIONX
+{
+ Text [ en-US ] = "X Position" ;
+};
+String STR_ItemNam_POSITIONY
+{
+ Text [ en-US ] = "Y Position" ;
+};
+String STR_ItemNam_SIZEWIDTH
+{
+ Text [ en-US ] = "Width" ;
+};
+String STR_ItemNam_SIZEHEIGHT
+{
+ Text [ en-US ] = "Height" ;
+};
+String STR_ItemNam_ROTATEANGLE
+{
+ Text [ en-US ] = "Rotation angle" ;
+};
+String STR_ItemNam_SHEARANGLE
+{
+ Text [ en-US ] = "Shear angle" ;
+};
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Ende der gecachten Strings
+
+ // und hier noch Bitmaps
+Bitmap BMAP_GrafikEi { File = "grafikei.bmp" ; };
+Bitmap BMAP_GrafikDe { File = "grafikde.bmp" ; };
+
+// Strings fuer den Vorlagen-Dialog
+String SIP_UNKNOWN_ATTR
+{
+ Text [ en-US ] = "Unknown attribute";
+};
+
+// Strings fuer den Vorlagen-Dialog
+String SIP_XA_LINESTYLE
+{
+ Text [ en-US ] = "Line style";
+};
+
+String SIP_XA_LINEDASH
+{
+ Text [ en-US ] = "Line pattern";
+};
+
+String SIP_XA_LINEWIDTH
+{
+ Text [ en-US ] = "Line width";
+};
+
+String SIP_XA_LINECOLOR
+{
+ Text [ en-US ] = "Line color";
+};
+
+String SIP_XA_LINESTART
+{
+ Text [ en-US ] = "Line head";
+};
+
+String SIP_XA_LINEEND
+{
+ Text [ en-US ] = "Line end";
+};
+
+String SIP_XA_LINESTARTWIDTH
+{
+ Text [ en-US ] = "Line head width";
+};
+
+String SIP_XA_LINEENDWIDTH
+{
+ Text [ en-US ] = "Line end width";
+};
+
+String SIP_XA_LINESTARTCENTER
+{
+ Text [ en-US ] = "Center arrowhead";
+};
+
+String SIP_XA_LINEENDCENTER
+{
+ Text [ en-US ] = "Center arrowend";
+};
+
+String SIP_XA_LINETRANSPARENCE
+{
+ Text [ en-US ] = "Line transparency";
+};
+
+String SIP_XA_LINEJOINT
+{
+ Text [ en-US ] = "Line joint";
+};
+
+String SIP_XA_LINERESERVED2
+{
+ Text [ en-US ] = "Line reserved for 2";
+};
+
+String SIP_XA_LINERESERVED3
+{
+ Text [ en-US ] = "Line reserved for 3";
+};
+
+String SIP_XA_LINERESERVED4
+{
+ Text [ en-US ] = "Line reserved for 4";
+};
+
+String SIP_XA_LINERESERVED5
+{
+ Text [ en-US ] = "Line reserved for 5";
+};
+
+String SIP_XA_LINERESERVED_LAST
+{
+ Text [ en-US ] = "Line reserved for 6";
+};
+
+String SIP_XATTRSET_LINE
+{
+ Text [ en-US ] = "Line attributes";
+};
+
+String SIP_XA_FILLSTYLE
+{
+ Text [ en-US ] = "Fill style";
+};
+
+String SIP_XA_FILLCOLOR
+{
+ Text [ en-US ] = "Fillcolor";
+};
+
+String SIP_XA_FILLGRADIENT
+{
+ Text [ en-US ] = "Gradient";
+};
+
+String SIP_XA_FILLHATCH
+{
+ Text [ en-US ] = "Hatching";
+};
+
+String SIP_XA_FILLBITMAP
+{
+ Text [ en-US ] = "Fillbitmap";
+};
+
+String SIP_XA_FILLTRANSPARENCE
+{
+ Text [ en-US ] = "Transparency";
+};
+
+String SIP_XA_GRADIENTSTEPCOUNT
+{
+ Text [ en-US ] = "Number of gradient steps";
+};
+
+String SIP_XA_FILLBMP_TILE
+{
+ Text [ en-US ] = "Tile fill";
+};
+
+String SIP_XA_FILLBMP_POS
+{
+ Text [ en-US ] = "Fillbitmap position";
+};
+
+String SIP_XA_FILLBMP_SIZEX
+{
+ Text [ en-US ] = "Fillbitmap width";
+};
+
+String SIP_XA_FILLBMP_SIZEY
+{
+ Text [ en-US ] = "Height of fillbitmap";
+};
+
+String SIP_XA_FILLFLOATTRANSPARENCE
+{
+ Text [ en-US ] = "Transparent gradient";
+};
+
+String SIP_XA_SECONDARYFILLCOLOR
+{
+ Text [ en-US ] = "Fill reserved for 2";
+};
+
+String SIP_XA_FILLBMP_SIZELOG
+{
+ Text [ en-US ] = "Tile size not in %";
+};
+
+String SIP_XA_FILLBMP_TILEOFFSETX
+{
+ Text [ en-US ] = "Tile offset X in %";
+};
+
+String SIP_XA_FILLBMP_TILEOFFSETY
+{
+ Text [ en-US ] = "Tile offset Y in %";
+};
+
+String SIP_XA_FILLBMP_STRETCH
+{
+ Text [ en-US ] = "Bitmap scaling";
+};
+
+String SIP_XA_FILLRESERVED3
+{
+ Text [ en-US ] = "Bitmap reserved for 3";
+};
+
+String SIP_XA_FILLRESERVED4
+{
+ Text [ en-US ] = "Bitmap reserved for 4";
+};
+
+String SIP_XA_FILLRESERVED5
+{
+ Text [ en-US ] = "Bitmap reserved for 5";
+};
+
+String SIP_XA_FILLRESERVED6
+{
+ Text [ en-US ] = "Bitmap reserved for 6";
+};
+
+String SIP_XA_FILLRESERVED7
+{
+ Text [ en-US ] = "Bitmap reserved for 7";
+};
+
+String SIP_XA_FILLRESERVED8
+{
+ Text [ en-US ] = "Bitmap reserved for 8";
+};
+
+String SIP_XA_FILLBMP_POSOFFSETX
+{
+ Text [ en-US ] = "Tile position X in %";
+};
+
+String SIP_XA_FILLBMP_POSOFFSETY
+{
+ Text [ en-US ] = "Tile position Y in %";
+};
+
+String SIP_XA_FILLBACKGROUND
+{
+ Text [ en-US ] = "Background fill";
+};
+
+String SIP_XA_FILLRESERVED10
+{
+ Text [ en-US ] = "Fill reserved for 10";
+};
+
+String SIP_XA_FILLRESERVED11
+{
+ Text [ en-US ] = "Fill reserved for 11";
+};
+
+String SIP_XA_FILLRESERVED_LAST
+{
+ Text [ en-US ] = "Fill reserved for 12";
+};
+
+String SIP_XATTRSET_FILL
+{
+ Text [ en-US ] = "Area attributes";
+};
+
+String SIP_XA_FORMTXTSTYLE
+{
+ Text [ en-US ] = "Fontwork style";
+};
+
+String SIP_XA_FORMTXTADJUST
+{
+ Text [ en-US ] = "Fontwork alignment";
+};
+
+String SIP_XA_FORMTXTDISTANCE
+{
+ Text [ en-US ] = "Fontwork spacing";
+};
+
+String SIP_XA_FORMTXTSTART
+{
+ Text [ en-US ] = "Fontwork font begin";
+};
+
+String SIP_XA_FORMTXTMIRROR
+{
+ Text [ en-US ] = "Fontwork mirror";
+};
+
+String SIP_XA_FORMTXTOUTLINE
+{
+ Text [ en-US ] = "Fontwork outline";
+};
+
+String SIP_XA_FORMTXTSHADOW
+{
+ Text [ en-US ] = "Fontwork shadow";
+};
+
+String SIP_XA_FORMTXTSHDWCOLOR
+{
+ Text [ en-US ] = "Fontwork shadow color";
+};
+
+String SIP_XA_FORMTXTSHDWXVAL
+{
+ Text [ en-US ] = "Fontwork shadow offset X";
+};
+
+String SIP_XA_FORMTXTSHDWYVAL
+{
+ Text [ en-US ] = "Fontwork shadow offset Y";
+};
+
+String SIP_XA_FORMTXTSTDFORM
+{
+ Text [ en-US ] = "Fontwork default form";
+};
+
+String SIP_XA_FORMTXTHIDEFORM
+{
+ Text [ en-US ] = "Hide fontwork outline";
+};
+
+String SIP_XA_FORMTXTSHDWTRANSP
+{
+ Text [ en-US ] = "Fontwork shadow transparency";
+};
+
+String SIP_XA_FTRESERVED2
+{
+ Text [ en-US ] = "Fontwork reserved for 2";
+};
+
+String SIP_XA_FTRESERVED3
+{
+ Text [ en-US ] = "Fontwork reserved for 3";
+};
+
+String SIP_XA_FTRESERVED4
+{
+ Text [ en-US ] = "Fontwork reserved for 4";
+};
+
+String SIP_XA_FTRESERVED5
+{
+ Text [ en-US ] = "Fontwork reserved for 5";
+};
+
+String SIP_XA_FTRESERVED_LAST
+{
+ Text [ en-US ] = "Fontwork reserved for 6";
+};
+
+String SIP_SA_SHADOW
+{
+ Text [ en-US ] = "Shadow";
+};
+
+String SIP_SA_SHADOWCOLOR
+{
+ Text [ en-US ] = "Shadow color";
+};
+
+String SIP_SA_SHADOWXDIST
+{
+ Text [ en-US ] = "Shadow spacing X";
+};
+
+String SIP_SA_SHADOWYDIST
+{
+ Text [ en-US ] = "Shadow spacing Y";
+};
+
+String SIP_SA_SHADOWTRANSPARENCE
+{
+ Text [ en-US ] = "Shadow transparency";
+};
+
+String SIP_SA_SHADOW3D
+{
+ Text [ en-US ] = "3D shadow";
+};
+
+String SIP_SA_SHADOWPERSP
+{
+ Text [ en-US ] = "Perspective shadow";
+};
+
+String SIP_SA_CAPTIONTYPE
+{
+ Text [ en-US ] = "Type of legend";
+};
+
+String SIP_SA_CAPTIONFIXEDANGLE
+{
+ Text [ en-US ] = "Fixed legend angle";
+};
+
+String SIP_SA_CAPTIONANGLE
+{
+ Text [ en-US ] = "Legend angle";
+};
+
+String SIP_SA_CAPTIONGAP
+{
+ Text [ en-US ] = "Legend lines spacing";
+};
+
+String SIP_SA_CAPTIONESCDIR
+{
+ Text [ en-US ] = "Legend exit alignment";
+};
+
+String SIP_SA_CAPTIONESCISREL
+{
+ Text [ en-US ] = "Relative exit legend";
+};
+
+String SIP_SA_CAPTIONESCREL
+{
+ Text [ en-US ] = "Relative exit legend";
+};
+
+String SIP_SA_CAPTIONESCABS
+{
+ Text [ en-US ] = "Absolute exit of legend";
+};
+
+String SIP_SA_CAPTIONLINELEN
+{
+ Text [ en-US ] = "Legend line length";
+};
+
+String SIP_SA_CAPTIONFITLINELEN
+{
+ Text [ en-US ] = "AutoLength of legend lines";
+};
+
+String SIP_SA_ECKENRADIUS
+{
+ Text [ en-US ] = "Corner radius";
+};
+
+String SIP_SA_TEXT_MINFRAMEHEIGHT
+{
+ Text [ en-US ] = "Minimal frame height";
+};
+
+String SIP_SA_TEXT_AUTOGROWHEIGHT
+{
+ Text [ en-US ] = "AutoFit height";
+};
+
+String SIP_SA_TEXT_FITTOSIZE
+{
+ Text [ en-US ] = "Fit text to frame";
+};
+
+String SIP_SA_TEXT_LEFTDIST
+{
+ Text [ en-US ] = "Left text frame spacing";
+};
+
+String SIP_SA_TEXT_RIGHTDIST
+{
+ Text [ en-US ] = "Right text frame spacing";
+};
+
+String SIP_SA_TEXT_UPPERDIST
+{
+ Text [ en-US ] = "Upper text frame spacing";
+};
+
+String SIP_SA_TEXT_LOWERDIST
+{
+ Text [ en-US ] = "Lower text frame spacing";
+};
+
+String SIP_SA_TEXT_VERTADJUST
+{
+ Text [ en-US ] = "Vertical text anchor";
+};
+
+String SIP_SA_TEXT_MAXFRAMEHEIGHT
+{
+ Text [ en-US ] = "Maximal frame height";
+};
+
+String SIP_SA_TEXT_MINFRAMEWIDTH
+{
+ Text [ en-US ] = "Minimal frame width";
+};
+
+String SIP_SA_TEXT_MAXFRAMEWIDTH
+{
+ Text [ en-US ] = "Maximal frame width";
+};
+
+String SIP_SA_TEXT_AUTOGROWWIDTH
+{
+ Text [ en-US ] = "AutoFit width";
+};
+
+String SIP_SA_TEXT_HORZADJUST
+{
+ Text [ en-US ] = "Horizontal text anchor";
+};
+
+String SIP_SA_TEXT_ANIKIND
+{
+ Text [ en-US ] = "Ticker";
+};
+
+String SIP_SA_TEXT_ANIDIRECTION
+{
+ Text [ en-US ] = "Ticker direction";
+};
+
+String SIP_SA_TEXT_ANISTARTINSIDE
+{
+ Text [ en-US ] = "Ticker start inside";
+};
+
+String SIP_SA_TEXT_ANISTOPINSIDE
+{
+ Text [ en-US ] = "Ticker stop inside";
+};
+
+String SIP_SA_TEXT_ANICOUNT
+{
+ Text [ en-US ] = "Number of ticker runs";
+};
+
+String SIP_SA_TEXT_ANIDELAY
+{
+ Text [ en-US ] = "Speed of ticker";
+};
+
+String SIP_SA_TEXT_ANIAMOUNT
+{
+ Text [ en-US ] = "Ticker step size";
+};
+
+String SIP_SA_TEXT_CONTOURFRAME
+{
+ Text [ en-US ] = "Outline text flow";
+};
+
+String SIP_SA_CUSTOMSHAPE_ADJUSTMENT
+{
+ Text[ en-US ] = "Shape Adjustment";
+};
+
+String SIP_SA_XMLATTRIBUTES
+{
+ Text [ en-US ] = "User-defined attributes";
+};
+
+String SIP_SA_TEXT_USEFIXEDCELLHEIGHT
+{
+ Text [ en-US ] = "Use font-independent line spacing";
+};
+
+String SIP_SA_WORDWRAP
+{
+ Text[ en-US ] = "Word wrap text in shape";
+};
+
+String SIP_SA_AUTOGROWSIZE
+{
+ Text[ en-US ] = "Auto grow shape to fit text";
+};
+
+String SIP_SA_RESERVE18
+{
+ Text [ en-US ] = "SvDraw reserved for 18";
+};
+
+String SIP_SA_RESERVE19
+{
+ Text [ en-US ] = "SvDraw reserved for 19";
+};
+
+String SIP_SA_EDGEKIND
+{
+ Text [ en-US ] = "Type of connector";
+};
+
+String SIP_SA_EDGENODE1HORZDIST
+{
+ Text [ en-US ] = "Horz. spacing object 1";
+};
+
+String SIP_SA_EDGENODE1VERTDIST
+{
+ Text [ en-US ] = "Vert. spacing object 1";
+};
+
+String SIP_SA_EDGENODE2HORZDIST
+{
+ Text [ en-US ] = "Horz. spacing object 2";
+};
+
+String SIP_SA_EDGENODE2VERTDIST
+{
+ Text [ en-US ] = "Vert. spacing object 2";
+};
+
+String SIP_SA_EDGENODE1GLUEDIST
+{
+ Text [ en-US ] = "Glue spacing object 1";
+};
+
+String SIP_SA_EDGENODE2GLUEDIST
+{
+ Text [ en-US ] = "Glue spacing object 2";
+};
+
+String SIP_SA_EDGELINEDELTAANZ
+{
+ Text [ en-US ] = "Number of movable lines";
+};
+
+String SIP_SA_EDGELINE1DELTA
+{
+ Text [ en-US ] = "Offset line 1";
+};
+
+String SIP_SA_EDGELINE2DELTA
+{
+ Text [ en-US ] = "Offset line 2";
+};
+
+String SIP_SA_EDGELINE3DELTA
+{
+ Text [ en-US ] = "Offset line 3";
+};
+
+String SIP_SA_MEASUREKIND
+{
+ Text [ en-US ] = "Type of dimensioning";
+};
+
+String SIP_SA_MEASURETEXTHPOS
+{
+ Text [ en-US ] = "Dimension value - horizontal position";
+};
+
+String SIP_SA_MEASURETEXTVPOS
+{
+ Text [ en-US ] = "Dimension value - vertical position";
+};
+
+String SIP_SA_MEASURELINEDIST
+{
+ Text [ en-US ] = "Dimension line space";
+};
+
+String SIP_SA_MEASUREHELPLINEOVERHANG
+{
+ Text [ en-US ] = "Dimension help line overhang";
+};
+
+String SIP_SA_MEASUREHELPLINEDIST
+{
+ Text [ en-US ] = "Dimension help line spacing";
+};
+
+String SIP_SA_MEASUREHELPLINE1LEN
+{
+ Text [ en-US ] = "Backlog of dimension help line 1";
+};
+
+String SIP_SA_MEASUREHELPLINE2LEN
+{
+ Text [ en-US ] = "Backlog of dimension help line 2";
+};
+
+String SIP_SA_MEASUREBELOWREFEDGE
+{
+ Text [ en-US ] = "Lower edge dimensioning";
+};
+
+String SIP_SA_MEASURETEXTROTA90
+{
+ Text [ en-US ] = "Dimension value across dimension line";
+};
+
+String SIP_SA_MEASURETEXTUPSIDEDOWN
+{
+ Text [ en-US ] = "Rotate dimension value by 180 degree";
+};
+
+String SIP_SA_MEASUREOVERHANG
+{
+ Text [ en-US ] = "Dimension line overhang";
+};
+
+String SIP_SA_MEASUREUNIT
+{
+ Text [ en-US ] = "Measure unit";
+};
+
+String SIP_SA_MEASURESCALE
+{
+ Text [ en-US ] = "Additional scale factor";
+};
+
+String SIP_SA_MEASURESHOWUNIT
+{
+ Text [ en-US ] = "Measure unit display";
+};
+
+String SIP_SA_MEASUREFORMATSTRING
+{
+ Text [ en-US ] = "Dimension value format";
+};
+
+String SIP_SA_MEASURETEXTAUTOANGLE
+{
+ Text [ en-US ] = "AutoPositioning of the dimension value";
+};
+
+String SIP_SA_MEASURETEXTAUTOANGLEVIEW
+{
+ Text [ en-US ] = "Angle for the automatic positioning of the dimension value";
+};
+
+String SIP_SA_MEASURETEXTISFIXEDANGLE
+{
+ Text [ en-US ] = "Determination of the dimension value angle";
+};
+
+String SIP_SA_MEASURETEXTFIXEDANGLE
+{
+ Text [ en-US ] = "Angle of the dimension value";
+};
+
+String SIP_SA_MEASUREDECIMALPLACES
+{
+ Text [ en-US ] = "Decimal places";
+};
+
+String SIP_SA_MEASURERESERVE05
+{
+ Text [ en-US ] = "Dimensioning reserved 5";
+};
+
+String SIP_SA_MEASURERESERVE06
+{
+ Text [ en-US ] = "Dimensioning reserved for 6";
+};
+
+String SIP_SA_MEASURERESERVE07
+{
+ Text [ en-US ] = "Dimensioning reserved for 7";
+};
+
+String SIP_SA_CIRCKIND
+{
+ Text [ en-US ] = "Type of circle";
+};
+
+String SIP_SA_CIRCSTARTANGLE
+{
+ Text [ en-US ] = "Start angle";
+};
+
+String SIP_SA_CIRCENDANGLE
+{
+ Text [ en-US ] = "End angle";
+};
+
+String SIP_SA_CIRCRESERVE0
+{
+ Text [ en-US ] = "Circle reserved for 0";
+};
+
+String SIP_SA_CIRCRESERVE1
+{
+ Text [ en-US ] = "Circle reserved for 1";
+};
+
+String SIP_SA_CIRCRESERVE2
+{
+ Text [ en-US ] = "Circle reserved for 2";
+};
+
+String SIP_SA_CIRCRESERVE3
+{
+ Text [ en-US ] = "Circle reserved for 3";
+};
+
+String SIP_SA_OBJMOVEPROTECT
+{
+ Text [ en-US ] = "Protected object position";
+};
+
+String SIP_SA_OBJSIZEPROTECT
+{
+ Text [ en-US ] = "Protected object size";
+};
+
+String SIP_SA_OBJPRINTABLE
+{
+ Text [ en-US ] = "Object, printable";
+};
+
+String SIP_SA_OBJVISIBLE
+{
+ Text [ en-US ] = "Object, visible";
+};
+
+String SIP_SA_LAYERID
+{
+ Text [ en-US ] = "Level ID";
+};
+
+String SIP_SA_LAYERNAME
+{
+ Text [ en-US ] = "Layer";
+};
+
+String SIP_SA_OBJECTNAME
+{
+ Text [ en-US ] = "Object name";
+};
+
+String SIP_SA_ALLPOSITIONX
+{
+ Text [ en-US ] = "Position X, complete";
+};
+
+String SIP_SA_ALLPOSITIONY
+{
+ Text [ en-US ] = "Position Y, complete";
+};
+
+String SIP_SA_ALLSIZEWIDTH
+{
+ Text [ en-US ] = "Total Width";
+};
+
+String SIP_SA_ALLSIZEHEIGHT
+{
+ Text [ en-US ] = "Height, complete";
+};
+
+String SIP_SA_ONEPOSITIONX
+{
+ Text [ en-US ] = "Single position X";
+};
+
+String SIP_SA_ONEPOSITIONY
+{
+ Text [ en-US ] = "Single position Y";
+};
+
+String SIP_SA_ONESIZEWIDTH
+{
+ Text [ en-US ] = "Single width";
+};
+
+String SIP_SA_ONESIZEHEIGHT
+{
+ Text [ en-US ] = "Single height";
+};
+
+String SIP_SA_LOGICSIZEWIDTH
+{
+ Text [ en-US ] = "Logical width";
+};
+
+String SIP_SA_LOGICSIZEHEIGHT
+{
+ Text [ en-US ] = "Logical height";
+};
+
+String SIP_SA_ROTATEANGLE
+{
+ Text [ en-US ] = "Single rotation angle";
+};
+
+String SIP_SA_SHEARANGLE
+{
+ Text [ en-US ] = "Single shear angle";
+};
+
+String SIP_SA_MOVEX
+{
+ Text [ en-US ] = "Move horizontally";
+};
+
+String SIP_SA_MOVEY
+{
+ Text [ en-US ] = "Move vertically";
+};
+
+String SIP_SA_RESIZEXONE
+{
+ Text [ en-US ] = "Resize X, single";
+};
+
+String SIP_SA_RESIZEYONE
+{
+ Text [ en-US ] = "Resize Y, single";
+};
+
+String SIP_SA_ROTATEONE
+{
+ Text [ en-US ] = "Single rotation";
+};
+
+String SIP_SA_HORZSHEARONE
+{
+ Text [ en-US ] = "Single horizontal shear";
+};
+
+String SIP_SA_VERTSHEARONE
+{
+ Text [ en-US ] = "Single vertical shear";
+};
+
+String SIP_SA_RESIZEXALL
+{
+ Text [ en-US ] = "Resize X, complete";
+};
+
+String SIP_SA_RESIZEYALL
+{
+ Text [ en-US ] = "Resize Y, complete";
+};
+
+String SIP_SA_ROTATEALL
+{
+ Text [ en-US ] = "Rotate all";
+};
+
+String SIP_SA_HORZSHEARALL
+{
+ Text [ en-US ] = "Shear horizontal, complete";
+};
+
+String SIP_SA_VERTSHEARALL
+{
+ Text [ en-US ] = "Shear vertical, complete";
+};
+
+String SIP_SA_TRANSFORMREF1X
+{
+ Text [ en-US ] = "Reference point 1 X";
+};
+
+String SIP_SA_TRANSFORMREF1Y
+{
+ Text [ en-US ] = "Reference point 1 Y";
+};
+
+String SIP_SA_TRANSFORMREF2X
+{
+ Text [ en-US ] = "Reference point 2 X";
+};
+
+String SIP_SA_TRANSFORMREF2Y
+{
+ Text [ en-US ] = "Reference point 2 Y";
+};
+
+String SIP_EE_PARA_HYPHENATE
+{
+ Text [ en-US ] = "Hyphenation";
+};
+
+String SIP_EE_PARA_BULLETSTATE
+{
+ Text [ en-US ] = "Display bullets";
+};
+
+String SIP_EE_PARA_OUTLLRSPACE
+{
+ Text [ en-US ] = "Numbering indents";
+};
+
+String SIP_EE_PARA_OUTLLEVEL
+{
+ Text [ en-US ] = "Numbering level";
+};
+
+String SIP_EE_PARA_BULLET
+{
+ Text [ en-US ] = "Bullets and Numberings";
+};
+
+String SIP_EE_PARA_LRSPACE
+{
+ Text [ en-US ] = "Indents";
+};
+
+String SIP_EE_PARA_ULSPACE
+{
+ Text [ en-US ] = "Paragraph spacing";
+};
+
+String SIP_EE_PARA_SBL
+{
+ Text [ en-US ] = "Line spacing";
+};
+
+String SIP_EE_PARA_JUST
+{
+ Text [ en-US ] = "Paragraph alignment";
+};
+
+String SIP_EE_PARA_TABS
+{
+ Text [ en-US ] = "Tabulators";
+};
+
+String SIP_EE_CHAR_COLOR
+{
+ Text [ en-US ] = "Font color";
+};
+
+String SIP_EE_CHAR_FONTINFO
+{
+ Text [ en-US ] = "Character set";
+};
+
+String SIP_EE_CHAR_FONTHEIGHT
+{
+ Text [ en-US ] = "Font size";
+};
+
+String SIP_EE_CHAR_FONTWIDTH
+{
+ Text [ en-US ] = "Font width";
+};
+
+String SIP_EE_CHAR_WEIGHT
+{
+ Text [ en-US ] = "Bold (thickness)";
+};
+
+String SIP_EE_CHAR_UNDERLINE
+{
+ Text [ en-US ] = "Underline";
+};
+
+String SIP_EE_CHAR_OVERLINE
+{
+ Text [ en-US ] = "Overline";
+};
+
+String SIP_EE_CHAR_STRIKEOUT
+{
+ Text [ en-US ] = "Strikethrough";
+};
+
+String SIP_EE_CHAR_ITALIC
+{
+ Text [ en-US ] = "Italic";
+};
+
+String SIP_EE_CHAR_OUTLINE
+{
+ Text [ en-US ] = "Outline";
+};
+
+String SIP_EE_CHAR_SHADOW
+{
+ Text [ en-US ] = "Font shadow";
+};
+
+String SIP_EE_CHAR_ESCAPEMENT
+{
+ Text [ en-US ] = "Superscript/subscript";
+};
+
+String SIP_EE_CHAR_PAIRKERNING
+{
+ Text [ en-US ] = "Kerning";
+};
+
+String SIP_EE_CHAR_KERNING
+{
+ Text [ en-US ] = "Manual kerning";
+};
+
+String SIP_EE_CHAR_WLM
+{
+ Text [ en-US ] = "No underline for spaces";
+};
+
+String SIP_EE_FEATURE_TAB
+{
+ Text [ en-US ] = "Tabulator";
+};
+
+String SIP_EE_FEATURE_LINEBR
+{
+ Text [ en-US ] = "Optional line break";
+};
+
+String SIP_EE_FEATURE_NOTCONV
+{
+ Text [ en-US ] = "Non-convertible character";
+};
+
+String SIP_EE_FEATURE_FIELD
+{
+ Text [ en-US ] = "Fields";
+};
+
+String SIP_SA_GRAFRED
+{
+ Text [ en-US ] = "Red";
+};
+String SIP_SA_GRAFGREEN
+{
+ Text [ en-US ] = "Green";
+};
+String SIP_SA_GRAFBLUE
+{
+ Text [ en-US ] = "Blue";
+};
+String SIP_SA_GRAFLUMINANCE
+{
+ Text [ en-US ] = "Brightness";
+};
+String SIP_SA_GRAFCONTRAST
+{
+ Text [ en-US ] = "Contrast";
+};
+String SIP_SA_GRAFGAMMA
+{
+ Text [ en-US ] = "Gamma";
+};
+String SIP_SA_GRAFTRANSPARENCE
+{
+ Text [ en-US ] = "Transparency";
+};
+String SIP_SA_GRAFINVERT
+{
+ Text [ en-US ] = "Invert";
+};
+String SIP_SA_GRAFMODE
+{
+ Text [ en-US ] = "Graphics mode";
+};
+String SIP_SA_GRAFCROP
+{
+ Text [ en-US ] = "Crop";
+
+};
+String SIP_SA_GRAFRESERVE3 { Text = "" ; };
+String SIP_SA_GRAFRESERVE4 { Text = "" ; };
+String SIP_SA_GRAFRESERVE5 { Text = "" ; };
+String SIP_SA_GRAFRESERVE6 { Text = "" ; };
+
+Bitmap SIP_SA_MARKERS
+{
+ File = "markers.bmp";
+};
+
+Bitmap SIP_SA_FINE_MARKERS
+{
+ File = "markers2.bmp";
+};
+
+// #100499#
+Bitmap BMP_SVXOLEOBJ
+{
+ File = "oleobj.bmp" ;
+};
+
+// #101928#
+Bitmap SIP_SA_ACCESSIBILITY_MARKERS
+{
+ File = "markersACC.bmp";
+};
+
+String STR_ObjNameSingulMEDIA
+{
+ Text [ en-US ] = "Media object" ;
+};
+String STR_ObjNamePluralMEDIA
+{
+ Text [ en-US ] = "Media objects" ;
+};
+
+// drawing layer table strings
+
+String STR_TABLE_ATTR
+{
+ Text [ en-US ] = "Apply table attributes" ;
+};
+String STR_TABLE_AUTOFMT
+{
+ Text [ en-US ] = "AutoFormat table" ;
+};
+String STR_TABLE_INSCOL
+{
+ Text [ en-US ] = "Insert column" ;
+};
+String STR_TABLE_INSROW
+{
+ Text [ en-US ] = "Insert row" ;
+};
+String STR_UNDO_COL_DELETE
+{
+ Text [ en-US ] = "Delete column" ;
+};
+String STR_UNDO_ROW_DELETE
+{
+ Text [ en-US ] = "Delete row" ;
+};
+String STR_TABLE_SPLIT
+{
+ Text [ en-US ] = "Split cells" ;
+};
+String STR_TABLE_MERGE
+{
+ Text [ en-US ] = "Merge cells" ;
+};
+String STR_TABLE_NUMFORMAT
+{
+ Text [ en-US ] = "Format cell" ;
+};
+
+String STR_TABLE_DISTRIBUTE_ROWS
+{
+ Text [ en-US ] = "Distribute rows" ;
+};
+
+String STR_TABLE_DISTRIBUTE_COLUMNS
+{
+ Text [ en-US ] = "Distribute columns" ;
+};
+
+String STR_TABLE_STYLE
+{
+ Text [ en-US ] = "Table style" ;
+};
+
+String STR_TABLE_STYLE_SETTINGS
+{
+ Text [ en-US ] = "Table style settings" ;
+};
+
+String STR_ObjNameSingulTable
+{
+ Text [ en-US ] = "Table";
+};
+String STR_ObjNamePluralTable
+{
+ Text [ en-US ] = "Tables";
+};
+
+Bitmap SIP_SA_CROP_MARKERS
+{
+ File = "cropmarkers.bmp";
+};
+
+Bitmap SIP_SA_CROP_FINE_MARKERS
+{
+ File = "cropmarkers2.bmp";
+};
+
+Bitmap SIP_SA_ACCESSIBILITY_CROP_MARKERS
+{
+ File = "cropmarkersACC.bmp";
+};
+
+// ******************************************************************* EOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/svx/source/svdraw/svdtext.cxx b/svx/source/svdraw/svdtext.cxx
new file mode 100644
index 000000000000..29018b6084ea
--- /dev/null
+++ b/svx/source/svdraw/svdtext.cxx
@@ -0,0 +1,224 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#define ITEMID_FONTHEIGHT EE_CHAR_FONTHEIGHT
+
+#include "svx/svdotext.hxx"
+#include "svx/svdetc.hxx"
+#include "editeng/outlobj.hxx"
+#include "svx/svdoutl.hxx"
+#include "svx/svdmodel.hxx"
+#include "editeng/fhgtitem.hxx"
+#include <editeng/eeitem.hxx>
+#include <svl/itemset.hxx>
+
+SdrText::SdrText( SdrTextObj& rObject, OutlinerParaObject* pOutlinerParaObject /* = 0 */ )
+: mpOutlinerParaObject( pOutlinerParaObject )
+, mrObject( rObject )
+, mpModel( rObject.GetModel() )
+, mbPortionInfoChecked( false )
+{
+ OSL_ENSURE(&mrObject, "SdrText created without SdrTextObj (!)");
+}
+
+SdrText::~SdrText()
+{
+ clearWeak();
+ delete mpOutlinerParaObject;
+}
+
+void SdrText::CheckPortionInfo( SdrOutliner& rOutliner )
+{
+ if(!mbPortionInfoChecked)
+ {
+ // #i102062# no action when the Outliner is the HitTestOutliner,
+ // this will remove WrongList info at the OPO
+ if(mpModel && &rOutliner == &mpModel->GetHitTestOutliner())
+ return;
+
+ // Optimierung: ggf. BigTextObject erzeugen
+ mbPortionInfoChecked=true;
+ if(mpOutlinerParaObject!=NULL && rOutliner.ShouldCreateBigTextObject())
+ {
+ // #i102062# MemoryLeak closed
+ delete mpOutlinerParaObject;
+ mpOutlinerParaObject = rOutliner.CreateParaObject();
+ }
+ }
+}
+
+void SdrText::ReformatText()
+{
+ mbPortionInfoChecked=FALSE;
+ mpOutlinerParaObject->ClearPortionInfo();
+}
+
+const SfxItemSet& SdrText::GetItemSet() const
+{
+ return const_cast< SdrText* >(this)->GetObjectItemSet();
+}
+
+void SdrText::SetOutlinerParaObject( OutlinerParaObject* pTextObject )
+{
+ if( mpOutlinerParaObject != pTextObject )
+ {
+ if( mpModel )
+ {
+ // Update HitTestOutliner
+ const SdrTextObj* pTestObj = mpModel->GetHitTestOutliner().GetTextObj();
+ if( pTestObj && pTestObj->GetOutlinerParaObject() == mpOutlinerParaObject )
+ mpModel->GetHitTestOutliner().SetTextObj( 0 );
+ }
+
+ if( mpOutlinerParaObject )
+ delete mpOutlinerParaObject;
+
+ mpOutlinerParaObject = pTextObject;
+
+ mbPortionInfoChecked = false;
+ }
+}
+
+OutlinerParaObject* SdrText::GetOutlinerParaObject() const
+{
+ return mpOutlinerParaObject;
+}
+
+/** returns the current OutlinerParaObject and removes it from this instance */
+OutlinerParaObject* SdrText::RemoveOutlinerParaObject()
+{
+ if( mpModel )
+ {
+ // Update HitTestOutliner
+ const SdrTextObj* pTestObj = mpModel->GetHitTestOutliner().GetTextObj();
+ if( pTestObj && pTestObj->GetOutlinerParaObject() == mpOutlinerParaObject )
+ mpModel->GetHitTestOutliner().SetTextObj( 0 );
+ }
+
+ OutlinerParaObject* pOPO = mpOutlinerParaObject;
+
+ mpOutlinerParaObject = 0;
+ mbPortionInfoChecked = false;
+
+ return pOPO;
+}
+
+void SdrText::SetModel( SdrModel* pNewModel )
+{
+ if( pNewModel == mpModel )
+ return;
+
+ SdrModel* pOldModel = mpModel;
+ mpModel = pNewModel;
+
+ if( mpOutlinerParaObject && pOldModel!=NULL && pNewModel!=NULL)
+ {
+ bool bHgtSet = GetObjectItemSet().GetItemState(EE_CHAR_FONTHEIGHT, TRUE) == SFX_ITEM_SET;
+
+ MapUnit aOldUnit(pOldModel->GetScaleUnit());
+ MapUnit aNewUnit(pNewModel->GetScaleUnit());
+ FASTBOOL bScaleUnitChanged=aNewUnit!=aOldUnit;
+ // und nun dem OutlinerParaObject einen neuen Pool verpassen
+ // !!! Hier muss noch DefTab und RefDevice der beiden Models
+ // !!! verglichen werden und dann ggf. AutoGrow zuschlagen !!!
+ // !!! fehlende Implementation !!!
+ ULONG nOldFontHgt=pOldModel->GetDefaultFontHeight();
+ ULONG nNewFontHgt=pNewModel->GetDefaultFontHeight();
+ BOOL bDefHgtChanged=nNewFontHgt!=nOldFontHgt;
+ BOOL bSetHgtItem=bDefHgtChanged && !bHgtSet;
+ if (bSetHgtItem)
+ { // #32665#
+ // zunaechst das HeightItem festklopfen, damit
+ // 1. Es eben bestehen bleibt und
+ // 2. DoStretchChars vom richtigen Wert ausgeht
+ SetObjectItem(SvxFontHeightItem(nOldFontHgt, 100, EE_CHAR_FONTHEIGHT));
+ }
+ // erst jetzt den Outliner holen, etc. damit obiges SetAttr auch wirkt
+ SdrOutliner& rOutliner = mrObject.ImpGetDrawOutliner();
+ rOutliner.SetText(*mpOutlinerParaObject);
+ delete mpOutlinerParaObject;
+ mpOutlinerParaObject=0;
+ if (bScaleUnitChanged)
+ {
+ Fraction aMetricFactor=GetMapFactor(aOldUnit,aNewUnit).X();
+
+ // Funktioniert nicht richtig:
+ // Geht am Outliner leider nur in %
+ // double nPercFloat=double(aMetricFactor)*100+0.5;
+ // USHORT nPerc=(USHORT)nPercFloat;
+ // rOutliner.DoStretchChars(100,nPerc);
+
+ if (bSetHgtItem)
+ {
+ // Und nun noch das Rahmenattribut korregieren
+ nOldFontHgt=BigMulDiv(nOldFontHgt,aMetricFactor.GetNumerator(),aMetricFactor.GetDenominator());
+ SetObjectItem(SvxFontHeightItem(nOldFontHgt, 100, EE_CHAR_FONTHEIGHT));
+ }
+ }
+ SetOutlinerParaObject(rOutliner.CreateParaObject()); // #34494#
+ mpOutlinerParaObject->ClearPortionInfo();
+ mbPortionInfoChecked=FALSE;
+ rOutliner.Clear();
+ }
+}
+
+void SdrText::ForceOutlinerParaObject( USHORT nOutlMode )
+{
+ if( mpModel && !mpOutlinerParaObject )
+ {
+ Outliner* pOutliner = SdrMakeOutliner( nOutlMode, mpModel );
+ if( pOutliner )
+ {
+ Outliner& aDrawOutliner = mpModel->GetDrawOutliner();
+ pOutliner->SetCalcFieldValueHdl( aDrawOutliner.GetCalcFieldValueHdl() );
+
+ pOutliner->SetStyleSheet( 0, GetStyleSheet());
+ OutlinerParaObject* pOutlinerParaObject = pOutliner->CreateParaObject();
+ SetOutlinerParaObject( pOutlinerParaObject );
+
+ delete pOutliner;
+ }
+ }
+}
+
+const SfxItemSet& SdrText::GetObjectItemSet()
+{
+ return mrObject.GetObjectItemSet();
+}
+
+void SdrText::SetObjectItem(const SfxPoolItem& rItem)
+{
+ mrObject.SetObjectItem( rItem );
+}
+
+SfxStyleSheet* SdrText::GetStyleSheet() const
+{
+ return mrObject.GetStyleSheet();
+}
diff --git a/svx/source/svdraw/svdtrans.cxx b/svx/source/svdraw/svdtrans.cxx
new file mode 100644
index 000000000000..ad4cf3763241
--- /dev/null
+++ b/svx/source/svdraw/svdtrans.cxx
@@ -0,0 +1,1271 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdtrans.hxx>
+#include <math.h>
+#include <svx/xpoly.hxx>
+
+#include <vcl/virdev.hxx>
+#include <tools/bigint.hxx>
+#include <tools/debug.hxx>
+#include <unotools/syslocale.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void MoveXPoly(XPolygon& rPoly, const Size& S)
+{
+ rPoly.Move(S.Width(),S.Height());
+}
+
+void MoveXPoly(XPolyPolygon& rPoly, const Size& S)
+{
+ rPoly.Move(S.Width(),S.Height());
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ResizeRect(Rectangle& rRect, const Point& rRef, const Fraction& rxFact, const Fraction& ryFact, FASTBOOL bNoJustify)
+{
+ Fraction xFact(rxFact);
+ Fraction yFact(ryFact);
+ //long nHgt=rRect.Bottom()-rRect.Top();
+
+ {
+ if (xFact.GetDenominator()==0) {
+ long nWdt=rRect.Right()-rRect.Left();
+ if (xFact.GetNumerator()>=0) { // DivZero abfangen
+ xFact=Fraction(xFact.GetNumerator(),1);
+ if (nWdt==0) rRect.Right()++;
+ } else {
+ xFact=Fraction(xFact.GetNumerator(),-1);
+ if (nWdt==0) rRect.Left()--;
+ }
+ }
+ rRect.Left() =rRef.X()+Round(((double)(rRect.Left() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
+ rRect.Right() =rRef.X()+Round(((double)(rRect.Right() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
+ }
+ {
+ if (yFact.GetDenominator()==0) {
+ long nHgt=rRect.Bottom()-rRect.Top();
+ if (yFact.GetNumerator()>=0) { // DivZero abfangen
+ yFact=Fraction(yFact.GetNumerator(),1);
+ if (nHgt==0) rRect.Bottom()++;
+ } else {
+ yFact=Fraction(yFact.GetNumerator(),-1);
+ if (nHgt==0) rRect.Top()--;
+ }
+
+ yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
+ }
+ rRect.Top() =rRef.Y()+Round(((double)(rRect.Top() -rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
+ rRect.Bottom()=rRef.Y()+Round(((double)(rRect.Bottom()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
+ }
+ if (!bNoJustify) rRect.Justify();
+}
+
+
+void ResizePoly(Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ USHORT nAnz=rPoly.GetSize();
+ for (USHORT i=0; i<nAnz; i++) {
+ ResizePoint(rPoly[i],rRef,xFact,yFact);
+ }
+}
+
+void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ USHORT nAnz=rPoly.GetPointCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ ResizePoint(rPoly[i],rRef,xFact,yFact);
+ }
+}
+
+void ResizePoly(PolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ ResizePoly(rPoly[i],rRef,xFact,yFact);
+ }
+}
+
+void ResizeXPoly(XPolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ ResizeXPoly(rPoly[i],rRef,xFact,yFact);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void RotatePoly(Polygon& rPoly, const Point& rRef, double sn, double cs)
+{
+ USHORT nAnz=rPoly.GetSize();
+ for (USHORT i=0; i<nAnz; i++) {
+ RotatePoint(rPoly[i],rRef,sn,cs);
+ }
+}
+
+void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs)
+{
+ USHORT nAnz=rPoly.GetPointCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ RotatePoint(rPoly[i],rRef,sn,cs);
+ }
+}
+
+void RotatePoly(PolyPolygon& rPoly, const Point& rRef, double sn, double cs)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ RotatePoly(rPoly[i],rRef,sn,cs);
+ }
+}
+
+void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ RotateXPoly(rPoly[i],rRef,sn,cs);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void MirrorRect(Rectangle& rRect, const Point& /*rRef1*/, const Point& /*rRef2*/, FASTBOOL bNoJustify)
+{
+ // !!! fehlende Implementation !!!
+ if (!bNoJustify) rRect.Justify();
+}
+
+void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2)
+{
+ long mx=rRef2.X()-rRef1.X();
+ long my=rRef2.Y()-rRef1.Y();
+ if (mx==0) { // Achse senkrecht
+ long dx=rRef1.X()-rPnt.X();
+ rPnt.X()+=2*dx;
+ } else if (my==0) { // Achse waagerecht
+ long dy=rRef1.Y()-rPnt.Y();
+ rPnt.Y()+=2*dy;
+ } else if (mx==my) { // Achse diagonal '\'
+ long dx1=rPnt.X()-rRef1.X();
+ long dy1=rPnt.Y()-rRef1.Y();
+ rPnt.X()=rRef1.X()+dy1;
+ rPnt.Y()=rRef1.Y()+dx1;
+ } else if (mx==-my) { // Achse diagonal '/'
+ long dx1=rPnt.X()-rRef1.X();
+ long dy1=rPnt.Y()-rRef1.Y();
+ rPnt.X()=rRef1.X()-dy1;
+ rPnt.Y()=rRef1.Y()-dx1;
+ } else { // beliebige Achse
+ // mal optimieren !!!
+ // Lot auf der Spiegelachse faellen oder so
+ long nRefWink=GetAngle(rRef2-rRef1);
+ rPnt-=rRef1;
+ long nPntWink=GetAngle(rPnt);
+ long nWink=2*(nRefWink-nPntWink);
+ double a=nWink*nPi180;
+ double nSin=sin(a);
+ double nCos=cos(a);
+ RotatePoint(rPnt,Point(),nSin,nCos);
+ rPnt+=rRef1;
+ }
+}
+
+void MirrorPoly(Polygon& rPoly, const Point& rRef1, const Point& rRef2)
+{
+ USHORT nAnz=rPoly.GetSize();
+ for (USHORT i=0; i<nAnz; i++) {
+ MirrorPoint(rPoly[i],rRef1,rRef2);
+ }
+}
+
+void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2)
+{
+ USHORT nAnz=rPoly.GetPointCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ MirrorPoint(rPoly[i],rRef1,rRef2);
+ }
+}
+
+void MirrorPoly(PolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ MirrorPoly(rPoly[i],rRef1,rRef2);
+ }
+}
+
+void MirrorXPoly(XPolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ MirrorXPoly(rPoly[i],rRef1,rRef2);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ShearPoly(Polygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
+{
+ USHORT nAnz=rPoly.GetSize();
+ for (USHORT i=0; i<nAnz; i++) {
+ ShearPoint(rPoly[i],rRef,tn,bVShear);
+ }
+}
+
+void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
+{
+ USHORT nAnz=rPoly.GetPointCount();
+ for (USHORT i=0; i<nAnz; i++) {
+ ShearPoint(rPoly[i],rRef,tn,bVShear);
+ }
+}
+
+void ShearPoly(PolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ ShearPoly(rPoly[i],rRef,tn,bVShear);
+ }
+}
+
+void ShearXPoly(XPolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
+{
+ USHORT nAnz=rPoly.Count();
+ for (USHORT i=0; i<nAnz; i++) {
+ ShearXPoly(rPoly[i],rRef,tn,bVShear);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@ @@@@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@ @@ @@ @@ @@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@ @@ @@@@ @@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
+ const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
+{
+ FASTBOOL bC1=pC1!=NULL;
+ FASTBOOL bC2=pC2!=NULL;
+ long x0=rPnt.X();
+ long y0=rPnt.Y();
+ long cx=rCenter.X();
+ long cy=rCenter.Y();
+ double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
+ double sn=sin(nWink);
+ double cs=cos(nWink);
+ RotatePoint(rPnt,rCenter,sn,cs);
+ if (bC1) {
+ if (bVert) {
+ // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
+ pC1->Y()-=y0;
+ // Resize, entsprechend der Entfernung vom Zentrum
+ pC1->Y()=Round(((double)pC1->Y()) /rRad.X()*(cx-pC1->X()));
+ pC1->Y()+=cy;
+ } else {
+ // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
+ pC1->X()-=x0;
+ // Resize, entsprechend der Entfernung vom Zentrum
+ long nPntRad=cy-pC1->Y();
+ double nFact=(double)nPntRad/(double)rRad.Y();
+ pC1->X()=Round((double)pC1->X()*nFact);
+ pC1->X()+=cx;
+ }
+ RotatePoint(*pC1,rCenter,sn,cs);
+ }
+ if (bC2) {
+ if (bVert) {
+ // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
+ pC2->Y()-=y0;
+ // Resize, entsprechend der Entfernung vom Zentrum
+ pC2->Y()=Round(((double)pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X()));
+ pC2->Y()+=cy;
+ } else {
+ // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
+ pC2->X()-=x0;
+ // Resize, entsprechend der Entfernung vom Zentrum
+ long nPntRad=rCenter.Y()-pC2->Y();
+ double nFact=(double)nPntRad/(double)rRad.Y();
+ pC2->X()=Round((double)pC2->X()*nFact);
+ pC2->X()+=cx;
+ }
+ RotatePoint(*pC2,rCenter,sn,cs);
+ }
+ rSin=sn;
+ rCos=cs;
+ return nWink;
+}
+
+double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
+ const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
+{
+ FASTBOOL bC1=pC1!=NULL;
+ FASTBOOL bC2=pC2!=NULL;
+ long x0=rPnt.X();
+ long y0=rPnt.Y();
+ long dx1=0,dy1=0;
+ long dxC1=0,dyC1=0;
+ long dxC2=0,dyC2=0;
+ if (bVert) {
+ long nStart=rCenter.X()-rRad.X();
+ dx1=rPnt.X()-nStart;
+ rPnt.X()=nStart;
+ if (bC1) {
+ dxC1=pC1->X()-nStart;
+ pC1->X()=nStart;
+ }
+ if (bC2) {
+ dxC2=pC2->X()-nStart;
+ pC2->X()=nStart;
+ }
+ } else {
+ long nStart=rCenter.Y()-rRad.Y();
+ dy1=rPnt.Y()-nStart;
+ rPnt.Y()=nStart;
+ if (bC1) {
+ dyC1=pC1->Y()-nStart;
+ pC1->Y()=nStart;
+ }
+ if (bC2) {
+ dyC2=pC2->Y()-nStart;
+ pC2->Y()=nStart;
+ }
+ }
+ double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
+ double sn=sin(nWink);
+ double cs=cos(nWink);
+ RotatePoint(rPnt,rCenter,sn,cs);
+ if (bC1) { if (bVert) pC1->Y()-=y0-rCenter.Y(); else pC1->X()-=x0-rCenter.X(); RotatePoint(*pC1,rCenter,sn,cs); }
+ if (bC2) { if (bVert) pC2->Y()-=y0-rCenter.Y(); else pC2->X()-=x0-rCenter.X(); RotatePoint(*pC2,rCenter,sn,cs); }
+ if (bVert) {
+ rPnt.X()+=dx1;
+ if (bC1) pC1->X()+=dxC1;
+ if (bC2) pC2->X()+=dxC2;
+ } else {
+ rPnt.Y()+=dy1;
+ if (bC1) pC1->Y()+=dyC1;
+ if (bC2) pC2->Y()+=dyC2;
+ }
+ rSin=sn;
+ rCos=cs;
+ return nWink;
+}
+
+double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
+ const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert,
+ const Rectangle rRefRect)
+{
+ //FASTBOOL bC1=pC1!=NULL;
+ //FASTBOOL bC2=pC2!=NULL;
+ //long x0=rPnt.X();
+ long y0=rPnt.Y();
+ CrookSlantXPoint(rPnt,pC1,pC2,rCenter,rRad,rSin,rCos,bVert);
+ if (bVert) {
+ } else {
+ //long nBase=rCenter.Y()-rRad.Y();
+ long nTop=rRefRect.Top();
+ long nBtm=rRefRect.Bottom();
+ long nHgt=nBtm-nTop;
+ long dy=rPnt.Y()-y0;
+ //FASTBOOL bOben=rRad.Y()<0;
+ double a=((double)(y0-nTop))/nHgt;
+ a*=dy;
+ rPnt.Y()=y0+Round(a);
+ } return 0.0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
+{
+ double nSin,nCos;
+ USHORT nPointAnz=rPoly.GetPointCount();
+ USHORT i=0;
+ while (i<nPointAnz) {
+ Point* pPnt=&rPoly[i];
+ Point* pC1=NULL;
+ Point* pC2=NULL;
+ if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
+ pC1=pPnt;
+ i++;
+ pPnt=&rPoly[i];
+ }
+ i++;
+ if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
+ pC2=&rPoly[i];
+ i++;
+ }
+ CrookRotateXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
+ }
+}
+
+void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
+{
+ double nSin,nCos;
+ USHORT nPointAnz=rPoly.GetPointCount();
+ USHORT i=0;
+ while (i<nPointAnz) {
+ Point* pPnt=&rPoly[i];
+ Point* pC1=NULL;
+ Point* pC2=NULL;
+ if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
+ pC1=pPnt;
+ i++;
+ pPnt=&rPoly[i];
+ }
+ i++;
+ if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
+ pC2=&rPoly[i];
+ i++;
+ }
+ CrookSlantXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
+ }
+}
+
+void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
+{
+ double nSin,nCos;
+ USHORT nPointAnz=rPoly.GetPointCount();
+ USHORT i=0;
+ while (i<nPointAnz) {
+ Point* pPnt=&rPoly[i];
+ Point* pC1=NULL;
+ Point* pC2=NULL;
+ if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
+ pC1=pPnt;
+ i++;
+ pPnt=&rPoly[i];
+ }
+ i++;
+ if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
+ pC2=&rPoly[i];
+ i++;
+ }
+ CrookStretchXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert,rRefRect);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
+{
+ USHORT nPolyAnz=rPoly.Count();
+ for (USHORT nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
+ CrookRotatePoly(rPoly[nPolyNum],rCenter,rRad,bVert);
+ }
+}
+
+void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
+{
+ USHORT nPolyAnz=rPoly.Count();
+ for (USHORT nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
+ CrookSlantPoly(rPoly[nPolyNum],rCenter,rRad,bVert);
+ }
+}
+
+void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
+{
+ USHORT nPolyAnz=rPoly.Count();
+ for (USHORT nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
+ CrookStretchPoly(rPoly[nPolyNum],rCenter,rRad,bVert,rRefRect);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+long GetAngle(const Point& rPnt)
+{
+ long a=0;
+ if (rPnt.Y()==0) {
+ if (rPnt.X()<0) a=-18000;
+ } else if (rPnt.X()==0) {
+ if (rPnt.Y()>0) a=-9000;
+ else a=9000;
+ } else {
+ a=Round((atan2((double)-rPnt.Y(),(double)rPnt.X())/nPi180));
+ }
+ return a;
+}
+
+long NormAngle180(long a)
+{
+ while (a<18000) a+=36000;
+ while (a>=18000) a-=36000;
+ return a;
+}
+
+long NormAngle360(long a)
+{
+ while (a<0) a+=36000;
+ while (a>=36000) a-=36000;
+ return a;
+}
+
+USHORT GetAngleSector(long nWink)
+{
+ while (nWink<0) nWink+=36000;
+ while (nWink>=36000) nWink-=36000;
+ if (nWink< 9000) return 0;
+ if (nWink<18000) return 1;
+ if (nWink<27000) return 2;
+ return 3;
+}
+
+long GetLen(const Point& rPnt)
+{
+ long x=Abs(rPnt.X());
+ long y=Abs(rPnt.Y());
+ if (x+y<0x8000) { // weil 7FFF * 7FFF * 2 = 7FFE0002
+ x*=x;
+ y*=y;
+ x+=y;
+ x=Round(sqrt((double)x));
+ return x;
+ } else {
+ double nx=x;
+ double ny=y;
+ nx*=nx;
+ ny*=ny;
+ nx+=ny;
+ nx=sqrt(nx);
+ if (nx>0x7FFFFFFF) {
+ return 0x7FFFFFFF; // Ueberlauf, mehr is nich!
+ } else {
+ return Round(nx);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void GeoStat::RecalcSinCos()
+{
+ if (nDrehWink==0) {
+ nSin=0.0;
+ nCos=1.0;
+ } else {
+ double a=nDrehWink*nPi180;
+ nSin=sin(a);
+ nCos=cos(a);
+ }
+}
+
+void GeoStat::RecalcTan()
+{
+ if (nShearWink==0) {
+ nTan=0.0;
+ } else {
+ double a=nShearWink*nPi180;
+ nTan=tan(a);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo)
+{
+ Polygon aPol(5);
+ aPol[0]=rRect.TopLeft();
+ aPol[1]=rRect.TopRight();
+ aPol[2]=rRect.BottomRight();
+ aPol[3]=rRect.BottomLeft();
+ aPol[4]=rRect.TopLeft();
+ if (rGeo.nShearWink!=0) ShearPoly(aPol,rRect.TopLeft(),rGeo.nTan);
+ if (rGeo.nDrehWink!=0) RotatePoly(aPol,rRect.TopLeft(),rGeo.nSin,rGeo.nCos);
+ return aPol;
+}
+
+void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo)
+{
+ rGeo.nDrehWink=GetAngle(rPol[1]-rPol[0]);
+ rGeo.nDrehWink=NormAngle360(rGeo.nDrehWink);
+ // Drehung ist damit im Kasten
+ rGeo.RecalcSinCos();
+
+ Point aPt1(rPol[1]-rPol[0]);
+ if (rGeo.nDrehWink!=0) RotatePoint(aPt1,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
+ long nWdt=aPt1.X();
+
+ Point aPt0(rPol[0]);
+ Point aPt3(rPol[3]-rPol[0]);
+ if (rGeo.nDrehWink!=0) RotatePoint(aPt3,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
+ long nHgt=aPt3.Y();
+
+ if(aPt3.X())
+ {
+ // #i74358# the axes are not orthogonal, so for getting the correct height,
+ // calculate the length of aPt3
+
+ // #i74358# this change was wrong, in the field of the old geometry stuff
+ // it is not an error. The new height always is the same as before; shear
+ // does not change object height at all. This is different from the interactions,
+ // but obviously wanted in the old versions.
+ //
+ // nHgt = static_cast< long >(sqrt(static_cast< double >(aPt3.X() * aPt3.X() + aPt3.Y() * aPt3.Y())));
+ }
+
+ long nShW=GetAngle(aPt3);
+ nShW-=27000; // ShearWink wird zur Senkrechten gemessen
+ nShW=-nShW; // Negieren, denn '+' ist Rechtskursivierung
+
+ FASTBOOL bMirr=aPt3.Y()<0;
+ if (bMirr) { // "Punktetausch" bei Spiegelung
+ nHgt=-nHgt;
+ nShW+=18000;
+ aPt0=rPol[3];
+ }
+ nShW=NormAngle180(nShW);
+ if (nShW<-9000 || nShW>9000) {
+ nShW=NormAngle180(nShW+18000);
+ }
+ if (nShW<-SDRMAXSHEAR) nShW=-SDRMAXSHEAR; // ShearWinkel begrenzen auf +/- 89.00 deg
+ if (nShW>SDRMAXSHEAR) nShW=SDRMAXSHEAR;
+ rGeo.nShearWink=nShW;
+ rGeo.RecalcTan();
+ Point aRU(aPt0);
+ aRU.X()+=nWdt;
+ aRU.Y()+=nHgt;
+ rRect=Rectangle(aPt0,aRU);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void OrthoDistance8(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
+{
+ long dx=rPt.X()-rPt0.X();
+ long dy=rPt.Y()-rPt0.Y();
+ long dxa=Abs(dx);
+ long dya=Abs(dy);
+ if (dx==0 || dy==0 || dxa==dya) return;
+ if (dxa>=dya*2) { rPt.Y()=rPt0.Y(); return; }
+ if (dya>=dxa*2) { rPt.X()=rPt0.X(); return; }
+ if ((dxa<dya) != bBigOrtho) {
+ rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
+ } else {
+ rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
+ }
+}
+
+void OrthoDistance4(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
+{
+ long dx=rPt.X()-rPt0.X();
+ long dy=rPt.Y()-rPt0.Y();
+ long dxa=Abs(dx);
+ long dya=Abs(dy);
+ if ((dxa<dya) != bBigOrtho) {
+ rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
+ } else {
+ rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+long BigMulDiv(long nVal, long nMul, long nDiv)
+{
+ BigInt aVal(nVal);
+ aVal*=nMul;
+ if (aVal.IsNeg()!=(nDiv<0)) {
+ aVal-=nDiv/2; // fuer korrektes Runden
+ } else {
+ aVal+=nDiv/2; // fuer korrektes Runden
+ }
+ if(nDiv)
+ {
+ aVal/=nDiv;
+ return long(aVal);
+ }
+ return 0x7fffffff;
+}
+
+void Kuerzen(Fraction& rF, unsigned nDigits)
+{
+ INT32 nMul=rF.GetNumerator();
+ INT32 nDiv=rF.GetDenominator();
+ FASTBOOL bNeg=FALSE;
+ if (nMul<0) { nMul=-nMul; bNeg=!bNeg; }
+ if (nDiv<0) { nDiv=-nDiv; bNeg=!bNeg; }
+ if (nMul==0 || nDiv==0) return;
+ UINT32 a;
+ a=UINT32(nMul); unsigned nMulZ=0; // Fuehrende Nullen zaehlen
+ while (a<0x00800000) { nMulZ+=8; a<<=8; }
+ while (a<0x80000000) { nMulZ++; a<<=1; }
+ a=UINT32(nDiv); unsigned nDivZ=0; // Fuehrende Nullen zaehlen
+ while (a<0x00800000) { nDivZ+=8; a<<=8; }
+ while (a<0x80000000) { nDivZ++; a<<=1; }
+ // Anzahl der verwendeten Digits bestimmen
+ int nMulDigits=32-nMulZ;
+ int nDivDigits=32-nDivZ;
+ // Nun bestimmen, wieviele Stellen hinten weg koennen
+ int nMulWeg=nMulDigits-nDigits; if (nMulWeg<0) nMulWeg=0;
+ int nDivWeg=nDivDigits-nDigits; if (nDivWeg<0) nDivWeg=0;
+ int nWeg=Min(nMulWeg,nDivWeg);
+ nMul>>=nWeg;
+ nDiv>>=nWeg;
+ if (nMul==0 || nDiv==0) {
+ DBG_WARNING("Oups, beim kuerzen einer Fraction hat sich Joe verrechnet.");
+ return;
+ }
+ if (bNeg) nMul=-nMul;
+ rF=Fraction(nMul,nDiv);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Wieviele eU-Einheiten passen in einen mm bzw. Inch?
+// Oder wie gross ist ein eU in mm bzw. Inch, und davon der Kehrwert
+
+FrPair GetInchOrMM(MapUnit eU)
+{
+ switch (eU) {
+ case MAP_1000TH_INCH: return FrPair(1000,1);
+ case MAP_100TH_INCH : return FrPair( 100,1);
+ case MAP_10TH_INCH : return FrPair( 10,1);
+ case MAP_INCH : return FrPair( 1,1);
+ case MAP_POINT : return FrPair( 72,1);
+ case MAP_TWIP : return FrPair(1440,1);
+ case MAP_100TH_MM : return FrPair( 100,1);
+ case MAP_10TH_MM : return FrPair( 10,1);
+ case MAP_MM : return FrPair( 1,1);
+ case MAP_CM : return FrPair( 1,10);
+ case MAP_PIXEL : {
+ VirtualDevice aVD;
+ aVD.SetMapMode(MapMode(MAP_100TH_MM));
+ Point aP(aVD.PixelToLogic(Point(64,64))); // 64 Pixel fuer bessere Genauigkeit
+ return FrPair(6400,aP.X(),6400,aP.Y());
+ }
+ case MAP_APPFONT: case MAP_SYSFONT: {
+ VirtualDevice aVD;
+ aVD.SetMapMode(MapMode(eU));
+ Point aP(aVD.LogicToPixel(Point(32,32))); // 32 Einheiten fuer bessere Genauigkeit
+ aVD.SetMapMode(MapMode(MAP_100TH_MM));
+ aP=aVD.PixelToLogic(aP);
+ return FrPair(3200,aP.X(),3200,aP.Y());
+ }
+ default: break;
+ }
+ return Fraction(1,1);
+}
+
+FrPair GetInchOrMM(FieldUnit eU)
+{
+ switch (eU) {
+ case FUNIT_INCH : return FrPair( 1,1);
+ case FUNIT_POINT : return FrPair( 72,1);
+ case FUNIT_TWIP : return FrPair(1440,1);
+ case FUNIT_100TH_MM : return FrPair( 100,1);
+ case FUNIT_MM : return FrPair( 1,1);
+ case FUNIT_CM : return FrPair( 1,10);
+ case FUNIT_M : return FrPair( 1,1000);
+ case FUNIT_KM : return FrPair( 1,1000000);
+ case FUNIT_PICA : return FrPair( 6,1);
+ case FUNIT_FOOT : return FrPair( 1,12);
+ case FUNIT_MILE : return FrPair( 1,63360);
+ default: break;
+ }
+ return Fraction(1,1);
+}
+
+// Den Faktor berechnen, der anzuwenden ist um n Einheiten von eS nach
+// eD umzurechnen. Z.B. GetMapFactor(UNIT_MM,UNIT_100TH_MM) => 100.
+
+FrPair GetMapFactor(MapUnit eS, MapUnit eD)
+{
+ if (eS==eD) return FrPair(1,1,1,1);
+ FrPair aS(GetInchOrMM(eS));
+ FrPair aD(GetInchOrMM(eD));
+ FASTBOOL bSInch=IsInch(eS);
+ FASTBOOL bDInch=IsInch(eD);
+ FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
+ if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
+ if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
+ return aRet;
+};
+
+FrPair GetMapFactor(MapUnit eS, FieldUnit eD)
+{
+ FrPair aS(GetInchOrMM(eS));
+ FrPair aD(GetInchOrMM(eD));
+ FASTBOOL bSInch=IsInch(eS);
+ FASTBOOL bDInch=IsInch(eD);
+ FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
+ if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
+ if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
+ return aRet;
+};
+
+FrPair GetMapFactor(FieldUnit eS, MapUnit eD)
+{
+ FrPair aS(GetInchOrMM(eS));
+ FrPair aD(GetInchOrMM(eD));
+ FASTBOOL bSInch=IsInch(eS);
+ FASTBOOL bDInch=IsInch(eD);
+ FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
+ if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
+ if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
+ return aRet;
+};
+
+FrPair GetMapFactor(FieldUnit eS, FieldUnit eD)
+{
+ if (eS==eD) return FrPair(1,1,1,1);
+ FrPair aS(GetInchOrMM(eS));
+ FrPair aD(GetInchOrMM(eD));
+ FASTBOOL bSInch=IsInch(eS);
+ FASTBOOL bDInch=IsInch(eD);
+ FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
+ if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
+ if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
+ return aRet;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ // 1 mile = 8 furlong = 63.360" = 1.609.344,0mm
+ // 1 furlong = 10 chains = 7.920" = 201.168,0mm
+ // 1 chain = 4 poles = 792" = 20.116,8mm
+ // 1 pole = 5 1/2 yd = 198" = 5.029,2mm
+ // 1 yd = 3 ft = 36" = 914,4mm
+ // 1 ft = 12 " = 1" = 304,8mm
+
+void GetMeterOrInch(MapUnit eMU, short& rnKomma, long& rnMul, long& rnDiv, FASTBOOL& rbMetr, FASTBOOL& rbInch)
+{
+ rnMul=1; rnDiv=1;
+ short nKomma=0;
+ FASTBOOL bMetr=FALSE,bInch=FALSE;
+ switch (eMU) {
+ // Metrisch
+ case MAP_100TH_MM : bMetr=TRUE; nKomma=5; break;
+ case MAP_10TH_MM : bMetr=TRUE; nKomma=4; break;
+ case MAP_MM : bMetr=TRUE; nKomma=3; break;
+ case MAP_CM : bMetr=TRUE; nKomma=2; break;
+ // Inch
+ case MAP_1000TH_INCH: bInch=TRUE; nKomma=3; break;
+ case MAP_100TH_INCH : bInch=TRUE; nKomma=2; break;
+ case MAP_10TH_INCH : bInch=TRUE; nKomma=1; break;
+ case MAP_INCH : bInch=TRUE; nKomma=0; break;
+ case MAP_POINT : bInch=TRUE; rnDiv=72; break; // 1Pt = 1/72"
+ case MAP_TWIP : bInch=TRUE; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
+ // Sonstiges
+ case MAP_PIXEL : break;
+ case MAP_SYSFONT : break;
+ case MAP_APPFONT : break;
+ case MAP_RELATIVE : break;
+ default: break;
+ } // switch
+ rnKomma=nKomma;
+ rbMetr=bMetr;
+ rbInch=bInch;
+}
+
+void GetMeterOrInch(FieldUnit eFU, short& rnKomma, long& rnMul, long& rnDiv, FASTBOOL& rbMetr, FASTBOOL& rbInch)
+{
+ rnMul=1; rnDiv=1;
+ short nKomma=0;
+ FASTBOOL bMetr=FALSE,bInch=FALSE;
+ switch (eFU) {
+ case FUNIT_NONE : break;
+ // Metrisch
+ case FUNIT_100TH_MM : bMetr=TRUE; nKomma=5; break;
+ case FUNIT_MM : bMetr=TRUE; nKomma=3; break;
+ case FUNIT_CM : bMetr=TRUE; nKomma=2; break;
+ case FUNIT_M : bMetr=TRUE; nKomma=0; break;
+ case FUNIT_KM : bMetr=TRUE; nKomma=-3; break;
+ // Inch
+ case FUNIT_TWIP : bInch=TRUE; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
+ case FUNIT_POINT : bInch=TRUE; rnDiv=72; break; // 1Pt = 1/72"
+ case FUNIT_PICA : bInch=TRUE; rnDiv=6; break; // 1Pica = 1/6" ?
+ case FUNIT_INCH : bInch=TRUE; break; // 1" = 1"
+ case FUNIT_FOOT : bInch=TRUE; rnMul=12; break; // 1Ft = 12"
+ case FUNIT_MILE : bInch=TRUE; rnMul=6336; nKomma=-1; break; // 1mile = 63360"
+ // sonstiges
+ case FUNIT_CUSTOM : break;
+ case FUNIT_PERCENT : nKomma=2; break;
+ } // switch
+ rnKomma=nKomma;
+ rbMetr=bMetr;
+ rbInch=bInch;
+}
+
+void SdrFormatter::Undirty()
+{
+ if (aScale.GetNumerator()==0 || aScale.GetDenominator()==0) aScale=Fraction(1,1);
+ FASTBOOL bSrcMetr,bSrcInch,bDstMetr,bDstInch;
+ long nMul1,nDiv1,nMul2,nDiv2;
+ short nKomma1,nKomma2;
+ // Zunaechst normalisieren auf m bzw. "
+ if (!bSrcFU) {
+ GetMeterOrInch(eSrcMU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
+ } else {
+ GetMeterOrInch(eSrcFU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
+ }
+ if (!bDstFU) {
+ GetMeterOrInch(eDstMU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
+ } else {
+ GetMeterOrInch(eDstFU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
+ }
+ nMul1*=nDiv2;
+ nDiv1*=nMul2;
+ nKomma1=nKomma1-nKomma2;
+
+ if (bSrcInch && bDstMetr) {
+ nKomma1+=4;
+ nMul1*=254;
+ }
+ if (bSrcMetr && bDstInch) {
+ nKomma1-=4;
+ nDiv1*=254;
+ }
+
+ // Temporaere Fraction zum Kuerzen
+ Fraction aTempFract(nMul1,nDiv1);
+ nMul1=aTempFract.GetNumerator();
+ nDiv1=aTempFract.GetDenominator();
+
+ nMul_=nMul1;
+ nDiv_=nDiv1;
+ nKomma_=nKomma1;
+ bDirty=FALSE;
+}
+
+
+void SdrFormatter::TakeStr(long nVal, XubString& rStr) const
+{
+ sal_Unicode aNullCode('0');
+
+ if(!nVal)
+ {
+ rStr = UniString();
+ rStr += aNullCode;
+ return;
+ }
+
+ // Hier fallen trotzdem evtl. Nachkommastellen weg, wg. MulDiv statt Real
+ BOOL bNeg(nVal < 0);
+ SvtSysLocale aSysLoc;
+ const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
+
+ ForceUndirty();
+
+ sal_Int16 nK(nKomma_);
+ XubString aStr;
+
+ if(bNeg)
+ nVal = -nVal;
+
+ while(nK <= -3)
+ {
+ nVal *= 1000;
+ nK += 3;
+ }
+
+ while(nK <= -1)
+ {
+ nVal *= 10;
+ nK++;
+ }
+
+ if(nMul_ != nDiv_)
+ nVal = BigMulDiv(nVal, nMul_, nDiv_);
+
+ aStr = UniString::CreateFromInt32(nVal);
+
+ if(nK > 0 && aStr.Len() <= nK )
+ {
+ // Komma erforderlich
+ sal_Int16 nAnz(nK - aStr.Len());
+
+ if(nAnz >= 0 && rLoc.isNumLeadingZero())
+ nAnz++;
+
+ for(xub_StrLen i=0; i<nAnz; i++)
+ aStr.Insert(aNullCode, 0);
+
+ // zuviele Nachkommastellen abhacken
+ xub_StrLen nNumDigits(rLoc.getNumDigits());
+ xub_StrLen nWeg(nK - nNumDigits);
+
+ if(nWeg > 0)
+ {
+ // hier muesste eigentlich noch gerundet werden!
+ aStr.Erase(aStr.Len() - nWeg);
+ nK = nNumDigits;
+ }
+ }
+
+ // Vorkommastellen fuer spaeter merken
+ xub_StrLen nVorKomma(aStr.Len() - nK);
+
+ if(nK > 0)
+ {
+ // KommaChar einfuegen
+ // erstmal trailing Zeros abhacken
+ while(nK > 0 && aStr.GetChar(aStr.Len() - 1) == aNullCode)
+ {
+ aStr.Erase(aStr.Len() - 1);
+ nK--;
+ }
+
+ if(nK > 0)
+ {
+ // na, noch Nachkommastellen da?
+ sal_Unicode cDec(rLoc.getNumDecimalSep().GetChar(0));
+ aStr.Insert(cDec, nVorKomma);
+ }
+ }
+
+ // ggf. Trennpunkte bei jedem Tausender einfuegen
+ if( nVorKomma > 3 )
+ {
+ String aThoSep( rLoc.getNumThousandSep() );
+ if ( aThoSep.Len() > 0 )
+ {
+ sal_Unicode cTho( aThoSep.GetChar(0) );
+ sal_Int32 i(nVorKomma - 3);
+
+ while(i > 0)
+ {
+ rStr.Insert(cTho, (xub_StrLen)i);
+ i -= 3;
+ }
+ }
+ }
+
+ if(!aStr.Len())
+ aStr += aNullCode;
+
+ if(bNeg && (aStr.Len() > 1 || aStr.GetChar(0) != aNullCode))
+ {
+ rStr.Insert(sal_Unicode('-'), 0);
+ }
+
+ rStr = aStr;
+}
+
+void SdrFormatter::TakeUnitStr(MapUnit eUnit, XubString& rStr)
+{
+ switch(eUnit)
+ {
+ // Metrisch
+ case MAP_100TH_MM :
+ {
+ sal_Char aText[] = "/100mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_10TH_MM :
+ {
+ sal_Char aText[] = "/10mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_MM :
+ {
+ sal_Char aText[] = "mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_CM :
+ {
+ sal_Char aText[] = "cm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+
+ // Inch
+ case MAP_1000TH_INCH:
+ {
+ sal_Char aText[] = "/1000\"";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_100TH_INCH :
+ {
+ sal_Char aText[] = "/100\"";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_10TH_INCH :
+ {
+ sal_Char aText[] = "/10\"";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_INCH :
+ {
+ rStr = UniString();
+ rStr += sal_Unicode('"');
+ break;
+ }
+ case MAP_POINT :
+ {
+ sal_Char aText[] = "pt";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_TWIP :
+ {
+ sal_Char aText[] = "twip";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+
+ // Sonstiges
+ case MAP_PIXEL :
+ {
+ sal_Char aText[] = "pixel";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_SYSFONT :
+ {
+ sal_Char aText[] = "sysfont";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_APPFONT :
+ {
+ sal_Char aText[] = "appfont";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case MAP_RELATIVE :
+ {
+ rStr = UniString();
+ rStr += sal_Unicode('%');
+ break;
+ }
+ default: break;
+ }
+}
+
+void SdrFormatter::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
+{
+ switch(eUnit)
+ {
+ default :
+ case FUNIT_NONE :
+ case FUNIT_CUSTOM :
+ {
+ rStr = UniString();
+ break;
+ }
+
+ // Metrisch
+ case FUNIT_100TH_MM:
+ {
+ sal_Char aText[] = "/100mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_MM :
+ {
+ sal_Char aText[] = "mm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_CM :
+ {
+ sal_Char aText[] = "cm";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_M :
+ {
+ rStr = UniString();
+ rStr += sal_Unicode('m');
+ break;
+ }
+ case FUNIT_KM :
+ {
+ sal_Char aText[] = "km";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+
+ // Inch
+ case FUNIT_TWIP :
+ {
+ sal_Char aText[] = "twip";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_POINT :
+ {
+ sal_Char aText[] = "pt";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_PICA :
+ {
+ sal_Char aText[] = "pica";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_INCH :
+ {
+ rStr = UniString();
+ rStr += sal_Unicode('"');
+ break;
+ }
+ case FUNIT_FOOT :
+ {
+ sal_Char aText[] = "ft";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+ case FUNIT_MILE :
+ {
+ sal_Char aText[] = "mile(s)";
+ rStr = UniString(aText, sizeof(aText-1));
+ break;
+ }
+
+ // sonstiges
+ case FUNIT_PERCENT:
+ {
+ rStr = UniString();
+ rStr += sal_Unicode('%');
+ break;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
new file mode 100644
index 000000000000..667dd3a340b5
--- /dev/null
+++ b/svx/source/svdraw/svdundo.cxx
@@ -0,0 +1,1871 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <svx/svdundo.hxx>
+#include "svditext.hxx"
+#include <svx/svdotext.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdlayer.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdview.hxx>
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/scene3d.hxx>
+#include <editeng/outlobj.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/sdr/properties/itemsettools.hxx>
+#include <svx/sdr/properties/properties.hxx>
+#include <svx/svdocapt.hxx>
+#include <svl/whiter.hxx>
+#include <svx/e3dsceneupdater.hxx>
+
+#include "svdviter.hxx"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// iterates over all views and unmarks this SdrObject if it is marked
+static void ImplUnmarkObject( SdrObject* pObj )
+{
+ SdrViewIter aIter( pObj );
+ for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
+ {
+ pView->MarkObj( pObj, pView->GetSdrPageView(), TRUE );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrUndoAction,SfxUndoAction);
+
+BOOL SdrUndoAction::CanRepeat(SfxRepeatTarget& rView) const
+{
+ SdrView* pV=PTR_CAST(SdrView,&rView);
+ if (pV!=NULL) return CanSdrRepeat(*pV);
+ return FALSE;
+}
+
+void SdrUndoAction::Repeat(SfxRepeatTarget& rView)
+{
+ SdrView* pV=PTR_CAST(SdrView,&rView);
+ if (pV!=NULL) SdrRepeat(*pV);
+ DBG_ASSERT(pV!=NULL,"Repeat: Uebergebenes SfxRepeatTarget ist keine SdrView");
+}
+
+XubString SdrUndoAction::GetRepeatComment(SfxRepeatTarget& rView) const
+{
+ SdrView* pV=PTR_CAST(SdrView,&rView);
+ if (pV!=NULL) return GetSdrRepeatComment(*pV);
+ return String();
+}
+
+bool SdrUndoAction::CanSdrRepeat(SdrView& /*rView*/) const
+{
+ return FALSE;
+}
+
+void SdrUndoAction::SdrRepeat(SdrView& /*rView*/)
+{
+}
+
+XubString SdrUndoAction::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ return String();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoGroup::SdrUndoGroup(SdrModel& rNewMod)
+: SdrUndoAction(rNewMod),
+ aBuf(1024,32,32),
+ eFunction(SDRREPFUNC_OBJ_NONE) /*#72642#*/
+{}
+
+SdrUndoGroup::SdrUndoGroup(SdrModel& rNewMod,const String& rStr)
+: SdrUndoAction(rNewMod),
+ aBuf(1024,32,32),
+ aComment(rStr),
+ eFunction(SDRREPFUNC_OBJ_NONE)
+{}
+
+SdrUndoGroup::~SdrUndoGroup()
+{
+ Clear();
+}
+
+void SdrUndoGroup::Clear()
+{
+ for (ULONG nu=0; nu<GetActionCount(); nu++) {
+ SdrUndoAction* pAct=GetAction(nu);
+ delete pAct;
+ }
+ aBuf.Clear();
+}
+
+void SdrUndoGroup::AddAction(SdrUndoAction* pAct)
+{
+ aBuf.Insert(pAct,CONTAINER_APPEND);
+}
+
+void SdrUndoGroup::push_front( SdrUndoAction* pAct )
+{
+ aBuf.Insert(pAct, (ULONG)0 );
+}
+
+void SdrUndoGroup::Undo()
+{
+ for (ULONG nu=GetActionCount(); nu>0;) {
+ nu--;
+ SdrUndoAction* pAct=GetAction(nu);
+ pAct->Undo();
+ }
+}
+
+void SdrUndoGroup::Redo()
+{
+ for (ULONG nu=0; nu<GetActionCount(); nu++) {
+ SdrUndoAction* pAct=GetAction(nu);
+ pAct->Redo();
+ }
+}
+
+XubString SdrUndoGroup::GetComment() const
+{
+ XubString aRet(aComment);
+ sal_Char aSearchText[] = "%1";
+ String aSearchString(aSearchText, sizeof(aSearchText-1));
+
+ aRet.SearchAndReplace(aSearchString, aObjDescription);
+
+ return aRet;
+}
+
+bool SdrUndoGroup::CanSdrRepeat(SdrView& rView) const
+{
+ switch (eFunction) {
+ case SDRREPFUNC_OBJ_NONE : return FALSE;
+ case SDRREPFUNC_OBJ_DELETE : return rView.AreObjectsMarked();
+ case SDRREPFUNC_OBJ_COMBINE_POLYPOLY: return rView.IsCombinePossible(FALSE);
+ case SDRREPFUNC_OBJ_COMBINE_ONEPOLY : return rView.IsCombinePossible(TRUE);
+ case SDRREPFUNC_OBJ_DISMANTLE_POLYS : return rView.IsDismantlePossible(FALSE);
+ case SDRREPFUNC_OBJ_DISMANTLE_LINES : return rView.IsDismantlePossible(TRUE);
+ case SDRREPFUNC_OBJ_CONVERTTOPOLY : return rView.IsConvertToPolyObjPossible(FALSE);
+ case SDRREPFUNC_OBJ_CONVERTTOPATH : return rView.IsConvertToPathObjPossible(FALSE);
+ case SDRREPFUNC_OBJ_GROUP : return rView.IsGroupPossible();
+ case SDRREPFUNC_OBJ_UNGROUP : return rView.IsUnGroupPossible();
+ case SDRREPFUNC_OBJ_PUTTOTOP : return rView.IsToTopPossible();
+ case SDRREPFUNC_OBJ_PUTTOBTM : return rView.IsToBtmPossible();
+ case SDRREPFUNC_OBJ_MOVTOTOP : return rView.IsToTopPossible();
+ case SDRREPFUNC_OBJ_MOVTOBTM : return rView.IsToBtmPossible();
+ case SDRREPFUNC_OBJ_REVORDER : return rView.IsReverseOrderPossible();
+ case SDRREPFUNC_OBJ_IMPORTMTF : return rView.IsImportMtfPossible();
+ default: break;
+ } // switch
+ return FALSE;
+}
+
+void SdrUndoGroup::SdrRepeat(SdrView& rView)
+{
+ switch (eFunction) {
+ case SDRREPFUNC_OBJ_NONE : break;
+ case SDRREPFUNC_OBJ_DELETE : rView.DeleteMarked(); break;
+ case SDRREPFUNC_OBJ_COMBINE_POLYPOLY: rView.CombineMarkedObjects(sal_False); break;
+ case SDRREPFUNC_OBJ_COMBINE_ONEPOLY : rView.CombineMarkedObjects(sal_True); break;
+ case SDRREPFUNC_OBJ_DISMANTLE_POLYS : rView.DismantleMarkedObjects(FALSE); break;
+ case SDRREPFUNC_OBJ_DISMANTLE_LINES : rView.DismantleMarkedObjects(TRUE); break;
+ case SDRREPFUNC_OBJ_CONVERTTOPOLY : rView.ConvertMarkedToPolyObj(FALSE); break;
+ case SDRREPFUNC_OBJ_CONVERTTOPATH : rView.ConvertMarkedToPathObj(FALSE); break;
+ case SDRREPFUNC_OBJ_GROUP : rView.GroupMarked(); break;
+ case SDRREPFUNC_OBJ_UNGROUP : rView.UnGroupMarked(); break;
+ case SDRREPFUNC_OBJ_PUTTOTOP : rView.PutMarkedToTop(); break;
+ case SDRREPFUNC_OBJ_PUTTOBTM : rView.PutMarkedToBtm(); break;
+ case SDRREPFUNC_OBJ_MOVTOTOP : rView.MovMarkedToTop(); break;
+ case SDRREPFUNC_OBJ_MOVTOBTM : rView.MovMarkedToBtm(); break;
+ case SDRREPFUNC_OBJ_REVORDER : rView.ReverseOrderOfMarked(); break;
+ case SDRREPFUNC_OBJ_IMPORTMTF : rView.DoImportMarkedMtf(); break;
+ default: break;
+ } // switch
+}
+
+XubString SdrUndoGroup::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aRet(aComment);
+ sal_Char aSearchText[] = "%1";
+ String aSearchString(aSearchText, sizeof(aSearchText-1));
+
+ aRet.SearchAndReplace(aSearchString, ImpGetResStr(STR_ObjNameSingulPlural));
+
+ return aRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@ @@@@@ @@@@@@ @@@@@ @@@@ @@@@@@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@@@@ @@ @@@@ @@ @@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@ @@@@@ @@@@ @@@@@ @@@@ @@ @@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoObj::SdrUndoObj(SdrObject& rNewObj):
+ SdrUndoAction(*rNewObj.GetModel()),
+ pObj(&rNewObj)
+{
+}
+
+void SdrUndoObj::GetDescriptionStringForObject( const SdrObject& _rForObject, USHORT nStrCacheID, String& rStr, FASTBOOL bRepeat )
+{
+ rStr = ImpGetResStr(nStrCacheID);
+ sal_Char aSearchText[] = "%1";
+ String aSearchString(aSearchText, sizeof(aSearchText-1));
+
+ xub_StrLen nPos = rStr.Search(aSearchString);
+
+ if(nPos != STRING_NOTFOUND)
+ {
+ rStr.Erase(nPos, 2);
+
+ if(bRepeat)
+ {
+ rStr.Insert(ImpGetResStr(STR_ObjNameSingulPlural), nPos);
+ }
+ else
+ {
+ XubString aStr;
+
+ _rForObject.TakeObjNameSingul(aStr);
+ rStr.Insert(aStr, nPos);
+ }
+ }
+}
+
+void SdrUndoObj::ImpTakeDescriptionStr(USHORT nStrCacheID, XubString& rStr, FASTBOOL bRepeat) const
+{
+ if ( pObj )
+ GetDescriptionStringForObject( *pObj, nStrCacheID, rStr, bRepeat );
+}
+
+// #94278# common call method for evtl. page change when UNDO/REDO
+// is triggered
+void SdrUndoObj::ImpShowPageOfThisObject()
+{
+ if(pObj && pObj->IsInserted() && pObj->GetPage() && pObj->GetModel())
+ {
+ SdrHint aHint(HINT_SWITCHTOPAGE);
+
+ aHint.SetObject(pObj);
+ aHint.SetPage(pObj->GetPage());
+
+ pObj->GetModel()->Broadcast(aHint);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoAttrObj::SdrUndoAttrObj(SdrObject& rNewObj, FASTBOOL bStyleSheet1, FASTBOOL bSaveText)
+: SdrUndoObj(rNewObj),
+ pUndoSet(NULL),
+ pRedoSet(NULL),
+ pRepeatSet(NULL),
+ pUndoStyleSheet(NULL),
+ pRedoStyleSheet(NULL),
+ pRepeatStyleSheet(NULL),
+ bHaveToTakeRedoSet(TRUE),
+ pTextUndo(NULL),
+
+ // #i8508#
+ pTextRedo(NULL),
+
+ pUndoGroup(NULL)
+{
+ bStyleSheet = bStyleSheet1;
+
+ SdrObjList* pOL = rNewObj.GetSubList();
+ BOOL bIsGroup(pOL!=NULL && pOL->GetObjCount());
+ BOOL bIs3DScene(bIsGroup && pObj->ISA(E3dScene));
+
+ if(bIsGroup)
+ {
+ // Aha, Gruppenobjekt
+ pUndoGroup = new SdrUndoGroup(*pObj->GetModel());
+ sal_uInt32 nObjAnz(pOL->GetObjCount());
+
+ for(sal_uInt32 nObjNum(0); nObjNum < nObjAnz; nObjNum++)
+ {
+ pUndoGroup->AddAction(
+ new SdrUndoAttrObj(*pOL->GetObj(nObjNum), bStyleSheet1));
+ }
+ }
+
+ if(!bIsGroup || bIs3DScene)
+ {
+ if(pUndoSet)
+ {
+ delete pUndoSet;
+ }
+
+ pUndoSet = new SfxItemSet(pObj->GetMergedItemSet());
+
+ if(bStyleSheet)
+ pUndoStyleSheet = pObj->GetStyleSheet();
+
+ if(bSaveText)
+ {
+ pTextUndo = pObj->GetOutlinerParaObject();
+ if(pTextUndo)
+ pTextUndo = new OutlinerParaObject(*pTextUndo);
+ }
+ }
+}
+
+SdrUndoAttrObj::~SdrUndoAttrObj()
+{
+ if(pUndoSet)
+ delete pUndoSet;
+ if(pRedoSet)
+ delete pRedoSet;
+ if(pRepeatSet)
+ delete pRepeatSet;
+ if(pUndoGroup)
+ delete pUndoGroup;
+ if(pTextUndo)
+ delete pTextUndo;
+
+ // #i8508#
+ if(pTextRedo)
+ delete pTextRedo;
+}
+
+void SdrUndoAttrObj::SetRepeatAttr(const SfxItemSet& rSet)
+{
+ if(pRepeatSet)
+ delete pRepeatSet;
+
+ pRepeatSet = new SfxItemSet(rSet);
+}
+
+void SdrUndoAttrObj::Undo()
+{
+ E3DModifySceneSnapRectUpdater aUpdater(pObj);
+ BOOL bIs3DScene(pObj && pObj->ISA(E3dScene));
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ if(!pUndoGroup || bIs3DScene)
+ {
+ if(bHaveToTakeRedoSet)
+ {
+ bHaveToTakeRedoSet = FALSE;
+
+ if(pRedoSet)
+ {
+ delete pRedoSet;
+ }
+
+ pRedoSet = new SfxItemSet(pObj->GetMergedItemSet());
+
+ if(bStyleSheet)
+ pRedoStyleSheet=pObj->GetStyleSheet();
+
+ if(pTextUndo)
+ {
+ // #i8508#
+ pTextRedo = pObj->GetOutlinerParaObject();
+
+ if(pTextRedo)
+ pTextRedo = new OutlinerParaObject(*pTextRedo);
+ }
+ }
+
+ if(bStyleSheet)
+ {
+ pRedoStyleSheet = pObj->GetStyleSheet();
+ pObj->SetStyleSheet(pUndoStyleSheet, TRUE);
+ }
+
+ sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
+
+ // #105122# Since ClearItem sets back everything to normal
+ // it also sets fit-to-size text to non-fit-to-size text and
+ // switches on autogrowheight (the default). That may lead to
+ // loosing the geometry size info for the object when it is
+ // re-layouted from AdjustTextFrameWidthAndHeight(). This makes
+ // rescuing the size of the object necessary.
+ const Rectangle aSnapRect = pObj->GetSnapRect();
+
+ if(pUndoSet)
+ {
+ // #109587#
+ if(pObj->ISA(SdrCaptionObj))
+ {
+ // do a more smooth item deletion here, else the text
+ // rect will be reformatted, especially when information regarding
+ // vertical text is changed. When clearing only set items it's
+ // slower, but safer regarding such information (it's not changed
+ // usually)
+ SfxWhichIter aIter(*pUndoSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+
+ while(nWhich)
+ {
+ if(SFX_ITEM_SET != pUndoSet->GetItemState(nWhich, sal_False))
+ {
+ pObj->ClearMergedItem(nWhich);
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+ else
+ {
+ pObj->ClearMergedItem();
+ }
+
+ pObj->SetMergedItemSet(*pUndoSet);
+ }
+
+ // #105122# Restore prev size here when it was changed.
+ if(aSnapRect != pObj->GetSnapRect())
+ {
+ pObj->NbcSetSnapRect(aSnapRect);
+ }
+
+ pObj->GetProperties().BroadcastItemChange(aItemChange);
+
+ if(pTextUndo)
+ {
+ pObj->SetOutlinerParaObject(new OutlinerParaObject(*pTextUndo));
+ }
+ }
+
+ if(pUndoGroup)
+ {
+ pUndoGroup->Undo();
+ }
+}
+
+void SdrUndoAttrObj::Redo()
+{
+ E3DModifySceneSnapRectUpdater aUpdater(pObj);
+ BOOL bIs3DScene(pObj && pObj->ISA(E3dScene));
+
+ if(!pUndoGroup || bIs3DScene)
+ {
+ if(bStyleSheet)
+ {
+ pUndoStyleSheet = pObj->GetStyleSheet();
+ pObj->SetStyleSheet(pRedoStyleSheet, TRUE);
+ }
+
+ sdr::properties::ItemChangeBroadcaster aItemChange(*pObj);
+
+ // #105122#
+ const Rectangle aSnapRect = pObj->GetSnapRect();
+
+ if(pRedoSet)
+ {
+ // #109587#
+ if(pObj->ISA(SdrCaptionObj))
+ {
+ // do a more smooth item deletion here, else the text
+ // rect will be reformatted, especially when information regarding
+ // vertical text is changed. When clearing only set items it's
+ // slower, but safer regarding such information (it's not changed
+ // usually)
+ SfxWhichIter aIter(*pRedoSet);
+ sal_uInt16 nWhich(aIter.FirstWhich());
+
+ while(nWhich)
+ {
+ if(SFX_ITEM_SET != pRedoSet->GetItemState(nWhich, sal_False))
+ {
+ pObj->ClearMergedItem(nWhich);
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+ }
+ else
+ {
+ pObj->ClearMergedItem();
+ }
+
+ pObj->SetMergedItemSet(*pRedoSet);
+ }
+
+ // #105122# Restore prev size here when it was changed.
+ if(aSnapRect != pObj->GetSnapRect())
+ {
+ pObj->NbcSetSnapRect(aSnapRect);
+ }
+
+ pObj->GetProperties().BroadcastItemChange(aItemChange);
+
+ // #i8508#
+ if(pTextRedo)
+ {
+ pObj->SetOutlinerParaObject(new OutlinerParaObject(*pTextRedo));
+ }
+ }
+
+ if(pUndoGroup)
+ {
+ pUndoGroup->Redo();
+ }
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+XubString SdrUndoAttrObj::GetComment() const
+{
+ XubString aStr;
+
+ if(bStyleSheet)
+ {
+ ImpTakeDescriptionStr(STR_EditSetStylesheet, aStr);
+ }
+ else
+ {
+ ImpTakeDescriptionStr(STR_EditSetAttributes, aStr);
+ }
+
+ return aStr;
+}
+
+void SdrUndoAttrObj::SdrRepeat(SdrView& rView)
+{
+ if(pRepeatSet)
+ {
+ rView.SetAttrToMarked(*pRepeatSet, FALSE);
+ }
+}
+
+bool SdrUndoAttrObj::CanSdrRepeat(SdrView& rView) const
+{
+ return (pRepeatSet!=0L && rView.AreObjectsMarked());
+}
+
+XubString SdrUndoAttrObj::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+
+ if(bStyleSheet)
+ {
+ ImpTakeDescriptionStr(STR_EditSetStylesheet, aStr, TRUE);
+ }
+ else
+ {
+ ImpTakeDescriptionStr(STR_EditSetAttributes, aStr, TRUE);
+ }
+
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoMoveObj::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ pObj->Move(Size(-aDistance.Width(),-aDistance.Height()));
+}
+
+void SdrUndoMoveObj::Redo()
+{
+ pObj->Move(Size(aDistance.Width(),aDistance.Height()));
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+XubString SdrUndoMoveObj::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditMove,aStr);
+ return aStr;
+}
+
+void SdrUndoMoveObj::SdrRepeat(SdrView& rView)
+{
+ rView.MoveMarkedObj(aDistance);
+}
+
+bool SdrUndoMoveObj::CanSdrRepeat(SdrView& rView) const
+{
+ return rView.AreObjectsMarked();
+}
+
+XubString SdrUndoMoveObj::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditMove,aStr,TRUE);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoGeoObj::SdrUndoGeoObj(SdrObject& rNewObj):
+ SdrUndoObj(rNewObj),
+ pUndoGeo(NULL),
+ pRedoGeo(NULL),
+ pUndoGroup(NULL)
+{
+ SdrObjList* pOL=rNewObj.GetSubList();
+ if (pOL!=NULL && pOL->GetObjCount() && !rNewObj.ISA(E3dScene))
+ {
+ // Aha, Gruppenobjekt
+ // AW: Aber keine 3D-Szene, dann nur fuer die Szene selbst den Undo anlegen
+ pUndoGroup=new SdrUndoGroup(*pObj->GetModel());
+ ULONG nObjAnz=pOL->GetObjCount();
+ for (ULONG nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
+ pUndoGroup->AddAction(new SdrUndoGeoObj(*pOL->GetObj(nObjNum)));
+ }
+ } else {
+ pUndoGeo=pObj->GetGeoData();
+ }
+}
+
+SdrUndoGeoObj::~SdrUndoGeoObj()
+{
+ if (pUndoGeo!=NULL) delete pUndoGeo;
+ if (pRedoGeo!=NULL) delete pRedoGeo;
+ if (pUndoGroup!=NULL) delete pUndoGroup;
+}
+
+void SdrUndoGeoObj::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ if(pUndoGroup)
+ {
+ pUndoGroup->Undo();
+
+ // #97172#
+ // only repaint, no objectchange
+ pObj->ActionChanged();
+ }
+ else
+ {
+ if (pRedoGeo!=NULL) delete pRedoGeo;
+ pRedoGeo=pObj->GetGeoData();
+ pObj->SetGeoData(*pUndoGeo);
+ }
+}
+
+void SdrUndoGeoObj::Redo()
+{
+ if(pUndoGroup)
+ {
+ pUndoGroup->Redo();
+
+ // #97172#
+ // only repaint, no objectchange
+ pObj->ActionChanged();
+ }
+ else
+ {
+ if (pUndoGeo!=NULL) delete pUndoGeo;
+ pUndoGeo=pObj->GetGeoData();
+ pObj->SetGeoData(*pRedoGeo);
+ }
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+XubString SdrUndoGeoObj::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_DragMethObjOwn,aStr);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoObjList::SdrUndoObjList(SdrObject& rNewObj, bool bOrdNumDirect)
+: SdrUndoObj(rNewObj),
+ bOwner(FALSE),
+ pView(NULL),
+ pPageView(NULL)
+{
+ pObjList=pObj->GetObjList();
+ if (bOrdNumDirect) {
+ nOrdNum=pObj->GetOrdNumDirect();
+ } else {
+ nOrdNum=pObj->GetOrdNum();
+ }
+}
+
+SdrUndoObjList::~SdrUndoObjList()
+{
+ if (pObj!=NULL && IsOwner())
+ {
+ // Attribute muessen wieder in den regulaeren Pool
+ SetOwner(FALSE);
+
+ // nun loeschen
+ SdrObject::Free( pObj );
+ }
+}
+
+void SdrUndoObjList::SetOwner(bool bNew)
+{
+ bOwner = bNew;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoRemoveObj::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ DBG_ASSERT(!pObj->IsInserted(),"UndoRemoveObj: pObj ist bereits Inserted");
+ if (!pObj->IsInserted())
+ {
+ // #i11426#
+ // For UNDOs in Calc/Writer it is necessary to adapt the anchor
+ // pos of the target object.
+ Point aOwnerAnchorPos(0, 0);
+
+ if(pObjList
+ && pObjList->GetOwnerObj()
+ && pObjList->GetOwnerObj()->ISA(SdrObjGroup))
+ {
+ aOwnerAnchorPos = pObjList->GetOwnerObj()->GetAnchorPos();
+ }
+
+ E3DModifySceneSnapRectUpdater aUpdater(pObjList->GetOwnerObj());
+ SdrInsertReason aReason(SDRREASON_UNDO);
+ pObjList->InsertObject(pObj,nOrdNum,&aReason);
+
+ // #i11426#
+ if(aOwnerAnchorPos.X() || aOwnerAnchorPos.Y())
+ {
+ pObj->NbcSetAnchorPos(aOwnerAnchorPos);
+ }
+ }
+}
+
+void SdrUndoRemoveObj::Redo()
+{
+ DBG_ASSERT(pObj->IsInserted(),"RedoRemoveObj: pObj ist nicht Inserted");
+ if (pObj->IsInserted())
+ {
+ ImplUnmarkObject( pObj );
+ E3DModifySceneSnapRectUpdater aUpdater(pObj);
+ pObjList->RemoveObject(nOrdNum);
+ }
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoInsertObj::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ DBG_ASSERT(pObj->IsInserted(),"UndoInsertObj: pObj ist nicht Inserted");
+ if (pObj->IsInserted())
+ {
+ ImplUnmarkObject( pObj );
+
+#ifdef DBG_UTIL
+ SdrObject* pChkObj=
+#endif
+ pObjList->RemoveObject(nOrdNum);
+ DBG_ASSERT(pChkObj==pObj,"UndoInsertObj: RemoveObjNum!=pObj");
+ }
+}
+
+void SdrUndoInsertObj::Redo()
+{
+ DBG_ASSERT(!pObj->IsInserted(),"RedoInsertObj: pObj ist bereits Inserted");
+ if (!pObj->IsInserted())
+ {
+ // --> OD 2005-05-10 #i45952# - restore anchor position of an object,
+ // which becomes a member of a group, because its cleared in method
+ // <InsertObject(..)>. Needed for correct ReDo in Writer.
+ Point aAnchorPos( 0, 0 );
+ if ( pObjList &&
+ pObjList->GetOwnerObj() &&
+ pObjList->GetOwnerObj()->ISA(SdrObjGroup) )
+ {
+ aAnchorPos = pObj->GetAnchorPos();
+ }
+ // <--
+
+ SdrInsertReason aReason(SDRREASON_UNDO);
+ pObjList->InsertObject(pObj,nOrdNum,&aReason);
+
+ // --> OD 2005-05-10 #i45952#
+ if ( aAnchorPos.X() || aAnchorPos.Y() )
+ {
+ pObj->NbcSetAnchorPos( aAnchorPos );
+ }
+ // <--
+ }
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoDelObj::Undo()
+{
+ SdrUndoRemoveObj::Undo();
+ DBG_ASSERT(IsOwner(),"UndoDeleteObj: pObj gehoert nicht der UndoAction");
+ SetOwner(FALSE);
+}
+
+void SdrUndoDelObj::Redo()
+{
+ SdrUndoRemoveObj::Redo();
+ DBG_ASSERT(!IsOwner(),"RedoDeleteObj: pObj gehoert bereits der UndoAction");
+ SetOwner(TRUE);
+}
+
+XubString SdrUndoDelObj::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditDelete,aStr);
+ return aStr;
+}
+
+void SdrUndoDelObj::SdrRepeat(SdrView& rView)
+{
+ rView.DeleteMarked();
+}
+
+bool SdrUndoDelObj::CanSdrRepeat(SdrView& rView) const
+{
+ return rView.AreObjectsMarked();
+}
+
+XubString SdrUndoDelObj::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_EditDelete,aStr,TRUE);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoNewObj::Undo()
+{
+ SdrUndoInsertObj::Undo();
+ DBG_ASSERT(!IsOwner(),"RedoNewObj: pObj gehoert bereits der UndoAction");
+ SetOwner(TRUE);
+}
+
+void SdrUndoNewObj::Redo()
+{
+ SdrUndoInsertObj::Redo();
+ DBG_ASSERT(IsOwner(),"RedoNewObj: pObj gehoert nicht der UndoAction");
+ SetOwner(FALSE);
+}
+
+String SdrUndoNewObj::GetComment( const SdrObject& _rForObject )
+{
+ String sComment;
+ GetDescriptionStringForObject( _rForObject, STR_UndoInsertObj, sComment );
+ return sComment;
+}
+
+XubString SdrUndoNewObj::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoInsertObj,aStr);
+ return aStr;
+}
+
+SdrUndoReplaceObj::SdrUndoReplaceObj(SdrObject& rOldObj1, SdrObject& rNewObj1, bool bOrdNumDirect)
+: SdrUndoObj(rOldObj1),
+ bOldOwner(FALSE),
+ bNewOwner(FALSE),
+ pNewObj(&rNewObj1)
+{
+ SetOldOwner(TRUE);
+
+ pObjList=pObj->GetObjList();
+ if (bOrdNumDirect) {
+ nOrdNum=pObj->GetOrdNumDirect();
+ } else {
+ nOrdNum=pObj->GetOrdNum();
+ }
+}
+
+SdrUndoReplaceObj::~SdrUndoReplaceObj()
+{
+ if (pObj!=NULL && IsOldOwner())
+ {
+ // Attribute muessen wieder in den regulaeren Pool
+ SetOldOwner(FALSE);
+
+ // nun loeschen
+ SdrObject::Free( pObj );
+ }
+ if (pNewObj!=NULL && IsNewOwner())
+ {
+ // Attribute muessen wieder in den regulaeren Pool
+ SetNewOwner(FALSE);
+
+ // nun loeschen
+ SdrObject::Free( pNewObj );
+ }
+}
+
+void SdrUndoReplaceObj::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ if (IsOldOwner() && !IsNewOwner())
+ {
+ DBG_ASSERT(!pObj->IsInserted(),"SdrUndoReplaceObj::Undo(): Altes Objekt ist bereits inserted!");
+ DBG_ASSERT(pNewObj->IsInserted(),"SdrUndoReplaceObj::Undo(): Neues Objekt ist nicht inserted!");
+ SetOldOwner(FALSE);
+ SetNewOwner(TRUE);
+
+ ImplUnmarkObject( pNewObj );
+ pObjList->ReplaceObject(pObj,nOrdNum);
+ }
+ else
+ {
+ DBG_ERROR("SdrUndoReplaceObj::Undo(): IsMine-Flags stehen verkehrt. Doppelter Undo-Aufruf?");
+ }
+}
+
+void SdrUndoReplaceObj::Redo()
+{
+ if (!IsOldOwner() && IsNewOwner())
+ {
+ DBG_ASSERT(!pNewObj->IsInserted(),"SdrUndoReplaceObj::Redo(): Neues Objekt ist bereits inserted!");
+ DBG_ASSERT(pObj->IsInserted(),"SdrUndoReplaceObj::Redo(): Altes Objekt ist nicht inserted!");
+ SetOldOwner(TRUE);
+ SetNewOwner(FALSE);
+
+ ImplUnmarkObject( pObj );
+ pObjList->ReplaceObject(pNewObj,nOrdNum);
+
+ }
+ else
+ {
+ DBG_ERROR("SdrUndoReplaceObj::Redo(): IsMine-Flags stehen verkehrt. Doppelter Redo-Aufruf?");
+ }
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+void SdrUndoReplaceObj::SetNewOwner(bool bNew)
+{
+ bNewOwner = bNew;
+}
+
+void SdrUndoReplaceObj::SetOldOwner(bool bNew)
+{
+ bOldOwner = bNew;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+XubString SdrUndoCopyObj::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoCopyObj,aStr);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// #i11702#
+
+SdrUndoObjectLayerChange::SdrUndoObjectLayerChange(SdrObject& rObj, SdrLayerID aOldLayer, SdrLayerID aNewLayer)
+: SdrUndoObj(rObj),
+ maOldLayer(aOldLayer),
+ maNewLayer(aNewLayer)
+{
+}
+
+void SdrUndoObjectLayerChange::Undo()
+{
+ ImpShowPageOfThisObject();
+ pObj->SetLayer(maOldLayer);
+}
+
+void SdrUndoObjectLayerChange::Redo()
+{
+ pObj->SetLayer(maNewLayer);
+ ImpShowPageOfThisObject();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoObjOrdNum::SdrUndoObjOrdNum(SdrObject& rNewObj, UINT32 nOldOrdNum1, UINT32 nNewOrdNum1):
+ SdrUndoObj(rNewObj),
+ nOldOrdNum(nOldOrdNum1),
+ nNewOrdNum(nNewOrdNum1)
+{
+}
+
+void SdrUndoObjOrdNum::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL==NULL) {
+ DBG_ERROR("UndoObjOrdNum: pObj hat keine ObjList");
+ return;
+ }
+ pOL->SetObjectOrdNum(nNewOrdNum,nOldOrdNum);
+}
+
+void SdrUndoObjOrdNum::Redo()
+{
+ SdrObjList* pOL=pObj->GetObjList();
+ if (pOL==NULL) {
+ DBG_ERROR("RedoObjOrdNum: pObj hat keine ObjList");
+ return;
+ }
+ pOL->SetObjectOrdNum(nOldOrdNum,nNewOrdNum);
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+XubString SdrUndoObjOrdNum::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoObjOrdNum,aStr);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoObjSetText::SdrUndoObjSetText(SdrObject& rNewObj, sal_Int32 nText)
+: SdrUndoObj(rNewObj)
+, pOldText(NULL)
+, pNewText(NULL)
+, bNewTextAvailable(FALSE)
+, bEmptyPresObj(FALSE)
+, mnText(nText)
+{
+ SdrText* pText = static_cast< SdrTextObj*>( &rNewObj )->getText(mnText);
+ if( pText && pText->GetOutlinerParaObject() )
+ pOldText = new OutlinerParaObject(*pText->GetOutlinerParaObject());
+
+ bEmptyPresObj = rNewObj.IsEmptyPresObj();
+}
+
+SdrUndoObjSetText::~SdrUndoObjSetText()
+{
+ if ( pOldText )
+ delete pOldText;
+ if ( pNewText )
+ delete pNewText;
+}
+
+void SdrUndoObjSetText::AfterSetText()
+{
+ if (!bNewTextAvailable)
+ {
+ SdrText* pText = static_cast< SdrTextObj*>( pObj )->getText(mnText);
+ if( pText && pText->GetOutlinerParaObject() )
+ pNewText = new OutlinerParaObject(*pText->GetOutlinerParaObject());
+ bNewTextAvailable=TRUE;
+ }
+}
+
+void SdrUndoObjSetText::Undo()
+{
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+
+ // alten Text sichern fuer Redo
+ if (!bNewTextAvailable)
+ AfterSetText();
+
+ // Text fuer Undo kopieren, denn SetOutlinerParaObject() ist Eigentumsuebereignung
+ OutlinerParaObject* pText1 = pOldText;
+ if(pText1)
+ pText1 = new OutlinerParaObject(*pText1);
+
+ SdrText* pText = static_cast< SdrTextObj*>( pObj )->getText(mnText);
+ if( pText )
+ pText->SetOutlinerParaObject(pText1);
+
+ pObj->SetEmptyPresObj( bEmptyPresObj );
+ pObj->ActionChanged();
+}
+
+void SdrUndoObjSetText::Redo()
+{
+ // Text fuer Undo kopieren, denn SetOutlinerParaObject() ist Eigentumsuebereignung
+ OutlinerParaObject* pText1 = pNewText;
+
+ if(pText1)
+ pText1 = new OutlinerParaObject(*pText1);
+
+ SdrText* pText = static_cast< SdrTextObj*>( pObj )->getText(mnText);
+ if( pText )
+ static_cast< SdrTextObj* >( pObj )->NbcSetOutlinerParaObjectForText( pText1, pText );
+
+ pObj->ActionChanged();
+
+ // #94278# Trigger PageChangeCall
+ ImpShowPageOfThisObject();
+}
+
+XubString SdrUndoObjSetText::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoObjSetText,aStr);
+ return aStr;
+}
+
+XubString SdrUndoObjSetText::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoObjSetText,aStr);
+ return aStr;
+}
+
+void SdrUndoObjSetText::SdrRepeat(SdrView& rView)
+{
+ if (bNewTextAvailable && rView.AreObjectsMarked())
+ {
+ const SdrMarkList& rML=rView.GetMarkedObjectList();
+
+ const bool bUndo = rView.IsUndoEnabled();
+ if( bUndo )
+ {
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoObjSetText,aStr);
+ rView.BegUndo(aStr);
+ }
+
+ ULONG nAnz=rML.GetMarkCount();
+ for (ULONG nm=0; nm<nAnz; nm++)
+ {
+ SdrObject* pObj2=rML.GetMark(nm)->GetMarkedSdrObj();
+ SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pObj2);
+ if (pTextObj!=NULL)
+ {
+ if( bUndo )
+ rView.AddUndo(new SdrUndoObjSetText(*pTextObj,0));
+
+ OutlinerParaObject* pText1=pNewText;
+ if (pText1!=NULL)
+ pText1 = new OutlinerParaObject(*pText1);
+ pTextObj->SetOutlinerParaObject(pText1);
+ }
+ }
+
+ if( bUndo )
+ rView.EndUndo();
+ }
+}
+
+bool SdrUndoObjSetText::CanSdrRepeat(SdrView& rView) const
+{
+ FASTBOOL bOk=FALSE;
+ if (bNewTextAvailable && rView.AreObjectsMarked()) {
+ bOk=TRUE;
+ }
+ return bOk;
+}
+
+// --> OD 2009-07-09 #i73249#
+SdrUndoObjStrAttr::SdrUndoObjStrAttr( SdrObject& rNewObj,
+ const ObjStrAttrType eObjStrAttr,
+ const String& sOldStr,
+ const String& sNewStr)
+ : SdrUndoObj( rNewObj ),
+ meObjStrAttr( eObjStrAttr ),
+ msOldStr( sOldStr ),
+ msNewStr( sNewStr )
+{
+}
+
+void SdrUndoObjStrAttr::Undo()
+{
+ ImpShowPageOfThisObject();
+
+ switch ( meObjStrAttr )
+ {
+ case OBJ_NAME:
+ {
+ pObj->SetName( msOldStr );
+ }
+ break;
+ case OBJ_TITLE:
+ {
+ pObj->SetTitle( msOldStr );
+ }
+ break;
+ case OBJ_DESCRIPTION:
+ {
+ pObj->SetDescription( msOldStr );
+ }
+ break;
+ }
+}
+
+void SdrUndoObjStrAttr::Redo()
+{
+ switch ( meObjStrAttr )
+ {
+ case OBJ_NAME:
+ {
+ pObj->SetName( msNewStr );
+ }
+ break;
+ case OBJ_TITLE:
+ {
+ pObj->SetTitle( msNewStr );
+ }
+ break;
+ case OBJ_DESCRIPTION:
+ {
+ pObj->SetDescription( msNewStr );
+ }
+ break;
+ }
+
+ ImpShowPageOfThisObject();
+}
+
+String SdrUndoObjStrAttr::GetComment() const
+{
+ String aStr;
+ switch ( meObjStrAttr )
+ {
+ case OBJ_NAME:
+ {
+ ImpTakeDescriptionStr( STR_UndoObjName, aStr );
+ aStr += sal_Unicode(' ');
+ aStr += sal_Unicode('\'');
+ aStr += msNewStr;
+ aStr += sal_Unicode('\'');
+ }
+ break;
+ case OBJ_TITLE:
+ {
+ ImpTakeDescriptionStr( STR_UndoObjTitle, aStr );
+ }
+ break;
+ case OBJ_DESCRIPTION:
+ {
+ ImpTakeDescriptionStr( STR_UndoObjDescription, aStr );
+ }
+ break;
+ }
+
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@@@ @@ @@ @@@@@ @@@@@
+// @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@@@@@ @@@@ @@@@ @@@@@
+// @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@
+// @@@@@ @@ @@ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoLayer::SdrUndoLayer(USHORT nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel):
+ SdrUndoAction(rNewModel),
+ pLayer(rNewLayerAdmin.GetLayer(nLayerNum)),
+ pLayerAdmin(&rNewLayerAdmin),
+ nNum(nLayerNum),
+ bItsMine(FALSE)
+{
+}
+
+SdrUndoLayer::~SdrUndoLayer()
+{
+ if (bItsMine) {
+ delete pLayer;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoNewLayer::Undo()
+{
+ DBG_ASSERT(!bItsMine,"SdrUndoNewLayer::Undo(): Layer gehoert bereits der UndoAction");
+ bItsMine=TRUE;
+#ifdef DBG_UTIL
+ SdrLayer* pCmpLayer=
+#endif
+ pLayerAdmin->RemoveLayer(nNum);
+ DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoNewLayer::Undo(): Removter Layer ist != pLayer");
+}
+
+void SdrUndoNewLayer::Redo()
+{
+ DBG_ASSERT(bItsMine,"SdrUndoNewLayer::Undo(): Layer gehoert nicht der UndoAction");
+ bItsMine=FALSE;
+ pLayerAdmin->InsertLayer(pLayer,nNum);
+}
+
+XubString SdrUndoNewLayer::GetComment() const
+{
+ return ImpGetResStr(STR_UndoNewLayer);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoDelLayer::Undo()
+{
+ DBG_ASSERT(bItsMine,"SdrUndoDelLayer::Undo(): Layer gehoert nicht der UndoAction");
+ bItsMine=FALSE;
+ pLayerAdmin->InsertLayer(pLayer,nNum);
+}
+
+void SdrUndoDelLayer::Redo()
+{
+ DBG_ASSERT(!bItsMine,"SdrUndoDelLayer::Undo(): Layer gehoert bereits der UndoAction");
+ bItsMine=TRUE;
+#ifdef DBG_UTIL
+ SdrLayer* pCmpLayer=
+#endif
+ pLayerAdmin->RemoveLayer(nNum);
+ DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoDelLayer::Redo(): Removter Layer ist != pLayer");
+}
+
+XubString SdrUndoDelLayer::GetComment() const
+{
+ return ImpGetResStr(STR_UndoDelLayer);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoMoveLayer::Undo()
+{
+#ifdef DBG_UTIL
+ SdrLayer* pCmpLayer=
+#endif
+ pLayerAdmin->RemoveLayer(nNeuPos);
+ DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoMoveLayer::Undo(): Removter Layer ist != pLayer");
+ pLayerAdmin->InsertLayer(pLayer,nNum);
+}
+
+void SdrUndoMoveLayer::Redo()
+{
+#ifdef DBG_UTIL
+ SdrLayer* pCmpLayer=
+#endif
+ pLayerAdmin->RemoveLayer(nNum);
+ DBG_ASSERT(pCmpLayer==pLayer,"SdrUndoMoveLayer::Redo(): Removter Layer ist != pLayer");
+ pLayerAdmin->InsertLayer(pLayer,nNeuPos);
+}
+
+XubString SdrUndoMoveLayer::GetComment() const
+{
+ return ImpGetResStr(STR_UndoMovLayer);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@@@@ @@@@ @@@@ @@@@@ @@@@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@
+// @@@@@ @@@@@@ @@ @@@ @@@@ @@@@
+// @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@@@@ @@@@@ @@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoPage::SdrUndoPage(SdrPage& rNewPg)
+: SdrUndoAction(*rNewPg.GetModel()),
+ mrPage(rNewPg)
+{
+}
+
+void SdrUndoPage::ImpInsertPage(USHORT nNum)
+{
+ DBG_ASSERT(!mrPage.IsInserted(),"SdrUndoPage::ImpInsertPage(): mrPage ist bereits Inserted");
+ if (!mrPage.IsInserted()) {
+ if (mrPage.IsMasterPage()) {
+ rMod.InsertMasterPage(&mrPage,nNum);
+ } else {
+ rMod.InsertPage(&mrPage,nNum);
+ }
+ }
+}
+
+void SdrUndoPage::ImpRemovePage(USHORT nNum)
+{
+ DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpRemovePage(): mrPage ist nicht Inserted");
+ if (mrPage.IsInserted()) {
+ SdrPage* pChkPg=NULL;
+ if (mrPage.IsMasterPage()) {
+ pChkPg=rMod.RemoveMasterPage(nNum);
+ } else {
+ pChkPg=rMod.RemovePage(nNum);
+ }
+ DBG_ASSERT(pChkPg==&mrPage,"SdrUndoPage::ImpRemovePage(): RemovePage!=&mrPage");
+ }
+}
+
+void SdrUndoPage::ImpMovePage(USHORT nOldNum, USHORT nNewNum)
+{
+ DBG_ASSERT(mrPage.IsInserted(),"SdrUndoPage::ImpMovePage(): mrPage ist nicht Inserted");
+ if (mrPage.IsInserted()) {
+ if (mrPage.IsMasterPage()) {
+ rMod.MoveMasterPage(nOldNum,nNewNum);
+ } else {
+ rMod.MovePage(nOldNum,nNewNum);
+ }
+ }
+}
+
+void SdrUndoPage::ImpTakeDescriptionStr(USHORT nStrCacheID, XubString& rStr, USHORT /*n*/, FASTBOOL /*bRepeat*/) const
+{
+ rStr=ImpGetResStr(nStrCacheID);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoPageList::SdrUndoPageList(SdrPage& rNewPg):
+ SdrUndoPage(rNewPg),
+ bItsMine(FALSE)
+{
+ nPageNum=rNewPg.GetPageNum();
+}
+
+SdrUndoPageList::~SdrUndoPageList()
+{
+ if(bItsMine)
+ {
+ delete (&mrPage);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg):
+ SdrUndoPageList(rNewPg),
+ pUndoGroup(NULL)
+{
+ bItsMine = TRUE;
+
+ // Und nun ggf. die MasterPage-Beziehungen merken
+ if(mrPage.IsMasterPage())
+ {
+ sal_uInt16 nPageAnz(rMod.GetPageCount());
+
+ for(sal_uInt16 nPageNum2(0); nPageNum2 < nPageAnz; nPageNum2++)
+ {
+ SdrPage* pDrawPage = rMod.GetPage(nPageNum2);
+
+ if(pDrawPage->TRG_HasMasterPage())
+ {
+ SdrPage& rMasterPage = pDrawPage->TRG_GetMasterPage();
+
+ if(&mrPage == &rMasterPage)
+ {
+ if(!pUndoGroup)
+ {
+ pUndoGroup = new SdrUndoGroup(rMod);
+ }
+
+ pUndoGroup->AddAction(rMod.GetSdrUndoFactory().CreateUndoPageRemoveMasterPage(*pDrawPage));
+ }
+ }
+ }
+ }
+}
+
+SdrUndoDelPage::~SdrUndoDelPage()
+{
+ if (pUndoGroup!=NULL) {
+ delete pUndoGroup;
+ }
+}
+
+void SdrUndoDelPage::Undo()
+{
+ ImpInsertPage(nPageNum);
+ if (pUndoGroup!=NULL) { // MasterPage-Beziehungen wiederherstellen
+ pUndoGroup->Undo();
+ }
+ DBG_ASSERT(bItsMine,"UndoDeletePage: mrPage gehoert nicht der UndoAction");
+ bItsMine=FALSE;
+}
+
+void SdrUndoDelPage::Redo()
+{
+ ImpRemovePage(nPageNum);
+ // Die MasterPage-Beziehungen werden ggf. von selbst geloesst
+ DBG_ASSERT(!bItsMine,"RedoDeletePage: mrPage gehoert bereits der UndoAction");
+ bItsMine=TRUE;
+}
+
+XubString SdrUndoDelPage::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoDelPage,aStr,0,FALSE);
+ return aStr;
+}
+
+XubString SdrUndoDelPage::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoDelPage,aStr,0,FALSE);
+ return aStr;
+}
+
+void SdrUndoDelPage::SdrRepeat(SdrView& /*rView*/)
+{
+}
+
+bool SdrUndoDelPage::CanSdrRepeat(SdrView& /*rView*/) const
+{
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoNewPage::Undo()
+{
+ ImpRemovePage(nPageNum);
+ DBG_ASSERT(!bItsMine,"UndoNewPage: mrPage gehoert bereits der UndoAction");
+ bItsMine=TRUE;
+}
+
+void SdrUndoNewPage::Redo()
+{
+ ImpInsertPage(nPageNum);
+ DBG_ASSERT(bItsMine,"RedoNewPage: mrPage gehoert nicht der UndoAction");
+ bItsMine=FALSE;
+}
+
+XubString SdrUndoNewPage::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoNewPage,aStr,0,FALSE);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+XubString SdrUndoCopyPage::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoCopPage,aStr,0,FALSE);
+ return aStr;
+}
+
+XubString SdrUndoCopyPage::GetSdrRepeatComment(SdrView& /*rView*/) const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoCopPage,aStr,0,FALSE);
+ return aStr;
+}
+
+void SdrUndoCopyPage::SdrRepeat(SdrView& /*rView*/)
+{
+
+}
+
+bool SdrUndoCopyPage::CanSdrRepeat(SdrView& /*rView*/) const
+{
+ return FALSE;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrUndoSetPageNum::Undo()
+{
+ ImpMovePage(nNewPageNum,nOldPageNum);
+}
+
+void SdrUndoSetPageNum::Redo()
+{
+ ImpMovePage(nOldPageNum,nNewPageNum);
+}
+
+XubString SdrUndoSetPageNum::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoMovPage,aStr,0,FALSE);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@ @@@@ @@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@@ @@@@ @@@@@ @@@@
+// @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@@@@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@@@@@@ @@@@@@ @@@@ @@ @@@@ @@@@@ @@@@@ @@@@@@ @@ @@@ @@@@ @@@@
+// @@ @ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@@@ @@ @@@@@ @@ @@ @@ @@ @@ @@@@@ @@@@@ @@@@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoPageMasterPage::SdrUndoPageMasterPage(SdrPage& rChangedPage)
+: SdrUndoPage(rChangedPage),
+ mbOldHadMasterPage(mrPage.TRG_HasMasterPage())
+{
+ // get current state from page
+ if(mbOldHadMasterPage)
+ {
+ maOldSet = mrPage.TRG_GetMasterPageVisibleLayers();
+ maOldMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
+ }
+}
+
+SdrUndoPageMasterPage::~SdrUndoPageMasterPage()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoPageRemoveMasterPage::SdrUndoPageRemoveMasterPage(SdrPage& rChangedPage)
+: SdrUndoPageMasterPage(rChangedPage)
+{
+}
+
+void SdrUndoPageRemoveMasterPage::Undo()
+{
+ if(mbOldHadMasterPage)
+ {
+ mrPage.TRG_SetMasterPage(*mrPage.GetModel()->GetMasterPage(maOldMasterPageNumber));
+ mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
+ }
+}
+
+void SdrUndoPageRemoveMasterPage::Redo()
+{
+ mrPage.TRG_ClearMasterPage();
+}
+
+XubString SdrUndoPageRemoveMasterPage::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoDelPageMasterDscr,aStr,0,FALSE);
+ return aStr;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrUndoPageChangeMasterPage::SdrUndoPageChangeMasterPage(SdrPage& rChangedPage)
+: SdrUndoPageMasterPage(rChangedPage),
+ mbNewHadMasterPage(sal_False)
+{
+}
+
+void SdrUndoPageChangeMasterPage::Undo()
+{
+ // remember values from new page
+ if(mrPage.TRG_HasMasterPage())
+ {
+ mbNewHadMasterPage = sal_True;
+ maNewSet = mrPage.TRG_GetMasterPageVisibleLayers();
+ maNewMasterPageNumber = mrPage.TRG_GetMasterPage().GetPageNum();
+ }
+
+ // restore old values
+ if(mbOldHadMasterPage)
+ {
+ mrPage.TRG_ClearMasterPage();
+ mrPage.TRG_SetMasterPage(*mrPage.GetModel()->GetMasterPage(maOldMasterPageNumber));
+ mrPage.TRG_SetMasterPageVisibleLayers(maOldSet);
+ }
+}
+
+void SdrUndoPageChangeMasterPage::Redo()
+{
+ // restore new values
+ if(mbNewHadMasterPage)
+ {
+ mrPage.TRG_ClearMasterPage();
+ mrPage.TRG_SetMasterPage(*mrPage.GetModel()->GetMasterPage(maNewMasterPageNumber));
+ mrPage.TRG_SetMasterPageVisibleLayers(maNewSet);
+ }
+}
+
+XubString SdrUndoPageChangeMasterPage::GetComment() const
+{
+ XubString aStr;
+ ImpTakeDescriptionStr(STR_UndoChgPageMasterDscr,aStr,0,FALSE);
+ return aStr;
+}
+
+///////////////////////////////////////////////////////////////////////
+SdrUndoFactory::~SdrUndoFactory(){}
+// shapes
+SdrUndoAction* SdrUndoFactory::CreateUndoMoveObject( SdrObject& rObject )
+{
+ return new SdrUndoMoveObj( rObject );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoMoveObject( SdrObject& rObject, const Size& rDist )
+{
+ return new SdrUndoMoveObj( rObject, rDist );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoGeoObject( SdrObject& rObject )
+{
+ return new SdrUndoGeoObj( rObject );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1, bool bSaveText )
+{
+ return new SdrUndoAttrObj( rObject, bStyleSheet1 ? TRUE : FALSE, bSaveText ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoRemoveObject( SdrObject& rObject, bool bOrdNumDirect )
+{
+ return new SdrUndoRemoveObj( rObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoInsertObject( SdrObject& rObject, bool bOrdNumDirect )
+{
+ return new SdrUndoInsertObj( rObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoDeleteObject( SdrObject& rObject, bool bOrdNumDirect )
+{
+ return new SdrUndoDelObj( rObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoNewObject( SdrObject& rObject, bool bOrdNumDirect )
+{
+ return new SdrUndoNewObj( rObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoCopyObject( SdrObject& rObject, bool bOrdNumDirect )
+{
+ return new SdrUndoCopyObj( rObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoObjectOrdNum( SdrObject& rObject, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1)
+{
+ return new SdrUndoObjOrdNum( rObject, nOldOrdNum1, nNewOrdNum1 );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoReplaceObject( SdrObject& rOldObject, SdrObject& rNewObject, bool bOrdNumDirect )
+{
+ return new SdrUndoReplaceObj( rOldObject, rNewObject, bOrdNumDirect ? TRUE : FALSE );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoObjectLayerChange( SdrObject& rObject, SdrLayerID aOldLayer, SdrLayerID aNewLayer )
+{
+ return new SdrUndoObjectLayerChange( rObject, aOldLayer, aNewLayer );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoObjectSetText( SdrObject& rNewObj, sal_Int32 nText )
+{
+ return new SdrUndoObjSetText( rNewObj, nText );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoObjectStrAttr( SdrObject& rObject,
+ SdrUndoObjStrAttr::ObjStrAttrType eObjStrAttrType,
+ String sOldStr,
+ String sNewStr )
+{
+ return new SdrUndoObjStrAttr( rObject, eObjStrAttrType, sOldStr, sNewStr );
+}
+
+
+// layer
+SdrUndoAction* SdrUndoFactory::CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
+{
+ return new SdrUndoNewLayer( nLayerNum, rNewLayerAdmin, rNewModel );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoDeleteLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel)
+{
+ return new SdrUndoDelLayer( nLayerNum, rNewLayerAdmin, rNewModel );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoMoveLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel, sal_uInt16 nNeuPos1)
+{
+ return new SdrUndoMoveLayer( nLayerNum, rNewLayerAdmin, rNewModel, nNeuPos1 );
+}
+
+// page
+SdrUndoAction* SdrUndoFactory::CreateUndoDeletePage(SdrPage& rPage)
+{
+ return new SdrUndoDelPage( rPage );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoNewPage(SdrPage& rPage)
+{
+ return new SdrUndoNewPage( rPage );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoCopyPage(SdrPage& rPage)
+{
+ return new SdrUndoCopyPage( rPage );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoSetPageNum(SdrPage& rNewPg, sal_uInt16 nOldPageNum1, sal_uInt16 nNewPageNum1)
+{
+ return new SdrUndoSetPageNum( rNewPg, nOldPageNum1, nNewPageNum1 );
+}
+ // master page
+SdrUndoAction* SdrUndoFactory::CreateUndoPageRemoveMasterPage(SdrPage& rChangedPage)
+{
+ return new SdrUndoPageRemoveMasterPage( rChangedPage );
+}
+
+SdrUndoAction* SdrUndoFactory::CreateUndoPageChangeMasterPage(SdrPage& rChangedPage)
+{
+ return new SdrUndoPageChangeMasterPage(rChangedPage);
+}
+
+// eof
diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx
new file mode 100644
index 000000000000..7a4305b9581f
--- /dev/null
+++ b/svx/source/svdraw/svdview.cxx
@@ -0,0 +1,1606 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+#include <editeng/eeitem.hxx>
+
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include <svx/svdpagv.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdedxv.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdopath.hxx> // fuer GetContext
+#include <svx/svdograf.hxx> // fuer GetContext
+#include <svx/svdomedia.hxx> // fuer GetContext
+#include <svx/svdetc.hxx> // Fuer SdrEngineDefaults
+
+#ifdef DBG_UTIL
+#include <svdibrow.hxx>
+#endif
+
+#include "svx/svdoutl.hxx"
+#include "svx/svdview.hxx"
+#include "editeng/editview.hxx" // fuer GetField
+#include "editeng/flditem.hxx" // fuer URLField
+#include "svx/obj3d.hxx"
+#include "svx/svddrgmt.hxx"
+#include "svx/svdoutl.hxx"
+#include "svx/svdotable.hxx"
+#include <tools/tenccvt.hxx>
+#include <svx/sdr/overlay/overlaypolypolygon.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <sdrpaintwindow.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdrhittesthelper.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrViewEvent::SdrViewEvent()
+: pHdl(NULL),
+ pObj(NULL),
+ pRootObj(NULL),
+ pPV(NULL),
+ pURLField(NULL),
+ eHit(SDRHIT_NONE),
+ eEvent(SDREVENT_NONE),
+ eHdlKind(HDL_MOVE),
+ eEndCreateCmd(SDRCREATE_NEXTPOINT),
+ nMouseClicks(0),
+ nMouseMode(0),
+ nMouseCode(0),
+ nHlplIdx(0),
+ nGlueId(0),
+ bMouseDown(FALSE),
+ bMouseUp(FALSE),
+ bDoubleHdlSize(FALSE),
+ bIsAction(FALSE),
+ bIsTextEdit(FALSE),
+ bTextEditHit(FALSE),
+ bAddMark(FALSE),
+ bUnmark(FALSE),
+ bPrevNextMark(FALSE),
+ bMarkPrev(FALSE),
+ bInsPointNewObj(FALSE),
+ bDragWithCopy(FALSE),
+ bCaptureMouse(FALSE),
+ bReleaseMouse(FALSE)
+{
+}
+
+SdrViewEvent::~SdrViewEvent()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// helper class for all D&D overlays
+
+void SdrDropMarkerOverlay::ImplCreateOverlays(const SdrView& rView, const basegfx::B2DPolyPolygon& rPolyPolygon)
+{
+ for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
+ {
+ SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
+ ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
+
+ if(pTargetOverlay)
+ {
+ ::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(
+ rPolyPolygon);
+ pTargetOverlay->add(*pNew);
+ maObjects.append(*pNew);
+ }
+ }
+}
+
+SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const SdrObject& rObject)
+{
+ ImplCreateOverlays(rView, rObject.TakeXorPoly());
+}
+
+SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Rectangle& rRectangle)
+{
+ basegfx::B2DPolygon aB2DPolygon;
+ aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
+ aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
+ aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
+ aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
+ aB2DPolygon.setClosed(true);
+
+ basegfx::B2DPolyPolygon aB2DPolyPolygon;
+ aB2DPolyPolygon.append(aB2DPolygon);
+
+ ImplCreateOverlays(rView, aB2DPolyPolygon);
+}
+
+SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Point& rStart, const Point& rEnd)
+{
+ basegfx::B2DPolygon aB2DPolygon;
+ aB2DPolygon.append(basegfx::B2DPoint(rStart.X(), rStart.Y()));
+ aB2DPolygon.append(basegfx::B2DPoint(rEnd.X(), rEnd.Y()));
+ aB2DPolygon.setClosed(true);
+
+ basegfx::B2DPolyPolygon aB2DPolyPolygon;
+ aB2DPolyPolygon.append(aB2DPolygon);
+
+ ImplCreateOverlays(rView, aB2DPolyPolygon);
+}
+
+SdrDropMarkerOverlay::~SdrDropMarkerOverlay()
+{
+ // The OverlayObjects are cleared using the destructor of OverlayObjectList.
+ // That destructor calls clear() at the list which removes all objects from the
+ // OverlayManager and deletes them.
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// @@ @@ @@ @@@@@ @@ @@
+// @@ @@ @@ @@ @@ @@
+// @@ @@ @@ @@ @@ @ @@
+// @@@@@ @@ @@@@ @@@@@@@
+// @@@ @@ @@ @@@@@@@
+// @@@ @@ @@ @@@ @@@
+// @ @@ @@@@@ @@ @@
+//
+////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+TYPEINIT1(SdrView,SdrCreateView);
+
+SdrView::SdrView(SdrModel* pModel1, OutputDevice* pOut)
+: SdrCreateView(pModel1,pOut),
+ bNoExtendedMouseDispatcher(FALSE),
+ bNoExtendedKeyDispatcher(FALSE),
+ bNoExtendedCommandDispatcher(FALSE),
+ mbMasterPagePaintCaching(sal_False)
+{
+ bTextEditOnObjectsWithoutTextIfTextTool=FALSE;
+
+ maAccessibilityOptions.AddListener(this);
+
+ onAccessibilityOptionsChanged();
+}
+
+SdrView::~SdrView()
+{
+ maAccessibilityOptions.RemoveListener(this);
+}
+
+BOOL SdrView::KeyInput(const KeyEvent& rKEvt, Window* pWin)
+{
+ SetActualWin(pWin);
+ BOOL bRet=SdrCreateView::KeyInput(rKEvt,pWin);
+ if (!bRet && !IsExtendedKeyInputDispatcherEnabled()) {
+ bRet=TRUE;
+ switch (rKEvt.GetKeyCode().GetFullFunction()) {
+ case KEYFUNC_CUT : Cut(); break;
+ case KEYFUNC_COPY : Yank(); break;
+ case KEYFUNC_PASTE : Paste(pWin); break;
+ case KEYFUNC_DELETE: DeleteMarked(); break;
+ case KEYFUNC_UNDO: pMod->Undo(); break;
+ case KEYFUNC_REDO: pMod->Redo(); break;
+ case KEYFUNC_REPEAT: pMod->Repeat(*this); break;
+ default: {
+ switch (rKEvt.GetKeyCode().GetFullCode()) {
+ case KEY_ESCAPE: {
+ if (IsTextEdit()) SdrEndTextEdit();
+ if (IsAction()) BrkAction();
+ if (pWin!=NULL) pWin->ReleaseMouse();
+ } break;
+ case KEY_DELETE: DeleteMarked(); break;
+ case KEY_CUT: case KEY_DELETE+KEY_SHIFT: Cut(); break;
+ case KEY_COPY: case KEY_INSERT+KEY_MOD1: Yank(); break;
+ case KEY_PASTE: case KEY_INSERT+KEY_SHIFT: Paste(pWin); break;
+ case KEY_UNDO: case KEY_BACKSPACE+KEY_MOD2: pMod->Undo(); break;
+ case KEY_BACKSPACE+KEY_MOD2+KEY_SHIFT: pMod->Redo(); break;
+ case KEY_REPEAT: case KEY_BACKSPACE+KEY_MOD2+KEY_MOD1: pMod->Repeat(*this); break;
+ case KEY_MOD1+KEY_A: MarkAll(); break;
+ default: bRet=FALSE;
+ } // switch
+ }
+ } // switch
+ if (bRet && pWin!=NULL) {
+ pWin->SetPointer(GetPreferedPointer(
+ pWin->PixelToLogic(pWin->ScreenToOutputPixel( pWin->GetPointerPosPixel() ) ),
+ pWin,
+ rKEvt.GetKeyCode().GetModifier()));
+ }
+ }
+ return bRet;
+}
+
+BOOL SdrView::MouseButtonDown(const MouseEvent& rMEvt, Window* pWin)
+{
+ SetActualWin(pWin);
+ if (rMEvt.IsLeft()) aDragStat.SetMouseDown(TRUE);
+ BOOL bRet=SdrCreateView::MouseButtonDown(rMEvt,pWin);
+ if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
+ SdrViewEvent aVEvt;
+ PickAnything(rMEvt,SDRMOUSEBUTTONDOWN,aVEvt);
+ bRet=DoMouseEvent(aVEvt);
+ }
+ return bRet;
+}
+
+BOOL SdrView::MouseButtonUp(const MouseEvent& rMEvt, Window* pWin)
+{
+ SetActualWin(pWin);
+ if (rMEvt.IsLeft()) aDragStat.SetMouseDown(FALSE);
+ BOOL bAction=IsAction();
+ BOOL bRet=!bAction && SdrCreateView::MouseButtonUp(rMEvt,pWin);
+ if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) {
+ SdrViewEvent aVEvt;
+ PickAnything(rMEvt,SDRMOUSEBUTTONUP,aVEvt);
+ bRet=DoMouseEvent(aVEvt);
+ }
+ return bRet;
+}
+
+BOOL SdrView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
+{
+ SetActualWin(pWin);
+ aDragStat.SetMouseDown(rMEvt.IsLeft());
+ BOOL bRet=SdrCreateView::MouseMove(rMEvt,pWin);
+ if (!IsExtendedMouseEventDispatcherEnabled() && !IsTextEditInSelectionMode()) {
+ SdrViewEvent aVEvt;
+ PickAnything(rMEvt,SDRMOUSEMOVE,aVEvt);
+ if (DoMouseEvent(aVEvt)) bRet=TRUE;
+ }
+
+ // #87792# Removed code which did let the mouse snap on object
+ // points
+
+ return bRet;
+}
+
+BOOL SdrView::Command(const CommandEvent& rCEvt, Window* pWin)
+{
+ SetActualWin(pWin);
+ BOOL bRet=SdrCreateView::Command(rCEvt,pWin);
+ return bRet;
+}
+
+/* new interface src537 */
+BOOL SdrView::GetAttributes(SfxItemSet& rTargetSet, BOOL bOnlyHardAttr) const
+{
+ return SdrCreateView::GetAttributes(rTargetSet, bOnlyHardAttr);
+}
+
+SfxStyleSheet* SdrView::GetStyleSheet() const
+{
+ //BOOL bOk=FALSE;
+ return SdrCreateView::GetStyleSheet(); //bOk);
+}
+
+SdrHitKind SdrView::PickAnything(const MouseEvent& rMEvt, USHORT nEventKind, SdrViewEvent& rVEvt) const
+{
+ rVEvt.bMouseDown=nEventKind==SDRMOUSEBUTTONDOWN;
+ rVEvt.bMouseUp=nEventKind==SDRMOUSEBUTTONUP;
+ rVEvt.nMouseClicks=rMEvt.GetClicks();
+ rVEvt.nMouseMode=rMEvt.GetMode();
+ rVEvt.nMouseCode=rMEvt.GetButtons() | rMEvt.GetModifier();
+ const OutputDevice* pOut=pActualOutDev;
+ if (pOut==NULL)
+ {
+ pOut = GetFirstOutputDevice();
+ //pOut=GetWin(0);
+ }
+ Point aPnt(rMEvt.GetPosPixel());
+ if (pOut!=NULL) aPnt=pOut->PixelToLogic(aPnt);
+ rVEvt.aLogicPos=aPnt;
+ return PickAnything(aPnt,rVEvt);
+}
+
+// Mit der Maus draggen (Move)
+// Beispiel beim erzeugen eines Rechtecks. MouseDown muss ohne
+// ModKey erfolgen, weil sonst i.d.R. Markieren forciert wird (s.u.)
+// Drueckt man dann beim MouseMove gleichzeitig Shift, Ctrl, und Alt,
+// so erzeugt man ein zentrisches Quadrat ohne Fang.
+// Die Doppelbelegung von Ortho und Shift stellt i.d.R. kein Problem dar,
+// da sich beides meisst gegenseitig ausschliesst. Einzig Shear (das beim
+// Verzerren, nicht dass beim Drehen) beruecksichtigt beides gleichzeitig.
+// Dass muss der Anwender erstmal noch umschiffen (z.B. mit einer Hilfslinie).
+#define MODKEY_NoSnap bCtrl /* Fang temporaer aus */
+#define MODKEY_Ortho bShift /* na eben ortho */
+#define MODKEY_Center bAlt /* Zentrisch erzeugen/resizen */
+#define MODKEY_AngleSnap bShift
+#define MODKEY_CopyDrag bCtrl /* Draggen mit kopieren */
+
+// irgendwo hinklicken (MouseDown)
+#define MODKEY_PolyPoly bAlt /* Neues Poly bei InsPt und bei Create */
+#define MODKEY_MultiMark bShift /* MarkObj ohne vorher UnmarkAll */
+#define MODKEY_Unmark bAlt /* Unmark durch Rahmenaufziehen */
+#define MODKEY_ForceMark bCtrl /* Rahmenaufziehen erzwingen, auch wenn Obj an MausPos */
+#define MODKEY_DeepMark bAlt /* MarkNextObj */
+#define MODKEY_DeepBackw bShift /* MarkNextObj rueckwaerts */
+
+SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) const
+{
+ const OutputDevice* pOut=pActualOutDev;
+ if (pOut==NULL)
+ {
+ pOut = GetFirstOutputDevice();
+ //pOut=GetWin(0);
+ }
+
+ // #i73628# Use a non-changeable copy of he logic pos
+ const Point aLocalLogicPosition(rLogicPos);
+
+ BOOL bEditMode=IsEditMode();
+ BOOL bPointMode=bEditMode && HasMarkablePoints();
+ BOOL bGluePointMode=IsGluePointEditMode();
+ BOOL bInsPolyPt=bPointMode && IsInsObjPointMode() && IsInsObjPointPossible();
+ BOOL bInsGluePt=bGluePointMode && IsInsGluePointMode() && IsInsGluePointPossible();
+ BOOL bIsTextEdit=IsTextEdit();
+ BOOL bTextEditHit=IsTextEditHit(aLocalLogicPosition,0/*nHitTolLog*/);
+ BOOL bTextEditSel=IsTextEditInSelectionMode();
+ BOOL bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
+ BOOL bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
+ BOOL bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
+ SdrHitKind eHit=SDRHIT_NONE;
+ SdrHdl* pHdl=pOut!=NULL && !bTextEditSel ? PickHandle(aLocalLogicPosition) : NULL;
+ SdrPageView* pPV=NULL;
+ SdrObject* pObj=NULL;
+ SdrObject* pHitObj=NULL;
+ USHORT nHitPassNum=0;
+ USHORT nHlplIdx=0;
+ USHORT nGlueId=0;
+ BOOL bUnmarkedObjHit=FALSE;
+ if (bTextEditHit || bTextEditSel)
+ {
+ eHit=SDRHIT_TEXTEDIT;
+ bTextEditHit=TRUE;
+ }
+ else if (pHdl!=NULL)
+ {
+ eHit=SDRHIT_HANDLE; // Handle getroffen hat hoechste Prioritaet
+ }
+ else if (bEditMode && IsHlplVisible() && IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
+ {
+ eHit=SDRHIT_HELPLINE; // Hilfslinie im Vordergrund getroffen zum verschieben
+ }
+ else if (bGluePointMode && PickGluePoint(aLocalLogicPosition,pObj,nGlueId,pPV))
+ {
+ eHit=SDRHIT_GLUEPOINT; // nichtmarkierter Klebepunkt getroffen
+ }
+ else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|SDRSEARCH_MARKED,&pObj,NULL,&nHitPassNum))
+ {
+ eHit=SDRHIT_MARKEDOBJECT;
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
+ if( pTableObj )
+ {
+ sal_Int32 nX = 0, nY = 0;
+ switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
+ {
+ case sdr::table::SDRTABLEHIT_CELL:
+ eHit = SDRHIT_CELL;
+ break;
+ case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
+ eHit = SDRHIT_TEXTEDITOBJ;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (PickObj(aLocalLogicPosition,nHitTolLog,pHitObj,pPV,SDRSEARCH_DEEP|/*SDRSEARCH_TESTMARKABLE|*/SDRSEARCH_ALSOONMASTER|SDRSEARCH_WHOLEPAGE,&pObj,NULL,&nHitPassNum))
+ {
+ // MasterPages und WholePage fuer Macro und URL
+ eHit=SDRHIT_UNMARKEDOBJECT;
+ ::sdr::table::SdrTableObj* pTableObj = dynamic_cast< ::sdr::table::SdrTableObj* >( pObj );
+ if( pTableObj )
+ {
+ sal_Int32 nX = 0, nY = 0;
+ switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, 0 ) )
+ {
+ case sdr::table::SDRTABLEHIT_CELL:
+ eHit = SDRHIT_CELL;
+ break;
+ case sdr::table::SDRTABLEHIT_CELLTEXTAREA:
+ eHit = SDRHIT_TEXTEDITOBJ;
+ break;
+ default:
+ break;
+ }
+ }
+ bUnmarkedObjHit=TRUE;
+ }
+ else if (bEditMode && IsHlplVisible() && !IsHlplFront() && pOut!=NULL && PickHelpLine(aLocalLogicPosition,nHitTolLog,*pOut,nHlplIdx,pPV))
+ {
+ eHit=SDRHIT_HELPLINE; // Hilfslinie im Vordergrund getroffen zum verschieben
+ }
+ if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
+ {
+ bool bRoot=pObj->HasMacro();
+ BOOL bDeep=pObj!=pHitObj && pHitObj->HasMacro();
+ BOOL bMid=FALSE; // Gruppierte Gruppe mit Macro getroffen?
+ SdrObject* pMidObj=NULL;
+ if (pObj!=pHitObj)
+ {
+ SdrObject* pObjTmp=NULL;
+ pObjTmp=pHitObj->GetUpGroup();
+ if (pObjTmp==pObj) pObjTmp=NULL;
+ while (pObjTmp!=NULL)
+ {
+ if (pObjTmp->HasMacro())
+ {
+ bMid=TRUE;
+ pMidObj=pObjTmp;
+ }
+ pObjTmp=pObjTmp->GetUpGroup();
+ if (pObjTmp==pObj) pObjTmp=NULL;
+ }
+ }
+
+ if (bDeep || bMid || bRoot)
+ {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=aLocalLogicPosition;
+ aHitRec.aDownPos=aLocalLogicPosition;
+ aHitRec.nTol=nHitTolLog;
+ aHitRec.pVisiLayer=&pPV->GetVisibleLayers();
+ aHitRec.pPageView=pPV;
+ if (bDeep) bDeep=pHitObj->IsMacroHit(aHitRec);
+ if (bMid ) bMid =pMidObj->IsMacroHit(aHitRec);
+ if (bRoot) bRoot=pObj->IsMacroHit(aHitRec);
+ if (bRoot || bMid || bDeep)
+ {
+ // Prio: 1.Root, 2.Mid, 3.Deep
+ rVEvt.pRootObj=pObj;
+ if (!bRoot) pObj=pMidObj;
+ if (!bRoot && !bMid) pObj=pHitObj;
+ eHit=SDRHIT_MACRO;
+ }
+ }
+ }
+ // auf URL-Field checken
+ if (IsMacroMode() && eHit==SDRHIT_UNMARKEDOBJECT)
+ {
+ SdrTextObj* pTextObj=PTR_CAST(SdrTextObj,pHitObj);
+ if (pTextObj!=NULL && pTextObj->HasText())
+ {
+ bool bTEHit(pPV &&
+ SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));
+
+ if (bTEHit)
+ {
+ Rectangle aTextRect;
+ Rectangle aAnchor;
+ SdrOutliner* pOutliner = &pTextObj->ImpGetDrawOutliner();
+ if( pTextObj->GetModel() )
+ pOutliner = &pTextObj->GetModel()->GetHitTestOutliner();
+
+ pTextObj->TakeTextRect( *pOutliner, aTextRect, FALSE, &aAnchor, FALSE );
+
+ // #i73628# Use a text-relative position for hit test in hit test outliner
+ Point aTemporaryTextRelativePosition(aLocalLogicPosition - aTextRect.TopLeft());
+
+ // FitToSize berueksichtigen
+ SdrFitToSizeType eFit=pTextObj->GetFitToSize();
+ BOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
+ if (bFitToSize) {
+ Fraction aX(aTextRect.GetWidth()-1,aAnchor.GetWidth()-1);
+ Fraction aY(aTextRect.GetHeight()-1,aAnchor.GetHeight()-1);
+ ResizePoint(aTemporaryTextRelativePosition,Point(),aX,aY);
+ }
+ // Drehung berueksichtigen
+ const GeoStat& rGeo=pTextObj->GetGeoStat();
+ if (rGeo.nDrehWink!=0) RotatePoint(aTemporaryTextRelativePosition,Point(),-rGeo.nSin,rGeo.nCos); // -sin fuer Unrotate
+ // Laufschrift berueksichtigen fehlt noch ...
+ if(pActualOutDev && pActualOutDev->GetOutDevType() == OUTDEV_WINDOW)
+ {
+ OutlinerView aOLV(pOutliner, (Window*)pActualOutDev);
+ const EditView& aEV=aOLV.GetEditView();
+ const SvxFieldItem* pItem=aEV.GetField(aTemporaryTextRelativePosition);
+ if (pItem!=NULL) {
+ const SvxFieldData* pFld=pItem->GetField();
+ const SvxURLField* pURL=PTR_CAST(SvxURLField,pFld);
+ if (pURL!=NULL) {
+ eHit=SDRHIT_URLFIELD;
+ rVEvt.pURLField=pURL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (nHitPassNum==SDRSEARCHPASS_DIRECT &&
+ (eHit==SDRHIT_MARKEDOBJECT || eHit==SDRHIT_UNMARKEDOBJECT) &&
+ (IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit())
+ {
+ // Ringsum die TextEditArea ein Rand zum Selektieren ohne Textedit
+ Rectangle aBoundRect(pHitObj->GetCurrentBoundRect());
+
+ // #105130# Force to SnapRect when Fontwork
+ if(pHitObj->ISA(SdrTextObj) && ((SdrTextObj*)pHitObj)->IsFontwork())
+ {
+ aBoundRect = pHitObj->GetSnapRect();
+ }
+
+ // #105130# Old test for hit on BoundRect is completely wrong
+ // and never worked, doing it new here.
+ sal_Int32 nTolerance(nHitTolLog);
+ sal_Bool bBoundRectHit(sal_False);
+
+ if(pOut)
+ {
+ nTolerance = pOut->PixelToLogic(Size(2, 0)).Width();
+ }
+
+ if( (aLocalLogicPosition.X() >= aBoundRect.Left() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Left() + nTolerance)
+ || (aLocalLogicPosition.X() >= aBoundRect.Right() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Right() + nTolerance)
+ || (aLocalLogicPosition.Y() >= aBoundRect.Top() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Top() + nTolerance)
+ || (aLocalLogicPosition.Y() >= aBoundRect.Bottom() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Bottom() + nTolerance))
+ {
+ bBoundRectHit = sal_True;
+ }
+
+ if(!bBoundRectHit)
+ {
+ bool bTEHit(pPV &&
+ SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));
+
+ // TextEdit an Objekten im gesperrten Layer
+ if (pPV->GetLockedLayers().IsSet(pHitObj->GetLayer()))
+ {
+ bTEHit=FALSE;
+ }
+
+ if (bTEHit)
+ {
+ rVEvt.pRootObj=pObj;
+ pObj=pHitObj;
+ eHit=SDRHIT_TEXTEDITOBJ;
+ }
+ }
+ }
+ if (nHitPassNum!=SDRSEARCHPASS_DIRECT && eHit==SDRHIT_UNMARKEDOBJECT) {
+ eHit=SDRHIT_NONE;
+ pObj=NULL;
+ pPV=NULL;
+ }
+ BOOL bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
+ BOOL bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT)!=0;
+ BOOL bMouseDown=rVEvt.bMouseDown;
+ BOOL bMouseUp=rVEvt.bMouseUp;
+ SdrEventKind eEvent=SDREVENT_NONE;
+ BOOL bIsAction=IsAction();
+
+ if (bIsAction)
+ {
+ if (bMouseDown)
+ {
+ if (bMouseRight) eEvent=SDREVENT_BCKACTION;
+ }
+ else if (bMouseUp)
+ {
+ if (bMouseLeft)
+ {
+ eEvent=SDREVENT_ENDACTION;
+ if (IsDragObj())
+ {
+ eEvent=SDREVENT_ENDDRAG;
+ rVEvt.bDragWithCopy=MODKEY_CopyDrag;
+ }
+ else if (IsCreateObj() || IsInsObjPoint())
+ {
+ eEvent=IsCreateObj() ? SDREVENT_ENDCREATE : SDREVENT_ENDINSOBJPOINT;
+ rVEvt.eEndCreateCmd=SDRCREATE_NEXTPOINT;
+ if (MODKEY_PolyPoly) rVEvt.eEndCreateCmd=SDRCREATE_NEXTOBJECT;
+ if (rVEvt.nMouseClicks>1) rVEvt.eEndCreateCmd=SDRCREATE_FORCEEND;
+ }
+ else if (IsMarking())
+ {
+ eEvent=SDREVENT_ENDMARK;
+ if (!aDragStat.IsMinMoved())
+ {
+ eEvent=SDREVENT_BRKMARK;
+ rVEvt.bAddMark=MODKEY_MultiMark;
+ }
+ }
+ }
+ }
+ else
+ {
+ eEvent=SDREVENT_MOVACTION;
+ }
+ }
+ else if (eHit==SDRHIT_TEXTEDIT)
+ {
+ eEvent=SDREVENT_TEXTEDIT;
+ }
+ else if (bMouseDown && bMouseLeft)
+ {
+ if (rVEvt.nMouseClicks==2 && rVEvt.nMouseCode==MOUSE_LEFT && pObj!=NULL && pHitObj!=NULL && pHitObj->HasTextEdit() && eHit==SDRHIT_MARKEDOBJECT)
+ {
+ rVEvt.pRootObj=pObj;
+ pObj=pHitObj;
+ eEvent=SDREVENT_BEGTEXTEDIT;
+ }
+ else if (MODKEY_ForceMark && eHit!=SDRHIT_URLFIELD)
+ {
+ eEvent=SDREVENT_BEGMARK; // AddMark,Unmark */
+ }
+ else if (eHit==SDRHIT_HELPLINE)
+ {
+ eEvent=SDREVENT_BEGDRAGHELPLINE; // nix weiter
+ }
+ else if (eHit==SDRHIT_GLUEPOINT)
+ {
+ eEvent=SDREVENT_MARKGLUEPOINT; // AddMark+Drag
+ rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // falls bei Deep nicht getroffen
+ }
+ else if (eHit==SDRHIT_HANDLE)
+ {
+ eEvent=SDREVENT_BEGDRAGOBJ; // Mark+Drag,AddMark+Drag,DeepMark+Drag,Unmark
+ BOOL bGlue=pHdl->GetKind()==HDL_GLUE;
+ BOOL bPoly=!bGlue && IsPointMarkable(*pHdl);
+ BOOL bMarked=bGlue || bPoly && pHdl->IsSelected();
+ if (bGlue || bPoly)
+ {
+ eEvent=bGlue ? SDREVENT_MARKGLUEPOINT : SDREVENT_MARKPOINT;
+ if (MODKEY_DeepMark)
+ {
+ rVEvt.bAddMark=TRUE;
+ rVEvt.bPrevNextMark=TRUE;
+ rVEvt.bMarkPrev=MODKEY_DeepBackw;
+ }
+ else if (MODKEY_MultiMark)
+ {
+ rVEvt.bAddMark=TRUE;
+ rVEvt.bUnmark=bMarked; // Toggle
+ if (bGlue)
+ {
+ pObj=pHdl->GetObj();
+ nGlueId=(sal_uInt16)pHdl->GetObjHdlNum();
+ }
+ }
+ else if (bMarked)
+ {
+ eEvent=SDREVENT_BEGDRAGOBJ; // MarkState nicht aendern, nur Drag
+ }
+ }
+ }
+ else if (bInsPolyPt && (MODKEY_PolyPoly || (!MODKEY_MultiMark && !MODKEY_DeepMark)))
+ {
+ eEvent=SDREVENT_BEGINSOBJPOINT;
+ rVEvt.bInsPointNewObj=MODKEY_PolyPoly;
+ }
+ else if (bInsGluePt && !MODKEY_MultiMark && !MODKEY_DeepMark)
+ {
+ eEvent=SDREVENT_BEGINSGLUEPOINT;
+ }
+ else if (eHit==SDRHIT_TEXTEDITOBJ)
+ {
+ eEvent=SDREVENT_BEGTEXTEDIT; // AddMark+Drag,DeepMark+Drag,Unmark
+ if (MODKEY_MultiMark || MODKEY_DeepMark)
+ { // falls bei Deep nicht getroffen
+ eEvent=SDREVENT_MARKOBJ;
+ }
+ }
+ else if (eHit==SDRHIT_MACRO)
+ {
+ eEvent=SDREVENT_BEGMACROOBJ; // AddMark+Drag
+ if (MODKEY_MultiMark || MODKEY_DeepMark)
+ { // falls bei Deep nicht getroffen
+ eEvent=SDREVENT_MARKOBJ;
+ }
+ }
+ else if (eHit==SDRHIT_URLFIELD)
+ {
+ eEvent=SDREVENT_EXECUTEURL; // AddMark+Drag
+ if (MODKEY_MultiMark || MODKEY_DeepMark)
+ { // falls bei Deep nicht getroffen
+ eEvent=SDREVENT_MARKOBJ;
+ }
+ }
+ else if (eHit==SDRHIT_MARKEDOBJECT)
+ {
+ eEvent=SDREVENT_BEGDRAGOBJ; // DeepMark+Drag,Unmark
+
+ if (MODKEY_MultiMark || MODKEY_DeepMark)
+ { // falls bei Deep nicht getroffen
+ eEvent=SDREVENT_MARKOBJ;
+ }
+ }
+ else if (IsCreateMode())
+ {
+ eEvent=SDREVENT_BEGCREATEOBJ; // Nix weiter
+ }
+ else if (eHit==SDRHIT_UNMARKEDOBJECT)
+ {
+ eEvent=SDREVENT_MARKOBJ; // AddMark+Drag
+ }
+ else
+ {
+ eEvent=SDREVENT_BEGMARK;
+ }
+
+ if (eEvent==SDREVENT_MARKOBJ)
+ {
+ rVEvt.bAddMark=MODKEY_MultiMark || MODKEY_DeepMark; // falls bei Deep nicht getroffen
+ rVEvt.bPrevNextMark=MODKEY_DeepMark;
+ rVEvt.bMarkPrev=MODKEY_DeepMark && MODKEY_DeepBackw;
+ }
+ if (eEvent==SDREVENT_BEGMARK)
+ {
+ rVEvt.bAddMark=MODKEY_MultiMark;
+ rVEvt.bUnmark=MODKEY_Unmark;
+ }
+ }
+ rVEvt.bIsAction=bIsAction;
+ rVEvt.bIsTextEdit=bIsTextEdit;
+ rVEvt.bTextEditHit=bTextEditHit;
+ rVEvt.aLogicPos=aLocalLogicPosition;
+ rVEvt.pHdl=pHdl;
+ rVEvt.pObj=pObj;
+ if(rVEvt.pRootObj==NULL)
+ rVEvt.pRootObj=pObj;
+ rVEvt.pPV=pPV;
+ rVEvt.nHlplIdx=nHlplIdx;
+ rVEvt.nGlueId=nGlueId;
+ rVEvt.eHit=eHit;
+ rVEvt.eEvent=eEvent;
+ rVEvt.bCaptureMouse=bMouseLeft && bMouseDown && eEvent!=SDREVENT_NONE;
+ rVEvt.bReleaseMouse=bMouseLeft && bMouseUp;
+#ifdef DGB_UTIL
+ if (rVEvt.pRootObj!=NULL) {
+ if (rVEvt.pRootObj->GetObjList()!=rVEvt.pPV->GetObjList()) {
+ DBG_ERROR("SdrView::PickAnything(): pRootObj->GetObjList()!=pPV->GetObjList() !");
+ }
+ }
+#endif
+ return eHit;
+}
+
+BOOL SdrView::DoMouseEvent(const SdrViewEvent& rVEvt)
+{
+ BOOL bRet=FALSE;
+ SdrHitKind eHit=rVEvt.eHit;
+ Point aLogicPos(rVEvt.aLogicPos);
+
+ BOOL bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0;
+ BOOL bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0;
+ BOOL bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0;
+ BOOL bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT)!=0;
+ //BOOL bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT)!=0;
+ BOOL bMouseDown=rVEvt.bMouseDown;
+ BOOL bMouseUp=rVEvt.bMouseUp;
+ if (bMouseDown) {
+ if (bMouseLeft) aDragStat.SetMouseDown(TRUE);
+ } else if (bMouseUp) {
+ if (bMouseLeft) aDragStat.SetMouseDown(FALSE);
+ } else { // ansonsten MoueMove
+ aDragStat.SetMouseDown(bMouseLeft);
+ }
+
+#ifdef MODKEY_NoSnap
+ SetSnapEnabled(!MODKEY_NoSnap);
+#endif
+#ifdef MODKEY_Ortho
+ SetOrtho(MODKEY_Ortho!=IsOrthoDesired());
+#endif
+#ifdef MODKEY_BigOrtho
+ SetBigOrtho(MODKEY_BigOrtho);
+#endif
+#ifdef MODKEY_AngleSnap
+ SetAngleSnapEnabled(MODKEY_AngleSnap);
+#endif
+#ifdef MODKEY_CopyDrag
+ SetDragWithCopy(MODKEY_CopyDrag);
+#endif
+#ifdef MODKEY_Center
+ SetCreate1stPointAsCenter(MODKEY_Center);
+ SetResizeAtCenter(MODKEY_Center);
+ SetCrookAtCenter(MODKEY_Center);
+#endif
+ if (bMouseLeft && bMouseDown && rVEvt.bIsTextEdit && (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_NONE)) {
+ SdrEndTextEdit(); // Danebengeklickt, Ende mit Edit
+ // pHdl ist dann ungueltig. Sollte aber egal sein, wein pHdl==NULL
+ // sein muesste (wg. eHit).
+ }
+ switch (rVEvt.eEvent) {
+ case SDREVENT_NONE: bRet=FALSE; break;
+ case SDREVENT_TEXTEDIT: bRet=FALSE; break; // Events an die OutlinerView werden hier nicht beruecksichtigt
+ case SDREVENT_MOVACTION: MovAction(aLogicPos); bRet=TRUE; break;
+ case SDREVENT_ENDACTION: EndAction(); bRet=TRUE; break;
+ case SDREVENT_BCKACTION: BckAction(); bRet=TRUE; break;
+ case SDREVENT_BRKACTION: BrkAction(); bRet=TRUE; break;
+ case SDREVENT_ENDMARK : EndAction(); bRet=TRUE; break;
+ case SDREVENT_BRKMARK : {
+ BrkAction();
+ if (!MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark)) {
+ // Kein Obj getroffen. Dann werden zuerst
+ // - Markierte Klebepunkte deselektiert
+ // - dann ggf. selektierte Polygonpunkte
+ // - und ansonsten Objekte
+ if (!rVEvt.bAddMark) UnmarkAll();
+ }
+ bRet=TRUE;
+ } break;
+ case SDREVENT_ENDCREATE: { // ggf. MarkObj
+ SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
+ if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
+ if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
+ if (!EndCreateObj(eCmd)) { // Event fuer Create nicht ausgewerten? -> Markieren
+ if (eHit==SDRHIT_UNMARKEDOBJECT || eHit==SDRHIT_TEXTEDIT) {
+ MarkObj(rVEvt.pRootObj,rVEvt.pPV);
+ if (eHit==SDRHIT_TEXTEDIT)
+ {
+ BOOL bRet2(pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType() &&
+ SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L));
+
+ if(bRet2)
+ {
+ MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
+ 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);
+
+ OutlinerView* pOLV=GetTextEditOutlinerView();
+ if (pOLV!=NULL) {
+ pOLV->MouseButtonDown(aMEvt); // Event an den Outliner, aber ohne Doppelklick
+ pOLV->MouseButtonUp(aMEvt); // Event an den Outliner, aber ohne Doppelklick
+ }
+ }
+ }
+ bRet=TRUE; // Obj markiert und ggf. TextEdit gestartet
+ } else bRet=FALSE; // Create abgebrochen, sonst nix weiter.
+ } else bRet=TRUE; // EndCreate mit TRUE returniert
+ } break;
+ case SDREVENT_ENDDRAG: {
+ bRet=EndDragObj(IsDragWithCopy());
+ ForceMarkedObjToAnotherPage(); // Undo+Klammerung fehlt noch !!!
+ } break;
+ case SDREVENT_MARKOBJ: { // + ggf. BegDrag
+ if (!rVEvt.bAddMark) UnmarkAllObj();
+ BOOL bUnmark=rVEvt.bUnmark;
+ if (rVEvt.bPrevNextMark) {
+ bRet=MarkNextObj(aLogicPos,nHitTolLog,rVEvt.bMarkPrev);
+ } else {
+ SortMarkedObjects();
+ ULONG nAnz0=GetMarkedObjectCount();
+ bRet=MarkObj(aLogicPos,nHitTolLog,rVEvt.bAddMark);
+ SortMarkedObjects();
+ ULONG nAnz1=GetMarkedObjectCount();
+ bUnmark=nAnz1<nAnz0;
+ }
+ if (!bUnmark) {
+ BegDragObj(aLogicPos,NULL,(SdrHdl*)NULL,nMinMovLog);
+ bRet=TRUE;
+ }
+ } break;
+ case SDREVENT_MARKPOINT: { // + ggf. BegDrag
+ if (!rVEvt.bAddMark) UnmarkAllPoints();
+ if (rVEvt.bPrevNextMark) {
+ bRet=MarkNextPoint(aLogicPos,rVEvt.bMarkPrev);
+ } else {
+ bRet=MarkPoint(*rVEvt.pHdl,rVEvt.bUnmark);
+ }
+ if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
+ BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog);
+ bRet=TRUE;
+ }
+ } break;
+ case SDREVENT_MARKGLUEPOINT: { // + ggf. BegDrag
+ if (!rVEvt.bAddMark) UnmarkAllGluePoints();
+ if (rVEvt.bPrevNextMark) {
+ bRet=MarkNextGluePoint(aLogicPos,rVEvt.bMarkPrev);
+ } else {
+ bRet=MarkGluePoint(rVEvt.pObj,rVEvt.nGlueId,rVEvt.pPV,rVEvt.bUnmark);
+ }
+ if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) {
+ SdrHdl* pHdl=GetGluePointHdl(rVEvt.pObj,rVEvt.nGlueId);
+ BegDragObj(aLogicPos,NULL,pHdl,nMinMovLog);
+ bRet=TRUE;
+ }
+ } break;
+ case SDREVENT_BEGMARK: bRet=BegMark(aLogicPos,rVEvt.bAddMark,rVEvt.bUnmark); break;
+ case SDREVENT_BEGINSOBJPOINT: bRet = BegInsObjPoint(aLogicPos, MODKEY_PolyPoly); break;
+ case SDREVENT_ENDINSOBJPOINT: {
+ SdrCreateCmd eCmd=SDRCREATE_NEXTPOINT;
+ if (MODKEY_PolyPoly) eCmd=SDRCREATE_NEXTOBJECT;
+ if (rVEvt.nMouseClicks>1) eCmd=SDRCREATE_FORCEEND;
+ EndInsObjPoint(eCmd);
+ bRet=TRUE;
+ } break;
+ case SDREVENT_BEGINSGLUEPOINT: bRet=BegInsGluePoint(aLogicPos); break;
+ case SDREVENT_BEGDRAGHELPLINE: bRet=BegDragHelpLine(rVEvt.nHlplIdx,rVEvt.pPV); break;
+ case SDREVENT_BEGDRAGOBJ: bRet=BegDragObj(aLogicPos,NULL,rVEvt.pHdl,nMinMovLog); break;
+ case SDREVENT_BEGCREATEOBJ: {
+ if (nAktInvent==SdrInventor && nAktIdent==OBJ_CAPTION) {
+ long nHgt=SdrEngineDefaults::GetFontHeight();
+ bRet=BegCreateCaptionObj(aLogicPos,Size(5*nHgt,2*nHgt));
+ } else bRet=BegCreateObj(aLogicPos);
+ } break;
+ case SDREVENT_BEGMACROOBJ: bRet=BegMacroObj(aLogicPos,nHitTolLog,rVEvt.pObj,rVEvt.pPV,(Window*)pActualOutDev); break;
+ case SDREVENT_BEGTEXTEDIT: {
+ if (!IsObjMarked(rVEvt.pObj)) {
+ UnmarkAllObj();
+ MarkObj(rVEvt.pRootObj,rVEvt.pPV);
+ }
+
+ bRet = pActualOutDev && OUTDEV_WINDOW == pActualOutDev->GetOutDevType()&&
+ SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, (Window*)pActualOutDev, sal_False, (SdrOutliner*)0L);
+
+ if(bRet)
+ {
+ MouseEvent aMEvt(pActualOutDev->LogicToPixel(aLogicPos),
+ 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode);
+ OutlinerView* pOLV=GetTextEditOutlinerView();
+ if (pOLV!=NULL) pOLV->MouseButtonDown(aMEvt); // Event an den Outliner, aber ohne Doppelklick
+ }
+ } break;
+ default: break;
+ } // switch
+ if (bRet && pActualOutDev!=NULL && pActualOutDev->GetOutDevType()==OUTDEV_WINDOW) {
+ Window* pWin=(Window*)pActualOutDev;
+ // Maus links gedrueckt?
+ BOOL bLeftDown=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseDown;
+ // Maus links losgelassen?
+ BOOL bLeftUp=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && rVEvt.bMouseUp;
+ // Maus links gedrueckt oder gehalten?
+ BOOL bLeftDown1=(rVEvt.nMouseCode&MOUSE_LEFT)!=0 && !rVEvt.bMouseUp;
+ pWin->SetPointer(GetPreferedPointer(rVEvt.aLogicPos,pWin,
+ rVEvt.nMouseCode & (KEY_SHIFT|KEY_MOD1|KEY_MOD2),bLeftDown1));
+ BOOL bAction=IsAction();
+ if (bLeftDown && bAction) pWin->CaptureMouse();
+ else if (bLeftUp || (rVEvt.bIsAction && !bAction)) pWin->ReleaseMouse();
+ }
+ return bRet;
+}
+#include <editeng/outlobj.hxx>
+
+Pointer SdrView::GetPreferedPointer(const Point& rMousePos, const OutputDevice* pOut, USHORT nModifier, BOOL bLeftDown) const
+{
+ // Actions
+ if (IsCreateObj())
+ {
+ return pAktCreate->GetCreatePointer();
+ }
+ if (mpCurrentSdrDragMethod)
+ {
+ if ((IsDraggingPoints() || IsDraggingGluePoints()) && IsMouseHideWhileDraggingPoints())
+ return Pointer(POINTER_NULL);
+
+ OSL_TRACE("SdrView::GetPreferedPointer(%lx) %lx\n", this, mpCurrentSdrDragMethod);
+
+ return mpCurrentSdrDragMethod->GetSdrDragPointer();
+ }
+ if (IsMarkObj() || IsMarkPoints() || IsMarkGluePoints() || IsEncirclement() || IsSetPageOrg()) return Pointer(POINTER_ARROW);
+ if (IsDragHelpLine()) return GetDraggedHelpLinePointer();
+ if (IsMacroObj()) {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=pOut->LogicToPixel(rMousePos);
+ aHitRec.aDownPos=aMacroDownPos;
+ aHitRec.nTol=nMacroTol;
+ aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers();
+ aHitRec.pPageView=pMacroPV;
+ aHitRec.pOut=pMacroWin;
+ aHitRec.bDown=bMacroDown;
+ return pMacroObj->GetMacroPointer(aHitRec);
+ }
+ //USHORT nTol=nHitTolLog;
+ // TextEdit, ObjEdit, Macro
+ if (IsTextEdit() && (IsTextEditInSelectionMode() || IsTextEditHit(rMousePos,0/*nTol*/)))
+ {
+ if(!pOut || IsTextEditInSelectionMode())
+ {
+ if(pTextEditOutliner->IsVertical())
+ return Pointer(POINTER_TEXT_VERTICAL);
+ else
+ return Pointer(POINTER_TEXT);
+ }
+ // hier muss besser der Outliner was liefern:
+ Point aPos(pOut->LogicToPixel(rMousePos));
+ Pointer aPointer(pTextEditOutlinerView->GetPointer(aPos));
+ if (aPointer==POINTER_ARROW)
+ {
+ if(pTextEditOutliner->IsVertical())
+ aPointer = POINTER_TEXT_VERTICAL;
+ else
+ aPointer = POINTER_TEXT;
+ }
+ return aPointer;
+ }
+
+ SdrViewEvent aVEvt;
+ aVEvt.nMouseCode=(nModifier&(KEY_SHIFT|KEY_MOD1|KEY_MOD2))|MOUSE_LEFT; // um zu sehen, was bei MouseLeftDown passieren wuerde
+ aVEvt.bMouseDown=!bLeftDown; // Was waere wenn ...
+ aVEvt.bMouseUp=bLeftDown; // Was waere wenn ...
+ if (pOut!=NULL)
+ ((SdrView*)this)->SetActualWin(pOut);
+ SdrHitKind eHit=PickAnything(rMousePos,aVEvt);
+ SdrEventKind eEvent=aVEvt.eEvent;
+ switch (eEvent)
+ {
+ case SDREVENT_BEGCREATEOBJ:
+ return aAktCreatePointer;
+ case SDREVENT_MARKOBJ:
+ case SDREVENT_BEGMARK:
+ return Pointer(POINTER_ARROW);
+ case SDREVENT_MARKPOINT:
+ case SDREVENT_MARKGLUEPOINT:
+ return Pointer(POINTER_MOVEPOINT);
+ case SDREVENT_BEGINSOBJPOINT:
+ case SDREVENT_BEGINSGLUEPOINT:
+ return Pointer(POINTER_CROSS);
+ case SDREVENT_EXECUTEURL:
+ return Pointer(POINTER_REFHAND);
+ case SDREVENT_BEGMACROOBJ:
+ {
+ SdrObjMacroHitRec aHitRec;
+ aHitRec.aPos=aVEvt.aLogicPos;
+ aHitRec.aDownPos=aHitRec.aPos;
+ aHitRec.nTol=nHitTolLog;
+ aHitRec.pVisiLayer=&aVEvt.pPV->GetVisibleLayers();
+ aHitRec.pPageView=aVEvt.pPV;
+ aHitRec.pOut=(OutputDevice*)pOut;
+ return aVEvt.pObj->GetMacroPointer(aHitRec);
+ }
+ default: break;
+ } // switch
+
+ switch(eHit)
+ {
+ case SDRHIT_CELL:
+ return Pointer(POINTER_ARROW);
+ case SDRHIT_HELPLINE :
+ return aVEvt.pPV->GetHelpLines()[aVEvt.nHlplIdx].GetPointer();
+ case SDRHIT_GLUEPOINT:
+ return Pointer(POINTER_MOVEPOINT);
+ case SDRHIT_TEXTEDIT :
+ case SDRHIT_TEXTEDITOBJ:
+ {
+ SdrTextObj* pText = dynamic_cast< SdrTextObj* >( aVEvt.pObj );
+ if(pText && pText->HasText())
+ {
+ OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject();
+ if(pParaObj && pParaObj->IsVertical())
+ return Pointer(POINTER_TEXT_VERTICAL);
+ }
+ return Pointer(POINTER_TEXT);
+ }
+ default: break;
+ }
+
+ BOOL bMarkHit=eHit==SDRHIT_MARKEDOBJECT;
+ SdrHdl* pHdl=aVEvt.pHdl;
+ // Nun die Pointer fuer Dragging checken
+ if (pHdl!=NULL || bMarkHit) {
+ SdrHdlKind eHdl= pHdl!=NULL ? pHdl->GetKind() : HDL_MOVE;
+ BOOL bCorner=pHdl!=NULL && pHdl->IsCornerHdl();
+ BOOL bVertex=pHdl!=NULL && pHdl->IsVertexHdl();
+ BOOL bMov=eHdl==HDL_MOVE;
+ if (bMov && (eDragMode==SDRDRAG_MOVE || eDragMode==SDRDRAG_RESIZE || bMarkedHitMovesAlways)) {
+ if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
+ return Pointer(POINTER_MOVE);
+ }
+ switch (eDragMode) {
+ case SDRDRAG_ROTATE: {
+ if ((bCorner || bMov) && !IsRotateAllowed(TRUE))
+ return Pointer(POINTER_NOTALLOWED);
+
+ // Sind 3D-Objekte selektiert?
+ BOOL b3DObjSelected = FALSE;
+#ifndef SVX_LIGHT
+ for (UINT32 a=0; !b3DObjSelected && a<GetMarkedObjectCount(); a++) {
+ SdrObject* pObj = GetMarkedObjectByIndex(a);
+ if(pObj && pObj->ISA(E3dObject))
+ b3DObjSelected = TRUE;
+ }
+#endif
+ // Falls es um ein 3D-Objekt geht, muss trotz !IsShearAllowed
+ // weitergemacht werden, da es sich um eine Rotation statt um
+ // einen Shear handelt
+ if (bVertex && !IsShearAllowed() && !b3DObjSelected)
+ return Pointer(POINTER_NOTALLOWED);
+ if (bMov)
+ return Pointer(POINTER_ROTATE);
+ } break;
+ case SDRDRAG_SHEAR: case SDRDRAG_DISTORT: {
+ if (bCorner) {
+ if (!IsDistortAllowed(TRUE) && !IsDistortAllowed(FALSE)) return Pointer(POINTER_NOTALLOWED);
+ else return Pointer(POINTER_REFHAND);
+ }
+ if (bVertex && !IsShearAllowed()) return Pointer(POINTER_NOTALLOWED);
+ if (bMov) {
+ if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
+ return Pointer(POINTER_MOVE);
+ }
+ } break;
+ case SDRDRAG_MIRROR: {
+ if (bCorner || bVertex || bMov) {
+ SdrHdl* pH1=aHdl.GetHdl(HDL_REF1);
+ SdrHdl* pH2=aHdl.GetHdl(HDL_REF2);
+ BOOL b90=FALSE;
+ BOOL b45=FALSE;
+ Point aDif;
+ if (pH1!=NULL && pH2!=NULL) {
+ aDif=pH2->GetPos()-pH1->GetPos();
+ b90=(aDif.X()==0) || aDif.Y()==0;
+ b45=b90 || (Abs(aDif.X())==Abs(aDif.Y()));
+ }
+ BOOL bNo=FALSE;
+ if (!IsMirrorAllowed(TRUE,TRUE)) bNo=TRUE; // Spiegeln ueberhaupt nicht erlaubt
+ if (!IsMirrorAllowed(FALSE,FALSE) && !b45) bNo=TRUE; // freies Spiegeln nicht erlaubt
+ if (!IsMirrorAllowed(TRUE,FALSE) && !b90) bNo=TRUE; // Spiegeln hor/ver erlaubt
+ if (bNo) return Pointer(POINTER_NOTALLOWED);
+ if (b90) {
+ return Pointer(POINTER_MIRROR);
+ }
+ return Pointer(POINTER_MIRROR);
+ }
+ } break;
+
+ case SDRDRAG_TRANSPARENCE:
+ {
+ if(!IsTransparenceAllowed())
+ return Pointer(POINTER_NOTALLOWED);
+
+ return Pointer(POINTER_REFHAND);
+ }
+
+ case SDRDRAG_GRADIENT:
+ {
+ if(!IsGradientAllowed())
+ return Pointer(POINTER_NOTALLOWED);
+
+ return Pointer(POINTER_REFHAND);
+ }
+
+ case SDRDRAG_CROOK: {
+ if (bCorner || bVertex || bMov) {
+ if (!IsCrookAllowed(TRUE) && !IsCrookAllowed(FALSE)) return Pointer(POINTER_NOTALLOWED);
+ return Pointer(POINTER_CROOK);
+ }
+ }
+
+ case SDRDRAG_CROP:
+ {
+ return Pointer(POINTER_CROP);
+ }
+
+ default: {
+ if ((bCorner || bVertex) && !IsResizeAllowed(TRUE)) return Pointer(POINTER_NOTALLOWED);
+ }
+ }
+ if (pHdl!=NULL) return pHdl->GetPointer();
+ if (bMov) {
+ if (!IsMoveAllowed()) return Pointer(POINTER_ARROW); // weil Doppelklick oder Drag&Drop moeglich
+ return Pointer(POINTER_MOVE);
+ }
+ }
+ if (eEditMode==SDREDITMODE_CREATE) return aAktCreatePointer;
+ return Pointer(POINTER_ARROW);
+}
+
+XubString SdrView::GetStatusText()
+{
+ XubString aStr;
+ XubString aName;
+
+ aStr.AppendAscii("nix");
+
+ if (pAktCreate!=NULL)
+ {
+ aStr=pAktCreate->getSpecialDragComment(aDragStat);
+
+ if(!aStr.Len())
+ {
+ pAktCreate->TakeObjNameSingul(aName);
+ aStr = ImpGetResStr(STR_ViewCreateObj);
+ }
+ }
+ else if (mpCurrentSdrDragMethod)
+ {
+ if (bInsPolyPoint || IsInsertGluePoint())
+ {
+ aStr=aInsPointUndoStr;
+ }
+ else
+ {
+ if (aDragStat.IsMinMoved())
+ {
+ OSL_TRACE("SdrView::GetStatusText(%lx) %lx\n", this, mpCurrentSdrDragMethod);
+ mpCurrentSdrDragMethod->TakeSdrDragComment(aStr);
+ }
+ }
+ }
+ else if(IsMarkObj())
+ {
+ if(AreObjectsMarked())
+ {
+ aStr = ImpGetResStr(STR_ViewMarkMoreObjs);
+ }
+ else
+ {
+ aStr = ImpGetResStr(STR_ViewMarkObjs);
+ }
+ }
+ else if(IsMarkPoints())
+ {
+ if(HasMarkedPoints())
+ {
+ aStr = ImpGetResStr(STR_ViewMarkMorePoints);
+ }
+ else
+ {
+ aStr = ImpGetResStr(STR_ViewMarkPoints);
+ }
+ } else if (IsMarkGluePoints())
+ {
+ if(HasMarkedGluePoints())
+ {
+ aStr = ImpGetResStr(STR_ViewMarkMoreGluePoints);
+ }
+ else
+ {
+ aStr = ImpGetResStr(STR_ViewMarkGluePoints);
+ }
+ }
+ else if (IsTextEdit() && pTextEditOutlinerView!=NULL) {
+ aStr=ImpGetResStr(STR_ViewTextEdit); // "TextEdit - Zeile y Spalte x";
+ ESelection aSel(pTextEditOutlinerView->GetSelection());
+ long nPar=aSel.nEndPara,nLin=0,nCol=aSel.nEndPos;
+ if (aSel.nEndPara>0) {
+ for (USHORT nParaNum=0; nParaNum<aSel.nEndPara; nParaNum++) {
+ nLin+=pTextEditOutliner->GetLineCount(nParaNum);
+ }
+ }
+ // Noch 'ne kleine Unschoenheit:
+ // Am Ende einer Zeile eines mehrzeiligen Absatzes wird die Position
+ // der naechsten Zeile des selben Absatzes angezeigt, so es eine solche
+ // gibt.
+ USHORT nParaLine=0;
+ ULONG nParaLineAnz=pTextEditOutliner->GetLineCount(aSel.nEndPara);
+ BOOL bBrk=FALSE;
+ while (!bBrk) {
+ USHORT nLen=pTextEditOutliner->GetLineLen(aSel.nEndPara,nParaLine);
+ BOOL bLastLine=(nParaLine==nParaLineAnz-1);
+ if (nCol>nLen || (!bLastLine && nCol==nLen)) {
+ nCol-=nLen;
+ nLin++;
+ nParaLine++;
+ } else bBrk=TRUE;
+ if (nLen==0) bBrk=TRUE; // Sicherheitshalber
+ }
+
+ aStr.SearchAndReplaceAscii("%1", UniString::CreateFromInt32(nPar + 1));
+ aStr.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nLin + 1));
+ aStr.SearchAndReplaceAscii("%3", UniString::CreateFromInt32(nCol + 1));
+
+#ifdef DBG_UTIL
+ aStr += UniString( RTL_CONSTASCII_USTRINGPARAM( ", Level " ) );
+ aStr += UniString::CreateFromInt32( pTextEditOutliner->GetDepth( aSel.nEndPara ) );
+#endif
+ }
+
+ if(aStr.EqualsAscii("nix"))
+ {
+ if (AreObjectsMarked()) {
+ ImpTakeDescriptionStr(STR_ViewMarked,aStr);
+ if (IsGluePointEditMode()) {
+ if (HasMarkedGluePoints()) {
+ ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_GLUEPOINTSDESCRIPTION);
+ }
+ } else {
+ if (HasMarkedPoints()) {
+ ImpTakeDescriptionStr(STR_ViewMarked,aStr,0,IMPSDR_POINTSDESCRIPTION);
+ }
+ }
+ } else {
+ aStr.Erase();
+ }
+ }
+ else if(aName.Len())
+ {
+ aStr.SearchAndReplaceAscii("%1", aName);
+ }
+
+ if(aStr.Len())
+ {
+ // ersten Buchstaben gross schreiben
+ String aTmpStr(aStr.Copy(0, 1));
+ aTmpStr.ToUpperAscii();
+ aStr.Replace(0, 1, aTmpStr);
+ }
+ return aStr;
+}
+
+SdrViewContext SdrView::GetContext() const
+{
+ if( IsGluePointEditMode() )
+ return SDRCONTEXT_GLUEPOINTEDIT;
+
+ const ULONG nMarkAnz = GetMarkedObjectCount();
+
+ if( HasMarkablePoints() && !IsFrameHandles() )
+ {
+ BOOL bPath=TRUE;
+ for( ULONG nMarkNum = 0; nMarkNum < nMarkAnz && bPath; nMarkNum++ )
+ if (!GetMarkedObjectByIndex(nMarkNum)->ISA(SdrPathObj))
+ bPath=FALSE;
+
+ if( bPath )
+ return SDRCONTEXT_POINTEDIT;
+ }
+
+ if( GetMarkedObjectCount() )
+ {
+ BOOL bGraf = TRUE, bMedia = TRUE, bTable = TRUE;
+
+ for( ULONG nMarkNum = 0; nMarkNum < nMarkAnz && ( bGraf || bMedia ); nMarkNum++ )
+ {
+ const SdrObject* pMarkObj = GetMarkedObjectByIndex( nMarkNum );
+ DBG_ASSERT( pMarkObj, "SdrView::GetContext(), null pointer in mark list!" );
+
+ if( !pMarkObj )
+ continue;
+
+ if( !pMarkObj->ISA( SdrGrafObj ) )
+ bGraf = FALSE;
+
+ if( !pMarkObj->ISA( SdrMediaObj ) )
+ bMedia = FALSE;
+
+ if( !pMarkObj->ISA( ::sdr::table::SdrTableObj ) )
+ bTable = FALSE;
+ }
+
+ if( bGraf )
+ return SDRCONTEXT_GRAPHIC;
+ else if( bMedia )
+ return SDRCONTEXT_MEDIA;
+ else if( bTable )
+ return SDRCONTEXT_TABLE;
+ }
+
+ return SDRCONTEXT_STANDARD;
+}
+
+void SdrView::MarkAll()
+{
+ if (IsTextEdit()) {
+ GetTextEditOutlinerView()->SetSelection(ESelection(0,0,0xFFFF,0xFFFF));
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ } else if (IsGluePointEditMode()) MarkAllGluePoints();
+ else if (HasMarkablePoints()) MarkAllPoints();
+ else MarkAllObj();
+}
+
+void SdrView::UnmarkAll()
+{
+ if (IsTextEdit()) {
+ ESelection eSel=GetTextEditOutlinerView()->GetSelection();
+ eSel.nStartPara=eSel.nEndPara;
+ eSel.nStartPos=eSel.nEndPos;
+ GetTextEditOutlinerView()->SetSelection(eSel);
+#ifdef DBG_UTIL
+ if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
+#endif
+ } else if (HasMarkedGluePoints()) UnmarkAllGluePoints();
+ else if (HasMarkedPoints()) UnmarkAllPoints(); // ! Marked statt Markable !
+ else UnmarkAllObj();
+}
+
+BOOL SdrView::IsAllMarked() const
+{
+ if (IsTextEdit()) {
+ return ImpIsTextEditAllSelected();
+ }
+ if (IsGluePointEditMode()) {
+ ULONG nAnz=GetMarkableGluePointCount();
+ return nAnz!=0 && nAnz==GetMarkedGluePointCount();
+ }
+ if (HasMarkedPoints()) {
+ ULONG nAnz=GetMarkablePointCount();
+ return nAnz!=0 && nAnz==GetMarkedPointCount();
+ }
+ ULONG nAnz=GetMarkableObjCount();
+ return nAnz!=0 && nAnz == GetMarkedObjectCount();
+}
+
+BOOL SdrView::IsMarkPossible() const
+{
+ if(IsTextEdit())
+ {
+ return SdrTextObj::HasTextImpl( pTextEditOutliner );
+ }
+
+ if(IsGluePointEditMode())
+ {
+ return HasMarkableGluePoints();
+ }
+
+ if(HasMarkedPoints())
+ {
+ return HasMarkablePoints();
+ }
+
+ return HasMarkableObj();
+}
+
+BOOL SdrView::IsAllMarkPrevNextPossible() const
+{
+ if (IsTextEdit()) {
+ return FALSE;
+ }
+ if (IsGluePointEditMode()) {
+ return HasMarkableGluePoints();
+ }
+ if (HasMarkedPoints()) {
+ return HasMarkablePoints();
+ }
+ return HasMarkableObj();
+}
+
+BOOL SdrView::MarkNext(BOOL bPrev)
+{
+ if (IsTextEdit()) {
+ return FALSE;
+ }
+ if (IsGluePointEditMode() && HasMarkedGluePoints()) {
+ return MarkNextGluePoint(bPrev);
+ }
+ if (HasMarkedPoints()) {
+ return MarkNextPoint(bPrev);
+ }
+ return MarkNextObj(bPrev);
+}
+
+BOOL SdrView::MarkNext(const Point& rPnt, BOOL bPrev)
+{
+ if (IsTextEdit()) {
+ return FALSE;
+ }
+ if (IsGluePointEditMode() && HasMarkedGluePoints()) {
+ //return MarkNextGluePoint(rPnt,bPrev); fehlende Implementation !!!
+ }
+ if (HasMarkedPoints()) {
+ //return MarkNextPoint(rPnt,bPrev); fehlende Implementation !!!
+ }
+ return MarkNextObj(rPnt,-2,bPrev);
+}
+
+const Rectangle& SdrView::GetMarkedRect() const
+{
+ if (IsGluePointEditMode() && HasMarkedGluePoints()) {
+ return GetMarkedGluePointsRect();
+ }
+ if (HasMarkedPoints()) {
+ return GetMarkedPointsRect();
+ }
+ return GetMarkedObjRect();
+}
+
+void SdrView::SetMarkedRect(const Rectangle& rRect)
+{
+ if (IsGluePointEditMode() && HasMarkedGluePoints()) {
+ //SetMarkedGluePointsRect(rRect); fehlende Implementation !!!
+ } else if (HasMarkedPoints()) {
+ //SetMarkedPointsRect(rRect); fehlende Implementation !!!
+ } else SetMarkedObjRect(rRect);
+}
+
+void SdrView::DeleteMarked()
+{
+ if (IsTextEdit())
+ {
+ SdrObjEditView::KeyInput(KeyEvent(0,KeyCode(KEYFUNC_DELETE)),pTextEditWin);
+ }
+ else
+ {
+ if( mxSelectionController.is() && mxSelectionController->DeleteMarked() )
+ {
+ // action already performed by current selection controller, do nothing
+ }
+ else if (IsGluePointEditMode() && HasMarkedGluePoints())
+ {
+ DeleteMarkedGluePoints();
+ }
+ else if (GetContext()==SDRCONTEXT_POINTEDIT && HasMarkedPoints())
+ {
+ DeleteMarkedPoints();
+ }
+ else
+ {
+ DeleteMarkedObj();
+ }
+ }
+}
+
+BOOL SdrView::BegMark(const Point& rPnt, BOOL bAddMark, BOOL bUnmark)
+{
+ if (bUnmark) bAddMark=TRUE;
+ if (IsGluePointEditMode()) {
+ if (!bAddMark) UnmarkAllGluePoints();
+ return BegMarkGluePoints(rPnt,bUnmark);
+ } else if (HasMarkablePoints()) {
+ if (!bAddMark) UnmarkAllPoints();
+ return BegMarkPoints(rPnt,bUnmark);
+ } else {
+ if (!bAddMark) UnmarkAllObj();
+ return BegMarkObj(rPnt,bUnmark);
+ }
+}
+
+BOOL SdrView::IsDeleteMarkedPossible() const
+{
+ if (IsReadOnly()) return FALSE;
+ if (IsTextEdit()) return TRUE;
+ if (IsGluePointEditMode() && HasMarkedGluePoints()) return TRUE;
+ if (HasMarkedPoints()) return TRUE;
+ return IsDeleteMarkedObjPossible();
+}
+
+void SdrView::ConfigurationChanged( ::utl::ConfigurationBroadcaster*p, sal_uInt32 nHint)
+{
+ onAccessibilityOptionsChanged();
+ SdrCreateView::ConfigurationChanged(p, nHint);
+}
+
+SvtAccessibilityOptions& SdrView::getAccessibilityOptions()
+{
+ return maAccessibilityOptions;
+}
+
+/** method is called whenever the global SvtAccessibilityOptions is changed */
+void SdrView::onAccessibilityOptionsChanged()
+{
+}
+
+void SdrView::SetMasterPagePaintCaching(sal_Bool bOn)
+{
+ if(mbMasterPagePaintCaching != bOn)
+ {
+ mbMasterPagePaintCaching = bOn;
+
+ // reset at all SdrPageWindow's
+ SdrPageView* pPageView = GetSdrPageView();
+
+ if(pPageView)
+ {
+ for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
+ {
+ SdrPageWindow* pPageWindow = pPageView->GetPageWindow(b);
+ DBG_ASSERT(pPageWindow, "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)");
+
+ // force deletion of ObjectContact, so at re-display all VOCs
+ // will be re-created with updated flag setting
+ pPageWindow->ResetObjectContact();
+ }
+
+ // force redraw of this view
+ pPageView->InvalidateAllWin();
+ }
+ }
+}
+// eof
diff --git a/svx/source/svdraw/svdviter.cxx b/svx/source/svdraw/svdviter.cxx
new file mode 100644
index 000000000000..9c52ee87cf23
--- /dev/null
+++ b/svx/source/svdraw/svdviter.cxx
@@ -0,0 +1,351 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include "svdviter.hxx"
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdsob.hxx>
+#include <svl/brdcst.hxx>
+#include <sdrpaintwindow.hxx>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void SdrViewIter::ImpInitVars()
+{
+ mnListenerNum = 0L;
+ mnPageViewNum = 0L;
+ mnOutDevNum = 0L;
+ mpAktView = 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrViewIter::SdrViewIter(const SdrModel* pModel)
+{
+ mpModel = pModel;
+ mpPage = 0L;
+ mpObject = 0L;
+ ImpInitVars();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrViewIter::SdrViewIter(const SdrPage* pPage, sal_Bool bNoMasterPage)
+{
+ mpPage = pPage;
+ mpModel = (pPage) ? pPage->GetModel() : 0L;
+ mpObject = 0L;
+ mbNoMasterPage = bNoMasterPage;
+ ImpInitVars();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrViewIter::SdrViewIter(const SdrObject* pObject, sal_Bool bNoMasterPage)
+{
+ mpObject = pObject;
+ mpModel = (pObject) ? pObject->GetModel() : 0L;
+ mpPage = (pObject) ? pObject->GetPage() : 0L;
+ mbNoMasterPage = bNoMasterPage;
+
+ if(!mpModel || !mpPage)
+ {
+ mpModel = 0L;
+ mpPage = 0L;
+ }
+
+ ImpInitVars();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+sal_Bool SdrViewIter::ImpCheckPageView(SdrPageView* pPV) const
+{
+ if(mpPage)
+ {
+ sal_Bool bMaster(mpPage->IsMasterPage());
+ SdrPage* pPg = pPV->GetPage();
+
+ if(pPg == mpPage)
+ {
+ if(mpObject)
+ {
+ // Objekt gewuenscht? Na dann erstmal sehen, ob
+ // das Obj in dieser PageView auch sichtbar ist.
+ SetOfByte aObjLay;
+ mpObject->getMergedHierarchyLayerSet(aObjLay);
+ aObjLay &= pPV->GetVisibleLayers();
+ return !aObjLay.IsEmpty();
+ }
+ else
+ {
+ return sal_True;
+ }
+ }
+ else
+ {
+ if(!mbNoMasterPage && bMaster && (!mpObject || !mpObject->IsNotVisibleAsMaster()))
+ {
+ if(pPg->TRG_HasMasterPage())
+ {
+ SdrPage& rMasterPage = pPg->TRG_GetMasterPage();
+
+ if(&rMasterPage == mpPage)
+ {
+ // Aha, die gewuenschte Page ist also MasterPage in dieser PageView
+ if(mpObject)
+ {
+ // Objekt gewuenscht? Na dann erstmal sehen, ob
+ // das Obj in dieser PageView auch sichtbar ist.
+ SetOfByte aObjLay;
+ mpObject->getMergedHierarchyLayerSet(aObjLay);
+ aObjLay &= pPV->GetVisibleLayers();
+ aObjLay &= pPg->TRG_GetMasterPageVisibleLayers();
+
+ if(!aObjLay.IsEmpty())
+ {
+ return TRUE;
+ } // ansonsten die naechste MasterPage der Page ansehen...
+ }
+ else
+ {
+ return sal_True;
+ }
+ }
+ }
+ }
+
+ // MasterPage nicht erlaubt oder keine passende gefunden
+ return sal_False;
+ }
+ }
+ else
+ {
+ return sal_True;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrView* SdrViewIter::ImpFindView()
+{
+ if(mpModel)
+ {
+ sal_uInt32 nLsAnz(mpModel->GetListenerCount());
+
+ while(mnListenerNum < nLsAnz)
+ {
+ SfxListener* pLs = mpModel->GetListener((sal_uInt16)mnListenerNum);
+ mpAktView = PTR_CAST(SdrView, pLs);
+
+ if(mpAktView)
+ {
+ if(mpPage)
+ {
+ SdrPageView* pPV = mpAktView->GetSdrPageView();
+
+ if(pPV)
+ {
+ if(ImpCheckPageView(pPV))
+ {
+ return mpAktView;
+ }
+ }
+ }
+ else
+ {
+ return mpAktView;
+ }
+ }
+
+ mnListenerNum++;
+ }
+ }
+
+ mpAktView = 0L;
+ return mpAktView;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPageView* SdrViewIter::ImpFindPageView()
+{
+ if(mpModel)
+ {
+ while(mpAktView)
+ {
+ SdrPageView* pPV = mpAktView->GetSdrPageView();
+
+ if(pPV)
+ {
+ if(mpPage)
+ {
+ if(ImpCheckPageView(pPV))
+ {
+ return pPV;
+ }
+ }
+ else
+ {
+ return pPV;
+ }
+
+ mnPageViewNum++;
+ }
+
+ mnListenerNum++;
+ ImpFindView();
+ }
+ }
+
+ return 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OutputDevice* SdrViewIter::ImpFindOutDev()
+{
+ while(mpAktView)
+ {
+ const sal_uInt32 nOutDevAnz(mpAktView->PaintWindowCount());
+
+ if(mnOutDevNum < nOutDevAnz)
+ {
+ SdrPaintWindow* pPaintWindow = mpAktView->GetPaintWindow(mnOutDevNum);
+ return &pPaintWindow->GetOutputDevice();
+ }
+
+ mnListenerNum++;
+ ImpFindView();
+ }
+
+ return 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Window* SdrViewIter::ImpFindWindow()
+{
+ while(mpAktView)
+ {
+ const sal_uInt32 nOutDevAnz(mpAktView->PaintWindowCount());
+
+ while(mnOutDevNum < nOutDevAnz)
+ {
+ SdrPaintWindow* pPaintWindow = mpAktView->GetPaintWindow(mnOutDevNum);
+ OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
+
+ if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
+ {
+ return (Window*)(&rOutDev);
+ }
+
+ mnOutDevNum++;
+ }
+
+ mnListenerNum++;
+ ImpFindView();
+ }
+
+ return 0L;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrView* SdrViewIter::FirstView()
+{
+ ImpInitVars();
+ return ImpFindView();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrView* SdrViewIter::NextView()
+{
+ mnListenerNum++;
+ return ImpFindView();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPageView* SdrViewIter::FirstPageView()
+{
+ ImpInitVars();
+ ImpFindView();
+ return ImpFindPageView();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrPageView* SdrViewIter::NextPageView()
+{
+ mnPageViewNum++;
+ return ImpFindPageView();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OutputDevice* SdrViewIter::FirstOutDev()
+{
+ ImpInitVars();
+ ImpFindView();
+ return ImpFindOutDev();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+OutputDevice* SdrViewIter::NextOutDev()
+{
+ mnOutDevNum++;
+ return ImpFindOutDev();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Window* SdrViewIter::FirstWindow()
+{
+ ImpInitVars();
+ ImpFindView();
+ return ImpFindWindow();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Window* SdrViewIter::NextWindow()
+{
+ mnOutDevNum++;
+ return ImpFindWindow();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/svx/source/svdraw/svdxcgv.cxx b/svx/source/svdraw/svdxcgv.cxx
new file mode 100644
index 000000000000..d19b190b3d6a
--- /dev/null
+++ b/svx/source/svdraw/svdxcgv.cxx
@@ -0,0 +1,894 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+
+#include <vector>
+#include <editeng/editeng.hxx>
+#include "xexch.hxx"
+#include <svx/xflclit.hxx>
+#include <svx/svdxcgv.hxx>
+#include <svx/svdoutl.hxx>
+#include "svditext.hxx"
+#include <svx/svdetc.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdoole2.hxx> // fuer kein OLE im SdrClipboardFormat
+#include <svx/svdorect.hxx>
+#include <svx/svdoedge.hxx> // fuer Konnektoren uebers Clipboard
+#include <svx/svdopage.hxx> // fuer Konnektoren uebers Clipboard
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdtrans.hxx> // Fuer GetMapFactor zum umskalieren bei PasteModel
+#include "svdstr.hrc" // Namen aus der Resource
+#include "svdglob.hxx" // StringCache
+#include "xoutbmp.hxx"
+#include <vcl/metaact.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/itempool.hxx>
+#include <tools/bigint.hxx>
+#include <sot/formats.hxx>
+
+// #i13033#
+#include <clonelist.hxx>
+#include <vcl/virdev.hxx>
+
+// b4967543
+#include <svl/style.hxx>
+
+// #i72535#
+#include "fmobj.hxx"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SdrExchangeView::SdrExchangeView(SdrModel* pModel1, OutputDevice* pOut):
+ SdrObjEditView(pModel1,pOut)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Point SdrExchangeView::GetViewCenter(const OutputDevice* pOut) const
+{
+ Point aCenter;
+ if (pOut==NULL)
+ {
+ pOut = GetFirstOutputDevice();
+ }
+ if (pOut!=NULL) {
+ Point aOfs=pOut->GetMapMode().GetOrigin();
+ Size aOutSiz=pOut->GetOutputSize();
+ aOutSiz.Width()/=2;
+ aOutSiz.Height()/=2;
+ aCenter.X()=aOutSiz.Width() -aOfs.X();
+ aCenter.Y()=aOutSiz.Height()-aOfs.Y();
+ }
+ return aCenter;
+}
+
+Point SdrExchangeView::GetPastePos(SdrObjList* pLst, OutputDevice* pOut)
+{
+ Point aP(GetViewCenter(pOut));
+ SdrPage* pPg=NULL;
+ if (pLst!=NULL) pPg=pLst->GetPage();
+ if (pPg!=NULL) {
+ Size aSiz(pPg->GetSize());
+ aP.X()=aSiz.Width()/2;
+ aP.Y()=aSiz.Height()/2;
+ }
+ return aP;
+}
+
+BOOL SdrExchangeView::ImpLimitToWorkArea(Point& rPt) const
+{
+ BOOL bRet(FALSE);
+
+ if(!aMaxWorkArea.IsEmpty())
+ {
+ if(rPt.X()<aMaxWorkArea.Left())
+ {
+ rPt.X() = aMaxWorkArea.Left();
+ bRet = TRUE;
+ }
+
+ if(rPt.X()>aMaxWorkArea.Right())
+ {
+ rPt.X() = aMaxWorkArea.Right();
+ bRet = TRUE;
+ }
+
+ if(rPt.Y()<aMaxWorkArea.Top())
+ {
+ rPt.Y() = aMaxWorkArea.Top();
+ bRet = TRUE;
+ }
+
+ if(rPt.Y()>aMaxWorkArea.Bottom())
+ {
+ rPt.Y() = aMaxWorkArea.Bottom();
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+}
+
+void SdrExchangeView::ImpGetPasteObjList(Point& /*rPos*/, SdrObjList*& rpLst)
+{
+ if (rpLst==NULL)
+ {
+ SdrPageView* pPV = GetSdrPageView();
+
+ if (pPV!=NULL) {
+ rpLst=pPV->GetObjList();
+ }
+ }
+}
+
+BOOL SdrExchangeView::ImpGetPasteLayer(const SdrObjList* pObjList, SdrLayerID& rLayer) const
+{
+ BOOL bRet=FALSE;
+ rLayer=0;
+ if (pObjList!=NULL) {
+ const SdrPage* pPg=pObjList->GetPage();
+ if (pPg!=NULL) {
+ rLayer=pPg->GetLayerAdmin().GetLayerID(aAktLayer,TRUE);
+ if (rLayer==SDRLAYER_NOTFOUND) rLayer=0;
+ SdrPageView* pPV = GetSdrPageView();
+ if (pPV!=NULL) {
+ bRet=!pPV->GetLockedLayers().IsSet(rLayer) && pPV->GetVisibleLayers().IsSet(rLayer);
+ }
+ }
+ }
+ return bRet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL SdrExchangeView::Paste(const GDIMetaFile& rMtf, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
+{
+ Point aPos(rPos);
+ ImpGetPasteObjList(aPos,pLst);
+ ImpLimitToWorkArea( aPos );
+ if (pLst==NULL) return FALSE;
+ SdrLayerID nLayer;
+ if (!ImpGetPasteLayer(pLst,nLayer)) return FALSE;
+ BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+ if (bUnmark) UnmarkAllObj();
+ SdrGrafObj* pObj=new SdrGrafObj(Graphic(rMtf));
+ pObj->SetLayer(nLayer);
+ ImpPasteObject(pObj,*pLst,aPos,rMtf.GetPrefSize(),rMtf.GetPrefMapMode(),nOptions);
+ return TRUE;
+}
+
+BOOL SdrExchangeView::Paste(const Bitmap& rBmp, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
+{
+ Point aPos(rPos);
+ ImpGetPasteObjList(aPos,pLst);
+ ImpLimitToWorkArea( aPos );
+ if (pLst==NULL) return FALSE;
+ SdrLayerID nLayer;
+ if (!ImpGetPasteLayer(pLst,nLayer)) return FALSE;
+ BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+ if (bUnmark) UnmarkAllObj();
+ SdrGrafObj* pObj=new SdrGrafObj(Graphic(rBmp));
+ pObj->SetLayer(nLayer);
+ ImpPasteObject(pObj,*pLst,aPos,rBmp.GetSizePixel(),MapMode(MAP_PIXEL),nOptions);
+ return TRUE;
+}
+
+BOOL SdrExchangeView::Paste(const XubString& rStr, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
+{
+ if(!rStr.Len())
+ return FALSE;
+
+ Point aPos(rPos);
+ ImpGetPasteObjList(aPos,pLst);
+ ImpLimitToWorkArea( aPos );
+ if (pLst==NULL) return FALSE;
+ SdrLayerID nLayer;
+ if (!ImpGetPasteLayer(pLst,nLayer)) return FALSE;
+ BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+ if (bUnmark) UnmarkAllObj();
+ Rectangle aTextRect(0,0,500,500);
+ SdrPage* pPage=pLst->GetPage();
+ if (pPage!=NULL) {
+ aTextRect.SetSize(pPage->GetSize());
+ }
+ SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
+ pObj->SetModel(pMod);
+ pObj->SetLayer(nLayer);
+ pObj->NbcSetText(rStr); // #32424# SetText vor SetAttr, weil SetAttr sonst unwirksam!
+ if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
+
+ pObj->SetMergedItemSet(aDefaultAttr);
+
+ SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Fuellung oder Linie
+ aTempAttr.Put(XLineStyleItem(XLINE_NONE));
+ aTempAttr.Put(XFillStyleItem(XFILL_NONE));
+
+ pObj->SetMergedItemSet(aTempAttr);
+
+ pObj->FitFrameToTextSize();
+ Size aSiz(pObj->GetLogicRect().GetSize());
+ MapUnit eMap=pMod->GetScaleUnit();
+ Fraction aMap=pMod->GetScaleFraction();
+ ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
+ return TRUE;
+}
+
+BOOL SdrExchangeView::Paste(SvStream& rInput, const String& rBaseURL, USHORT eFormat, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
+{
+ Point aPos(rPos);
+ ImpGetPasteObjList(aPos,pLst);
+ ImpLimitToWorkArea( aPos );
+ if (pLst==NULL) return FALSE;
+ SdrLayerID nLayer;
+ if (!ImpGetPasteLayer(pLst,nLayer)) return FALSE;
+ BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+ if (bUnmark) UnmarkAllObj();
+ Rectangle aTextRect(0,0,500,500);
+ SdrPage* pPage=pLst->GetPage();
+ if (pPage!=NULL) {
+ aTextRect.SetSize(pPage->GetSize());
+ }
+ SdrRectObj* pObj=new SdrRectObj(OBJ_TEXT,aTextRect);
+ pObj->SetModel(pMod);
+ pObj->SetLayer(nLayer);
+ if (pDefaultStyleSheet!=NULL) pObj->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
+
+ pObj->SetMergedItemSet(aDefaultAttr);
+
+ SfxItemSet aTempAttr(pMod->GetItemPool()); // Keine Fuellung oder Linie
+ aTempAttr.Put(XLineStyleItem(XLINE_NONE));
+ aTempAttr.Put(XFillStyleItem(XFILL_NONE));
+
+ pObj->SetMergedItemSet(aTempAttr);
+
+ pObj->NbcSetText(rInput,rBaseURL,eFormat);
+ pObj->FitFrameToTextSize();
+ Size aSiz(pObj->GetLogicRect().GetSize());
+ MapUnit eMap=pMod->GetScaleUnit();
+ Fraction aMap=pMod->GetScaleFraction();
+ ImpPasteObject(pObj,*pLst,aPos,aSiz,MapMode(eMap,Point(0,0),aMap,aMap),nOptions);
+
+ // b4967543
+ if(pObj && pObj->GetModel() && pObj->GetOutlinerParaObject())
+ {
+ SdrOutliner& rOutliner = pObj->GetModel()->GetHitTestOutliner();
+ rOutliner.SetText(*pObj->GetOutlinerParaObject());
+
+ if(1L == rOutliner.GetParagraphCount())
+ {
+ SfxStyleSheet* pCandidate = rOutliner.GetStyleSheet(0L);
+
+ if(pCandidate)
+ {
+ if(pObj->GetModel()->GetStyleSheetPool() == &pCandidate->GetPool())
+ {
+ pObj->NbcSetStyleSheet(pCandidate, sal_True);
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL SdrExchangeView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, UINT32 nOptions)
+{
+ const SdrModel* pSrcMod=&rMod;
+ if (pSrcMod==pMod)
+ return FALSE; // na so geht's ja nun nicht
+
+ const bool bUndo = IsUndoEnabled();
+
+ if( bUndo )
+ BegUndo(ImpGetResStr(STR_ExchangePaste));
+
+ if( mxSelectionController.is() && mxSelectionController->PasteObjModel( rMod ) )
+ {
+ if( bUndo )
+ EndUndo();
+ return TRUE;
+ }
+
+ Point aPos(rPos);
+ ImpGetPasteObjList(aPos,pLst);
+ SdrPageView* pMarkPV=NULL;
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ if ( pPV->GetObjList() == pLst )
+ pMarkPV=pPV;
+ }
+
+ ImpLimitToWorkArea( aPos );
+ if (pLst==NULL)
+ return FALSE;
+
+ BOOL bUnmark=(nOptions&(SDRINSERT_DONTMARK|SDRINSERT_ADDMARK))==0 && !IsTextEdit();
+ if (bUnmark)
+ UnmarkAllObj();
+
+ // evtl. umskalieren bei unterschiedlicher MapUnit am Model
+ // Dafuer erstmal die Faktoren berechnen
+ MapUnit eSrcUnit=pSrcMod->GetScaleUnit();
+ MapUnit eDstUnit=pMod->GetScaleUnit();
+ BOOL bResize=eSrcUnit!=eDstUnit;
+ Fraction xResize,yResize;
+ Point aPt0;
+ if (bResize)
+ {
+ FrPair aResize(GetMapFactor(eSrcUnit,eDstUnit));
+ xResize=aResize.X();
+ yResize=aResize.Y();
+ }
+ SdrObjList* pDstLst=pLst;
+ USHORT nPg,nPgAnz=pSrcMod->GetPageCount();
+ for (nPg=0; nPg<nPgAnz; nPg++)
+ {
+ const SdrPage* pSrcPg=pSrcMod->GetPage(nPg);
+
+ // #104148# Use SnapRect, not BoundRect here
+ Rectangle aR=pSrcPg->GetAllObjSnapRect();
+
+ if (bResize)
+ ResizeRect(aR,aPt0,xResize,yResize);
+ Point aDist(aPos-aR.Center());
+ Size aSiz(aDist.X(),aDist.Y());
+ //ULONG nDstObjAnz0=pDstLst->GetObjCount();
+ ULONG nCloneErrCnt=0;
+ ULONG nOb,nObAnz=pSrcPg->GetObjCount();
+ BOOL bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ CloneList aCloneList;
+
+ for (nOb=0; nOb<nObAnz; nOb++)
+ {
+ const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);
+
+ // #116235#
+ SdrObject* pNeuObj = pSrcOb->Clone();
+
+ if (pNeuObj!=NULL)
+ {
+ if(bResize)
+ {
+ pNeuObj->GetModel()->SetPasteResize(TRUE); // #51139#
+ pNeuObj->NbcResize(aPt0,xResize,yResize);
+ pNeuObj->GetModel()->SetPasteResize(FALSE); // #51139#
+ }
+
+ // #i39861#
+ pNeuObj->SetModel(pDstLst->GetModel());
+ pNeuObj->SetPage(pDstLst->GetPage());
+
+ pNeuObj->NbcMove(aSiz);
+
+ const SdrPage* pPg = pDstLst->GetPage();
+
+ if(pPg)
+ {
+ // #i72535#
+ const SdrLayerAdmin& rAd = pPg->GetLayerAdmin();
+ SdrLayerID nLayer(0);
+
+ if(pNeuObj->ISA(FmFormObj))
+ {
+ // for FormControls, force to form layer
+ nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
+ }
+ else
+ {
+ nLayer = rAd.GetLayerID(aAktLayer, TRUE);
+ }
+
+ if(SDRLAYER_NOTFOUND == nLayer)
+ {
+ nLayer = 0;
+ }
+
+ pNeuObj->SetLayer(nLayer);
+ }
+
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pDstLst->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
+
+ if( bUndo )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj));
+
+ if (bMark) {
+ // Markhandles noch nicht sofort setzen!
+ // Das erledigt das ModelHasChanged der MarkView.
+ MarkObj(pNeuObj,pMarkPV,FALSE,TRUE);
+ }
+
+ // #i13033#
+ aCloneList.AddPair(pSrcOb, pNeuObj);
+ }
+ else
+ {
+ nCloneErrCnt++;
+ }
+ }
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ aCloneList.CopyConnections();
+
+ if(0L != nCloneErrCnt)
+ {
+#ifdef DBG_UTIL
+ ByteString aStr("SdrExchangeView::Paste(): Fehler beim Clonen ");
+
+ if(nCloneErrCnt == 1)
+ {
+ aStr += "eines Zeichenobjekts.";
+ }
+ else
+ {
+ aStr += "von ";
+ aStr += ByteString::CreateFromInt32( nCloneErrCnt );
+ aStr += " Zeichenobjekten.";
+ }
+
+ aStr += " Objektverbindungen werden nicht mitkopiert.";
+
+ DBG_ERROR(aStr.GetBuffer());
+#endif
+ }
+ }
+
+ if( bUndo )
+ EndUndo();
+
+ return TRUE;
+}
+
+BOOL SdrExchangeView::IsExchangeFormatSupported(ULONG nFormat) const
+{
+ return( FORMAT_PRIVATE == nFormat ||
+ FORMAT_GDIMETAFILE == nFormat ||
+ FORMAT_BITMAP == nFormat ||
+ FORMAT_RTF == nFormat ||
+ FORMAT_STRING == nFormat ||
+ SOT_FORMATSTR_ID_DRAWING == nFormat ||
+ SOT_FORMATSTR_ID_EDITENGINE == nFormat );
+}
+
+void SdrExchangeView::ImpPasteObject(SdrObject* pObj, SdrObjList& rLst, const Point& rCenter, const Size& rSiz, const MapMode& rMap, UINT32 nOptions)
+{
+ BigInt nSizX(rSiz.Width());
+ BigInt nSizY(rSiz.Height());
+ MapUnit eSrcMU=rMap.GetMapUnit();
+ MapUnit eDstMU=pMod->GetScaleUnit();
+ FrPair aMapFact(GetMapFactor(eSrcMU,eDstMU));
+ Fraction aDstFr(pMod->GetScaleFraction());
+ nSizX*=aMapFact.X().GetNumerator();
+ nSizX*=rMap.GetScaleX().GetNumerator();
+ nSizX*=aDstFr.GetDenominator();
+ nSizX/=aMapFact.X().GetDenominator();
+ nSizX/=rMap.GetScaleX().GetDenominator();
+ nSizX/=aDstFr.GetNumerator();
+ nSizY*=aMapFact.Y().GetNumerator();
+ nSizY*=rMap.GetScaleY().GetNumerator();
+ nSizX*=aDstFr.GetDenominator();
+ nSizY/=aMapFact.Y().GetDenominator();
+ nSizY/=rMap.GetScaleY().GetDenominator();
+ nSizY/=aDstFr.GetNumerator();
+ long xs=nSizX;
+ long ys=nSizY;
+ Point aPos(rCenter.X()-xs/2,rCenter.Y()-ys/2);
+ Rectangle aR(aPos.X(),aPos.Y(),aPos.X()+xs,aPos.Y()+ys);
+ pObj->SetLogicRect(aR);
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ rLst.InsertObject(pObj,CONTAINER_APPEND,&aReason);
+
+ if( IsUndoEnabled() )
+ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
+
+ SdrPageView* pMarkPV=NULL;
+ SdrPageView* pPV = GetSdrPageView();
+
+ if(pPV)
+ {
+ if (pPV->GetObjList()==&rLst)
+ pMarkPV=pPV;
+ }
+
+ BOOL bMark=pMarkPV!=NULL && !IsTextEdit() && (nOptions&SDRINSERT_DONTMARK)==0;
+ if (bMark)
+ { // Obj in der ersten gefundenen PageView markieren
+ MarkObj(pObj,pMarkPV);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Bitmap SdrExchangeView::GetMarkedObjBitmap( BOOL bNoVDevIfOneBmpMarked ) const
+{
+ Bitmap aBmp;
+
+ if( AreObjectsMarked() )
+ {
+ if( bNoVDevIfOneBmpMarked )
+ {
+ SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
+ SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() == 1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
+
+ if( pGrafObj && ( pGrafObj->GetGraphicType() == GRAPHIC_BITMAP ) )
+ aBmp = pGrafObj->GetTransformedGraphic().GetBitmap();
+ }
+
+ if( !aBmp )
+ {
+ const Graphic aGraphic( GetMarkedObjMetaFile( bNoVDevIfOneBmpMarked ) );
+
+ // #i102089# support user's settings of AA and LineSnap when the MetaFile gets
+ // rasterconverted to a bitmap
+ const SvtOptionsDrawinglayer aDrawinglayerOpt;
+ const GraphicConversionParameters aParameters(
+ Size(),
+ false,
+ aDrawinglayerOpt.IsAntiAliasing(),
+ aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete());
+
+ aBmp = aGraphic.GetBitmap(aParameters);
+ }
+ }
+
+ return aBmp;
+}
+
+// -----------------------------------------------------------------------------
+
+GDIMetaFile SdrExchangeView::GetMarkedObjMetaFile( BOOL bNoVDevIfOneMtfMarked ) const
+{
+ GDIMetaFile aMtf;
+
+ if( AreObjectsMarked() )
+ {
+ Rectangle aBound( GetMarkedObjBoundRect() );
+ Size aBoundSize( aBound.GetWidth(), aBound.GetHeight() );
+ MapMode aMap( pMod->GetScaleUnit(), Point(), pMod->GetScaleFraction(), pMod->GetScaleFraction() );
+
+ if( bNoVDevIfOneMtfMarked )
+ {
+ SdrObject* pGrafObjTmp = GetMarkedObjectByIndex( 0 );
+ SdrGrafObj* pGrafObj = ( GetMarkedObjectCount() ==1 ) ? PTR_CAST( SdrGrafObj, pGrafObjTmp ) : NULL;
+
+ if( pGrafObj )
+ {
+ Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
+
+ if( aGraphic.GetType() == GRAPHIC_BITMAP )
+ {
+ const Point aPos;
+
+ aMtf.AddAction( new MetaBmpExScaleAction( aPos, aBoundSize, aGraphic.GetBitmapEx() ) );
+ aMtf.SetPrefMapMode( aMap );
+ aMtf.SetPrefSize( aBoundSize );
+ }
+ else
+ aMtf = aGraphic.GetGDIMetaFile();
+ }
+ }
+
+ if( !aMtf.GetActionCount() )
+ {
+ VirtualDevice aOut;
+ Size aDummySize( 2, 2 );
+
+ aOut.SetOutputSizePixel( aDummySize );
+ aOut.EnableOutput( FALSE );
+ aOut.SetMapMode( aMap );
+
+ aMtf.Clear();
+ aMtf.Record( &aOut );
+
+ // Replace offset given formally to DrawMarkedObj and used at XOutDev with relative
+ // MapMode (which was also used in XOutDev in that case). Goal is to paint the object
+ // as if TopLeft point is (0,0)
+ const Fraction aNeutralFraction(1, 1);
+ const MapMode aRelativeMapMode(MAP_RELATIVE, Point(-aBound.Left(), -aBound.Top()), aNeutralFraction, aNeutralFraction);
+ aOut.SetMapMode(aRelativeMapMode);
+
+ DrawMarkedObj(aOut);
+
+ aMtf.Stop();
+ aMtf.WindStart();
+ aMtf.SetPrefMapMode( aMap );
+
+ // removed PrefSize extension. It is principially wrong to set a reduced size at
+ // the created MetaFile. The mentioned errors occurr at output time since the integer
+ // MapModes from VCL lead to errors. It is now corrected in the VCLRenderer for
+ // primitives (and may later be done in breaking up a MetaFile to primitives)
+ aMtf.SetPrefSize(aBoundSize);
+ }
+ }
+
+ return aMtf;
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic SdrExchangeView::GetAllMarkedGraphic() const
+{
+ Graphic aRet;
+
+ if( AreObjectsMarked() )
+ {
+ if( ( 1 == GetMarkedObjectCount() ) && GetSdrMarkByIndex( 0 ) )
+ aRet = SdrExchangeView::GetObjGraphic( pMod, GetMarkedObjectByIndex( 0 ) );
+ else
+ aRet = GetMarkedObjMetaFile( FALSE );
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic SdrExchangeView::GetObjGraphic( const SdrModel* pModel, const SdrObject* pObj )
+{
+ Graphic aRet;
+
+ if( pModel && pObj )
+ {
+ // try to get a graphic from the object first
+ const SdrGrafObj* pSdrGrafObj = dynamic_cast< const SdrGrafObj* >(pObj);
+ const SdrOle2Obj* pSdrOle2Obj = dynamic_cast< const SdrOle2Obj* >(pObj);
+
+ if(pSdrGrafObj)
+ {
+ // #110981# Make behaviour coherent with metafile
+ // recording below (which of course also takes
+ // view-transformed objects)
+ aRet = pSdrGrafObj->GetTransformedGraphic();
+ }
+ else if(pSdrOle2Obj)
+ {
+ if ( pSdrOle2Obj->GetGraphic() )
+ aRet = *pSdrOle2Obj->GetGraphic();
+ }
+
+ // if graphic could not be retrieved => go the hard way and create a MetaFile
+ if( ( GRAPHIC_NONE == aRet.GetType() ) || ( GRAPHIC_DEFAULT == aRet.GetType() ) )
+ {
+ VirtualDevice aOut;
+ GDIMetaFile aMtf;
+ const Rectangle aBoundRect( pObj->GetCurrentBoundRect() );
+ const MapMode aMap( pModel->GetScaleUnit(),
+ Point(),
+ pModel->GetScaleFraction(),
+ pModel->GetScaleFraction() );
+
+ aOut.EnableOutput( FALSE );
+ aOut.SetMapMode( aMap );
+ aMtf.Record( &aOut );
+ pObj->SingleObjectPainter( aOut ); // #110094#-17
+ aMtf.Stop();
+ aMtf.WindStart();
+
+ // #i99268# replace the original offset from using XOutDev's SetOffset
+ // NOT (as tried with #i92760#) with another MapMode which gets recorded
+ // by the Metafile itself (what always leads to problems), but by hardly
+ // moving the result
+ aMtf.Move(-aBoundRect.Left(), -aBoundRect.Top());
+
+ aMtf.SetPrefMapMode( aMap );
+ aMtf.SetPrefSize( aBoundRect.GetSize() );
+
+ if( aMtf.GetActionCount() )
+ aRet = aMtf;
+ }
+ }
+
+ return aRet;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrExchangeView::DrawMarkedObj(OutputDevice& rOut) const
+{
+ SortMarkedObjects();
+
+ ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
+ ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
+ ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
+ const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
+ const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), FALSE );
+ sal_uInt32 n, nCount;
+
+ for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
+ {
+ SdrMark* pMark = GetSdrMarkByIndex( n );
+
+ // paint objects on control layer on top of all otherobjects
+ if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
+ rObjVector2.push_back( pMark );
+ else
+ rObjVector1.push_back( pMark );
+ }
+
+ for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
+ {
+ ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
+
+ for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
+ {
+ SdrMark* pMark = rObjVector[ i ];
+ pMark->GetMarkedSdrObj()->SingleObjectPainter( rOut ); // #110094#-17
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+SdrModel* SdrExchangeView::GetMarkedObjModel() const
+{
+ // Wenn das sortieren der MarkList mal stoeren sollte,
+ // werde ich sie mir wohl kopieren muessen.
+ SortMarkedObjects();
+ SdrModel* pNeuMod=pMod->AllocModel();
+ SdrPage* pNeuPag=pNeuMod->AllocPage(FALSE);
+ pNeuMod->InsertPage(pNeuPag);
+
+ if( !mxSelectionController.is() || !mxSelectionController->GetMarkedObjModel( pNeuPag ) )
+ {
+ ::std::vector< ::std::vector< SdrMark* > > aObjVectors( 2 );
+ ::std::vector< SdrMark* >& rObjVector1 = aObjVectors[ 0 ];
+ ::std::vector< SdrMark* >& rObjVector2 = aObjVectors[ 1 ];
+ const SdrLayerAdmin& rLayerAdmin = pMod->GetLayerAdmin();
+ const sal_uInt32 nControlLayerId = rLayerAdmin.GetLayerID( rLayerAdmin.GetControlLayerName(), FALSE );
+ sal_uInt32 n, nCount, nCloneErrCnt = 0;
+
+ for( n = 0, nCount = GetMarkedObjectCount(); n < nCount; n++ )
+ {
+ SdrMark* pMark = GetSdrMarkByIndex( n );
+
+ // paint objects on control layer on top of all otherobjects
+ if( nControlLayerId == pMark->GetMarkedSdrObj()->GetLayer() )
+ rObjVector2.push_back( pMark );
+ else
+ rObjVector1.push_back( pMark );
+ }
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ CloneList aCloneList;
+
+ for( n = 0, nCount = aObjVectors.size(); n < nCount; n++ )
+ {
+ ::std::vector< SdrMark* >& rObjVector = aObjVectors[ n ];
+
+ for( sal_uInt32 i = 0; i < rObjVector.size(); i++ )
+ {
+ const SdrMark* pMark = rObjVector[ i ];
+ const SdrObject* pObj = pMark->GetMarkedSdrObj();
+ SdrObject* pNeuObj;
+
+ if( pObj->ISA( SdrPageObj ) )
+ {
+ // convert SdrPageObj's to a graphic representation, because
+ // virtual connection to referenced page gets lost in new model
+ pNeuObj = new SdrGrafObj( GetObjGraphic( pMod, pObj ), pObj->GetLogicRect() );
+ pNeuObj->SetPage( pNeuPag );
+ pNeuObj->SetModel( pNeuMod );
+ }
+ else
+ {
+ // #116235#
+ // pNeuObj = pObj->Clone( pNeuPag, pNeuMod );
+ pNeuObj = pObj->Clone();
+ pNeuObj->SetPage( pNeuPag );
+ pNeuObj->SetModel( pNeuMod );
+ }
+
+ if( pNeuObj )
+ {
+ SdrInsertReason aReason(SDRREASON_VIEWCALL);
+ pNeuPag->InsertObject(pNeuObj,CONTAINER_APPEND,&aReason);
+
+ // #i13033#
+ aCloneList.AddPair(pObj, pNeuObj);
+ }
+ else
+ nCloneErrCnt++;
+ }
+ }
+
+ // #i13033#
+ // New mechanism to re-create the connections of cloned connectors
+ aCloneList.CopyConnections();
+
+ if(0L != nCloneErrCnt)
+ {
+#ifdef DBG_UTIL
+ ByteString aStr("SdrExchangeView::GetMarkedObjModel(): Fehler beim Clonen ");
+
+ if(nCloneErrCnt == 1)
+ {
+ aStr += "eines Zeichenobjekts.";
+ }
+ else
+ {
+ aStr += "von ";
+ aStr += ByteString::CreateFromInt32( nCloneErrCnt );
+ aStr += " Zeichenobjekten.";
+ }
+
+ aStr += " Objektverbindungen werden nicht mitkopiert.";
+
+ DBG_ERROR(aStr.GetBuffer());
+#endif
+ }
+ }
+ return pNeuMod;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SdrExchangeView::Cut( ULONG /*nFormat */)
+{
+ DBG_ERROR( "SdrExchangeView::Cut: Not supported anymore" );
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrExchangeView::CutMarked( ULONG /*nFormat */)
+{
+ DBG_ERROR( "SdrExchangeView::CutMarked: Not supported anymore" );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SdrExchangeView::Yank(ULONG /*nFormat*/)
+{
+ DBG_ERROR( "SdrExchangeView::Yank: Not supported anymore" );
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void SdrExchangeView::YankMarked(ULONG /*nFormat*/)
+{
+ DBG_ERROR( "YankMarked: Not supported anymore" );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL SdrExchangeView::Paste(Window* /*pWin*/, ULONG /*nFormat*/)
+{
+ DBG_ERROR( "SdrExchangeView::Paste: Not supported anymore" );
+ return FALSE;
+}