diff options
Diffstat (limited to 'svx/source/sdr')
120 files changed, 26171 insertions, 0 deletions
diff --git a/svx/source/sdr/animation/animationstate.cxx b/svx/source/sdr/animation/animationstate.cxx new file mode 100644 index 000000000000..2fe1bcf9a235 --- /dev/null +++ b/svx/source/sdr/animation/animationstate.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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/animation/animationstate.hxx> +#include <tools/debug.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <drawinglayer/primitive2d/animatedprimitive2d.hxx> +#include <drawinglayer/animation/animationtiming.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace animation + { + double PrimitiveAnimation::getSmallestNextTime(double fCurrentTime) + { + double fRetval(0.0); + + if(maAnimatedPrimitives.hasElements()) + { + const sal_Int32 nCount(maAnimatedPrimitives.getLength()); + + for(sal_Int32 a(0L); a < nCount; a++) + { + const drawinglayer::primitive2d::Primitive2DReference xRef(maAnimatedPrimitives[a]); + const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* pCandidate = dynamic_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* >(xRef.get()); + OSL_ENSURE(pCandidate, "PrimitiveAnimation::getSmallestNextTime: wrong primitive in animated list (!)"); + + if(pCandidate) + { + const drawinglayer::animation::AnimationEntry& rAnimEntry = pCandidate->getAnimationEntry(); + const double fNextTime(rAnimEntry.getNextEventTime(fCurrentTime)); + + if(!::basegfx::fTools::equalZero(fNextTime)) + { + if(::basegfx::fTools::equalZero(fRetval)) + { + fRetval = fNextTime; + } + else if(::basegfx::fTools::less(fNextTime, fRetval)) + { + fRetval = fNextTime; + } + } + } + } + } + + return fRetval; + } + + void PrimitiveAnimation::prepareNextEvent() + { + const double fCurrentTime(mrVOContact.GetObjectContact().getPrimitiveAnimator().GetTime()); + const double fNextTime(getSmallestNextTime(fCurrentTime)); + + // getSmallestNextTime will be zero when animation ended. If not zero, a next step + // exists + if(!::basegfx::fTools::equalZero(fNextTime)) + { + // next time point exists, use it + sal_uInt32 nNextTime; + + if(fNextTime >= (double)0xffffff00) + { + // take care for very late points in time, e.g. when a text animation stops + // in a defined AnimationEntryFixed with endless (0xffffffff) duration + nNextTime = GetTime() + (1000 * 60 * 60); // one hour, works with vcl timers, 0xffffff00 was too much... + } + else + { + nNextTime = (sal_uInt32)fNextTime; + } + + // ensure step forward in integer timing, the floating step difference maybe smaller than 1.0. Use + // at least 25ms for next step + const sal_uInt32 nMinimumStepTime((sal_uInt32)fCurrentTime + 25L); + + if(nNextTime <= nMinimumStepTime) + { + nNextTime = nMinimumStepTime; + } + + // set time and reactivate by re-adding to the scheduler + SetTime(nNextTime); + mrVOContact.GetObjectContact().getPrimitiveAnimator().InsertEvent(this); + } + } + + PrimitiveAnimation::PrimitiveAnimation(sdr::contact::ViewObjectContact& rVOContact, const drawinglayer::primitive2d::Primitive2DSequence& rAnimatedPrimitives) + : Event(0L), + mrVOContact(rVOContact), + maAnimatedPrimitives(rAnimatedPrimitives) + { + // setup initially + prepareNextEvent(); + } + + PrimitiveAnimation::~PrimitiveAnimation() + { + // ensure that Event member is removed from PrimitiveAnimator + mrVOContact.GetObjectContact().getPrimitiveAnimator().RemoveEvent(this); + } + + // execute event, from base class Event + void PrimitiveAnimation::Trigger(sal_uInt32 /*nTime*/) + { + // schedule a repaint of associated object + mrVOContact.ActionChanged(); + + // re-setup + prepareNextEvent(); + } + } // end of namespace animation +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/animation/makefile.mk b/svx/source/sdr/animation/makefile.mk new file mode 100644 index 000000000000..a6750647f556 --- /dev/null +++ b/svx/source/sdr/animation/makefile.mk @@ -0,0 +1,46 @@ +#************************************************************************* +# +# 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=animation +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/animationstate.obj \ + $(SLO)$/objectanimator.obj \ + $(SLO)$/scheduler.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/animation/objectanimator.cxx b/svx/source/sdr/animation/objectanimator.cxx new file mode 100644 index 000000000000..2dc7d514fdeb --- /dev/null +++ b/svx/source/sdr/animation/objectanimator.cxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * 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/animation/objectanimator.hxx> +#include <tools/debug.hxx> +#include <svx/sdr/animation/animationstate.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace animation + { + primitiveAnimator::primitiveAnimator() + : Scheduler() + { + } + + primitiveAnimator::~primitiveAnimator() + { + } + } // end of namespace animation +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/animation/scheduler.cxx b/svx/source/sdr/animation/scheduler.cxx new file mode 100644 index 000000000000..50441f010fdb --- /dev/null +++ b/svx/source/sdr/animation/scheduler.cxx @@ -0,0 +1,315 @@ +/************************************************************************* + * + * 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/animation/scheduler.hxx> + +#include <vector> + +////////////////////////////////////////////////////////////////////////////// +// event class + +namespace sdr +{ + namespace animation + { + Event::Event(sal_uInt32 nTime) + : mnTime(nTime), + mpNext(0L) + { + } + + Event::~Event() + { + } + + Event* Event::GetNext() const + { + return mpNext; + } + + void Event::SetNext(Event* pNew) + { + if(pNew != mpNext) + { + mpNext = pNew; + } + } + + sal_uInt32 Event::GetTime() const + { + return mnTime; + } + + void Event::SetTime(sal_uInt32 nNew) + { + if(mnTime != nNew) + { + mnTime = nNew; + } + } + } // end of namespace animation +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eventlist class + +namespace sdr +{ + namespace animation + { + EventList::EventList() + : mpHead(0L) + { + } + + EventList::~EventList() + { + Clear(); + } + + void EventList::Insert(Event* pNew) + { + if(pNew) + { + Event* pCurrent = mpHead; + Event* pPrev = 0L; + + while(pCurrent && pCurrent->GetTime() < pNew->GetTime()) + { + pPrev = pCurrent; + pCurrent = pCurrent->GetNext(); + } + + if(pPrev) + { + pNew->SetNext(pPrev->GetNext()); + pPrev->SetNext(pNew); + } + else + { + pNew->SetNext(mpHead); + mpHead = pNew; + } + } + } + + void EventList::Remove(Event* pOld) + { + if(pOld && mpHead) + { + Event* pCurrent = mpHead; + Event* pPrev = 0L; + + while(pCurrent && pCurrent != pOld) + { + pPrev = pCurrent; + pCurrent = pCurrent->GetNext(); + } + + if(pPrev) + { + pPrev->SetNext(pOld->GetNext()); + } + else + { + mpHead = pOld->GetNext(); + } + + pOld->SetNext(0L); + } + } + + void EventList::Clear() + { + while(mpHead) + { + Event* pNext = mpHead->GetNext(); + mpHead->SetNext(0L); + mpHead = pNext; + } + } + + Event* EventList::GetFirst() + { + return mpHead; + } + } // end of namespace animation +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// scheduler class + +namespace sdr +{ + namespace animation + { + Scheduler::Scheduler() + : mnTime(0L), + mnDeltaTime(0L), + mbIsPaused(false) + { + } + + Scheduler::~Scheduler() + { + Stop(); + } + + void Scheduler::Timeout() + { + // stop timer and add time + Stop(); + mnTime += mnDeltaTime; + + // execute events + triggerEvents(); + + // re-start or stop timer according to event list + checkTimeout(); + } + + void Scheduler::triggerEvents() + { + Event* pNextEvent = maList.GetFirst(); + + if(pNextEvent) + { + // copy events which need to be executed to a vector. Remove them from + // the scheduler + ::std::vector< Event* > EventPointerVector; + + while(pNextEvent && pNextEvent->GetTime() <= mnTime) + { + maList.Remove(pNextEvent); + EventPointerVector.push_back(pNextEvent); + pNextEvent = maList.GetFirst(); + } + + // execute events from the vector + for(::std::vector< Event* >::iterator aCandidate = EventPointerVector.begin(); + aCandidate != EventPointerVector.end(); aCandidate++) + { + // trigger event. This may re-insert the event to the scheduler again + (*aCandidate)->Trigger(mnTime); + } + } + } + + void Scheduler::checkTimeout() + { + // re-start or stop timer according to event list + if(!IsPaused() && maList.GetFirst()) + { + mnDeltaTime = maList.GetFirst()->GetTime() - mnTime; + + if(0L != mnDeltaTime) + { + SetTimeout(mnDeltaTime); + Start(); + } + } + else + { + Stop(); + } + } + + sal_uInt32 Scheduler::GetTime() + { + return mnTime; + } + + // #i38135# + void Scheduler::SetTime(sal_uInt32 nTime) + { + // reset time + Stop(); + mnTime = nTime; + + // get event pointer + Event* pEvent = maList.GetFirst(); + + if(pEvent) + { + // retet event time points + while(pEvent) + { + pEvent->SetTime(nTime); + pEvent = pEvent->GetNext(); + } + + if(!IsPaused()) + { + // without delta time, init events by triggering them. This will invalidate + // painted objects and add them to the scheduler again + mnDeltaTime = 0L; + triggerEvents(); + checkTimeout(); + } + } + } + + void Scheduler::Reset(sal_uInt32 nTime) + { + mnTime = nTime; + mnDeltaTime = 0L; + maList.Clear(); + } + + void Scheduler::InsertEvent(Event* pNew) + { + if(pNew) + { + maList.Insert(pNew); + checkTimeout(); + } + } + + void Scheduler::RemoveEvent(Event* pOld) + { + if(pOld && maList.GetFirst()) + { + maList.Remove(pOld); + checkTimeout(); + } + } + + void Scheduler::SetPaused(bool bNew) + { + if(bNew != mbIsPaused) + { + mbIsPaused = bNew; + checkTimeout(); + } + } + } // end of namespace animation +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/makefile.mk b/svx/source/sdr/attribute/makefile.mk new file mode 100644 index 000000000000..177654ff1e1c --- /dev/null +++ b/svx/source/sdr/attribute/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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=attribute +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/sdrfilltextattribute.obj \ + $(SLO)$/sdrlinefillshadowtextattribute.obj \ + $(SLO)$/sdrlineshadowtextattribute.obj \ + $(SLO)$/sdrshadowtextattribute.obj \ + $(SLO)$/sdrtextattribute.obj \ + $(SLO)$/sdrformtextattribute.obj \ + $(SLO)$/sdrformtextoutlineattribute.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/attribute/sdrfilltextattribute.cxx b/svx/source/sdr/attribute/sdrfilltextattribute.cxx new file mode 100644 index 000000000000..e281c77068c5 --- /dev/null +++ b/svx/source/sdr/attribute/sdrfilltextattribute.cxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrallattribute.cxx,v $ + * + * $Revision: 1.2 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrfilltextattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + SdrFillTextAttribute::SdrFillTextAttribute( + const SdrFillAttribute& rFill, + const FillGradientAttribute& rFillFloatTransGradient, + const SdrTextAttribute& rTextAttribute) + : maFill(rFill), + maFillFloatTransGradient(rFillFloatTransGradient), + maTextAttribute(rTextAttribute) + { + } + + SdrFillTextAttribute::SdrFillTextAttribute() + : maFill(), + maFillFloatTransGradient(), + maTextAttribute() + { + } + + SdrFillTextAttribute::SdrFillTextAttribute(const SdrFillTextAttribute& rCandidate) + : maFill(rCandidate.getFill()), + maFillFloatTransGradient(rCandidate.getFillFloatTransGradient()), + maTextAttribute(rCandidate.getText()) + { + } + + SdrFillTextAttribute& SdrFillTextAttribute::operator=(const SdrFillTextAttribute& rCandidate) + { + maFill = rCandidate.getFill(); + maFillFloatTransGradient = rCandidate.getFillFloatTransGradient(); + maTextAttribute = rCandidate.getText(); + + return *this; + } + + bool SdrFillTextAttribute::isDefault() const + { + return(getFill().isDefault() + && getFillFloatTransGradient().isDefault() + && getText().isDefault()); + } + + bool SdrFillTextAttribute::operator==(const SdrFillTextAttribute& rCandidate) const + { + return(getFill() == rCandidate.getFill() + && getFillFloatTransGradient() == rCandidate.getFillFloatTransGradient() + && getText() == rCandidate.getText()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrformtextattribute.cxx b/svx/source/sdr/attribute/sdrformtextattribute.cxx new file mode 100644 index 000000000000..39037faa5031 --- /dev/null +++ b/svx/source/sdr/attribute/sdrformtextattribute.cxx @@ -0,0 +1,423 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrformtextattribute.hxx> +#include <basegfx/vector/b2enums.hxx> +#include <svl/itemset.hxx> +#include <svx/xftdiit.hxx> +#include <svx/xftstit.hxx> +#include <svx/xftshxy.hxx> +#include <svx/xftshtit.hxx> +#include <svx/xtextit0.hxx> +#include <svx/xftadit.hxx> +#include <svx/xftshit.hxx> +#include <svx/xftshcit.hxx> +#include <svx/xftmrit.hxx> +#include <svx/xftouit.hxx> +#include <svx/sdshtitm.hxx> +#include <svx/xlntrit.hxx> +#include <svx/sdshcitm.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlinjoit.hxx> +#include <svx/xlineit0.hxx> +#include <svx/xdash.hxx> +#include <svx/xlndsit.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> +#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// +// helper to get line, stroke and transparence attributes from SfxItemSet + +namespace +{ + basegfx::B2DLineJoin impGetB2DLineJoin(XLineJoint eLineJoint) + { + switch(eLineJoint) + { + case XLINEJOINT_MIDDLE : + { + return basegfx::B2DLINEJOIN_MIDDLE; + } + case XLINEJOINT_BEVEL : + { + return basegfx::B2DLINEJOIN_BEVEL; + } + case XLINEJOINT_MITER : + { + return basegfx::B2DLINEJOIN_MITER; + } + case XLINEJOINT_ROUND : + { + return basegfx::B2DLINEJOIN_ROUND; + } + default : + { + return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE + } + } + } + + sal_uInt8 impGetStrokeTransparence(bool bShadow, const SfxItemSet& rSet) + { + sal_uInt8 nRetval; + + if(bShadow) + { + nRetval = (sal_uInt8)((((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue() * 255) / 100); + } + else + { + nRetval = (sal_uInt8)((((XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue() * 255) / 100); + } + + return nRetval; + } + + drawinglayer::attribute::LineAttribute impGetLineAttribute(bool bShadow, const SfxItemSet& rSet) + { + basegfx::BColor aColorAttribute; + + if(bShadow) + { + const Color aShadowColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue()); + aColorAttribute = aShadowColor.getBColor(); + } + else + { + const Color aLineColor(((XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue()); + aColorAttribute = aLineColor.getBColor(); + } + + const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); + const XLineJoint eLineJoint = ((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue(); + + return drawinglayer::attribute::LineAttribute(aColorAttribute, (double)nLineWidth, impGetB2DLineJoin(eLineJoint)); + } + + drawinglayer::attribute::StrokeAttribute impGetStrokeAttribute(const SfxItemSet& rSet) + { + const XLineStyle eLineStyle = ((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue(); + double fFullDotDashLen(0.0); + ::std::vector< double > aDotDashArray; + + if(XLINE_DASH == eLineStyle) + { + const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue(); + + if(rDash.GetDots() || rDash.GetDashes()) + { + const sal_uInt32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); + fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nLineWidth); + } + } + + return drawinglayer::attribute::StrokeAttribute(aDotDashArray, fFullDotDashLen); + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class ImpSdrFormTextAttribute + { + public: + // refcounter + sal_uInt32 mnRefCount; + + // FormText (FontWork) Attributes + sal_Int32 mnFormTextDistance; // distance from line in upright direction + sal_Int32 mnFormTextStart; // shift from polygon start + sal_Int32 mnFormTextShdwXVal; // shadow distance or 10th degrees + sal_Int32 mnFormTextShdwYVal; // shadow distance or scaling + sal_uInt16 mnFormTextShdwTransp; // shadow transparence + XFormTextStyle meFormTextStyle; // on/off and char orientation + XFormTextAdjust meFormTextAdjust; // adjustment (left/right/center) and scale + XFormTextShadow meFormTextShadow; // shadow mode + Color maFormTextShdwColor; // shadow color + + // outline attributes; used when getFormTextOutline() is true and (for + // shadow) when getFormTextShadow() != XFTSHADOW_NONE + SdrFormTextOutlineAttribute maOutline; + SdrFormTextOutlineAttribute maShadowOutline; + + // bitfield + unsigned mbFormTextMirror : 1; // change orientation + unsigned mbFormTextOutline : 1; // show contour of objects + + ImpSdrFormTextAttribute(const SfxItemSet& rSet) + : mnRefCount(0), + mnFormTextDistance(((const XFormTextDistanceItem&)rSet.Get(XATTR_FORMTXTDISTANCE)).GetValue()), + mnFormTextStart(((const XFormTextStartItem&)rSet.Get(XATTR_FORMTXTSTART)).GetValue()), + mnFormTextShdwXVal(((const XFormTextShadowXValItem&)rSet.Get(XATTR_FORMTXTSHDWXVAL)).GetValue()), + mnFormTextShdwYVal(((const XFormTextShadowYValItem&)rSet.Get(XATTR_FORMTXTSHDWYVAL)).GetValue()), + mnFormTextShdwTransp(((const XFormTextShadowTranspItem&)rSet.Get(XATTR_FORMTXTSHDWTRANSP)).GetValue()), + meFormTextStyle(((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue()), + meFormTextAdjust(((const XFormTextAdjustItem&)rSet.Get(XATTR_FORMTXTADJUST)).GetValue()), + meFormTextShadow(((const XFormTextShadowItem&)rSet.Get(XATTR_FORMTXTSHADOW)).GetValue()), + maFormTextShdwColor(((const XFormTextShadowColorItem&)rSet.Get(XATTR_FORMTXTSHDWCOLOR)).GetColorValue()), + maOutline(), + maShadowOutline(), + mbFormTextMirror(((const XFormTextMirrorItem&)rSet.Get(XATTR_FORMTXTMIRROR)).GetValue()), + mbFormTextOutline(((const XFormTextOutlineItem&)rSet.Get(XATTR_FORMTXTOUTLINE)).GetValue()) + { + if(getFormTextOutline()) + { + const StrokeAttribute aStrokeAttribute(impGetStrokeAttribute(rSet)); + + // also need to prepare attributes for outlines + { + const LineAttribute aLineAttribute(impGetLineAttribute(false, rSet)); + const sal_uInt8 nTransparence(impGetStrokeTransparence(false, rSet)); + + maOutline = SdrFormTextOutlineAttribute( + aLineAttribute, aStrokeAttribute, nTransparence); + } + + if(XFTSHADOW_NONE != getFormTextShadow()) + { + // also need to prepare attributes for shadow outlines + const LineAttribute aLineAttribute(impGetLineAttribute(true, rSet)); + const sal_uInt8 nTransparence(impGetStrokeTransparence(true, rSet)); + + maShadowOutline = SdrFormTextOutlineAttribute( + aLineAttribute, aStrokeAttribute, nTransparence); + } + } + } + + ImpSdrFormTextAttribute() + : mnRefCount(0), + mnFormTextDistance(0), + mnFormTextStart(0), + mnFormTextShdwXVal(0), + mnFormTextShdwYVal(0), + mnFormTextShdwTransp(0), + meFormTextStyle(XFT_NONE), + meFormTextAdjust(XFT_CENTER), + meFormTextShadow(XFTSHADOW_NONE), + maFormTextShdwColor(), + maOutline(), + maShadowOutline(), + mbFormTextMirror(false), + mbFormTextOutline(false) + { + } + + // data read access + sal_Int32 getFormTextDistance() const { return mnFormTextDistance; } + sal_Int32 getFormTextStart() const { return mnFormTextStart; } + sal_Int32 getFormTextShdwXVal() const { return mnFormTextShdwXVal; } + sal_Int32 getFormTextShdwYVal() const { return mnFormTextShdwYVal; } + sal_uInt16 getFormTextShdwTransp() const { return mnFormTextShdwTransp; } + XFormTextStyle getFormTextStyle() const { return meFormTextStyle; } + XFormTextAdjust getFormTextAdjust() const { return meFormTextAdjust; } + XFormTextShadow getFormTextShadow() const { return meFormTextShadow; } + Color getFormTextShdwColor() const { return maFormTextShdwColor; } + const SdrFormTextOutlineAttribute& getOutline() const { return maOutline; } + const SdrFormTextOutlineAttribute& getShadowOutline() const { return maShadowOutline; } + bool getFormTextMirror() const { return mbFormTextMirror; } + bool getFormTextOutline() const { return mbFormTextOutline; } + + // compare operator + bool operator==(const ImpSdrFormTextAttribute& rCandidate) const + { + return (getFormTextDistance() == rCandidate.getFormTextDistance() + && getFormTextStart() == rCandidate.getFormTextStart() + && getFormTextShdwXVal() == rCandidate.getFormTextShdwXVal() + && getFormTextShdwYVal() == rCandidate.getFormTextShdwYVal() + && getFormTextShdwTransp() == rCandidate.getFormTextShdwTransp() + && getFormTextStyle() == rCandidate.getFormTextStyle() + && getFormTextAdjust() == rCandidate.getFormTextAdjust() + && getFormTextShadow() == rCandidate.getFormTextShadow() + && getFormTextShdwColor() == rCandidate.getFormTextShdwColor() + && getOutline() == rCandidate.getOutline() + && getShadowOutline() == rCandidate.getShadowOutline() + && getFormTextMirror() == rCandidate.getFormTextMirror() + && getFormTextOutline() == rCandidate.getFormTextOutline()); + } + + static ImpSdrFormTextAttribute* get_global_default() + { + static ImpSdrFormTextAttribute* pDefault = 0; + + if(!pDefault) + { + pDefault = new ImpSdrFormTextAttribute(); + + // never delete; start with RefCount 1, not 0 + pDefault->mnRefCount++; + } + + return pDefault; + } + }; + + SdrFormTextAttribute::SdrFormTextAttribute(const SfxItemSet& rSet) + : mpSdrFormTextAttribute(new ImpSdrFormTextAttribute(rSet)) + { + } + + SdrFormTextAttribute::SdrFormTextAttribute() + : mpSdrFormTextAttribute(ImpSdrFormTextAttribute::get_global_default()) + { + mpSdrFormTextAttribute->mnRefCount++; + } + + SdrFormTextAttribute::SdrFormTextAttribute(const SdrFormTextAttribute& rCandidate) + : mpSdrFormTextAttribute(rCandidate.mpSdrFormTextAttribute) + { + mpSdrFormTextAttribute->mnRefCount++; + } + + SdrFormTextAttribute::~SdrFormTextAttribute() + { + if(mpSdrFormTextAttribute->mnRefCount) + { + mpSdrFormTextAttribute->mnRefCount--; + } + else + { + delete mpSdrFormTextAttribute; + } + } + + bool SdrFormTextAttribute::isDefault() const + { + return mpSdrFormTextAttribute == ImpSdrFormTextAttribute::get_global_default(); + } + + SdrFormTextAttribute& SdrFormTextAttribute::operator=(const SdrFormTextAttribute& rCandidate) + { + if(rCandidate.mpSdrFormTextAttribute != mpSdrFormTextAttribute) + { + if(mpSdrFormTextAttribute->mnRefCount) + { + mpSdrFormTextAttribute->mnRefCount--; + } + else + { + delete mpSdrFormTextAttribute; + } + + mpSdrFormTextAttribute = rCandidate.mpSdrFormTextAttribute; + mpSdrFormTextAttribute->mnRefCount++; + } + + return *this; + } + + bool SdrFormTextAttribute::operator==(const SdrFormTextAttribute& rCandidate) const + { + if(rCandidate.mpSdrFormTextAttribute == mpSdrFormTextAttribute) + { + return true; + } + + if(rCandidate.isDefault() != isDefault()) + { + return false; + } + + return (*rCandidate.mpSdrFormTextAttribute == *mpSdrFormTextAttribute); + } + + sal_Int32 SdrFormTextAttribute::getFormTextDistance() const + { + return mpSdrFormTextAttribute->getFormTextDistance(); + } + + sal_Int32 SdrFormTextAttribute::getFormTextStart() const + { + return mpSdrFormTextAttribute->getFormTextStart(); + } + + sal_Int32 SdrFormTextAttribute::getFormTextShdwXVal() const + { + return mpSdrFormTextAttribute->getFormTextShdwXVal(); + } + + sal_Int32 SdrFormTextAttribute::getFormTextShdwYVal() const + { + return mpSdrFormTextAttribute->getFormTextShdwYVal(); + } + + sal_uInt16 SdrFormTextAttribute::getFormTextShdwTransp() const + { + return mpSdrFormTextAttribute->getFormTextShdwTransp(); + } + + XFormTextStyle SdrFormTextAttribute::getFormTextStyle() const + { + return mpSdrFormTextAttribute->getFormTextStyle(); + } + + XFormTextAdjust SdrFormTextAttribute::getFormTextAdjust() const + { + return mpSdrFormTextAttribute->getFormTextAdjust(); + } + + XFormTextShadow SdrFormTextAttribute::getFormTextShadow() const + { + return mpSdrFormTextAttribute->getFormTextShadow(); + } + + Color SdrFormTextAttribute::getFormTextShdwColor() const + { + return mpSdrFormTextAttribute->getFormTextShdwColor(); + } + + const SdrFormTextOutlineAttribute& SdrFormTextAttribute::getOutline() const + { + return mpSdrFormTextAttribute->getOutline(); + } + + const SdrFormTextOutlineAttribute& SdrFormTextAttribute::getShadowOutline() const + { + return mpSdrFormTextAttribute->getShadowOutline(); + } + + bool SdrFormTextAttribute::getFormTextMirror() const + { + return mpSdrFormTextAttribute->getFormTextMirror(); + } + + bool SdrFormTextAttribute::getFormTextOutline() const + { + return mpSdrFormTextAttribute->getFormTextOutline(); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrformtextoutlineattribute.cxx b/svx/source/sdr/attribute/sdrformtextoutlineattribute.cxx new file mode 100644 index 000000000000..6f1925f1f5a8 --- /dev/null +++ b/svx/source/sdr/attribute/sdrformtextoutlineattribute.cxx @@ -0,0 +1,185 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx> +#include <drawinglayer/attribute/lineattribute.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class ImpSdrFormTextOutlineAttribute + { + public: + // refcounter + sal_uInt32 mnRefCount; + + // one set of attributes for FormText (FontWork) outline visualisation + LineAttribute maLineAttribute; + StrokeAttribute maStrokeAttribute; + sal_uInt8 mnTransparence; + + ImpSdrFormTextOutlineAttribute( + const LineAttribute& rLineAttribute, + const StrokeAttribute& rStrokeAttribute, + sal_uInt8 nTransparence) + : mnRefCount(0), + maLineAttribute(rLineAttribute), + maStrokeAttribute(rStrokeAttribute), + mnTransparence(nTransparence) + { + } + + // data read access + const LineAttribute& getLineAttribute() const { return maLineAttribute; } + const StrokeAttribute& getStrokeAttribute() const { return maStrokeAttribute; } + sal_uInt8 getTransparence() const { return mnTransparence; } + + // compare operator + bool operator==(const ImpSdrFormTextOutlineAttribute& rCandidate) const + { + return (getLineAttribute() == rCandidate.getLineAttribute() + && getStrokeAttribute() == rCandidate.getStrokeAttribute() + && getTransparence() == rCandidate.getTransparence()); + } + + static ImpSdrFormTextOutlineAttribute* get_global_default() + { + static ImpSdrFormTextOutlineAttribute* pDefault = 0; + + if(!pDefault) + { + pDefault = new ImpSdrFormTextOutlineAttribute( + LineAttribute(), + StrokeAttribute(), + 0); + + // never delete; start with RefCount 1, not 0 + pDefault->mnRefCount++; + } + + return pDefault; + } + }; + + SdrFormTextOutlineAttribute::SdrFormTextOutlineAttribute( + const LineAttribute& rLineAttribute, + const StrokeAttribute& rStrokeAttribute, + sal_uInt8 nTransparence) + : mpSdrFormTextOutlineAttribute(new ImpSdrFormTextOutlineAttribute( + rLineAttribute, rStrokeAttribute, nTransparence)) + { + } + + SdrFormTextOutlineAttribute::SdrFormTextOutlineAttribute() + : mpSdrFormTextOutlineAttribute(ImpSdrFormTextOutlineAttribute::get_global_default()) + { + mpSdrFormTextOutlineAttribute->mnRefCount++; + } + + SdrFormTextOutlineAttribute::SdrFormTextOutlineAttribute(const SdrFormTextOutlineAttribute& rCandidate) + : mpSdrFormTextOutlineAttribute(rCandidate.mpSdrFormTextOutlineAttribute) + { + mpSdrFormTextOutlineAttribute->mnRefCount++; + } + + SdrFormTextOutlineAttribute::~SdrFormTextOutlineAttribute() + { + if(mpSdrFormTextOutlineAttribute->mnRefCount) + { + mpSdrFormTextOutlineAttribute->mnRefCount--; + } + else + { + delete mpSdrFormTextOutlineAttribute; + } + } + + bool SdrFormTextOutlineAttribute::isDefault() const + { + return mpSdrFormTextOutlineAttribute == ImpSdrFormTextOutlineAttribute::get_global_default(); + } + + SdrFormTextOutlineAttribute& SdrFormTextOutlineAttribute::operator=(const SdrFormTextOutlineAttribute& rCandidate) + { + if(rCandidate.mpSdrFormTextOutlineAttribute != mpSdrFormTextOutlineAttribute) + { + if(mpSdrFormTextOutlineAttribute->mnRefCount) + { + mpSdrFormTextOutlineAttribute->mnRefCount--; + } + else + { + delete mpSdrFormTextOutlineAttribute; + } + + mpSdrFormTextOutlineAttribute = rCandidate.mpSdrFormTextOutlineAttribute; + mpSdrFormTextOutlineAttribute->mnRefCount++; + } + + return *this; + } + + bool SdrFormTextOutlineAttribute::operator==(const SdrFormTextOutlineAttribute& rCandidate) const + { + if(rCandidate.mpSdrFormTextOutlineAttribute == mpSdrFormTextOutlineAttribute) + { + return true; + } + + if(rCandidate.isDefault() != isDefault()) + { + return false; + } + + return (*rCandidate.mpSdrFormTextOutlineAttribute == *mpSdrFormTextOutlineAttribute); + } + + const LineAttribute& SdrFormTextOutlineAttribute::getLineAttribute() const + { + return mpSdrFormTextOutlineAttribute->getLineAttribute(); + } + + const StrokeAttribute& SdrFormTextOutlineAttribute::getStrokeAttribute() const + { + return mpSdrFormTextOutlineAttribute->getStrokeAttribute(); + } + + sal_uInt8 SdrFormTextOutlineAttribute::getTransparence() const + { + return mpSdrFormTextOutlineAttribute->getTransparence(); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx b/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx new file mode 100644 index 000000000000..6d8356833829 --- /dev/null +++ b/svx/source/sdr/attribute/sdrlinefillshadowtextattribute.cxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrallattribute.cxx,v $ + * + * $Revision: 1.2 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrlinefillshadowtextattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute( + const SdrLineAttribute& rLine, + const SdrFillAttribute& rFill, + const SdrLineStartEndAttribute& rLineStartEnd, + const SdrShadowAttribute& rShadow, + const FillGradientAttribute& rFillFloatTransGradient, + const SdrTextAttribute& rTextAttribute) + : SdrLineShadowTextAttribute(rLine, rLineStartEnd, rShadow, rTextAttribute), + maFill(rFill), + maFillFloatTransGradient(rFillFloatTransGradient) + { + } + + SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute() + : SdrLineShadowTextAttribute(), + maFill(), + maFillFloatTransGradient() + { + } + + SdrLineFillShadowTextAttribute::SdrLineFillShadowTextAttribute(const SdrLineFillShadowTextAttribute& rCandidate) + : SdrLineShadowTextAttribute(rCandidate), + maFill(rCandidate.getFill()), + maFillFloatTransGradient(rCandidate.getFillFloatTransGradient()) + { + } + + SdrLineFillShadowTextAttribute& SdrLineFillShadowTextAttribute::operator=(const SdrLineFillShadowTextAttribute& rCandidate) + { + SdrLineShadowTextAttribute::operator=(rCandidate); + maFill = rCandidate.getFill(); + maFillFloatTransGradient = rCandidate.getFillFloatTransGradient(); + + return *this; + } + + bool SdrLineFillShadowTextAttribute::isDefault() const + { + return (SdrLineShadowTextAttribute::isDefault() + && getFill().isDefault() + && getFillFloatTransGradient().isDefault()); + } + + bool SdrLineFillShadowTextAttribute::operator==(const SdrLineFillShadowTextAttribute& rCandidate) const + { + return(SdrLineShadowTextAttribute::operator==(rCandidate) + && getFill() == rCandidate.getFill() + && getFillFloatTransGradient() == rCandidate.getFillFloatTransGradient()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx b/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx new file mode 100644 index 000000000000..6b863a11aa03 --- /dev/null +++ b/svx/source/sdr/attribute/sdrlineshadowtextattribute.cxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrallattribute.cxx,v $ + * + * $Revision: 1.2 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrlineshadowtextattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + SdrLineShadowTextAttribute::SdrLineShadowTextAttribute( + const SdrLineAttribute& rLine, + const SdrLineStartEndAttribute& rLineStartEnd, + const SdrShadowAttribute& rShadow, + const SdrTextAttribute& rTextAttribute) + : SdrShadowTextAttribute(rShadow, rTextAttribute), + maLine(rLine), + maLineStartEnd(rLineStartEnd) + { + } + + SdrLineShadowTextAttribute::SdrLineShadowTextAttribute() + : SdrShadowTextAttribute(), + maLine(), + maLineStartEnd() + { + } + + SdrLineShadowTextAttribute::SdrLineShadowTextAttribute(const SdrLineShadowTextAttribute& rCandidate) + : SdrShadowTextAttribute(rCandidate), + maLine(rCandidate.getLine()), + maLineStartEnd(rCandidate.getLineStartEnd()) + { + } + + SdrLineShadowTextAttribute& SdrLineShadowTextAttribute::operator=(const SdrLineShadowTextAttribute& rCandidate) + { + SdrShadowTextAttribute::operator=(rCandidate); + maLine = rCandidate.getLine(); + maLineStartEnd = rCandidate.getLineStartEnd(); + + return *this; + } + + bool SdrLineShadowTextAttribute::isDefault() const + { + return(SdrShadowTextAttribute::isDefault() + && getLine().isDefault() + && getLineStartEnd().isDefault()); + } + + bool SdrLineShadowTextAttribute::operator==(const SdrLineShadowTextAttribute& rCandidate) const + { + return(SdrShadowTextAttribute::operator==(rCandidate) + && getLine() == rCandidate.getLine() + && getLineStartEnd() == rCandidate.getLineStartEnd()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrshadowtextattribute.cxx b/svx/source/sdr/attribute/sdrshadowtextattribute.cxx new file mode 100644 index 000000000000..34485b57399c --- /dev/null +++ b/svx/source/sdr/attribute/sdrshadowtextattribute.cxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sdrallattribute.cxx,v $ + * + * $Revision: 1.2 $ + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrshadowtextattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + SdrShadowTextAttribute::SdrShadowTextAttribute( + const SdrShadowAttribute& rShadow, + const SdrTextAttribute& rTextAttribute) + : maShadow(rShadow), + maTextAttribute(rTextAttribute) + { + } + + SdrShadowTextAttribute::SdrShadowTextAttribute() + : maShadow(), + maTextAttribute() + { + } + + SdrShadowTextAttribute::SdrShadowTextAttribute(const SdrShadowTextAttribute& rCandidate) + : maShadow(rCandidate.getShadow()), + maTextAttribute(rCandidate.getText()) + { + } + + SdrShadowTextAttribute& SdrShadowTextAttribute::operator=(const SdrShadowTextAttribute& rCandidate) + { + maShadow = rCandidate.getShadow(); + maTextAttribute = rCandidate.getText(); + + return *this; + } + + bool SdrShadowTextAttribute::isDefault() const + { + return (getShadow().isDefault() + && getText().isDefault()); + } + + bool SdrShadowTextAttribute::operator==(const SdrShadowTextAttribute& rCandidate) const + { + return (getShadow() == rCandidate.getShadow() + && getText() == rCandidate.getText()); + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/attribute/sdrtextattribute.cxx b/svx/source/sdr/attribute/sdrtextattribute.cxx new file mode 100644 index 000000000000..a28430f127c1 --- /dev/null +++ b/svx/source/sdr/attribute/sdrtextattribute.cxx @@ -0,0 +1,461 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" + +#include <svx/sdr/attribute/sdrtextattribute.hxx> +#include <svx/sdr/attribute/sdrformtextattribute.hxx> +#include <svx/svdotext.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <editeng/flditem.hxx> +#include <svx/sdr/properties/properties.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace attribute + { + class ImpSdrTextAttribute + { + public: + // refcounter + sal_uInt32 mnRefCount; + + // all-text attributes. The SdrText itself and a copy + // of te OPO + const SdrText* mpSdrText; + const OutlinerParaObject* mpOutlinerParaObject; + + // Set when it's a FormText; contains all FormText attributes + SdrFormTextAttribute maSdrFormTextAttribute; + + // text distances + sal_Int32 maTextLeftDistance; + sal_Int32 maTextUpperDistance; + sal_Int32 maTextRightDistance; + sal_Int32 maTextLowerDistance; + + // #i101556# use versioning from text attributes to detect changes + sal_uInt32 maPropertiesVersion; + + // text alignments + SdrTextHorzAdjust maSdrTextHorzAdjust; + SdrTextVertAdjust maSdrTextVertAdjust; + + // bitfield + unsigned mbContour : 1; + unsigned mbFitToSize : 1; + unsigned mbHideContour : 1; + unsigned mbBlink : 1; + unsigned mbScroll : 1; + unsigned mbInEditMode : 1; + unsigned mbFixedCellHeight : 1; + unsigned mbWrongSpell : 1; + + public: + ImpSdrTextAttribute( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject, + XFormTextStyle eFormTextStyle, + sal_Int32 aTextLeftDistance, + sal_Int32 aTextUpperDistance, + sal_Int32 aTextRightDistance, + sal_Int32 aTextLowerDistance, + SdrTextHorzAdjust aSdrTextHorzAdjust, + SdrTextVertAdjust aSdrTextVertAdjust, + bool bContour, + bool bFitToSize, + bool bHideContour, + bool bBlink, + bool bScroll, + bool bInEditMode, + bool bFixedCellHeight, + bool bWrongSpell) + : mnRefCount(0), + mpSdrText(pSdrText), + mpOutlinerParaObject(new OutlinerParaObject(rOutlinerParaObject)), + maSdrFormTextAttribute(), + maTextLeftDistance(aTextLeftDistance), + maTextUpperDistance(aTextUpperDistance), + maTextRightDistance(aTextRightDistance), + maTextLowerDistance(aTextLowerDistance), + maPropertiesVersion(0), + maSdrTextHorzAdjust(aSdrTextHorzAdjust), + maSdrTextVertAdjust(aSdrTextVertAdjust), + mbContour(bContour), + mbFitToSize(bFitToSize), + mbHideContour(bHideContour), + mbBlink(bBlink), + mbScroll(bScroll), + mbInEditMode(bInEditMode), + mbFixedCellHeight(bFixedCellHeight), + mbWrongSpell(bWrongSpell) + { + if(pSdrText) + { + if(XFT_NONE != eFormTextStyle) + { + // text on path. Create FormText attribute + const SfxItemSet& rSet = pSdrText->GetItemSet(); + maSdrFormTextAttribute = SdrFormTextAttribute(rSet); + } + + // #i101556# init with version number to detect changes of single text + // attribute and/or style sheets in primitive data without having to + // copy that data locally (which would be better from principle) + maPropertiesVersion = pSdrText->GetObject().GetProperties().getVersion(); + } + } + + ImpSdrTextAttribute() + : mnRefCount(0), + mpSdrText(0), + mpOutlinerParaObject(0), + maSdrFormTextAttribute(), + maTextLeftDistance(0), + maTextUpperDistance(0), + maTextRightDistance(0), + maTextLowerDistance(0), + maPropertiesVersion(0), + maSdrTextHorzAdjust(SDRTEXTHORZADJUST_LEFT), + maSdrTextVertAdjust(SDRTEXTVERTADJUST_TOP), + mbContour(false), + mbFitToSize(false), + mbHideContour(false), + mbBlink(false), + mbScroll(false), + mbInEditMode(false), + mbFixedCellHeight(false), + mbWrongSpell(false) + { + } + + ~ImpSdrTextAttribute() + { + if(mpOutlinerParaObject) + { + delete mpOutlinerParaObject; + } + } + + // data read access + const SdrText& getSdrText() const + { + OSL_ENSURE(mpSdrText, "Access to text of default version of ImpSdrTextAttribute (!)"); + return *mpSdrText; + } + const OutlinerParaObject& getOutlinerParaObject() const + { + OSL_ENSURE(mpOutlinerParaObject, "Access to OutlinerParaObject of default version of ImpSdrTextAttribute (!)"); + return *mpOutlinerParaObject; + } + bool isContour() const { return mbContour; } + bool isFitToSize() const { return mbFitToSize; } + bool isHideContour() const { return mbHideContour; } + bool isBlink() const { return mbBlink; } + bool isScroll() const { return mbScroll; } + bool isInEditMode() const { return mbInEditMode; } + bool isFixedCellHeight() const { return mbFixedCellHeight; } + bool isWrongSpell() const { return mbWrongSpell; } + const SdrFormTextAttribute& getSdrFormTextAttribute() const { return maSdrFormTextAttribute; } + sal_Int32 getTextLeftDistance() const { return maTextLeftDistance; } + sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; } + sal_Int32 getTextRightDistance() const { return maTextRightDistance; } + sal_Int32 getTextLowerDistance() const { return maTextLowerDistance; } + sal_uInt32 getPropertiesVersion() const { return maPropertiesVersion; } + SdrTextHorzAdjust getSdrTextHorzAdjust() const { return maSdrTextHorzAdjust; } + SdrTextVertAdjust getSdrTextVertAdjust() const { return maSdrTextVertAdjust; } + + // compare operator + bool operator==(const ImpSdrTextAttribute& rCandidate) const + { + if(mpOutlinerParaObject != rCandidate.mpOutlinerParaObject) + { + if(mpOutlinerParaObject && rCandidate.mpOutlinerParaObject) + { + // compares OPO and it's contents, but traditionally not the RedLining + // which is not seen as model, but as temporary information + if(!(getOutlinerParaObject() == rCandidate.getOutlinerParaObject())) + { + return false; + } + + // #i102062# for primitive visualisation, the WrongList (SpellChecking) + // is important, too, so use isWrongListEqual since there is no WrongList + // comparison in the regular OutlinerParaObject compare (since it's + // not-persistent data) + if(!(getOutlinerParaObject().isWrongListEqual(rCandidate.getOutlinerParaObject()))) + { + return false; + } + } + else + { + // only one is zero; not equal + return false; + } + } + + return ( + getSdrFormTextAttribute() == rCandidate.getSdrFormTextAttribute() + && getTextLeftDistance() == rCandidate.getTextLeftDistance() + && getTextUpperDistance() == rCandidate.getTextUpperDistance() + && getTextRightDistance() == rCandidate.getTextRightDistance() + && getTextLowerDistance() == rCandidate.getTextLowerDistance() + && getPropertiesVersion() == rCandidate.getPropertiesVersion() + + && getSdrTextHorzAdjust() == rCandidate.getSdrTextHorzAdjust() + && getSdrTextVertAdjust() == rCandidate.getSdrTextVertAdjust() + + && isContour() == rCandidate.isContour() + && isFitToSize() == rCandidate.isFitToSize() + && isHideContour() == rCandidate.isHideContour() + && isBlink() == rCandidate.isBlink() + && isScroll() == rCandidate.isScroll() + && isInEditMode() == rCandidate.isInEditMode() + && isFixedCellHeight() == rCandidate.isFixedCellHeight() + && isWrongSpell() == rCandidate.isWrongSpell()); + } + + static ImpSdrTextAttribute* get_global_default() + { + static ImpSdrTextAttribute* pDefault = 0; + + if(!pDefault) + { + // use default constructor + pDefault = new ImpSdrTextAttribute(); + + // never delete; start with RefCount 1, not 0 + pDefault->mnRefCount++; + } + + return pDefault; + } + }; + + SdrTextAttribute::SdrTextAttribute( + const SdrText& rSdrText, + const OutlinerParaObject& rOutlinerParaObject, + XFormTextStyle eFormTextStyle, + sal_Int32 aTextLeftDistance, + sal_Int32 aTextUpperDistance, + sal_Int32 aTextRightDistance, + sal_Int32 aTextLowerDistance, + SdrTextHorzAdjust aSdrTextHorzAdjust, + SdrTextVertAdjust aSdrTextVertAdjust, + bool bContour, + bool bFitToSize, + bool bHideContour, + bool bBlink, + bool bScroll, + bool bInEditMode, + bool bFixedCellHeight, + bool bWrongSpell) + : mpSdrTextAttribute(new ImpSdrTextAttribute( + &rSdrText, rOutlinerParaObject, eFormTextStyle, aTextLeftDistance, aTextUpperDistance, + aTextRightDistance, aTextLowerDistance, aSdrTextHorzAdjust, aSdrTextVertAdjust, bContour, + bFitToSize, bHideContour, bBlink, bScroll, bInEditMode, bFixedCellHeight, bWrongSpell)) + { + } + + SdrTextAttribute::SdrTextAttribute() + : mpSdrTextAttribute(ImpSdrTextAttribute::get_global_default()) + { + mpSdrTextAttribute->mnRefCount++; + } + + SdrTextAttribute::SdrTextAttribute(const SdrTextAttribute& rCandidate) + : mpSdrTextAttribute(rCandidate.mpSdrTextAttribute) + { + mpSdrTextAttribute->mnRefCount++; + } + + SdrTextAttribute::~SdrTextAttribute() + { + if(mpSdrTextAttribute->mnRefCount) + { + mpSdrTextAttribute->mnRefCount--; + } + else + { + delete mpSdrTextAttribute; + } + } + + bool SdrTextAttribute::isDefault() const + { + return mpSdrTextAttribute == ImpSdrTextAttribute::get_global_default(); + } + + SdrTextAttribute& SdrTextAttribute::operator=(const SdrTextAttribute& rCandidate) + { + if(rCandidate.mpSdrTextAttribute != mpSdrTextAttribute) + { + if(mpSdrTextAttribute->mnRefCount) + { + mpSdrTextAttribute->mnRefCount--; + } + else + { + delete mpSdrTextAttribute; + } + + mpSdrTextAttribute = rCandidate.mpSdrTextAttribute; + mpSdrTextAttribute->mnRefCount++; + } + + return *this; + } + + bool SdrTextAttribute::operator==(const SdrTextAttribute& rCandidate) const + { + if(rCandidate.mpSdrTextAttribute == mpSdrTextAttribute) + { + return true; + } + + if(rCandidate.isDefault() != isDefault()) + { + return false; + } + + return (*rCandidate.mpSdrTextAttribute == *mpSdrTextAttribute); + } + + const SdrText& SdrTextAttribute::getSdrText() const + { + return mpSdrTextAttribute->getSdrText(); + } + + const OutlinerParaObject& SdrTextAttribute::getOutlinerParaObject() const + { + return mpSdrTextAttribute->getOutlinerParaObject(); + } + + bool SdrTextAttribute::isContour() const + { + return mpSdrTextAttribute->isContour(); + } + + bool SdrTextAttribute::isFitToSize() const + { + return mpSdrTextAttribute->isFitToSize(); + } + + bool SdrTextAttribute::isHideContour() const + { + return mpSdrTextAttribute->isHideContour(); + } + + bool SdrTextAttribute::isBlink() const + { + return mpSdrTextAttribute->isBlink(); + } + + bool SdrTextAttribute::isScroll() const + { + return mpSdrTextAttribute->isScroll(); + } + + bool SdrTextAttribute::isInEditMode() const + { + return mpSdrTextAttribute->isInEditMode(); + } + + bool SdrTextAttribute::isFixedCellHeight() const + { + return mpSdrTextAttribute->isFixedCellHeight(); + } + + bool SdrTextAttribute::isWrongSpell() const + { + return mpSdrTextAttribute->isWrongSpell(); + } + + const SdrFormTextAttribute& SdrTextAttribute::getSdrFormTextAttribute() const + { + return mpSdrTextAttribute->getSdrFormTextAttribute(); + } + + sal_Int32 SdrTextAttribute::getTextLeftDistance() const + { + return mpSdrTextAttribute->getTextLeftDistance(); + } + + sal_Int32 SdrTextAttribute::getTextUpperDistance() const + { + return mpSdrTextAttribute->getTextUpperDistance(); + } + + sal_Int32 SdrTextAttribute::getTextRightDistance() const + { + return mpSdrTextAttribute->getTextRightDistance(); + } + + sal_Int32 SdrTextAttribute::getTextLowerDistance() const + { + return mpSdrTextAttribute->getTextLowerDistance(); + } + + sal_uInt32 SdrTextAttribute::getPropertiesVersion() const + { + return mpSdrTextAttribute->getPropertiesVersion(); + } + + SdrTextHorzAdjust SdrTextAttribute::getSdrTextHorzAdjust() const + { + return mpSdrTextAttribute->getSdrTextHorzAdjust(); + } + + SdrTextVertAdjust SdrTextAttribute::getSdrTextVertAdjust() const + { + return mpSdrTextAttribute->getSdrTextVertAdjust(); + } + + void SdrTextAttribute::getBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const + { + if(isBlink()) + { + getSdrText().GetObject().impGetBlinkTextTiming(rAnimList); + } + } + + void SdrTextAttribute::getScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const + { + if(isScroll()) + { + getSdrText().GetObject().impGetScrollTextTiming(rAnimList, fFrameLength, fTextLength); + } + } + } // end of namespace attribute +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/displayinfo.cxx b/svx/source/sdr/contact/displayinfo.cxx new file mode 100644 index 000000000000..d964611c59a0 --- /dev/null +++ b/svx/source/sdr/contact/displayinfo.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 <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <vcl/svapp.hxx> +#include <svx/svdobj.hxx> +#include <vcl/gdimtf.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> + +#define ALL_GHOSTED_DRAWMODES (DRAWMODE_GHOSTEDLINE|DRAWMODE_GHOSTEDFILL|DRAWMODE_GHOSTEDTEXT|DRAWMODE_GHOSTEDBITMAP|DRAWMODE_GHOSTEDGRADIENT) + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + DisplayInfo::DisplayInfo() + : maProcessLayers(true), // init layer info with all bits set to draw everything on default + maRedrawArea(), + mbControlLayerProcessingActive(false), + mbPageProcessingActive(true), + mbGhostedDrawModeActive(false), + mbSubContentActive(false) + { + } + + DisplayInfo::~DisplayInfo() + { + } + + // Access to LayerInfos (which layers to proccess) + void DisplayInfo::SetProcessLayers(const SetOfByte& rSet) + { + maProcessLayers = rSet; + } + + // access to RedrawArea + void DisplayInfo::SetRedrawArea(const Region& rRegion) + { + maRedrawArea = rRegion; + } + + void DisplayInfo::SetControlLayerProcessingActive(bool bDoProcess) + { + if((bool)mbControlLayerProcessingActive != bDoProcess) + { + mbControlLayerProcessingActive = bDoProcess; + } + } + + void DisplayInfo::SetPageProcessingActive(bool bDoProcess) + { + if((bool)mbPageProcessingActive != bDoProcess) + { + mbPageProcessingActive = bDoProcess; + } + } + + void DisplayInfo::ClearGhostedDrawMode() + { + mbGhostedDrawModeActive = false; + } + + void DisplayInfo::SetGhostedDrawMode() + { + mbGhostedDrawModeActive = true; + } + + void DisplayInfo::SetSubContentActive(bool bNew) + { + if((bool)mbSubContentActive != bNew) + { + mbSubContentActive = bNew; + } + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/makefile.mk b/svx/source/sdr/contact/makefile.mk new file mode 100644 index 000000000000..9e4356c4aa52 --- /dev/null +++ b/svx/source/sdr/contact/makefile.mk @@ -0,0 +1,92 @@ +#************************************************************************* +# +# 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=..$/..$/.. +PRJINC=$(PRJ)$/source + +PRJNAME=svx +TARGET=contact +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/viewobjectcontactofunocontrol.obj + +SLOFILES=\ + $(EXCEPTIONSFILES) \ + $(SLO)$/displayinfo.obj \ + $(SLO)$/viewcontact.obj \ + $(SLO)$/viewcontactofe3d.obj \ + $(SLO)$/viewcontactofsdrobj.obj \ + $(SLO)$/viewcontactofvirtobj.obj \ + $(SLO)$/viewcontactoftextobj.obj \ + $(SLO)$/viewcontactofsdrrectobj.obj \ + $(SLO)$/viewcontactofsdrpathobj.obj \ + $(SLO)$/viewcontactofsdrole2obj.obj \ + $(SLO)$/viewcontactofsdrcircobj.obj \ + $(SLO)$/viewcontactofsdrcaptionobj.obj \ + $(SLO)$/viewcontactofsdrmeasureobj.obj \ + $(SLO)$/viewcontactofsdredgeobj.obj \ + $(SLO)$/viewcontactofsdrpage.obj \ + $(SLO)$/viewcontactofmasterpagedescriptor.obj \ + $(SLO)$/viewcontactofgroup.obj \ + $(SLO)$/viewcontactofe3dscene.obj \ + $(SLO)$/viewcontactofe3dcube.obj \ + $(SLO)$/viewcontactofe3dextrude.obj \ + $(SLO)$/viewcontactofe3dlathe.obj \ + $(SLO)$/viewcontactofe3dsphere.obj \ + $(SLO)$/viewcontactofe3dpolygon.obj \ + $(SLO)$/viewcontactofpageobj.obj \ + $(SLO)$/viewcontactofgraphic.obj \ + $(SLO)$/viewcontactofsdrobjcustomshape.obj \ + $(SLO)$/viewcontactofsdrmediaobj.obj \ + $(SLO)$/viewcontactofunocontrol.obj \ + $(SLO)$/objectcontact.obj \ + $(SLO)$/objectcontacttools.obj \ + $(SLO)$/objectcontactofobjlistpainter.obj \ + $(SLO)$/objectcontactofpageview.obj \ + $(SLO)$/viewobjectcontact.obj \ + $(SLO)$/viewobjectcontactofe3d.obj \ + $(SLO)$/viewobjectcontactredirector.obj \ + $(SLO)$/viewobjectcontactofsdrmediaobj.obj \ + $(SLO)$/viewobjectcontactofgroup.obj \ + $(SLO)$/viewobjectcontactofe3dscene.obj \ + $(SLO)$/viewobjectcontactofsdrpage.obj \ + $(SLO)$/viewobjectcontactofsdrobj.obj \ + $(SLO)$/viewobjectcontactofpageobj.obj \ + $(SLO)$/viewobjectcontactofsdrole2obj.obj \ + $(SLO)$/viewobjectcontactofgraphic.obj \ + $(SLO)$/viewobjectcontactofmasterpagedescriptor.obj \ + $(SLO)$/sdrmediawindow.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/contact/objectcontact.cxx b/svx/source/sdr/contact/objectcontact.cxx new file mode 100644 index 000000000000..bda2e1529988 --- /dev/null +++ b/svx/source/sdr/contact/objectcontact.cxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * 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/objectcontact.hxx> +#include <tools/debug.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/event/eventhandler.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ObjectContact::ObjectContact() + : maViewObjectContactVector(), + maPrimitiveAnimator(), + mpEventHandler(0), + mpViewObjectContactRedirector(0), + maViewInformation2D(uno::Sequence< beans::PropertyValue >()), + mbIsPreviewRenderer(false) + { + } + + ObjectContact::~ObjectContact() + { + // get rid of all registered contacts + // #i84257# To avoid that each 'delete pCandidate' again uses + // the local RemoveViewObjectContact with a search and removal in the + // vector, simply copy and clear local vector. + std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector); + maViewObjectContactVector.clear(); + + while(aLocalVOCList.size()) + { + ViewObjectContact* pCandidate = aLocalVOCList.back(); + aLocalVOCList.pop_back(); + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)"); + + // ViewObjectContacts only make sense with View and Object contacts. + // When the contact to the SdrObject is deleted like in this case, + // all ViewObjectContacts can be deleted, too. + delete pCandidate; + } + + // assert when there were new entries added during deletion + DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList (!)"); + + // delete the EventHandler. This will destroy all still contained events. + DeleteEventHandler(); + } + + // LazyInvalidate request. Default implementation directly handles + // this by calling back triggerLazyInvalidate() at the VOC + void ObjectContact::setLazyInvalidate(ViewObjectContact& rVOC) + { + rVOC.triggerLazyInvalidate(); + } + + // call this to support evtl. preparations for repaint. Default does nothing + void ObjectContact::PrepareProcessDisplay() + { + } + + // A new ViewObjectContact was created and shall be remembered. + void ObjectContact::AddViewObjectContact(ViewObjectContact& rVOContact) + { + maViewObjectContactVector.push_back(&rVOContact); + } + + // A ViewObjectContact was deleted and shall be forgotten. + void ObjectContact::RemoveViewObjectContact(ViewObjectContact& rVOContact) + { + std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact); + + if(aFindResult != maViewObjectContactVector.end()) + { + maViewObjectContactVector.erase(aFindResult); + } + } + + // Process the whole displaying + void ObjectContact::ProcessDisplay(DisplayInfo& /*rDisplayInfo*/) + { + // default does nothing + } + + // test if visualizing of entered groups is switched on at all + bool ObjectContact::DoVisualizeEnteredGroup() const + { + // Don not do that as default + return false; + } + + // get active group's (the entered group) ViewContact + const ViewContact* ObjectContact::getActiveViewContact() const + { + // default has no active VC + return 0; + } + + // Invalidate given rectangle at the window/output which is represented by + // this ObjectContact. + void ObjectContact::InvalidatePartOfView(const basegfx::B2DRange& /*rRange*/) const + { + // nothing to do here in the default version + } + + // Get info if given Rectangle is visible in this view + bool ObjectContact::IsAreaVisible(const basegfx::B2DRange& /*rRange*/) const + { + // always visible in default version + return true; + } + + // Get info about the need to visualize GluePoints + bool ObjectContact::AreGluePointsVisible() const + { + return false; + } + + // method to create a EventHandler. Needs to give a result. + sdr::event::TimerEventHandler* ObjectContact::CreateEventHandler() + { + // Create and return a new EventHandler + return new sdr::event::TimerEventHandler(); + } + + // method to get the primitiveAnimator + sdr::animation::primitiveAnimator& ObjectContact::getPrimitiveAnimator() + { + return maPrimitiveAnimator; + } + + // method to get the EventHandler. It will + // return a existing one or create a new one using CreateEventHandler(). + sdr::event::TimerEventHandler& ObjectContact::GetEventHandler() const + { + if(!HasEventHandler()) + { + const_cast< ObjectContact* >(this)->mpEventHandler = const_cast< ObjectContact* >(this)->CreateEventHandler(); + DBG_ASSERT(mpEventHandler, "ObjectContact::GetEventHandler(): Got no EventHandler (!)"); + } + + return *mpEventHandler; + } + + // delete the EventHandler + void ObjectContact::DeleteEventHandler() + { + if(mpEventHandler) + { + // If there are still Events registered, something has went wrong + delete mpEventHandler; + mpEventHandler = 0L; + } + } + + // test if there is an EventHandler without creating one on demand + bool ObjectContact::HasEventHandler() const + { + return (0L != mpEventHandler); + } + + // check if text animation is allowed. Default is sal_true. + bool ObjectContact::IsTextAnimationAllowed() const + { + return true; + } + + // check if graphic animation is allowed. Default is sal_true. + bool ObjectContact::IsGraphicAnimationAllowed() const + { + return true; + } + + // check if asynchronious graphis loading is allowed. Default is false. + bool ObjectContact::IsAsynchronGraphicsLoadingAllowed() const + { + return false; + } + + // access to ViewObjectContactRedirector + ViewObjectContactRedirector* ObjectContact::GetViewObjectContactRedirector() const + { + return mpViewObjectContactRedirector; + } + + void ObjectContact::SetViewObjectContactRedirector(ViewObjectContactRedirector* pNew) + { + if(mpViewObjectContactRedirector != pNew) + { + mpViewObjectContactRedirector = pNew; + } + } + + // check if buffering of MasterPages is allowed. Default is false. + bool ObjectContact::IsMasterPageBufferingAllowed() const + { + return false; + } + + // print? Default is false + bool ObjectContact::isOutputToPrinter() const + { + return false; + } + + // window? Default is true + bool ObjectContact::isOutputToWindow() const + { + return true; + } + + // VirtualDevice? Default is false + bool ObjectContact::isOutputToVirtualDevice() const + { + return false; + } + + // recording MetaFile? Default is false + bool ObjectContact::isOutputToRecordingMetaFile() const + { + return false; + } + + // pdf export? Default is false + bool ObjectContact::isOutputToPDFFile() const + { + return false; + } + + // gray display mode + bool ObjectContact::isDrawModeGray() const + { + return false; + } + + // gray display mode + bool ObjectContact::isDrawModeBlackWhite() const + { + return false; + } + + // high contrast display mode + bool ObjectContact::isDrawModeHighContrast() const + { + return false; + } + + // access to SdrPageView. Default implementation returns NULL + SdrPageView* ObjectContact::TryToGetSdrPageView() const + { + return 0; + } + + // access to OutputDevice. Default implementation returns NULL + OutputDevice* ObjectContact::TryToGetOutputDevice() const + { + return 0; + } + + void ObjectContact::resetViewPort() + { + const drawinglayer::geometry::ViewInformation2D& rCurrentVI2D = getViewInformation2D(); + + if(!rCurrentVI2D.getViewport().isEmpty()) + { + const basegfx::B2DRange aEmptyRange; + + drawinglayer::geometry::ViewInformation2D aNewVI2D( + rCurrentVI2D.getObjectTransformation(), + rCurrentVI2D.getViewTransformation(), + aEmptyRange, + rCurrentVI2D.getVisualizedPage(), + rCurrentVI2D.getViewTime(), + rCurrentVI2D.getExtendedInformationSequence()); + + updateViewInformation2D(aNewVI2D); + } + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx b/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx new file mode 100644 index 000000000000..da8518d7f1a1 --- /dev/null +++ b/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx @@ -0,0 +1,207 @@ +/************************************************************************* + * + * 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/objectcontactofobjlistpainter.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/svdmodel.hxx> +#include <drawinglayer/processor2d/vclprocessor2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <unoapi.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ObjectContactPainter::ObjectContactPainter() + { + } + + // The destructor. + ObjectContactPainter::~ObjectContactPainter() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + sal_uInt32 ObjectContactOfObjListPainter::GetPaintObjectCount() const + { + return maStartObjects.size(); + } + + ViewContact& ObjectContactOfObjListPainter::GetPaintObjectViewContact(sal_uInt32 nIndex) const + { + const SdrObject* pObj = maStartObjects[nIndex]; + DBG_ASSERT(pObj, "ObjectContactOfObjListPainter: Corrupt SdrObjectVector (!)"); + return pObj->GetViewContact(); + } + + ObjectContactOfObjListPainter::ObjectContactOfObjListPainter( + OutputDevice& rTargetDevice, + const SdrObjectVector& rObjects, + const SdrPage* pProcessedPage) + : ObjectContactPainter(), + mrTargetOutputDevice(rTargetDevice), + maStartObjects(rObjects), + mpProcessedPage(pProcessedPage) + { + } + + ObjectContactOfObjListPainter::~ObjectContactOfObjListPainter() + { + } + + // Process the whole displaying + void ObjectContactOfObjListPainter::ProcessDisplay(DisplayInfo& rDisplayInfo) + { + const sal_uInt32 nCount(GetPaintObjectCount()); + + if(nCount) + { + OutputDevice* pTargetDevice = TryToGetOutputDevice(); + + if(pTargetDevice) + { + // update current ViewInformation2D at the ObjectContact + const GDIMetaFile* pMetaFile = pTargetDevice->GetConnectMetaFile(); + const bool bOutputToRecordingMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + basegfx::B2DRange aViewRange; + + // create ViewRange + if(!bOutputToRecordingMetaFile) + { + // use visible pixels, but transform to world coordinates + const Size aOutputSizePixel(pTargetDevice->GetOutputSizePixel()); + aViewRange = ::basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + aViewRange.transform(pTargetDevice->GetInverseViewTransformation()); + } + + // upate local ViewInformation2D + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + basegfx::B2DHomMatrix(), + pTargetDevice->GetViewTransformation(), + aViewRange, + GetXDrawPageForSdrPage(const_cast< SdrPage* >(mpProcessedPage)), + 0.0, + 0); + updateViewInformation2D(aNewViewInformation2D); + + // collect primitive data in a sequence; this will already use the updated ViewInformation2D + drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence; + + for(sal_uInt32 a(0L); a < nCount; a++) + { + const ViewObjectContact& rViewObjectContact = GetPaintObjectViewContact(a).GetViewObjectContact(*this); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xPrimitiveSequence, + rViewObjectContact.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + } + + // if there is something to show, use a vclProcessor to render it + if(xPrimitiveSequence.hasElements()) + { + drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = createBaseProcessor2DFromOutputDevice( + *pTargetDevice, getViewInformation2D()); + + if(pProcessor2D) + { + pProcessor2D->process(xPrimitiveSequence); + delete pProcessor2D; + } + } + } + } + } + + OutputDevice* ObjectContactOfObjListPainter::TryToGetOutputDevice() const + { + return &mrTargetOutputDevice; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + sal_uInt32 ObjectContactOfPagePainter::GetPaintObjectCount() const + { + return (GetStartPage() ? 1L : 0L); + } + + ViewContact& ObjectContactOfPagePainter::GetPaintObjectViewContact(sal_uInt32 /*nIndex*/) const + { + DBG_ASSERT(GetStartPage(), "ObjectContactOfPagePainter::GetPaintObjectViewContact: no StartPage set (!)"); + return GetStartPage()->GetViewContact(); + } + + ObjectContactOfPagePainter::ObjectContactOfPagePainter( + const SdrPage* pPage, + ObjectContact& rOriginalObjectContact) + : ObjectContactPainter(), + mrOriginalObjectContact(rOriginalObjectContact), + mxStartPage(const_cast< SdrPage* >(pPage)) // no SdrPageWeakRef available to hold a const SdrPage* + { + } + + ObjectContactOfPagePainter::~ObjectContactOfPagePainter() + { + } + + void ObjectContactOfPagePainter::SetStartPage(const SdrPage* pPage) + { + if(pPage != GetStartPage()) + { + mxStartPage.reset(const_cast< SdrPage* >(pPage)); // no SdrPageWeakRef available to hold a const SdrPage* + } + } + + OutputDevice* ObjectContactOfPagePainter::TryToGetOutputDevice() const + { + return mrOriginalObjectContact.TryToGetOutputDevice(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx new file mode 100644 index 000000000000..1652855d84a8 --- /dev/null +++ b/svx/source/sdr/contact/objectcontactofpageview.cxx @@ -0,0 +1,485 @@ +/************************************************************************* + * + * 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/objectcontactofpageview.hxx> +#include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdview.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> +#include <drawinglayer/processor2d/vclprocessor2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <com/sun/star/rendering/XSpriteCanvas.hpp> +#include <unoapi.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // internal access to SdrPage of SdrPageView + SdrPage* ObjectContactOfPageView::GetSdrPage() const + { + return GetPageWindow().GetPageView().GetPage(); + } + + ObjectContactOfPageView::ObjectContactOfPageView(SdrPageWindow& rPageWindow) + : ObjectContact(), + mrPageWindow(rPageWindow) + { + // init PreviewRenderer flag + setPreviewRenderer(((SdrPaintView&)rPageWindow.GetPageView().GetView()).IsPreviewRenderer()); + + // init timer + SetTimeout(1); + Stop(); + } + + ObjectContactOfPageView::~ObjectContactOfPageView() + { + // execute missing LazyInvalidates and stop timer + Timeout(); + } + + // LazyInvalidate request. Take action. + void ObjectContactOfPageView::setLazyInvalidate(ViewObjectContact& /*rVOC*/) + { + // do NOT call parent, but remember that something is to do by + // starting the LazyInvalidateTimer + Start(); + } + + // call this to support evtl. preparations for repaint + void ObjectContactOfPageView::PrepareProcessDisplay() + { + if(IsActive()) + { + static bool bInvalidateDuringPaint(true); + + if(bInvalidateDuringPaint) + { + // there are still non-triggered LazyInvalidate events, trigger these + Timeout(); + } + } + } + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + void ObjectContactOfPageView::Timeout() + { + // stop the timer + Stop(); + + // invalidate all LazyInvalidate VOCs new situations + const sal_uInt32 nVOCCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nVOCCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + pCandidate->triggerLazyInvalidate(); + } + } + + // Process the whole displaying + void ObjectContactOfPageView::ProcessDisplay(DisplayInfo& rDisplayInfo) + { + const SdrPage* pStartPage = GetSdrPage(); + + if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty()) + { + const ViewContact& rDrawPageVC = pStartPage->GetViewContact(); + + if(rDrawPageVC.GetObjectCount()) + { + DoProcessDisplay(rDisplayInfo); + } + } + + // after paint take care of the evtl. scheduled asynchronious commands. + // Do this by resetting the timer contained there. Thus, after the paint + // that timer will be triggered and the events will be executed. + if(HasEventHandler()) + { + sdr::event::TimerEventHandler& rEventHandler = GetEventHandler(); + + if(!rEventHandler.IsEmpty()) + { + rEventHandler.Restart(); + } + } + } + + // Process the whole displaying. Only use given DsiplayInfo, do not access other + // OutputDevices then the given ones. + void ObjectContactOfPageView::DoProcessDisplay(DisplayInfo& rDisplayInfo) + { + // visualize entered group when that feature is switched on and it's not + // a print output. #i29129# No ghosted display for printing. + sal_Bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter()); + + // Visualize entered groups: Set to ghosted as default + // start. Do this only for the DrawPage, not for MasterPages + if(bVisualizeEnteredGroup) + { + rDisplayInfo.SetGhostedDrawMode(); + } + + // #114359# save old and set clip region + OutputDevice* pOutDev = TryToGetOutputDevice(); + OSL_ENSURE(0 != pOutDev, "ObjectContactOfPageView without OutDev, someone has overloaded TryToGetOutputDevice wrong (!)"); + sal_Bool bClipRegionPushed(sal_False); + const Region& rRedrawArea(rDisplayInfo.GetRedrawArea()); + + if(!rRedrawArea.IsEmpty()) + { + bClipRegionPushed = sal_True; + pOutDev->Push(PUSH_CLIPREGION); + pOutDev->IntersectClipRegion(rRedrawArea); + } + + // Get start node and process DrawPage contents + const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this); + + // update current ViewInformation2D at the ObjectContact + const double fCurrentTime(getPrimitiveAnimator().GetTime()); + OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); + basegfx::B2DRange aViewRange; + + // create ViewRange + if(isOutputToRecordingMetaFile()) + { + if(isOutputToPDFFile() || isOutputToPrinter()) + { + // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is + // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this, + // all existing objects will be collected as primitives and processed. + // OD 2009-03-05 #i99876# perform the same also for SW on printing. + const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); + + aViewRange = basegfx::B2DRange( + aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), + aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); + } + } + else + { + // use visible pixels, but transform to world coordinates + const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); + aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + + // if a clip region is set, use it + if(!rDisplayInfo.GetRedrawArea().IsEmpty()) + { + // get logic clip range and create discrete one + const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); + basegfx::B2DRange aLogicClipRange( + aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), + aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); + basegfx::B2DRange aDiscreteClipRange(aLogicClipRange); + aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation()); + + // align the discrete one to discrete boundaries (pixel bounds). Also + // expand X and Y max by one due to Rectangle definition source + aDiscreteClipRange.expand(basegfx::B2DTuple( + floor(aDiscreteClipRange.getMinX()), + floor(aDiscreteClipRange.getMinY()))); + aDiscreteClipRange.expand(basegfx::B2DTuple( + 1.0 + ceil(aDiscreteClipRange.getMaxX()), + 1.0 + ceil(aDiscreteClipRange.getMaxY()))); + + // intersect current ViewRange with ClipRange + aViewRange.intersect(aDiscreteClipRange); + } + + // transform to world coordinates + aViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); + } + + // update local ViewInformation2D + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + basegfx::B2DHomMatrix(), + rTargetOutDev.GetViewTransformation(), + aViewRange, + GetXDrawPageForSdrPage(GetSdrPage()), + fCurrentTime, + 0); + updateViewInformation2D(aNewViewInformation2D); + + // get whole Primitive2DSequence; this will already make use of updated ViewInformation2D + // and may use the MapMode from the Target OutDev in the DisplayInfo + drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence(rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + + // if there is something to show, use a primitive processor to render it. There + // is a choice between VCL and Canvas processors currently. The decision is made in + // createBaseProcessor2DFromOutputDevice and takes into accout things like the + // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered + // currently using the shown boolean. Canvas is not yet the default. + if(xPrimitiveSequence.hasElements()) + { + // prepare OutputDevice (historical stuff, maybe soon removed) + rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing + pOutDev->SetLayoutMode(0); // reset, default is no BiDi/RTL + + // create renderer + drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = createBaseProcessor2DFromOutputDevice( + rTargetOutDev, getViewInformation2D()); + + if(pProcessor2D) + { + pProcessor2D->process(xPrimitiveSequence); + delete pProcessor2D; + } + } + + // #114359# restore old ClipReghion + if(bClipRegionPushed) + { + pOutDev->Pop(); + } + + // Visualize entered groups: Reset to original DrawMode + if(bVisualizeEnteredGroup) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + } + + // test if visualizing of entered groups is switched on at all + bool ObjectContactOfPageView::DoVisualizeEnteredGroup() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.DoVisualizeEnteredGroup(); + } + + // get active group's (the entered group) ViewContact + const ViewContact* ObjectContactOfPageView::getActiveViewContact() const + { + SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList(); + + if(pActiveGroupList) + { + if(pActiveGroupList->ISA(SdrPage)) + { + // It's a Page itself + return &(((SdrPage*)pActiveGroupList)->GetViewContact()); + } + else if(pActiveGroupList->GetOwnerObj()) + { + // Group object + return &(pActiveGroupList->GetOwnerObj()->GetViewContact()); + } + } + else if(GetSdrPage()) + { + // use page of associated SdrPageView + return &(GetSdrPage()->GetViewContact()); + } + + return 0; + } + + // Invalidate given rectangle at the window/output which is represented by + // this ObjectContact. + void ObjectContactOfPageView::InvalidatePartOfView(const basegfx::B2DRange& rRange) const + { + // invalidate at associated PageWindow + GetPageWindow().InvalidatePageWindow(rRange); + } + + // Get info if given Rectangle is visible in this view + bool ObjectContactOfPageView::IsAreaVisible(const basegfx::B2DRange& rRange) const + { + // compare with the visible rectangle + if(rRange.isEmpty()) + { + // no range -> not visible + return false; + } + else + { + const OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); + const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); + basegfx::B2DRange aLogicViewRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + + aLogicViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); + + if(!aLogicViewRange.isEmpty() && !aLogicViewRange.overlaps(rRange)) + { + return false; + } + } + + // call parent + return ObjectContact::IsAreaVisible(rRange); + } + + // Get info about the need to visualize GluePoints + bool ObjectContactOfPageView::AreGluePointsVisible() const + { + return GetPageWindow().GetPageView().GetView().ImpIsGlueVisible(); + } + + // check if text animation is allowed. + bool ObjectContactOfPageView::IsTextAnimationAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); + return rOpt.GetIsAllowAnimatedText(); + } + + // check if graphic animation is allowed. + bool ObjectContactOfPageView::IsGraphicAnimationAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); + return rOpt.GetIsAllowAnimatedGraphics(); + } + + // check if asynchronious graphis loading is allowed. Default is sal_False. + bool ObjectContactOfPageView::IsAsynchronGraphicsLoadingAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.IsSwapAsynchron(); + } + + // check if buffering of MasterPages is allowed. Default is sal_False. + bool ObjectContactOfPageView::IsMasterPageBufferingAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.IsMasterPagePaintCaching(); + } + + // print? + bool ObjectContactOfPageView::isOutputToPrinter() const + { + return (OUTDEV_PRINTER == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // window? + bool ObjectContactOfPageView::isOutputToWindow() const + { + return (OUTDEV_WINDOW == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // VirtualDevice? + bool ObjectContactOfPageView::isOutputToVirtualDevice() const + { + return (OUTDEV_VIRDEV == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // recording MetaFile? + bool ObjectContactOfPageView::isOutputToRecordingMetaFile() const + { + GDIMetaFile* pMetaFile = mrPageWindow.GetPaintWindow().GetOutputDevice().GetConnectMetaFile(); + return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + } + + // pdf export? + bool ObjectContactOfPageView::isOutputToPDFFile() const + { + return (0 != mrPageWindow.GetPaintWindow().GetOutputDevice().GetPDFWriter()); + } + + // gray display mode + bool ObjectContactOfPageView::isDrawModeGray() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_GRAYLINE|DRAWMODE_GRAYFILL|DRAWMODE_BLACKTEXT|DRAWMODE_GRAYBITMAP|DRAWMODE_GRAYGRADIENT)); + } + + // gray display mode + bool ObjectContactOfPageView::isDrawModeBlackWhite() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_BLACKLINE|DRAWMODE_BLACKTEXT|DRAWMODE_WHITEFILL|DRAWMODE_GRAYBITMAP|DRAWMODE_WHITEGRADIENT)); + } + + // high contrast display mode + bool ObjectContactOfPageView::isDrawModeHighContrast() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_SETTINGSLINE|DRAWMODE_SETTINGSFILL|DRAWMODE_SETTINGSTEXT|DRAWMODE_SETTINGSGRADIENT)); + } + + // access to SdrPageView + SdrPageView* ObjectContactOfPageView::TryToGetSdrPageView() const + { + return &(mrPageWindow.GetPageView()); + } + + + // access to OutputDevice + OutputDevice* ObjectContactOfPageView::TryToGetOutputDevice() const + { + SdrPreRenderDevice* pPreRenderDevice = mrPageWindow.GetPaintWindow().GetPreRenderDevice(); + + if(pPreRenderDevice) + { + return &(pPreRenderDevice->GetPreRenderDevice()); + } + else + { + return &(mrPageWindow.GetPaintWindow().GetOutputDevice()); + } + } + + // set all UNO controls displayed in the view to design/alive mode + void ObjectContactOfPageView::SetUNOControlsDesignMode( bool _bDesignMode ) const + { + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const ViewObjectContact* pVOC = getViewObjectContact(a); + const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC); + + if(pUnoObjectVOC) + { + pUnoObjectVOC->setControlDesignMode(_bDesignMode); + } + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontacttools.cxx b/svx/source/sdr/contact/objectcontacttools.cxx new file mode 100644 index 000000000000..5776bd8847ce --- /dev/null +++ b/svx/source/sdr/contact/objectcontacttools.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * 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/objectcontacttools.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/range/b2drange.hxx> +#include <vcl/gdimtf.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/processor2d/vclmetafileprocessor2d.hxx> +#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> +#include <drawinglayer/processor2d/canvasprocessor.hxx> +#include <vcl/window.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::processor2d::BaseProcessor2D* createBaseProcessor2DFromOutputDevice( + OutputDevice& rTargetOutDev, + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D) + { + const GDIMetaFile* pMetaFile = rTargetOutDev.GetConnectMetaFile(); + const bool bOutputToRecordingMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + + if(bOutputToRecordingMetaFile) + { + // create MetaFile Vcl-Processor and process + return new drawinglayer::processor2d::VclMetafileProcessor2D(rViewInformation2D, rTargetOutDev); + } + else + { +#ifdef WIN32 + // for a first AA incarnation VCL-PixelRenderer will be okay since + // simple (and fast) GDIPlus support over VCL will be used. + // Leaving the code below as a hint for what to do when we will + // use canvas renderers in the future + + //static SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + + //if(false && aSvtOptionsDrawinglayer.IsAntiAliasing()) + //{ + // // for WIN32 AA, create cairo canvas processor + // return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); + //} + //else + //{ + // create Pixel Vcl-Processor + return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); + //} +#else + static bool bTryTestCanvas(false); + + if(bTryTestCanvas) + { + // create test-cancas-Processor + return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); + } + else + { + // create Pixel Vcl-Processor + return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); + } +#endif + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/sdrmediawindow.cxx b/svx/source/sdr/contact/sdrmediawindow.cxx new file mode 100644 index 000000000000..f380a4b8a022 --- /dev/null +++ b/svx/source/sdr/contact/sdrmediawindow.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * 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 "sdrmediawindow.hxx" +#include <svtools/transfer.hxx> + +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <vcl/window.hxx> + +namespace sdr { namespace contact { + +// ------------------ +// - SdrMediaWindow - +// ------------------ + +SdrMediaWindow::SdrMediaWindow( Window* pParent, ViewObjectContactOfSdrMediaObj& rViewObjContact ) : + ::avmedia::MediaWindow( pParent, false ), + mrViewObjectContactOfSdrMediaObj( rViewObjContact ) +{ +} + +// ------------------------------------------------------------------------------ + +SdrMediaWindow::~SdrMediaWindow() +{ +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseMove( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseMove( aTransformedEvent ); + setPointer( pWindow->GetPointer() ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseButtonDown( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseButtonDown( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseButtonUp( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseButtonUp( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::KeyInput( const KeyEvent& rKEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + pWindow->KeyInput( rKEvt ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::KeyUp( const KeyEvent& rKEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + pWindow->KeyUp( rKEvt ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::Command( const CommandEvent& rCEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const CommandEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ), + rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() ); + + pWindow->Command( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +sal_Int8 SdrMediaWindow::AcceptDrop( const AcceptDropEvent& rEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + sal_Int8 nRet = DND_ACTION_NONE; + + if( pWindow ) + { + DropTargetHelper* pDropTargetHelper = dynamic_cast< DropTargetHelper* >( pWindow ); + + if( pDropTargetHelper ) + { + nRet = pDropTargetHelper->AcceptDrop( rEvt ); + } + } + + return( nRet ); +} + +// ------------------------------------------------------------------------------ + +sal_Int8 SdrMediaWindow::ExecuteDrop( const ExecuteDropEvent& rEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + sal_Int8 nRet = DND_ACTION_NONE; + + if( pWindow ) + { + DropTargetHelper* pDropTargetHelper = dynamic_cast< DropTargetHelper* >( pWindow ); + + if( pDropTargetHelper ) + { + nRet = pDropTargetHelper->ExecuteDrop( rEvt ); + } + } + + return( nRet ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::StartDrag( sal_Int8 nAction, const Point& rPosPixel ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + { + DragSourceHelper* pDragSourceHelper = dynamic_cast< DragSourceHelper* >( pWindow ); + + if( pDragSourceHelper ) + { + pDragSourceHelper->StartDrag( nAction, rPosPixel ); + } + } +} + +} } diff --git a/svx/source/sdr/contact/sdrmediawindow.hxx b/svx/source/sdr/contact/sdrmediawindow.hxx new file mode 100644 index 000000000000..0b9c42cdb615 --- /dev/null +++ b/svx/source/sdr/contact/sdrmediawindow.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * 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 _SDR_CONTACT_SDRMEDIAWIMNDOW_HXX + +#include <avmedia/mediawindow.hxx> + +namespace sdr { namespace contact { + +// ------------------ +// - SdrMediaWindow - +// ------------------ + +class ViewObjectContactOfSdrMediaObj; + +class SdrMediaWindow : public ::avmedia::MediaWindow +{ +public: + + SdrMediaWindow( Window* pParent, ViewObjectContactOfSdrMediaObj& rViewObjContact ); + ~SdrMediaWindow(); + + virtual void MouseMove( const MouseEvent& rMEvt ); + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + virtual void MouseButtonUp( const MouseEvent& rMEvt ); + + virtual void KeyInput( const KeyEvent& rKEvt ); + virtual void KeyUp( const KeyEvent& rKEvt ); + + virtual void Command( const CommandEvent& rCEvt ); + + virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ); + virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ); + + virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ); + +private: + + ViewObjectContactOfSdrMediaObj& mrViewObjectContactOfSdrMediaObj; +}; + +} } + +#endif + diff --git a/svx/source/sdr/contact/viewcontact.cxx b/svx/source/sdr/contact/viewcontact.cxx new file mode 100644 index 000000000000..3057acf55df1 --- /dev/null +++ b/svx/source/sdr/contact/viewcontact.cxx @@ -0,0 +1,329 @@ +/************************************************************************* + * + * 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/viewcontact.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. Default is to create + // a standard ViewObjectContact containing the given ObjectContact and *this + ViewObjectContact& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + return *(new ViewObjectContact(rObjectContact, *this)); + } + + ViewContact::ViewContact() + : maViewObjectContactVector(), + mxViewIndependentPrimitive2DSequence() + { + } + + // Methods to react on start getting viewed or stop getting + // viewed. This info is derived from the count of members of + // registered ViewObjectContacts. Default does nothing. + void ViewContact::StartGettingViewed() + { + } + + void ViewContact::StopGettingViewed() + { + } + + ViewContact::~ViewContact() + { + deleteAllVOCs(); + } + + void ViewContact::deleteAllVOCs() + { + // get rid of all VOCs + // #i84257# To avoid that each 'delete pCandidate' again uses + // the local RemoveViewObjectContact with a search and removal in the + // vector, simply copy and clear local vector. + std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector); + maViewObjectContactVector.clear(); + + while(aLocalVOCList.size()) + { + ViewObjectContact* pCandidate = aLocalVOCList.back(); + aLocalVOCList.pop_back(); + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList in VC (!)"); + + // ViewObjectContacts only make sense with View and Object contacts. + // When the contact to the SdrObject is deleted like in this case, + // all ViewObjectContacts can be deleted, too. + delete pCandidate; + } + + // assert when there were new entries added during deletion + DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)"); + } + + // get a Object-specific ViewObjectContact for a specific + // ObjectContact (->View). Always needs to return something. + ViewObjectContact& ViewContact::GetViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = 0L; + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + // first search if there exists a VOC for the given OC + for(sal_uInt32 a(0); !pRetval && a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)"); + + if(&(pCandidate->GetObjectContact()) == &rObjectContact) + { + pRetval = pCandidate; + } + } + + if(!pRetval) + { + // create a new one. It's inserted to the local list from the + // VieObjectContact constructor via AddViewObjectContact() + pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact); + } + + return *pRetval; + } + + // A new ViewObjectContact was created and shall be remembered. + void ViewContact::AddViewObjectContact(ViewObjectContact& rVOContact) + { + maViewObjectContactVector.push_back(&rVOContact); + + if(1L == maViewObjectContactVector.size()) + { + StartGettingViewed(); + } + } + + // A ViewObjectContact was deleted and shall be forgotten. + void ViewContact::RemoveViewObjectContact(ViewObjectContact& rVOContact) + { + std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact); + + if(aFindResult != maViewObjectContactVector.end()) + { + maViewObjectContactVector.erase(aFindResult); + + if(0 == maViewObjectContactVector.size()) + { + // This may need to get asynchron later since it eventually triggers + // deletes of OCs where the VOC is still added. + StopGettingViewed(); + } + } + } + + // Test if this ViewContact has ViewObjectContacts at all. This can + // be used to test if this ViewContact is visualized ATM or not + bool ViewContact::HasViewObjectContacts(bool bExcludePreviews) const + { + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + if(bExcludePreviews) + { + for(sal_uInt32 a(0); a < nCount; a++) + { + if(!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer()) + { + return true; + } + } + + return false; + } + else + { + return (0L != nCount); + } + } + + // Test if this ViewContact has ViewObjectContacts at all. This can + // be used to test if this ViewContact is visualized ATM or not + bool ViewContact::isAnimatedInAnyViewObjectContact() const + { + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + if(maViewObjectContactVector[a]->isAnimated()) + { + return true; + } + } + + return false; + } + + // Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L + // and GetViewContact default pops up an assert since it's an error if + // GetObjectCount has a result != 0 and it's not overloaded. + sal_uInt32 ViewContact::GetObjectCount() const + { + // no sub-objects + return 0; + } + + ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const + { + // This is the default implementation; call would be an error + DBG_ERROR("ViewContact::GetViewContact: This call needs to be overloaded when GetObjectCount() can return results != 0 (!)"); + return (ViewContact&)(*this); + } + + ViewContact* ViewContact::GetParentContact() const + { + // default has no parent + return 0; + } + + void ViewContact::ActionChildInserted(ViewContact& rChild) + { + // propagate change to all exsisting visualisations which + // will force a VOC for the new child and invalidate it's range + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)"); + + // take action at all VOCs. At the VOCs ObjectContact the initial + // rectangle will be invalidated at the associated OutputDevice. + pCandidate->ActionChildInserted(rChild); + } + } + + // React on changes of the object of this ViewContact + void ViewContact::ActionChanged() + { + // propagate change to all existing VOCs. This will invalidate + // all drawn visualisations in all known views + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)"); + + pCandidate->ActionChanged(); + } + } + + // access to SdrObject and/or SdrPage. May return 0L like the default + // implementations do. Needs to be overloaded as needed. + SdrObject* ViewContact::TryToGetSdrObject() const + { + return 0L; + } + + SdrPage* ViewContact::TryToGetSdrPage() const + { + return 0L; + } + + ////////////////////////////////////////////////////////////////////////////// + // primitive stuff + + drawinglayer::primitive2d::Primitive2DSequence ViewContact::createViewIndependentPrimitive2DSequence() const + { + // This is the default impelemtation and should never be called (see header). If this is called, + // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by + // providing a seqence of primitives -> which cannot be correct. + // Since we have no access to any known model data here, the default implementation creates a yellow placeholder + // hairline polygon with a default size of (1000, 1000, 5000, 3000) + DBG_ERROR("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)"); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0))); + const basegfx::BColor aYellow(1.0, 1.0, 0.0); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContact::getViewIndependentPrimitive2DSequence() const + { + // local up-to-date checks. Create new list and compare. + const drawinglayer::primitive2d::Primitive2DSequence xNew(createViewIndependentPrimitive2DSequence()); + + if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence, xNew)) + { + // has changed, copy content + const_cast< ViewContact* >(this)->mxViewIndependentPrimitive2DSequence = xNew; + } + + // return current Primitive2DSequence + return mxViewIndependentPrimitive2DSequence; + } + + // add Gluepoints (if available) + drawinglayer::primitive2d::Primitive2DSequence ViewContact::createGluePointPrimitive2DSequence() const + { + // default returns empty reference + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + void ViewContact::flushViewObjectContacts(bool bWithHierarchy) + { + if(bWithHierarchy) + { + // flush DrawingLayer hierarchy + const sal_uInt32 nCount(GetObjectCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewContact& rChild = GetViewContact(a); + rChild.flushViewObjectContacts(bWithHierarchy); + } + } + + // delete local VOCs + deleteAllVOCs(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3d.cxx b/svx/source/sdr/contact/viewcontactofe3d.cxx new file mode 100644 index 000000000000..9d6b253a676a --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3d.cxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * 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/viewcontactofe3d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3d.hxx> +#include <svx/obj3d.hxx> +#include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <svx/scene3d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <drawinglayer/attribute/sdrsceneattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightingattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightattribute3d.hxx> +#include <drawinglayer/attribute/sdrlineattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + const sdr::contact::ViewContactOfE3dScene* tryToFindVCOfE3DScene( + const sdr::contact::ViewContact& rCandidate, + basegfx::B3DHomMatrix& o_rInBetweenObjectTransform) + { + const sdr::contact::ViewContactOfE3dScene* pSceneParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(rCandidate.GetParentContact()); + + if(pSceneParent) + { + // each 3d object (including in-between scenes) should have a scene as parent + const sdr::contact::ViewContactOfE3dScene* pSceneParentParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(pSceneParent->GetParentContact()); + + if(pSceneParentParent) + { + // the parent scene of rCandidate is a in-between scene, call recursively and collect + // the in-between scene's object transformation part in o_rInBetweenObjectTransform + const basegfx::B3DHomMatrix& rSceneParentTransform = pSceneParent->GetE3dScene().GetTransform(); + o_rInBetweenObjectTransform = rSceneParentTransform * o_rInBetweenObjectTransform; + return tryToFindVCOfE3DScene(*pSceneParent, o_rInBetweenObjectTransform); + } + else + { + // the parent scene is the outmost scene + return pSceneParent; + } + } + + // object hierarchy structure is incorrect; no result + return 0; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::impCreateWithGivenPrimitive3DSequence( + const drawinglayer::primitive3d::Primitive3DSequence& rxContent3D) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(rxContent3D.hasElements()) + { + // try to get the outmost ViewObjectContactOfE3dScene for this single 3d object, + // the ones on the way there are grouping scenes. Collect the in-between scene's + // transformations to build a correct object transformation for the embedded + // object + basegfx::B3DHomMatrix aInBetweenObjectTransform; + const ViewContactOfE3dScene* pVCOfE3DScene = tryToFindVCOfE3DScene(*this, aInBetweenObjectTransform); + + if(pVCOfE3DScene) + { + basegfx::B3DVector aLightNormal; + const double fShadowSlant(pVCOfE3DScene->getSdrSceneAttribute().getShadowSlant()); + const basegfx::B3DRange& rAllContentRange = pVCOfE3DScene->getAllContentRange3D(); + drawinglayer::geometry::ViewInformation3D aViewInformation3D(pVCOfE3DScene->getViewInformation3D()); + + if(pVCOfE3DScene->getSdrLightingAttribute().getLightVector().size()) + { + // get light normal from first light and normalize + aLightNormal = pVCOfE3DScene->getSdrLightingAttribute().getLightVector()[0].getDirection(); + aLightNormal.normalize(); + } + + if(!aInBetweenObjectTransform.isIdentity()) + { + // if aInBetweenObjectTransform is used, create combined ViewInformation3D which + // contains the correct object transformation for the embedded 3d object + aViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aViewInformation3D.getObjectTransformation() * aInBetweenObjectTransform, + aViewInformation3D.getOrientation(), + aViewInformation3D.getProjection(), + aViewInformation3D.getDeviceToView(), + aViewInformation3D.getViewTime(), + aViewInformation3D.getExtendedInformationSequence()); + } + + // create embedded 2d primitive and add. LightNormal and ShadowSlant are needed for evtl. + // 3D shadow extraction for correct B2DRange calculation (shadow is part of the object) + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::Embedded3DPrimitive2D( + rxContent3D, + pVCOfE3DScene->getObjectTransformation(), + aViewInformation3D, + aLightNormal, + fShadowSlant, + rAllContentRange)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + return xRetval; + } + + ViewContactOfE3d::ViewContactOfE3d(E3dObject& rSdrObject) + : ViewContactOfSdrObj(rSdrObject) + { + } + + ViewContactOfE3d::~ViewContactOfE3d() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getVIP3DSWithoutObjectTransform() const + { + // local up-to-date checks. Create new list and compare. + drawinglayer::primitive3d::Primitive3DSequence xNew(createViewIndependentPrimitive3DSequence()); + + if(!drawinglayer::primitive3d::arePrimitive3DSequencesEqual(mxViewIndependentPrimitive3DSequence, xNew)) + { + // has changed, copy content + const_cast< ViewContactOfE3d* >(this)->mxViewIndependentPrimitive3DSequence = xNew; + } + + // return current Primitive2DSequence + return mxViewIndependentPrimitive3DSequence; + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getViewIndependentPrimitive3DSequence() const + { + // get sequence without object transform + drawinglayer::primitive3d::Primitive3DSequence xRetval(getVIP3DSWithoutObjectTransform()); + + if(xRetval.hasElements()) + { + // add object transform if it's used + const basegfx::B3DHomMatrix& rObjectTransform(GetE3dObject().GetTransform()); + + if(!rObjectTransform.isIdentity()) + { + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::TransformPrimitive3D( + rObjectTransform, + xRetval)); + + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + } + } + + // return current Primitive2DSequence + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::createViewIndependentPrimitive2DSequence() const + { + // also need to create a 2D embedding when the view-independent part is requested, + // see view-dependent part in ViewObjectContactOfE3d::createPrimitive2DSequence + // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator + return impCreateWithGivenPrimitive3DSequence(getViewIndependentPrimitive3DSequence()); + } + + ViewObjectContact& ViewContactOfE3d::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfE3d(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfE3d::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::attribute::SdrLineAttribute* ViewContactOfE3d::impCreateFallbackLineAttribute(const basegfx::BColor& rBColor) const + { + static bool bFallbackToCreateAsLineForTest(false); + + if(bFallbackToCreateAsLineForTest) + { + return new drawinglayer::attribute::SdrLineAttribute(rBColor); + } + else + { + return 0; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dcube.cxx b/svx/source/sdr/contact/viewcontactofe3dcube.cxx new file mode 100644 index 000000000000..84d456a7a430 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dcube.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * 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/viewcontactofe3dcube.hxx> +#include <svx/cube3d.hxx> +#include <drawinglayer/primitive3d/sdrcubeprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/range/b3drange.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dCube::ViewContactOfE3dCube(E3dCubeObj& rCubeObj) + : ViewContactOfE3d(rCubeObj) + { + } + + ViewContactOfE3dCube::~ViewContactOfE3dCube() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dCube::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dCubeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get cube geometry and use as traslation and scaling for unit cube + basegfx::B3DRange aCubeRange; + const basegfx::B3DVector aCubeSize(GetE3dCubeObj().GetCubeSize()); + const basegfx::B3DPoint aCubePosition(GetE3dCubeObj().GetCubePos()); + basegfx::B3DHomMatrix aWorldTransform; + + if(GetE3dCubeObj().GetPosIsCenter()) + { + const basegfx::B3DVector aHalfCubeSize(aCubeSize / 2.0); + aCubeRange.expand(aCubePosition - aHalfCubeSize); + aCubeRange.expand(aCubePosition + aHalfCubeSize); + } + else + { + aCubeRange.expand(aCubePosition); + aCubeRange.expand(aCubePosition + aCubeSize); + } + + // add scale and translate to world transformation + const basegfx::B3DVector abjectRange(aCubeRange.getRange()); + aWorldTransform.scale(abjectRange.getX(), abjectRange.getY(), abjectRange.getZ()); + aWorldTransform.translate(aCubeRange.getMinX(), aCubeRange.getMinY(), aCubeRange.getMinZ()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size to get a perfect mapping for + // the front/back sides + const basegfx::B2DVector aTextureSize(aCubeSize.getX(), aCubeSize.getY()); + + // create primitive and add + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrCubePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dextrude.cxx b/svx/source/sdr/contact/viewcontactofe3dextrude.cxx new file mode 100644 index 000000000000..1ff1d81c827c --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dextrude.cxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * 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/viewcontactofe3dextrude.hxx> +#include <svx/extrud3d.hxx> +#include <drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dExtrude::ViewContactOfE3dExtrude(E3dExtrudeObj& rExtrude) + : ViewContactOfE3d(rExtrude) + { + } + + ViewContactOfE3dExtrude::~ViewContactOfE3dExtrude() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dExtrude::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dExtrudeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get extrude geometry + const basegfx::B2DPolyPolygon aPolyPolygon(GetE3dExtrudeObj().GetExtrudePolygon()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size; use size of top/bottom cap to get a perfect mapping + // for the caps. The in-between geometry will get a stretched size with a + // relative factor size of caps to extrude depth + const basegfx::B2DRange aRange(basegfx::tools::getRange(aPolyPolygon)); + const basegfx::B2DVector aTextureSize(aRange.getWidth(), aRange.getHeight()); + + // get more data + const double fDepth((double)GetE3dExtrudeObj().GetExtrudeDepth()); + const double fDiagonal((double)GetE3dExtrudeObj().GetPercentDiagonal() / 100.0); + const double fBackScale((double)GetE3dExtrudeObj().GetPercentBackScale() / 100.0); + const bool bSmoothNormals(GetE3dExtrudeObj().GetSmoothNormals()); // Plane itself + const bool bSmoothLids(GetE3dExtrudeObj().GetSmoothLids()); // Front/back + const bool bCharacterMode(GetE3dExtrudeObj().GetCharacterMode()); + const bool bCloseFront(GetE3dExtrudeObj().GetCloseFront()); + const bool bCloseBack(GetE3dExtrudeObj().GetCloseBack()); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrExtrudePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + aPolyPolygon, fDepth, fDiagonal, fBackScale, bSmoothNormals, true, bSmoothLids, + bCharacterMode, bCloseFront, bCloseBack)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dlathe.cxx b/svx/source/sdr/contact/viewcontactofe3dlathe.cxx new file mode 100644 index 000000000000..3cd55fcde828 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dlathe.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 <svx/sdr/contact/viewcontactofe3dlathe.hxx> +#include <svx/lathe3d.hxx> +#include <drawinglayer/primitive3d/sdrlatheprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dLathe::ViewContactOfE3dLathe(E3dLatheObj& rLathe) + : ViewContactOfE3d(rLathe) + { + } + + ViewContactOfE3dLathe::~ViewContactOfE3dLathe() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dLathe::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dLatheObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get extrude geometry + const basegfx::B2DPolyPolygon aPolyPolygon(GetE3dLatheObj().GetPolyPoly2D()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size. Use the polygon length of the longest polygon for + // height and the rotated radius for width (using polygon center) to get a good + // texture mapping + const sal_uInt32 nPolygonCount(aPolyPolygon.count()); + double fPolygonMaxLength(0.0); + + for(sal_uInt32 a(0); a < nPolygonCount; a++) + { + const basegfx::B2DPolygon aCandidate(aPolyPolygon.getB2DPolygon(a)); + const double fPolygonLength(basegfx::tools::getLength(aCandidate)); + fPolygonMaxLength = std::max(fPolygonMaxLength, fPolygonLength); + } + + const basegfx::B2DRange aPolyPolygonRange(basegfx::tools::getRange(aPolyPolygon)); + const basegfx::B2DVector aTextureSize( + F_PI * fabs(aPolyPolygonRange.getCenter().getX()), // PI * d + fPolygonMaxLength); + + // get more data + const sal_uInt32 nHorizontalSegments(GetE3dLatheObj().GetHorizontalSegments()); + const sal_uInt32 nVerticalSegments(GetE3dLatheObj().GetVerticalSegments()); + const double fDiagonal((double)GetE3dLatheObj().GetPercentDiagonal() / 100.0); + const double fBackScale((double)GetE3dLatheObj().GetBackScale() / 100.0); + const double fRotation(((double)GetE3dLatheObj().GetEndAngle() / 1800.0) * F_PI); + const bool bSmoothNormals(GetE3dLatheObj().GetSmoothNormals()); // Plane itself + const bool bSmoothLids(GetE3dLatheObj().GetSmoothLids()); // Front/back + const bool bCharacterMode(GetE3dLatheObj().GetCharacterMode()); + const bool bCloseFront(GetE3dLatheObj().GetCloseFront()); + const bool bCloseBack(GetE3dLatheObj().GetCloseBack()); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrLathePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + aPolyPolygon, nHorizontalSegments, nVerticalSegments, + fDiagonal, fBackScale, fRotation, + bSmoothNormals, true, bSmoothLids, bCharacterMode, bCloseFront, bCloseBack)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx new file mode 100644 index 000000000000..ee6943bccd4a --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * 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/viewcontactofe3dpolygon.hxx> +#include <svx/polygn3d.hxx> +#include <drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dPolygon::ViewContactOfE3dPolygon(E3dPolygonObj& rPolygon) + : ViewContactOfE3d(rPolygon) + { + } + + ViewContactOfE3dPolygon::~ViewContactOfE3dPolygon() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dPolygon::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dPolygonObj().GetMergedItemSet(); + const bool bSuppressFill(GetE3dPolygonObj().GetLineOnly()); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, bSuppressFill)); + + // get extrude geometry + basegfx::B3DPolyPolygon aPolyPolygon3D(GetE3dPolygonObj().GetPolyPolygon3D()); + const basegfx::B3DPolyPolygon aPolyNormals3D(GetE3dPolygonObj().GetPolyNormals3D()); + const basegfx::B2DPolyPolygon aPolyTexture2D(GetE3dPolygonObj().GetPolyTexture2D()); + const bool bNormals(aPolyNormals3D.count() && aPolyNormals3D.count() == aPolyPolygon3D.count()); + const bool bTexture(aPolyTexture2D.count() && aPolyTexture2D.count() == aPolyPolygon3D.count()); + + if(bNormals || bTexture) + { + for(sal_uInt32 a(0L); a < aPolyPolygon3D.count(); a++) + { + basegfx::B3DPolygon aCandidate3D(aPolyPolygon3D.getB3DPolygon(a)); + basegfx::B3DPolygon aNormals3D; + basegfx::B2DPolygon aTexture2D; + + if(bNormals) + { + aNormals3D = aPolyNormals3D.getB3DPolygon(a); + } + + if(bTexture) + { + aTexture2D = aPolyTexture2D.getB2DPolygon(a); + } + + for(sal_uInt32 b(0L); b < aCandidate3D.count(); b++) + { + if(bNormals) + { + sal_uInt32 nNormalCount = aNormals3D.count(); + if( b < nNormalCount ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b)); + else if( nNormalCount > 0 ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(0)); + } + if(bTexture) + { + sal_uInt32 nTextureCount = aTexture2D.count(); + if( b < nTextureCount ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b)); + else if( nTextureCount > 0 ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(0)); + } + } + + aPolyPolygon3D.setB3DPolygon(a, aCandidate3D); + } + } + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size + basegfx::B2DVector aTextureSize(1.0, 1.0); + + if(bTexture) + { + // #i98314# + // create texture size from object's size + const basegfx::B3DRange aObjectRange(basegfx::tools::getRange(aPolyPolygon3D)); + + double fWidth(0.0); + double fHeight(0.0); + + // this is a polygon object, so Width/Height and/or Depth may be zero (e.g. left + // wall of chart). Take this into account + if(basegfx::fTools::equalZero(aObjectRange.getWidth())) + { + // width is zero, use height and depth + fWidth = aObjectRange.getHeight(); + fHeight = aObjectRange.getDepth(); + } + else if(basegfx::fTools::equalZero(aObjectRange.getHeight())) + { + // height is zero, use width and depth + fWidth = aObjectRange.getWidth(); + fHeight = aObjectRange.getDepth(); + } + else + { + // use width and height + fWidth = aObjectRange.getWidth(); + fHeight = aObjectRange.getHeight(); + } + + if(basegfx::fTools::lessOrEqual(fWidth, 0.0) ||basegfx::fTools::lessOrEqual(fHeight, 0.0)) + { + // no texture; fallback to very small size + aTextureSize.setX(0.01); + aTextureSize.setY(0.01); + } + else + { + aTextureSize.setX(fWidth); + aTextureSize.setY(fHeight); + } + } + + // #i98295# + // unfortunately, this SdrObject type which allows a free 3d geometry definition was defined + // wrong topologically in relation to it's plane normal and 3D visibility when it was invented + // a long time ago. Since the API allows creation of this SDrObject type, it is not possible to + // simply change this definition. Only the chart should use it, and at least this object type + // only exists at Runtime (is not saved and/or loaded in any FileFormat). Still someone external + // may have used it in it's API. To not risk wrong 3D lightings, i have to switch the orientation + // of the polygon here + aPolyPolygon3D.flip(); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrPolyPolygonPrimitive3D( + aPolyPolygon3D, aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dscene.cxx b/svx/source/sdr/contact/viewcontactofe3dscene.cxx new file mode 100644 index 000000000000..8a7d7694a315 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dscene.cxx @@ -0,0 +1,478 @@ +/************************************************************************* + * + * 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/viewcontactofe3dscene.hxx> +#include <svx/polysc3d.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/range/b3drange.hxx> +#include <drawinglayer/primitive3d/baseprimitive3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <drawinglayer/primitive2d/sceneprimitive2d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // pActiveVC is only true if ghosted is still activated and maybe needs to be switched off in this path + void createSubPrimitive3DVector( + const sdr::contact::ViewContact& rCandidate, + drawinglayer::primitive3d::Primitive3DSequence& o_rAllTarget, + drawinglayer::primitive3d::Primitive3DSequence* o_pVisibleTarget, + const SetOfByte* pVisibleLayerSet, + const bool bTestSelectedVisibility) + { + const sdr::contact::ViewContactOfE3dScene* pViewContactOfE3dScene = dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(&rCandidate); + + if(pViewContactOfE3dScene) + { + const sal_uInt32 nChildrenCount(rCandidate.GetObjectCount()); + + if(nChildrenCount) + { + // provide new collection sequences + drawinglayer::primitive3d::Primitive3DSequence aNewAllTarget; + drawinglayer::primitive3d::Primitive3DSequence aNewVisibleTarget; + + // add children recursively + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector( + rCandidate.GetViewContact(a), + aNewAllTarget, + o_pVisibleTarget ? &aNewVisibleTarget : 0, + pVisibleLayerSet, + bTestSelectedVisibility); + } + + // create transform primitive for the created content combining content and transformtion + const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::TransformPrimitive3D( + pViewContactOfE3dScene->GetE3dScene().GetTransform(), + aNewAllTarget)); + + // add created content to all target + drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(o_rAllTarget, xReference); + + // add created content to visibiel target if exists + if(o_pVisibleTarget) + { + drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(*o_pVisibleTarget, xReference); + } + } + } + else + { + // access view independent representation of rCandidate + const sdr::contact::ViewContactOfE3d* pViewContactOfE3d = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&rCandidate); + + if(pViewContactOfE3d) + { + drawinglayer::primitive3d::Primitive3DSequence xPrimitive3DSeq(pViewContactOfE3d->getViewIndependentPrimitive3DSequence()); + + if(xPrimitive3DSeq.hasElements()) + { + // add to all target vector + drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(o_rAllTarget, xPrimitive3DSeq); + + if(o_pVisibleTarget) + { + // test visibility. Primitive is visible when both tests are true (AND) + bool bVisible(true); + + if(pVisibleLayerSet) + { + // test layer visibility + const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject(); + const SdrLayerID aLayerID(rE3dObject.GetLayer()); + + bVisible = pVisibleLayerSet->IsSet(aLayerID); + } + + if(bVisible && bTestSelectedVisibility) + { + // test selected visibility (see 3D View's DrawMarkedObj implementation) + const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject(); + + bVisible = rE3dObject.GetSelected(); + } + + if(bVisible && o_pVisibleTarget) + { + // add to visible target vector + drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(*o_pVisibleTarget, xPrimitive3DSeq); + } + } + } + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfE3dScene(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfE3dScene::ViewContactOfE3dScene(E3dScene& rScene) + : ViewContactOfSdrObj(rScene), + maViewInformation3D(), + maObjectTransformation(), + maSdrSceneAttribute(), + maSdrLightingAttribute() + { + } + + void ViewContactOfE3dScene::createViewInformation3D(const basegfx::B3DRange& rContentRange) + { + basegfx::B3DHomMatrix aTransformation; + basegfx::B3DHomMatrix aOrientation; + basegfx::B3DHomMatrix aProjection; + basegfx::B3DHomMatrix aDeviceToView; + + // create transformation (scene as group's transformation) + // For historical reasons, the outmost scene's transformation is handles as part of the + // view transformation. This means that the BoundRect of the contained 3D Objects is + // without that transformation and makes it necessary to NOT add the first scene to the + // Primitive3DSequence of contained objects. + { + aTransformation = GetE3dScene().GetTransform(); + } + + // create orientation (world to camera coordinate system) + { + // calculate orientation from VRP, VPN and VUV + const B3dCamera& rSceneCamera = GetE3dScene().GetCameraSet(); + const basegfx::B3DPoint aVRP(rSceneCamera.GetVRP()); + const basegfx::B3DVector aVPN(rSceneCamera.GetVRP()); + const basegfx::B3DVector aVUV(rSceneCamera.GetVUV()); + + aOrientation.orientation(aVRP, aVPN, aVUV); + } + + // create projection (camera coordinate system to relative 2d where X,Y and Z are [0.0 .. 1.0]) + { + const basegfx::B3DHomMatrix aWorldToCamera(aOrientation * aTransformation); + basegfx::B3DRange aCameraRange(rContentRange); + aCameraRange.transform(aWorldToCamera); + + // remember Z-Values, but change orientation + const double fMinZ(-aCameraRange.getMaxZ()); + const double fMaxZ(-aCameraRange.getMinZ()); + + // construct temorary matrix from world to device. Use unit values here to measure expansion + basegfx::B3DHomMatrix aWorldToDevice(aWorldToCamera); + const drawinglayer::attribute::SdrSceneAttribute& rSdrSceneAttribute = getSdrSceneAttribute(); + + if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode()) + { + aWorldToDevice.frustum(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ); + } + else + { + aWorldToDevice.ortho(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ); + } + + // create B3DRange in device. This will create the real used ranges + // in camera space. Do not use the Z-Values, though. + basegfx::B3DRange aDeviceRange(rContentRange); + aDeviceRange.transform(aWorldToDevice); + + // set projection + if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode()) + { + aProjection.frustum( + aDeviceRange.getMinX(), aDeviceRange.getMaxX(), + aDeviceRange.getMinY(), aDeviceRange.getMaxY(), + fMinZ, fMaxZ); + } + else + { + aProjection.ortho( + aDeviceRange.getMinX(), aDeviceRange.getMaxX(), + aDeviceRange.getMinY(), aDeviceRange.getMaxY(), + fMinZ, fMaxZ); + } + } + + // create device to view transform + { + // create standard deviceToView projection for geometry + // input is [-1.0 .. 1.0] in X,Y and Z. bring to [0.0 .. 1.0]. Also + // necessary to flip Y due to screen orientation + // Z is not needed, but will also be brought to [0.0 .. 1.0] + aDeviceToView.scale(0.5, -0.5, 0.5); + aDeviceToView.translate(0.5, 0.5, 0.5); + } + + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + maViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aTransformation, aOrientation, aProjection, + aDeviceToView, 0.0, aEmptyProperties); + } + + void ViewContactOfE3dScene::createObjectTransformation() + { + // create 2d Object Transformation from relative point in 2d scene to world + const Rectangle& rRectangle = GetE3dScene().GetSnapRect(); + + maObjectTransformation.set(0, 0, rRectangle.getWidth()); + maObjectTransformation.set(1, 1, rRectangle.getHeight()); + maObjectTransformation.set(0, 2, rRectangle.Left()); + maObjectTransformation.set(1, 2, rRectangle.Top()); + } + + void ViewContactOfE3dScene::createSdrSceneAttribute() + { + const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet(); + maSdrSceneAttribute = drawinglayer::primitive2d::createNewSdrSceneAttribute(rItemSet); + } + + void ViewContactOfE3dScene::createSdrLightingAttribute() + { + const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet(); + maSdrLightingAttribute = drawinglayer::primitive2d::createNewSdrLightingAttribute(rItemSet); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createScenePrimitive2DSequence( + const SetOfByte* pLayerVisibility) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nChildrenCount(GetObjectCount()); + + if(nChildrenCount) + { + // create 3d scene primitive with visible content tested against rLayerVisibility + drawinglayer::primitive3d::Primitive3DSequence aAllSequence; + drawinglayer::primitive3d::Primitive3DSequence aVisibleSequence; + const bool bTestLayerVisibility(0 != pLayerVisibility); + const bool bTestSelectedVisibility(GetE3dScene().GetDrawOnlySelected()); + const bool bTestVisibility(bTestLayerVisibility || bTestSelectedVisibility); + + // add children recursively. Do NOT start with (*this), this would create + // a 3D transformPrimitive for the start scene. While this is theoretically not + // a bad thing, for historical reasons the transformation of the outmost scene + // is seen as part of the ViewTransformation (see text in createViewInformation3D) + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector( + GetViewContact(a), + aAllSequence, + bTestLayerVisibility ? &aVisibleSequence : 0, + bTestLayerVisibility ? pLayerVisibility : 0, + bTestSelectedVisibility); + } + + const sal_uInt32 nAllSize(aAllSequence.hasElements() ? aAllSequence.getLength() : 0); + const sal_uInt32 nVisibleSize(aVisibleSequence.hasElements() ? aVisibleSequence.getLength() : 0); + + if((bTestVisibility && nVisibleSize) || nAllSize) + { + // for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D + // needs to be given for evtl. decompositions. At the same time createViewInformation3D + // currently is based on creating the target-ViewInformation3D using a given range. To + // get the true range, use a neutral ViewInformation3D here. This leaves all matrices + // on identity and the time on 0.0. + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties); + const basegfx::B3DRange aContentRange( + drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(aAllSequence, aNeutralViewInformation3D)); + + // create 2d primitive 3dscene with generated sub-list from collector + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::ScenePrimitive2D( + bTestVisibility ? aVisibleSequence : aAllSequence, + getSdrSceneAttribute(), + getSdrLightingAttribute(), + getObjectTransformation(), + getViewInformation3D(aContentRange))); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + // always append an invisible outline for the cases where no visible content exists + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, getObjectTransformation())); + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(GetObjectCount()) + { + // create a default ScenePrimitive2D (without visibility test of members) + xRetval = createScenePrimitive2DSequence(0); + } + + return xRetval; + } + + void ViewContactOfE3dScene::ActionChanged() + { + // call parent + ViewContactOfSdrObj::ActionChanged(); + + // mark locally cached values as invalid + maViewInformation3D = drawinglayer::geometry::ViewInformation3D(); + maObjectTransformation.identity(); + maSdrSceneAttribute = drawinglayer::attribute::SdrSceneAttribute(); + maSdrLightingAttribute = drawinglayer::attribute::SdrLightingAttribute(); + } + + const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D() const + { + if(maViewInformation3D.isDefault()) + { + // this version will create the content range on demand locally and thus is less + // performant than the other one. Since the information is buffered the planned + // behaviour is that the version with the given range is used initially. + basegfx::B3DRange aContentRange(getAllContentRange3D()); + + if(aContentRange.isEmpty()) + { + // empty scene, no 3d action should be necessary. Prepare some + // fallback size + OSL_ENSURE(false, "No need to get ViewInformation3D from an empty scene (!)"); + aContentRange.expand(basegfx::B3DPoint(-100.0, -100.0, -100.0)); + aContentRange.expand(basegfx::B3DPoint( 100.0, 100.0, 100.0)); + } + + const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(aContentRange); + } + + return maViewInformation3D; + } + + const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D(const basegfx::B3DRange& rContentRange) const + { + if(maViewInformation3D.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(rContentRange); + } + + return maViewInformation3D; + } + + const basegfx::B2DHomMatrix& ViewContactOfE3dScene::getObjectTransformation() const + { + if(maObjectTransformation.isIdentity()) + { + const_cast < ViewContactOfE3dScene* >(this)->createObjectTransformation(); + } + + return maObjectTransformation; + } + + const drawinglayer::attribute::SdrSceneAttribute& ViewContactOfE3dScene::getSdrSceneAttribute() const + { + if(maSdrSceneAttribute.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createSdrSceneAttribute(); + } + + return maSdrSceneAttribute; + } + + const drawinglayer::attribute::SdrLightingAttribute& ViewContactOfE3dScene::getSdrLightingAttribute() const + { + if(maSdrLightingAttribute.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createSdrLightingAttribute(); + } + + return maSdrLightingAttribute; + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dScene::getAllPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence aAllPrimitive3DSequence; + const sal_uInt32 nChildrenCount(GetObjectCount()); + + // add children recursively. Do NOT start with (*this), this would create + // a 3D transformPrimitive for the start scene. While this is theoretically not + // a bad thing, for historical reasons the transformation of the outmost scene + // is seen as part of the ViewTransformation (see text in createViewInformation3D) + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector(GetViewContact(a), aAllPrimitive3DSequence, 0, 0, false); + } + + return aAllPrimitive3DSequence; + } + + basegfx::B3DRange ViewContactOfE3dScene::getAllContentRange3D() const + { + const drawinglayer::primitive3d::Primitive3DSequence xAllSequence(getAllPrimitive3DSequence()); + basegfx::B3DRange aAllContentRange3D; + + if(xAllSequence.hasElements()) + { + // for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D + // needs to be given for evtl. decompositions. Use a neutral ViewInformation3D here. This + // leaves all matrices on identity and the time on 0.0. + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties); + + aAllContentRange3D = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(xAllSequence, aNeutralViewInformation3D); + } + + return aAllContentRange3D; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dsphere.cxx b/svx/source/sdr/contact/viewcontactofe3dsphere.cxx new file mode 100644 index 000000000000..c16633f7f2c9 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dsphere.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/sdr/contact/viewcontactofe3dsphere.hxx> +#include <svx/sphere3d.hxx> +#include <drawinglayer/primitive3d/sdrsphereprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dSphere::ViewContactOfE3dSphere(E3dSphereObj& rSphere) + : ViewContactOfE3d(rSphere) + { + } + + ViewContactOfE3dSphere::~ViewContactOfE3dSphere() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dSphere::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dSphereObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get sphere center and size for geometry + basegfx::B3DRange aSphereRange; + const basegfx::B3DPoint aSpherePosition(GetE3dSphereObj().Center()); + const basegfx::B3DVector aSphereSize(GetE3dSphereObj().Size()); + basegfx::B3DHomMatrix aWorldTransform; + + aWorldTransform.translate(-0.5, -0.5, -0.5); + aWorldTransform.scale(aSphereSize.getX(), aSphereSize.getY(), aSphereSize.getZ()); + aWorldTransform.translate(aSpherePosition.getX(), aSpherePosition.getY(), aSpherePosition.getZ()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // get segment count + const sal_uInt32 nHorizontalSegments(GetE3dSphereObj().GetHorizontalSegments()); + const sal_uInt32 nVerticalSegments(GetE3dSphereObj().GetVerticalSegments()); + + // calculate texture size, use radii for (2 * PI * r) to get a perfect + // mapping on the sphere + const basegfx::B2DVector aTextureSize( + F_PI * ((aSphereSize.getX() + aSphereSize.getZ()) / 2.0), // PI * d + F_PI2 * aSphereSize.getY()); // half outline, (PI * d)/2 -> PI/2 * d + + // create primitive and add + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrSpherePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + nHorizontalSegments, nVerticalSegments)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx new file mode 100644 index 000000000000..7172b0840476 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx @@ -0,0 +1,463 @@ +/************************************************************************* + * + * 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/viewcontactofgraphic.hxx> +#include <svx/sdr/contact/viewobjectcontactofgraphic.hxx> +#include <svx/svdograf.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svl/itemset.hxx> + +#ifndef ITEMID_GRF_CROP +#define ITEMID_GRF_CROP 0 +#endif + +#include <svx/sdgcpitm.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrgrafprimitive2d.hxx> +#include "svdstr.hrc" +#include <svdglob.hxx> +#include <vcl/svapp.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/colritem.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfGraphic::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfGraphic(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfGraphic::ViewContactOfGraphic(SdrGrafObj& rGrafObj) + : ViewContactOfTextObj(rGrafObj) + { + } + + ViewContactOfGraphic::~ViewContactOfGraphic() + { + } + + void ViewContactOfGraphic::flushGraphicObjects() + { + // #i102380# The graphic is swapped out. To let that have an effect ist is necessary to + // delete copies of the GraphicObject which are not swapped out and have no SwapHandler set + // (this is what happnes when the GraphicObject gets copied to a SdrGrafPrimitive2D). This + // is best achieved for the VC by clearing the local decomposition cache. It would be possible + // to also do this for the VOC cache, but that VOCs exist exactly expresss that the object + // gets visualised, so this would be wrong. + flushViewIndependentPrimitive2DSequence(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute, + const GraphicAttr& rLocalGrafInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and + // without attributes + basegfx::B2DHomMatrix aSmallerMatrix; + + // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic + // into account. Since EmptyPresObj's are only used in Draw/Impress, it is + // safe to assume 100th mm as target. + Size aPrefSize(GetGrafObject().GetGrafPrefSize()); + + if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0); + const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0); + + if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) + { + // create the EmptyPresObj fallback visualisation. The fallback graphic + // is already provided in rGraphicObject in this case, use it + aSmallerMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aPrefSize.getWidth(), aPrefSize.getHeight(), fOffsetX, fOffsetY); + aSmallerMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate) + * aSmallerMatrix; + + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + aSmallerMatrix, + drawinglayer::attribute::SdrLineFillShadowTextAttribute(), + rGraphicObject, + rLocalGrafInfo)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForDraft( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + if(rAttribute.getLine().isDefault()) + { + // create a surrounding frame when no linestyle given + const Color aColor(Application::GetSettings().GetStyleSettings().GetShadowColor()); + const basegfx::BColor aBColor(aColor.getBColor()); + basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon()); + aOutline.transform(rObjectMatrix); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( + aOutline, + aBColor))); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + // define a distance value, used for distance from bitmap to borders and from bitmap + // to text, too (2 mm) + const double fDistance(200.0); + + // consume borders from values + aScale.setX(std::max(0.0, aScale.getX() - (2.0 * fDistance))); + aScale.setY(std::max(0.0, aScale.getY() - (2.0 * fDistance))); + aTranslate.setX(aTranslate.getX() + fDistance); + aTranslate.setY(aTranslate.getY() + fDistance); + + // draw a draft bitmap + const Bitmap aDraftBitmap(ResId(BMAP_GrafikEi, *ImpGetResMgr())); + + if(!aDraftBitmap.IsEmpty()) + { + Size aPrefSize(aDraftBitmap.GetPrefSize()); + + if(MAP_PIXEL == aDraftBitmap.GetPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aDraftBitmap.GetSizePixel(), MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aDraftBitmap.GetPrefMapMode(), MAP_100TH_MM); + } + + const double fBitmapScaling(2.0); + const double fWidth(aPrefSize.getWidth() * fBitmapScaling); + const double fHeight(aPrefSize.getHeight() * fBitmapScaling); + + if(basegfx::fTools::more(fWidth, 1.0) + && basegfx::fTools::more(fHeight, 1.0) + && basegfx::fTools::lessOrEqual(fWidth, aScale.getX()) + && basegfx::fTools::lessOrEqual(fHeight, aScale.getY())) + { + const basegfx::B2DHomMatrix aBitmapMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + fWidth, fHeight, fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::BitmapPrimitive2D( + BitmapEx(aDraftBitmap), + aBitmapMatrix))); + + // consume bitmap size in X + aScale.setX(std::max(0.0, aScale.getX() - (fWidth + fDistance))); + aTranslate.setX(aTranslate.getX() + fWidth + fDistance); + } + } + + // Build the text for the draft object + XubString aDraftText = GetGrafObject().GetFileName(); + + if(!aDraftText.Len()) + { + aDraftText = GetGrafObject().GetName(); + aDraftText.AppendAscii(" ..."); + } + + if(aDraftText.Len() && GetGrafObject().GetModel()) + { + // #i103255# Goal is to produce TextPrimitives which hold the given text as + // BlockText in the available space. It would be very tricky to do + // an own word wrap/line layout here. + // Using SdrBlockTextPrimitive2D OTOH is critical since it internally + // uses the SdrObject it references. To solve this, create a temp + // SdrObject with Attributes and Text, generate a SdrBlockTextPrimitive2D + // directly and immediately decompose it. After that, it is no longer + // needed and can be deleted. + + // create temp RectObj as TextObj and set needed attributes + SdrRectObj aRectObj(OBJ_TEXT); + aRectObj.SetModel(GetGrafObject().GetModel()); + aRectObj.NbcSetText(aDraftText); + aRectObj.SetMergedItem(SvxColorItem(Color(COL_LIGHTRED), EE_CHAR_COLOR)); + + // get SdrText and OPO + SdrText* pSdrText = aRectObj.getText(0); + OutlinerParaObject* pOPO = aRectObj.GetOutlinerParaObject(); + + if(pSdrText && pOPO) + { + // directly use the remaining space as TextRangeTransform + const basegfx::B2DHomMatrix aTextRangeTransform(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, fShearX, fRotate, aTranslate)); + + // directly create temp SdrBlockTextPrimitive2D + drawinglayer::primitive2d::SdrBlockTextPrimitive2D aBlockTextPrimitive( + pSdrText, + *pOPO, + aTextRangeTransform, + SDRTEXTHORZADJUST_LEFT, + SDRTEXTVERTADJUST_TOP, + false, + false, + false, + false, + false); + + // decompose immediately with neutral ViewInformation. This will + // layout the text to more simple TextPrimitives from drawinglayer + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence( + xRetval, + aBlockTextPrimitive.get2DDecomposition(aViewInformation2D)); + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SfxItemSet& rItemSet = GetGrafObject().GetMergedItemSet(); + drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetGrafObject().getText(0))); + + // create and fill GraphicAttr + GraphicAttr aLocalGrafInfo; + const sal_uInt16 nTrans(((SdrGrafTransparenceItem&)rItemSet.Get(SDRATTR_GRAFTRANSPARENCE)).GetValue()); + const SdrGrafCropItem& rCrop((const SdrGrafCropItem&)rItemSet.Get(SDRATTR_GRAFCROP)); + aLocalGrafInfo.SetLuminance(((SdrGrafLuminanceItem&)rItemSet.Get(SDRATTR_GRAFLUMINANCE)).GetValue()); + aLocalGrafInfo.SetContrast(((SdrGrafContrastItem&)rItemSet.Get(SDRATTR_GRAFCONTRAST)).GetValue()); + aLocalGrafInfo.SetChannelR(((SdrGrafRedItem&)rItemSet.Get(SDRATTR_GRAFRED)).GetValue()); + aLocalGrafInfo.SetChannelG(((SdrGrafGreenItem&)rItemSet.Get(SDRATTR_GRAFGREEN)).GetValue()); + aLocalGrafInfo.SetChannelB(((SdrGrafBlueItem&)rItemSet.Get(SDRATTR_GRAFBLUE)).GetValue()); + aLocalGrafInfo.SetGamma(((SdrGrafGamma100Item&)rItemSet.Get(SDRATTR_GRAFGAMMA)).GetValue() * 0.01); + aLocalGrafInfo.SetTransparency((BYTE)::basegfx::fround(Min(nTrans, (USHORT)100) * 2.55)); + aLocalGrafInfo.SetInvert(((SdrGrafInvertItem&)rItemSet.Get(SDRATTR_GRAFINVERT)).GetValue()); + aLocalGrafInfo.SetDrawMode(((SdrGrafModeItem&)rItemSet.Get(SDRATTR_GRAFMODE)).GetValue()); + aLocalGrafInfo.SetCrop(rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom()); + + if(aAttribute.isDefault() && 255L != aLocalGrafInfo.GetTransparency()) + { + // no fill, no line, no text (invisible), but the graphic content is visible. + // Create evtl. shadow for content which was not created by createNewSdrLineFillShadowTextAttribute yet + const drawinglayer::attribute::SdrShadowAttribute aShadow( + drawinglayer::primitive2d::createNewSdrShadowAttribute(rItemSet)); + + if(!aShadow.isDefault()) + { + // create new attribute set if indeed shadow is used + aAttribute = drawinglayer::attribute::SdrLineFillShadowTextAttribute( + aAttribute.getLine(), + aAttribute.getFill(), + aAttribute.getLineStartEnd(), + aShadow, + aAttribute.getFillFloatTransGradient(), + aAttribute.getText()); + } + } + + // take unrotated snap rect for position and size. Directly use model data, not getBoundRect() or getSnapRect() + // which will use the primitive data we just create in the near future + const Rectangle& rRectangle = GetGrafObject().GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // look for mirroring + const GeoStat& rGeoStat(GetGrafObject().GetGeoStat()); + const sal_Int32 nDrehWink(rGeoStat.nDrehWink); + const bool bRota180(18000 == nDrehWink); + const bool bMirrored(GetGrafObject().IsMirrored()); + const sal_uInt16 nMirrorCase(bRota180 ? (bMirrored ? 3 : 4) : (bMirrored ? 2 : 1)); + bool bHMirr((2 == nMirrorCase ) || (4 == nMirrorCase)); + bool bVMirr((3 == nMirrorCase ) || (4 == nMirrorCase)); + + // set mirror flags at LocalGrafInfo. Take into account that the geometry in + // aObjectRange is already changed and rotated when bRota180 is used. To rebuild + // that old behaviour (as long as part of the model data), correct the H/V flags + // accordingly. The created bitmapPrimitive WILL use the rotation, too. + if(bRota180) + { + // if bRota180 which is used for vertical mirroring, the graphic will already be rotated + // by 180 degrees. To correct, switch off VMirror and invert HMirroring. + bHMirr = !bHMirr; + bVMirr = false; + } + + if(bHMirr || bVMirr) + { + aLocalGrafInfo.SetMirrorFlags((bHMirr ? BMP_MIRROR_HORZ : 0)|(bVMirr ? BMP_MIRROR_VERT : 0)); + } + + // fill object matrix + const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); + const double fRotate(nDrehWink ? (36000 - nDrehWink) * F_PI18000 : 0.0); + const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + fShearX, fRotate, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // get the current, unchenged graphic obect from SdrGrafObj + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + + if(visualisationUsesPresObj()) + { + // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one + // with the content which is the placeholder graphic + xRetval = createVIP2DSForPresObj(aObjectMatrix, aAttribute, aLocalGrafInfo); + } + else if(visualisationUsesDraft()) + { + // #i102380# The graphic is swapped out. To not force a swap-in here, there is a mechanism + // which shows a swapped-out-visualisation (which gets created here now) and an asynchronious + // visual update mechanism for swapped-out grapgics when they were loaded (see AsynchGraphicLoadingEvent + // and ViewObjectContactOfGraphic implementation). Not forcing the swap-in here allows faster + // (non-blocking) processing here and thus in the effect e.g. fast scrolling through pages + xRetval = createVIP2DSForDraft(aObjectMatrix, aAttribute); + } + else + { + // create primitive. Info: Calling the copy-constructor of GraphicObject in this + // SdrGrafPrimitive2D constructor will force a full swap-in of the graphic + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + aObjectMatrix, + aAttribute, + rGraphicObject, + aLocalGrafInfo)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + // always append an invisible outline for the cases where no visible content exists + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectMatrix)); + + return xRetval; + } + + bool ViewContactOfGraphic::visualisationUsesPresObj() const + { + return GetGrafObject().IsEmptyPresObj(); + } + + bool ViewContactOfGraphic::visualisationUsesDraft() const + { + // no draft when already PresObj + if(visualisationUsesPresObj()) + return false; + + // draft when swapped out + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + static bool bAllowReplacements(true); + + if(rGraphicObject.IsSwappedOut() && bAllowReplacements) + return true; + + // draft when no graphic + if(GRAPHIC_NONE == rGraphicObject.GetType() || GRAPHIC_DEFAULT == rGraphicObject.GetType()) + return true; + + return false; + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofgroup.cxx b/svx/source/sdr/contact/viewcontactofgroup.cxx new file mode 100644 index 000000000000..6252811d32a3 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofgroup.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * 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/viewcontactofgroup.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewobjectcontactofgroup.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfGroup::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfGroup(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfGroup::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfGroup::ViewContactOfGroup(SdrObjGroup& rGroup) + : ViewContactOfSdrObj(rGroup) + { + } + + ViewContactOfGroup::~ViewContactOfGroup() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGroup::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nObjectCount(GetObjectCount()); + + if(nObjectCount) + { + // collect all sub-primitives + for(sal_uInt32 a(0); a < nObjectCount; a++) + { + const ViewContact& rCandidate(GetViewContact(a)); + const drawinglayer::primitive2d::Primitive2DSequence aCandSeq(rCandidate.getViewIndependentPrimitive2DSequence()); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, aCandSeq); + } + } + else + { + // append an invisible outline for the cases where no visible content exists + const Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); + const basegfx::B2DRange aCurrentRange( + aCurrentBoundRect.Left(), aCurrentBoundRect.Top(), + aCurrentBoundRect.Right(), aCurrentBoundRect.Bottom()); + + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aCurrentRange)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx new file mode 100644 index 000000000000..6ca5f1c4d172 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx @@ -0,0 +1,126 @@ +/************************************************************************* + * + * 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/viewcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <vcl/timer.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdr/contact/viewcontactofsdrpage.hxx> +#include <svx/sdr/contact/viewobjectcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <svx/svdpage.hxx> +#include <drawinglayer/attribute/sdrfillattribute.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/attribute/fillgradientattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfMasterPageDescriptor::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + return *(new ViewObjectContactOfMasterPageDescriptor(rObjectContact, *this)); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfMasterPageDescriptor::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + drawinglayer::attribute::SdrFillAttribute aFill; + const SdrPageProperties* pCorrectProperties = GetMasterPageDescriptor().getCorrectSdrPageProperties(); + + if(pCorrectProperties) + { + // create page fill attributes when correct properties were identified + aFill = drawinglayer::primitive2d::createNewSdrFillAttribute(pCorrectProperties->GetItemSet()); + } + + if(!aFill.isDefault()) + { + // direct model data is the page size, get and use it + const SdrPage& rOwnerPage = GetMasterPageDescriptor().GetOwnerPage(); + const basegfx::B2DRange aInnerRange( + rOwnerPage.GetLftBorder(), rOwnerPage.GetUppBorder(), + rOwnerPage.GetWdt() - rOwnerPage.GetRgtBorder(), + rOwnerPage.GetHgt() - rOwnerPage.GetLwrBorder()); + const basegfx::B2DPolygon aInnerPolgon(basegfx::tools::createPolygonFromRect(aInnerRange)); + const basegfx::B2DHomMatrix aEmptyTransform; + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aInnerPolgon), + aEmptyTransform, + aFill, + drawinglayer::attribute::FillGradientAttribute())); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + return xRetval; + } + + // basic constructor + ViewContactOfMasterPageDescriptor::ViewContactOfMasterPageDescriptor(sdr::MasterPageDescriptor& rDescriptor) + : ViewContact(), + mrMasterPageDescriptor(rDescriptor) + { + } + + // The destructor. + ViewContactOfMasterPageDescriptor::~ViewContactOfMasterPageDescriptor() + { + } + + sal_uInt32 ViewContactOfMasterPageDescriptor::GetObjectCount() const + { + return GetMasterPageDescriptor().GetUsedPage().GetObjCount(); + } + + ViewContact& ViewContactOfMasterPageDescriptor::GetViewContact(sal_uInt32 nIndex) const + { + return GetMasterPageDescriptor().GetUsedPage().GetObj(nIndex)->GetViewContact(); + } + + ViewContact* ViewContactOfMasterPageDescriptor::GetParentContact() const + { + return &(GetMasterPageDescriptor().GetOwnerPage().GetViewContact()); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofpageobj.cxx b/svx/source/sdr/contact/viewcontactofpageobj.cxx new file mode 100644 index 000000000000..3740ec27bdb5 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofpageobj.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * 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/viewcontactofpageobj.hxx> +#include <svx/svdopage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewobjectcontactofpageobj.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageObj(rObjectContact, *this); + return *pRetval; + } + + // Access to referenced page + const SdrPage* ViewContactOfPageObj::GetReferencedPage() const + { + return GetPageObj().GetReferencedPage(); + } + + ViewContactOfPageObj::ViewContactOfPageObj(SdrPageObj& rPageObj) + : ViewContactOfSdrObj(rPageObj) + { + } + + ViewContactOfPageObj::~ViewContactOfPageObj() + { + } + + // #i35972# React on changes of the object of this ViewContact + void ViewContactOfPageObj::ActionChanged() + { + static bool bIsInActionChange(false); + + if(!bIsInActionChange) + { + // set recursion flag, see description in *.hxx + bIsInActionChange = true; + + // call parent + ViewContactOfSdrObj::ActionChanged(); + + // reset recursion flag, see description in *.hxx + bIsInActionChange = false; + } + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageObj::createViewIndependentPrimitive2DSequence() const + { + // ceate graphical visualisation data. Since this is the view-independent version which should not be used, + // create a replacement graphic visualisation here. Use GetLastBoundRect to access the model data directly + // which is aOutRect for SdrPageObj. + const Rectangle aModelRectangle(GetPageObj().GetLastBoundRect()); + const basegfx::B2DRange aModelRange(aModelRectangle.Left(), aModelRectangle.Top(), aModelRectangle.Right(), aModelRectangle.Bottom()); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aModelRange)); + const basegfx::BColor aYellow(1.0, 1.0, 0.0); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx new file mode 100644 index 000000000000..84e60392a88f --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * 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/viewcontactofsdrcaptionobj.hxx> +#include <svx/svdocapt.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrcaptionprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// +// includes for special text box shadow (SC) + +#include <svl/itemset.hxx> +#include <svx/xhatch.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xflclit.hxx> +#include <svx/xfltrit.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrCaptionObj::ViewContactOfSdrCaptionObj(SdrCaptionObj& rCaptionObj) + : ViewContactOfSdrRectObj(rCaptionObj) + { + } + + ViewContactOfSdrCaptionObj::~ViewContactOfSdrCaptionObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCaptionObj::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrCaptionObj& rCaptionObj(GetCaptionObj()); + const SfxItemSet& rItemSet = rCaptionObj.GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + rCaptionObj.getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = rCaptionObj.GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(rCaptionObj.GetGeoStat()); + + // fill object matrix + basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // calculate corner radius + double fCornerRadiusX; + double fCornerRadiusY; + drawinglayer::primitive2d::calculateRelativeCornerRadius( + rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); + + // create primitive. Always create one (even if invisible) to let the decomposition + // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrCaptionPrimitive2D( + aObjectMatrix, + aAttribute, + rCaptionObj.getTailPolygon(), + fCornerRadiusX, + fCornerRadiusY)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + + if(!aAttribute.isDefault() && rCaptionObj.GetSpecialTextBoxShadow()) + { + // for SC, the caption object may have a specialized shadow. The usual object shadow is off + // and a specialized shadow gets created here (see old paint) + const SdrShadowColorItem& rShadColItem = (SdrShadowColorItem&)(rItemSet.Get(SDRATTR_SHADOWCOLOR)); + const sal_uInt16 nTransp(((SdrShadowTransparenceItem&)(rItemSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); + const Color aShadCol(rShadColItem.GetColorValue()); + const XFillStyle eStyle = ((XFillStyleItem&)(rItemSet.Get(XATTR_FILLSTYLE))).GetValue(); + + // Create own ItemSet and modify as needed + // Always hide lines for special calc shadow + SfxItemSet aSet(rItemSet); + aSet.Put(XLineStyleItem(XLINE_NONE)); + + if(XFILL_HATCH == eStyle) + { + // #41666# Hatch color is set hard to shadow color + XHatch aHatch = ((XFillHatchItem&)(rItemSet.Get(XATTR_FILLHATCH))).GetHatchValue(); + aHatch.SetColor(aShadCol); + aSet.Put(XFillHatchItem(String(),aHatch)); + } + else + { + if(XFILL_NONE != eStyle && XFILL_SOLID != eStyle) + { + // force fill to solid (for Gradient and Bitmap) + aSet.Put(XFillStyleItem(XFILL_SOLID)); + } + + aSet.Put(XFillColorItem(String(),aShadCol)); + aSet.Put(XFillTransparenceItem(nTransp)); + } + + // crete FillAttribute from modified ItemSet + const drawinglayer::attribute::SdrFillAttribute aFill( + drawinglayer::primitive2d::createNewSdrFillAttribute(aSet)); + drawinglayer::primitive2d::Primitive2DReference xSpecialShadow; + + if(!aFill.isDefault() && 1.0 != aFill.getTransparence()) + { + // add shadow offset to object matrix + const sal_uInt32 nXDist(((SdrShadowXDistItem&)(rItemSet.Get(SDRATTR_SHADOWXDIST))).GetValue()); + const sal_uInt32 nYDist(((SdrShadowYDistItem&)(rItemSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); + aObjectMatrix.translate(nXDist, nYDist); + + // create unit outline polygon as geometry (see SdrCaptionPrimitive2D::create2DDecomposition) + basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), fCornerRadiusX, fCornerRadiusY)); + + // create the specialized shadow primitive + xSpecialShadow = drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + aObjectMatrix, + aFill, + drawinglayer::attribute::FillGradientAttribute()); + } + + if(xSpecialShadow.is()) + { + // if we really got a special shadow, create a two-element retval with the shadow + // behind the standard object's geometry + xRetval.realloc(2); + + xRetval[0] = xSpecialShadow; + xRetval[1] = xReference; + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx new file mode 100644 index 000000000000..f6f2f094001b --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * 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/viewcontactofsdrcircobj.hxx> +#include <svx/svdocirc.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrellipseprimitive2d.hxx> +#include <svl/itemset.hxx> +#include <svx/sxciaitm.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrCircObj::ViewContactOfSdrCircObj(SdrCircObj& rCircObj) + : ViewContactOfSdrRectObj(rCircObj) + { + } + + ViewContactOfSdrCircObj::~ViewContactOfSdrCircObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCircObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetCircObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetCircObj().getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetCircObj().GetGeoRect(); + const basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(GetCircObj().GetGeoStat()); + + // fill object matrix + const basegfx::B2DHomMatrix aObjectMatrix( + basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // create primitive data + const sal_uInt16 nIdentifier(GetCircObj().GetObjIdentifier()); + + // always create primitives to allow the decomposition of SdrEllipsePrimitive2D + // or SdrEllipseSegmentPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + if(OBJ_CIRC == nIdentifier) + { + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrEllipsePrimitive2D( + aObjectMatrix, + aAttribute)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + else + { + const sal_Int32 nNewStart(((SdrCircStartAngleItem&)rItemSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue()); + const sal_Int32 nNewEnd(((SdrCircEndAngleItem&)rItemSet.Get(SDRATTR_CIRCENDANGLE)).GetValue()); + const double fStart(((36000 - nNewEnd) % 36000) * F_PI18000); + const double fEnd(((36000 - nNewStart) % 36000) * F_PI18000); + const bool bCloseSegment(OBJ_CARC != nIdentifier); + const bool bCloseUsingCenter(OBJ_SECT == nIdentifier); + + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrEllipseSegmentPrimitive2D( + aObjectMatrix, + aAttribute, + fStart, + fEnd, + bCloseSegment, + bCloseUsingCenter)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx new file mode 100644 index 000000000000..7b4ec93afb38 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * 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/viewcontactofsdredgeobj.hxx> +#include <svx/svdoedge.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrconnectorprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrEdgeObj::ViewContactOfSdrEdgeObj(SdrEdgeObj& rEdgeObj) + : ViewContactOfTextObj(rEdgeObj) + { + } + + ViewContactOfSdrEdgeObj::~ViewContactOfSdrEdgeObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrEdgeObj::createViewIndependentPrimitive2DSequence() const + { + const basegfx::B2DPolygon& rEdgeTrack = GetEdgeObj().getEdgeTrack(); + + // what to do when no EdgeTrack is provided (HitTest and selectability) ? + OSL_ENSURE(0 != rEdgeTrack.count(), "Connectors with no geometry are not allowed (!)"); + + // ckeck attributes + const SfxItemSet& rItemSet = GetEdgeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineShadowTextAttribute( + rItemSet, + GetEdgeObj().getText(0))); + + // create primitive. Always create primitives to allow the decomposition of + // SdrConnectorPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrConnectorPrimitive2D( + aAttribute, + rEdgeTrack)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx new file mode 100644 index 000000000000..9d0d38f688eb --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * 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/viewcontactofsdrmeasureobj.hxx> +#include <svx/svdomeas.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svl/itemset.hxx> +#include <svx/sxmbritm.hxx> +#include <svx/sxmlhitm.hxx> +#include <svx/sxmtritm.hxx> +#include <svx/sxmtaitm.hxx> +#include <svx/sdr/primitive2d/sdrmeasureprimitive2d.hxx> +#include <svx/sxmtpitm.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrMeasureObj::ViewContactOfSdrMeasureObj(SdrMeasureObj& rMeasureObj) + : ViewContactOfTextObj(rMeasureObj) + { + } + + ViewContactOfSdrMeasureObj::~ViewContactOfSdrMeasureObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrMeasureObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetMeasureObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineShadowTextAttribute( + rItemSet, + GetMeasureObj().getText(0))); + + // take properties which are the model data. + const ::basegfx::B2DPoint aStart(GetMeasureObj().GetPoint(0).X(), GetMeasureObj().GetPoint(0).Y()); + const ::basegfx::B2DPoint aEnd(GetMeasureObj().GetPoint(1).X(), GetMeasureObj().GetPoint(1).Y()); + const double fDistance(((SdrMeasureLineDistItem&)rItemSet.Get(SDRATTR_MEASURELINEDIST)).GetValue()); + const double fUpperDistance(((SdrMeasureHelplineOverhangItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue()); + const double fLowerDistance(((SdrMeasureHelplineDistItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINEDIST)).GetValue()); + const double fLeftDelta(((SdrMeasureHelpline1LenItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINE1LEN)).GetValue()); + const double fRightDelta(((SdrMeasureHelpline2LenItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINE2LEN)).GetValue()); + const bool bBelow(((SdrMeasureBelowRefEdgeItem&)rItemSet.Get(SDRATTR_MEASUREBELOWREFEDGE)).GetValue()); + const bool bTextRotation(((SdrMeasureTextRota90Item&)rItemSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue()); + const bool bTextAutoAngle(((SdrMeasureTextAutoAngleItem&)rItemSet.Get(SDRATTR_MEASURETEXTAUTOANGLE)).GetValue()); + drawinglayer::primitive2d::MeasureTextPosition aMTPHor(drawinglayer::primitive2d::MEASURETEXTPOSITION_AUTOMATIC); + drawinglayer::primitive2d::MeasureTextPosition aMTPVer(drawinglayer::primitive2d::MEASURETEXTPOSITION_AUTOMATIC); + + switch(((SdrMeasureTextHPosItem&)rItemSet.Get(SDRATTR_MEASURETEXTHPOS)).GetValue()) + { + case SDRMEASURE_TEXTLEFTOUTSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_NEGATIVE; + break; + } + case SDRMEASURE_TEXTINSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_CENTERED; + break; + } + case SDRMEASURE_TEXTRIGHTOUTSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_POSITIVE; + break; + } + default : // SDRMEASURE_TEXTHAUTO + { + break; + } + } + + switch(((SdrMeasureTextVPosItem&)rItemSet.Get(SDRATTR_MEASURETEXTVPOS)).GetValue()) + { + case SDRMEASURE_ABOVE : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_NEGATIVE; + break; + } + case SDRMEASURETEXT_BREAKEDLINE : + case SDRMEASURETEXT_VERTICALCENTERED : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_CENTERED; + break; + } + case SDRMEASURE_BELOW : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_POSITIVE; + break; + } + default : // SDRMEASURE_TEXTVAUTO + { + break; + } + } + + // create primitive with the model data. Always create primitives to allow the + // decomposition of SdrMeasurePrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrMeasurePrimitive2D( + aAttribute, aStart, aEnd, + aMTPHor, aMTPVer, fDistance, + fUpperDistance, fLowerDistance, + fLeftDelta, fRightDelta, bBelow, + bTextRotation, bTextAutoAngle)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx new file mode 100644 index 000000000000..ab6598840a8e --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * 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/viewcontactofsdrmediaobj.hxx> +#include <svx/svdomedia.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <drawinglayer/primitive2d/mediaprimitive2d.hxx> + +namespace sdr { namespace contact { + +// ---------------------------- +// - ViewContactOfSdrMediaObj - +// ---------------------------- + +ViewContactOfSdrMediaObj::ViewContactOfSdrMediaObj( SdrMediaObj& rMediaObj ) : + ViewContactOfSdrObj( rMediaObj ) +{ +} + +// ------------------------------------------------------------------------------ + +ViewContactOfSdrMediaObj::~ViewContactOfSdrMediaObj() +{ +} + +// ------------------------------------------------------------------------------ + +ViewObjectContact& ViewContactOfSdrMediaObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) +{ + return *( new ViewObjectContactOfSdrMediaObj( rObjectContact, *this, static_cast< SdrMediaObj& >( GetSdrObject() ).getMediaProperties() ) ); +} + +// ------------------------------------------------------------------------------ + +bool ViewContactOfSdrMediaObj::hasPreferredSize() const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + // return true if all have their preferred size + const sal_uInt32 nCount(getViewObjectContactCount()); + bool bRetval(true); + + for(sal_uInt32 a(0); bRetval && a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate && !static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->hasPreferredSize()) + { + bRetval = false; + } + } + + return bRetval; +} + +// ------------------------------------------------------------------------------ + +Size ViewContactOfSdrMediaObj::getPreferredSize() const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + // return first useful size -> the size from the first which is visualized as a window + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + Size aSize(pCandidate ? static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->getPreferredSize() : Size()); + + if(0 != aSize.getWidth() || 0 != aSize.getHeight()) + { + return aSize; + } + } + + return Size(); +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::updateMediaItem( ::avmedia::MediaItem& rItem ) const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate) + { + static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->updateMediaItem(rItem); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::executeMediaItem( const ::avmedia::MediaItem& rItem ) +{ + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate) + { + static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->executeMediaItem(rItem); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewState ) +{ + static_cast< SdrMediaObj& >(GetSdrObject()).mediaPropertiesChanged(rNewState); +} + +}} // end of namespace sdr::contact + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrMediaObj::createViewIndependentPrimitive2DSequence() const + { + // create range using the model data directly. This is in SdrTextObj::aRect which i will access using + // GetGeoRect() to not trigger any calculations. It's the unrotated geometry which is okay for MediaObjects ATM. + const Rectangle& rRectangle(GetSdrMediaObj().GetGeoRect()); + const basegfx::B2DRange aRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aTransform; + aTransform.set(0, 0, aRange.getWidth()); + aTransform.set(1, 1, aRange.getHeight()); + aTransform.set(0, 2, aRange.getMinX()); + aTransform.set(1, 2, aRange.getMinY()); + + // create media primitive. Always create primitives to allow the + // decomposition of MediaPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const basegfx::BColor aBackgroundColor(67.0 / 255.0, 67.0 / 255.0, 67.0 / 255.0); + const rtl::OUString& rURL(GetSdrMediaObj().getURL()); + const sal_uInt32 nPixelBorder(4L); + const drawinglayer::primitive2d::Primitive2DReference xRetval( + new drawinglayer::primitive2d::MediaPrimitive2D( + aTransform, rURL, aBackgroundColor, nPixelBorder)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrobj.cxx b/svx/source/sdr/contact/viewcontactofsdrobj.cxx new file mode 100644 index 000000000000..6d609108e580 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrobj.cxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * 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/viewcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrObj(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfSdrObj::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrObj::ViewContactOfSdrObj(SdrObject& rObj) + : ViewContact(), + mrObject(rObj), + meRememberedAnimationKind(SDRTEXTANI_NONE) + { + // init AnimationKind + if(GetSdrObject().ISA(SdrTextObj)) + { + SdrTextObj& rTextObj = (SdrTextObj&)GetSdrObject(); + meRememberedAnimationKind = rTextObj.GetTextAniKind(); + } + } + + ViewContactOfSdrObj::~ViewContactOfSdrObj() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfSdrObj::GetObjectCount() const + { + if(GetSdrObject().GetSubList()) + { + return GetSdrObject().GetSubList()->GetObjCount(); + } + + return 0L; + } + + ViewContact& ViewContactOfSdrObj::GetViewContact(sal_uInt32 nIndex) const + { + DBG_ASSERT(GetSdrObject().GetSubList(), + "ViewContactOfSdrObj::GetViewContact: Access to non-existent Sub-List (!)"); + SdrObject* pObj = GetSdrObject().GetSubList()->GetObj(nIndex); + DBG_ASSERT(pObj, "ViewContactOfSdrObj::GetViewContact: Corrupt SdrObjList (!)"); + return pObj->GetViewContact(); + } + + ViewContact* ViewContactOfSdrObj::GetParentContact() const + { + ViewContact* pRetval = 0L; + SdrObjList* pObjList = GetSdrObject().GetObjList(); + + if(pObjList) + { + if(pObjList->ISA(SdrPage)) + { + // Is a page + pRetval = &(((SdrPage*)pObjList)->GetViewContact()); + } + else + { + // Is a group? + if(pObjList->GetOwnerObj()) + { + pRetval = &(pObjList->GetOwnerObj()->GetViewContact()); + } + } + } + + return pRetval; + } + + // React on changes of the object of this ViewContact + void ViewContactOfSdrObj::ActionChanged() + { + // look for own changes + if(GetSdrObject().ISA(SdrTextObj)) + { + SdrTextObj& rTextObj = (SdrTextObj&)GetSdrObject(); + + if(rTextObj.GetTextAniKind() != meRememberedAnimationKind) + { + // #i38135# now remember new type + meRememberedAnimationKind = rTextObj.GetTextAniKind(); + } + } + + // call parent + ViewContact::ActionChanged(); + } + + // overload for acessing the SdrObject + SdrObject* ViewContactOfSdrObj::TryToGetSdrObject() const + { + return &GetSdrObject(); + } + + ////////////////////////////////////////////////////////////////////////////// + // primitive stuff + + // add Gluepoints (if available) + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObj::createGluePointPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrGluePointList* pGluePointList = GetSdrObject().GetGluePointList(); + + if(pGluePointList) + { + const sal_uInt32 nCount(pGluePointList->GetCount()); + + if(nCount) + { + // prepare point vector + std::vector< basegfx::B2DPoint > aGluepointVector; + + // create GluePoint primitives. ATM these are relative to the SnapRect + for(sal_uInt32 a(0L); a < nCount; a++) + { + const SdrGluePoint& rCandidate = (*pGluePointList)[(sal_uInt16)a]; + const Point aPosition(rCandidate.GetAbsolutePos(GetSdrObject())); + + aGluepointVector.push_back(basegfx::B2DPoint(aPosition.X(), aPosition.Y())); + } + + if(aGluepointVector.size()) + { + const basegfx::BColor aBackPen(1.0, 1.0, 1.0); + const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::MarkerArrayPrimitive2D( + aGluepointVector, + drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor))); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx new file mode 100644 index 000000000000..6fa63f7c073e --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx @@ -0,0 +1,241 @@ +/************************************************************************* + * + * 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/viewcontactofsdrobjcustomshape.hxx> +#include <svx/svdoashp.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svditer.hxx> +#include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <svx/obj3d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrObjCustomShape::ViewContactOfSdrObjCustomShape(SdrObjCustomShape& rCustomShape) + : ViewContactOfTextObj(rCustomShape) + { + } + + ViewContactOfSdrObjCustomShape::~ViewContactOfSdrObjCustomShape() + { + } + + basegfx::B2DRange ViewContactOfSdrObjCustomShape::getCorrectedTextBoundRect() const + { + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + Rectangle aTextBound(aObjectBound); + GetCustomShapeObj().GetTextBounds(aTextBound); + basegfx::B2DRange aTextRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + + // no need to correct if no extra text range + if(aTextRange != aObjectRange) + { + const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); + + // only correct when rotation and/or shear is used + if(rGeoStat.nShearWink || rGeoStat.nDrehWink ) + { + // text range needs to be corrected by + // aObjectRange.getCenter() - aRotObjectRange.getCenter() since it's + // defined differenly by using rotation around object center. Start + // with positive part + basegfx::B2DVector aTranslation(aObjectRange.getCenter()); + + // get rotated and sheared object's range + basegfx::B2DRange aRotObjectRange(aObjectRange); + basegfx::B2DHomMatrix aRotMatrix; + + aRotMatrix.translate(-aObjectRange.getMinimum().getX(), -aObjectRange.getMinimum().getY()); + + if(rGeoStat.nShearWink) + { + aRotMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aRotMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + aRotMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + aRotObjectRange.transform(aRotMatrix); + + // add negative translation part + aTranslation -= aRotObjectRange.getCenter(); + + // create new range + aTextRange = basegfx::B2DRange( + aTextRange.getMinX() + aTranslation.getX(), aTextRange.getMinY() + aTranslation.getY(), + aTextRange.getMaxX() + aTranslation.getX(), aTextRange.getMaxY() + aTranslation.getY()); + } + } + + return aTextRange; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObjCustomShape::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SfxItemSet& rItemSet = GetCustomShapeObj().GetMergedItemSet(); + + // #i98072# Get shandow and text; eventually suppress the text if it's + // a TextPath FontworkGallery object + const drawinglayer::attribute::SdrShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrShadowTextAttribute( + rItemSet, + GetCustomShapeObj().getText(0), + GetCustomShapeObj().IsTextPath())); + drawinglayer::primitive2d::Primitive2DSequence xGroup; + bool bHasText(!aAttribute.getText().isDefault()); + + // create Primitive2DSequence from sub-geometry + const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape(); + bool b3DShape(false); + + if(pSdrObjRepresentation) + { + SdrObjListIter aIterator(*pSdrObjRepresentation); + + while(aIterator.IsMore()) + { + SdrObject& rCandidate = *aIterator.Next(); + + if(!b3DShape && dynamic_cast< E3dObject* >(&rCandidate)) + { + b3DShape = true; + } + + const drawinglayer::primitive2d::Primitive2DSequence xNew(rCandidate.GetViewContact().getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xGroup, xNew); + } + } + + if(bHasText || xGroup.hasElements()) + { + // prepare text box geometry + basegfx::B2DHomMatrix aTextBoxMatrix; + bool bWordWrap(false); + + if(bHasText) + { + // take unrotated snap rect as default, then get the + // unrotated text box. Rotation needs to be done centered + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + + // #i101684# get the text range unrotated and absolute to the object range + const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); + + // give text object a size + aTextBoxMatrix.scale(aTextRange.getWidth(), aTextRange.getHeight()); + + // check if we have a rotation/shear at all to take care of + const double fExtraTextRotation(GetCustomShapeObj().GetExtraTextRotation()); + const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); + + if(rGeoStat.nShearWink || rGeoStat.nDrehWink || !basegfx::fTools::equalZero(fExtraTextRotation)) + { + if(aObjectRange != aTextRange) + { + // move relative to unrotated object range + aTextBoxMatrix.translate( + aTextRange.getMinX() - aObjectRange.getMinimum().getX(), + aTextRange.getMinY() - aObjectRange.getMinimum().getY()); + } + + if(!basegfx::fTools::equalZero(fExtraTextRotation)) + { + basegfx::B2DVector aTranslation( + ( aTextRange.getWidth() / 2 ) + ( aTextRange.getMinX() - aObjectRange.getMinimum().getX() ), + ( aTextRange.getHeight() / 2 ) + ( aTextRange.getMinY() - aObjectRange.getMinimum().getY() ) ); + aTextBoxMatrix.translate( -aTranslation.getX(), -aTranslation.getY() ); + aTextBoxMatrix.rotate((360.0 - fExtraTextRotation) * F_PI180); + aTextBoxMatrix.translate( aTranslation.getX(), aTranslation.getY() ); + } + + if(rGeoStat.nShearWink) + { + aTextBoxMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aTextBoxMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + // give text it's target position + aTextBoxMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + } + else + { + aTextBoxMatrix.translate(aTextRange.getMinX(), aTextRange.getMinY()); + } + + // check if SdrTextWordWrapItem is set + bWordWrap = ((SdrTextWordWrapItem&)(GetCustomShapeObj().GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue(); + } + + // create primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrCustomShapePrimitive2D( + aAttribute, + xGroup, + aTextBoxMatrix, + bWordWrap, + b3DShape, + false)); // #SJ# New parameter to force to clipped BlockText for SC + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + // always append an invisible outline for the cases where no visible content exists + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange( + aObjectBound.Left(), aObjectBound.Top(), + aObjectBound.Right(), aObjectBound.Bottom()); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectRange)); + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx new file mode 100644 index 000000000000..b88578113c5d --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * 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/viewcontactofsdrole2obj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrole2obj.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrole2primitive2d.hxx> +#include <drawinglayer/primitive2d/graphicprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <svtools/colorcfg.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <vcl/svapp.hxx> +#include <svx/sdr/primitive2d/sdrolecontentprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrOle2Obj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrOle2Obj(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrOle2Obj::ViewContactOfSdrOle2Obj(SdrOle2Obj& rOle2Obj) + : ViewContactOfSdrRectObj(rOle2Obj) + { + } + + ViewContactOfSdrOle2Obj::~ViewContactOfSdrOle2Obj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createPrimitive2DSequenceWithParameters( + bool bHighContrast) const + { + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetOle2Obj().GetGeoRect(); + const basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + // create object matrix + const GeoStat& rGeoStat(GetOle2Obj().GetGeoStat()); + const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); + const double fRotate(rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0); + const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // Prepare attribute settings, will be used soon anyways + const SfxItemSet& rItemSet = GetOle2Obj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetOle2Obj().getText(0))); + + // #i102063# embed OLE content in an own primitive; this will be able to decompose accessing + // the weak SdrOle2 reference and will also implement getB2DRange() for fast BoundRect + // calculations without OLE Graphic access (which may trigger e.g. chart recalculation). + // It will also take care of HighContrast and ScaleContent + const drawinglayer::primitive2d::Primitive2DReference xOleContent( + new drawinglayer::primitive2d::SdrOleContentPrimitive2D( + GetOle2Obj(), + aObjectMatrix, + + // #i104867# add GraphicVersion number to be able to check for + // content change in the primitive later + GetOle2Obj().getEmbeddedObjectRef().getGraphicVersion(), + + bHighContrast)); + + // create primitive. Use Ole2 primitive here. Prepare attribute settings, will + // be used soon anyways. Always create primitives to allow the decomposition of + // SdrOle2Primitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DSequence xOLEContent(&xOleContent, 1); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrOle2Primitive2D( + xOLEContent, + aObjectMatrix, + aAttribute)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createViewIndependentPrimitive2DSequence() const + { + // do as if no HC and call standard creator + return createPrimitive2DSequenceWithParameters(false); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrpage.cxx b/svx/source/sdr/contact/viewcontactofsdrpage.cxx new file mode 100644 index 000000000000..b80b6fcbba88 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrpage.cxx @@ -0,0 +1,693 @@ +/************************************************************************* + * + * 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/viewcontactofsdrpage.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrpage.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <vcl/svapp.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/attribute/sdrfillattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +#define PAPER_SHADOW(SIZE) (SIZE >> 8) + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfPageSubObject::ViewContactOfPageSubObject(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : mrParentViewContactOfSdrPage(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageSubObject::~ViewContactOfPageSubObject() + { + } + + ViewContact* ViewContactOfPageSubObject::GetParentContact() const + { + return &mrParentViewContactOfSdrPage; + } + + const SdrPage& ViewContactOfPageSubObject::getPage() const + { + return mrParentViewContactOfSdrPage.GetSdrPage(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageBackground::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageBackground(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageBackground::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information. Use the + // svtools::DOCCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aInitColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + const basegfx::BColor aRGBColor(aInitColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::BackgroundColorPrimitive2D(aRGBColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfPageBackground::ViewContactOfPageBackground(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageBackground::~ViewContactOfPageBackground() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageShadow::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageShadow(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageShadow::createViewIndependentPrimitive2DSequence() const + { + const SdrPage& rPage = getPage(); + basegfx::B2DHomMatrix aPageMatrix; + aPageMatrix.set(0, 0, (double)rPage.GetWdt()); + aPageMatrix.set(1, 1, (double)rPage.GetHgt()); + + // create page shadow polygon + const double fPageBorderFactor(1.0 / 256.0); + basegfx::B2DPolygon aPageShadowPolygon; + aPageShadowPolygon.append(basegfx::B2DPoint(1.0, fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0 + fPageBorderFactor, fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0 + fPageBorderFactor, 1.0 + fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(fPageBorderFactor, 1.0 + fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(fPageBorderFactor, 1.0)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0, 1.0)); + aPageShadowPolygon.setClosed(true); + aPageShadowPolygon.transform(aPageMatrix); + + // We have only the page information, not the view information. Use the + // svtools::FONTCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aShadowColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor); + const basegfx::BColor aRGBShadowColor(aShadowColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPageShadowPolygon), aRGBShadowColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfPageShadow::ViewContactOfPageShadow(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageShadow::~ViewContactOfPageShadow() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfMasterPage::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfMasterPage(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfMasterPage::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // this class is used when the page is a MasterPage and is responsible to + // create a visualisation for the MPBGO, if exists. This needs to be suppressed + // when a SdrPage which uses a MasterPage creates it's output. Suppression + // is done in the corresponding VOC since DisplayInfo data is needed + const SdrPage& rPage = getPage(); + + if(rPage.IsMasterPage()) + { + if(0 == rPage.GetPageNum()) + { + // #i98063# + // filter MasterPage 0 since it's the HandoutPage. Thus, it's a + // MasterPage, but has no MPBGO, so there is nothing to do here. + } + else + { + drawinglayer::attribute::SdrFillAttribute aFill; + + // #i110846# Suppress SdrPage FillStyle for MasterPages without StyleSheets, + // else the PoolDefault (XFILL_COLOR and Blue8) will be used. Normally, all + // MasterPages should have a StyleSheet excactly for this reason, but historically + // e.g. the Notes MasterPage has no StyleSheet set (and there maybe others). + if(rPage.getSdrPageProperties().GetStyleSheet()) + { + // create page fill attributes with correct properties + aFill = drawinglayer::primitive2d::createNewSdrFillAttribute( + rPage.getSdrPageProperties().GetItemSet()); + } + + if(!aFill.isDefault()) + { + // direct model data is the page size, get and use it + const basegfx::B2DRange aInnerRange( + rPage.GetLftBorder(), rPage.GetUppBorder(), + rPage.GetWdt() - rPage.GetRgtBorder(), rPage.GetHgt() - rPage.GetLwrBorder()); + const basegfx::B2DPolygon aInnerPolgon(basegfx::tools::createPolygonFromRect(aInnerRange)); + const basegfx::B2DHomMatrix aEmptyTransform; + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aInnerPolgon), + aEmptyTransform, + aFill, + drawinglayer::attribute::FillGradientAttribute())); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } + + return xRetval; + } + + ViewContactOfMasterPage::ViewContactOfMasterPage(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfMasterPage::~ViewContactOfMasterPage() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageFill::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageFill(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageFill::createViewIndependentPrimitive2DSequence() const + { + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageFillRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + const basegfx::B2DPolygon aPageFillPolygon(basegfx::tools::createPolygonFromRect(aPageFillRange)); + + // We have only the page information, not the view information. Use the + // svtools::DOCCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aPageFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + + // create and add primitive + const basegfx::BColor aRGBColor(aPageFillColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPageFillPolygon), aRGBColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfPageFill::ViewContactOfPageFill(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageFill::~ViewContactOfPageFill() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfOuterPageBorder::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfOuterPageBorder(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfOuterPageBorder::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageBorderRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + + // We have only the page information, not the view information. Use the + // svtools::FONTCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aBorderColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor); + const basegfx::BColor aRGBBorderColor(aBorderColor.getBColor()); + + if(rPage.getPageBorderOnlyLeftRight()) + { + // #i93597# for Report Designer, the page border shall be only displayed right and left, + // but not top and bottom. Create simplified geometry. + basegfx::B2DPolygon aLeft, aRight; + + aLeft.append(basegfx::B2DPoint(aPageBorderRange.getMinX(), aPageBorderRange.getMinY())); + aLeft.append(basegfx::B2DPoint(aPageBorderRange.getMinX(), aPageBorderRange.getMaxY())); + + aRight.append(basegfx::B2DPoint(aPageBorderRange.getMaxX(), aPageBorderRange.getMinY())); + aRight.append(basegfx::B2DPoint(aPageBorderRange.getMaxX(), aPageBorderRange.getMaxY())); + + xRetval.realloc(2); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aLeft, aRGBBorderColor)); + xRetval[1] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aRight, aRGBBorderColor)); + } + else + { + xRetval.realloc(1); + const basegfx::B2DPolygon aPageBorderPolygon(basegfx::tools::createPolygonFromRect(aPageBorderRange)); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aPageBorderPolygon, aRGBBorderColor)); + } + + return xRetval; + } + + ViewContactOfOuterPageBorder::ViewContactOfOuterPageBorder(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfOuterPageBorder::~ViewContactOfOuterPageBorder() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfInnerPageBorder::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfInnerPageBorder(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfInnerPageBorder::createViewIndependentPrimitive2DSequence() const + { + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageBorderRange( + (double)rPage.GetLftBorder(), (double)rPage.GetUppBorder(), + (double)(rPage.GetWdt() - rPage.GetRgtBorder()), (double)(rPage.GetHgt() - rPage.GetLwrBorder())); + const basegfx::B2DPolygon aPageBorderPolygon(basegfx::tools::createPolygonFromRect(aPageBorderRange)); + + // We have only the page information, not the view information. Use the + // svtools::FONTCOLOR or svtools::DOCBOUNDARIES color for initialisation + const svtools::ColorConfig aColorConfig; + Color aBorderColor; + + if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) + { + aBorderColor = aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor; + } + else + { + aBorderColor = aColorConfig.GetColorValue(svtools::DOCBOUNDARIES).nColor; + } + + // create page outer border primitive + const basegfx::BColor aRGBBorderColor(aBorderColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aPageBorderPolygon, aRGBBorderColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfInnerPageBorder::ViewContactOfInnerPageBorder(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfInnerPageBorder::~ViewContactOfInnerPageBorder() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageHierarchy::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageHierarchy(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageHierarchy::createViewIndependentPrimitive2DSequence() const + { + // collect sub-hierarchy + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nObjectCount(GetObjectCount()); + + // collect all sub-primitives + for(sal_uInt32 a(0); a < nObjectCount; a++) + { + const ViewContact& rCandidate(GetViewContact(a)); + const drawinglayer::primitive2d::Primitive2DSequence aCandSeq(rCandidate.getViewIndependentPrimitive2DSequence()); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, aCandSeq); + } + + return xRetval; + } + + ViewContactOfPageHierarchy::ViewContactOfPageHierarchy(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageHierarchy::~ViewContactOfPageHierarchy() + { + } + + sal_uInt32 ViewContactOfPageHierarchy::GetObjectCount() const + { + return getPage().GetObjCount(); + } + + ViewContact& ViewContactOfPageHierarchy::GetViewContact(sal_uInt32 nIndex) const + { + SdrObject* pObj = getPage().GetObj(nIndex); + DBG_ASSERT(pObj, "ViewContactOfPageHierarchy::GetViewContact: Corrupt SdrObjList (!)"); + return pObj->GetViewContact(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfGrid::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageGrid(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGrid::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information and thus no grid settings. Create empty + // default. For the view-dependent implementation, see ViewObjectContactOfPageGrid::createPrimitive2DSequence + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + ViewContactOfGrid::ViewContactOfGrid(ViewContactOfSdrPage& rParentViewContactOfSdrPage, bool bFront) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage), + mbFront(bFront) + { + } + + ViewContactOfGrid::~ViewContactOfGrid() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfHelplines::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageHelplines(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfHelplines::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information and thus no helplines. Create empty + // default. For the view-dependent implementation, see ViewObjectContactOfPageHelplines::createPrimitive2DSequence + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + ViewContactOfHelplines::ViewContactOfHelplines(ViewContactOfSdrPage& rParentViewContactOfSdrPage, bool bFront) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage), + mbFront(bFront) + { + } + + ViewContactOfHelplines::~ViewContactOfHelplines() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrPage::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrPage(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrPage::ViewContactOfSdrPage(SdrPage& rPage) + : ViewContact(), + mrPage(rPage), + maViewContactOfPageBackground(*this), + maViewContactOfPageShadow(*this), + maViewContactOfPageFill(*this), + maViewContactOfMasterPage(*this), + maViewContactOfOuterPageBorder(*this), + maViewContactOfInnerPageBorder(*this), + maViewContactOfGridBack(*this, false), + maViewContactOfHelplinesBack(*this, false), + maViewContactOfPageHierarchy(*this), + maViewContactOfGridFront(*this, true), + maViewContactOfHelplinesFront(*this, true) + { + } + + ViewContactOfSdrPage::~ViewContactOfSdrPage() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfSdrPage::GetObjectCount() const + { + // Fixed count of content. It contains PageBackground (Wiese), PageShadow, PageFill, + // then - depending on if the page has a MasterPage - either MasterPage Hierarchy + // or MPBGO. Also OuterPageBorder, InnerPageBorder and two pairs of Grid and Helplines + // (for front and back) which internally are visible or not depending on the current + // front/back setting for those. + return 11; + } + + ViewContact& ViewContactOfSdrPage::GetViewContact(sal_uInt32 nIndex) const + { + switch(nIndex) + { + case 0: return (ViewContact&)maViewContactOfPageBackground; + case 1: return (ViewContact&)maViewContactOfPageShadow; + case 2: return (ViewContact&)maViewContactOfPageFill; + case 3: + { + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + return rPage.TRG_GetMasterPageDescriptorViewContact(); + } + else + { + return (ViewContact&)maViewContactOfMasterPage; + } + } + case 4: return (ViewContact&)maViewContactOfOuterPageBorder; + case 5: return (ViewContact&)maViewContactOfInnerPageBorder; + case 6: return (ViewContact&)maViewContactOfGridBack; + case 7: return (ViewContact&)maViewContactOfHelplinesBack; + case 8: return (ViewContact&)maViewContactOfPageHierarchy; + case 9: return (ViewContact&)maViewContactOfGridFront; + default: return (ViewContact&)maViewContactOfHelplinesFront; + } + } + + // React on changes of the object of this ViewContact + void ViewContactOfSdrPage::ActionChanged() + { + // call parent + ViewContact::ActionChanged(); + + // apply to local viewContacts, they all rely on page information. Exception + // is the sub hierarchy; this will not be influenced by the change + maViewContactOfPageBackground.ActionChanged(); + maViewContactOfPageShadow.ActionChanged(); + maViewContactOfPageFill.ActionChanged(); + + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + rPage.TRG_GetMasterPageDescriptorViewContact().ActionChanged(); + } + else if(rPage.IsMasterPage()) + { + maViewContactOfMasterPage.ActionChanged(); + } + + maViewContactOfOuterPageBorder.ActionChanged(); + maViewContactOfInnerPageBorder.ActionChanged(); + maViewContactOfGridBack.ActionChanged(); + maViewContactOfHelplinesBack.ActionChanged(); + maViewContactOfGridFront.ActionChanged(); + maViewContactOfHelplinesFront.ActionChanged(); + } + + // overload for acessing the SdrPage + SdrPage* ViewContactOfSdrPage::TryToGetSdrPage() const + { + return &GetSdrPage(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPage::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // collect all sub-sequences including sub hierarchy. + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageBackground.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageShadow.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageFill.getViewIndependentPrimitive2DSequence()); + + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + rPage.TRG_GetMasterPageDescriptorViewContact().getViewIndependentPrimitive2DSequence()); + } + else if(rPage.IsMasterPage()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + maViewContactOfMasterPage.getViewIndependentPrimitive2DSequence()); + } + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfOuterPageBorder.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfInnerPageBorder.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageHierarchy.getViewIndependentPrimitive2DSequence()); + + // Only add front versions of grid and helplines since no visibility test is done, + // so adding the back incarnations is not necessary. This makes the Front + // visualisation the default when no visibility tests are done. + // + // Since we have no view here, no grid and helpline definitions are available currently. The used + // methods at ViewContactOfHelplines and ViewContactOfGrid return only empty sequences and + // do not need to be called ATM. This may change later if grid or helpline info gets + // model data (it should not). Keeping the lines commented to hold this hint. + // + // drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfGridFront.getViewIndependentPrimitive2DSequence()); + // drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfHelplinesFront.getViewIndependentPrimitive2DSequence()); + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx new file mode 100644 index 000000000000..bc4c500ff155 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * 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/viewcontactofsdrpathobj.hxx> +#include <svx/svdopath.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrPathObj::ViewContactOfSdrPathObj(SdrPathObj& rPathObj) + : ViewContactOfTextObj(rPathObj) + { + } + + ViewContactOfSdrPathObj::~ViewContactOfSdrPathObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPathObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetPathObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetPathObj().getText(0))); + basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); + sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); + sal_uInt32 nPointCount(0); + + for(sal_uInt32 a(0); a < nPolyCount; a++) + { + nPointCount += aUnitPolyPolygon.getB2DPolygon(a).count(); + } + + if(!nPointCount) + { + OSL_ENSURE(false, "PolyPolygon object without geometry detected, this should not be created (!)"); + basegfx::B2DPolygon aFallbackLine; + aFallbackLine.append(basegfx::B2DPoint(0.0, 0.0)); + aFallbackLine.append(basegfx::B2DPoint(1000.0, 1000.0)); + aUnitPolyPolygon = basegfx::B2DPolyPolygon(aFallbackLine); + + nPolyCount = 1; + } + + // prepare object transformation and unit polygon (direct model data) + basegfx::B2DHomMatrix aObjectMatrix; + const bool bIsLine( + !aUnitPolyPolygon.areControlPointsUsed() + && 1 == nPolyCount + && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); + + if(bIsLine) + { + // special handling for single line mode (2 points) + const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); + const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0)); + const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1)); + const basegfx::B2DVector aLine(aEnd - aStart); + + // #i102548# create new unit polygon for line (horizontal) + basegfx::B2DPolygon aNewPolygon; + aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0)); + aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0)); + aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon); + + // #i102548# fill objectMatrix with rotation and offset (no shear for lines) + aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aLine.getLength(), 1.0, + 0.0, + atan2(aLine.getY(), aLine.getX()), + aStart.getX(), aStart.getY()); + } + else + { + // #i102548# create unscaled, unsheared, unrotated and untranslated polygon + // (unit polygon) by creating the object matrix and back-transforming the polygon + const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon)); + const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); + const double fWidth(aObjectRange.getWidth()); + const double fHeight(aObjectRange.getHeight()); + const double fScaleX(basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth); + const double fScaleY(basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight); + + aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + fScaleX, fScaleY, + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY()); + + // ceate unit polygon from object's absolute path + basegfx::B2DHomMatrix aInverse(aObjectMatrix); + aInverse.invert(); + aUnitPolyPolygon.transform(aInverse); + } + + // create primitive. Always create primitives to allow the decomposition of + // SdrPathPrimitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrPathPrimitive2D( + aObjectMatrix, + aAttribute, + aUnitPolyPolygon)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx new file mode 100644 index 000000000000..fdbfa16dd584 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * 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/viewcontactofsdrrectobj.hxx> +#include <svx/svdorect.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx> +#include <svl/itemset.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <svx/svdmodel.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrRectObj::ViewContactOfSdrRectObj(SdrRectObj& rRectObj) + : ViewContactOfTextObj(rRectObj) + { + } + + ViewContactOfSdrRectObj::~ViewContactOfSdrRectObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrRectObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetRectObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetRectObj().getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetRectObj().GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(GetRectObj().GetGeoStat()); + + // fill object matrix + basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // calculate corner radius + sal_uInt32 nCornerRadius(((SdrEckenradiusItem&)(rItemSet.Get(SDRATTR_ECKENRADIUS))).GetValue()); + double fCornerRadiusX; + double fCornerRadiusY; + drawinglayer::primitive2d::calculateRelativeCornerRadius(nCornerRadius, aObjectRange, fCornerRadiusX, fCornerRadiusY); + + // #i105856# use knowledge about pickthrough from the model + const bool bPickThroughTransparentTextFrames( + GetRectObj().GetModel() && GetRectObj().GetModel()->IsPickThroughTransparentTextFrames()); + + // create primitive. Always create primitives to allow the decomposition of + // SdrRectanglePrimitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrRectanglePrimitive2D( + aObjectMatrix, + aAttribute, + fCornerRadiusX, + fCornerRadiusY, + // #i105856# use fill for HitTest when TextFrame and not PickThrough + GetRectObj().IsTextFrame() && !bPickThroughTransparentTextFrames)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactoftextobj.cxx b/svx/source/sdr/contact/viewcontactoftextobj.cxx new file mode 100644 index 000000000000..bfa7aa41565c --- /dev/null +++ b/svx/source/sdr/contact/viewcontactoftextobj.cxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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/viewcontactoftextobj.hxx> +#include <svx/svdotext.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfTextObj::ViewContactOfTextObj(SdrTextObj& rTextObj) + : ViewContactOfSdrObj(rTextObj) + { + } + + ViewContactOfTextObj::~ViewContactOfTextObj() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofunocontrol.cxx b/svx/source/sdr/contact/viewcontactofunocontrol.cxx new file mode 100644 index 000000000000..2a4d527fdcdd --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofunocontrol.cxx @@ -0,0 +1,181 @@ +/************************************************************************* + * + * 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 <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdrpagewindow.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/XWindow2.hpp> +/** === end UNO includes === **/ + +#include "sdrpaintwindow.hxx" +#include <tools/diagnose_ex.h> +#include <vcl/pdfextoutdevdata.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/controlprimitive2d.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +//........................................................................ +namespace sdr { namespace contact { +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::awt::XControl; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::awt::XControlContainer; + using ::com::sun::star::awt::XControlModel; + using ::com::sun::star::awt::XWindow2; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::Exception; + /** === end UNO using === **/ + + //==================================================================== + //= ViewContactOfUnoControl + //==================================================================== + class ViewContactOfUnoControl_Impl + { + public: + ViewContactOfUnoControl_Impl(); + ~ViewContactOfUnoControl_Impl(); + + private: + ViewContactOfUnoControl_Impl( const ViewContactOfUnoControl_Impl& ); // never implemented + ViewContactOfUnoControl_Impl& operator=( const ViewContactOfUnoControl_Impl& ); // never implemented + }; + + //-------------------------------------------------------------------- + ViewContactOfUnoControl_Impl::ViewContactOfUnoControl_Impl() + { + } + + //-------------------------------------------------------------------- + ViewContactOfUnoControl_Impl::~ViewContactOfUnoControl_Impl() + { + } + + //==================================================================== + //= ViewContactOfUnoControl + //==================================================================== + DBG_NAME( ViewContactOfUnoControl ) + //-------------------------------------------------------------------- + ViewContactOfUnoControl::ViewContactOfUnoControl( SdrUnoObj& _rUnoObject ) + :ViewContactOfSdrObj( _rUnoObject ) + ,m_pImpl( new ViewContactOfUnoControl_Impl ) + { + DBG_CTOR( ViewContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + ViewContactOfUnoControl::~ViewContactOfUnoControl() + { + DBG_DTOR( ViewContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewContactOfUnoControl::getTemporaryControlForWindow( + const Window& _rWindow, Reference< XControlContainer >& _inout_ControlContainer ) const + { + SdrUnoObj* pUnoObject = dynamic_cast< SdrUnoObj* >( TryToGetSdrObject() ); + OSL_ENSURE( pUnoObject, "ViewContactOfUnoControl::getTemporaryControlForDevice: no SdrUnoObj!" ); + if ( !pUnoObject ) + return NULL; + return ViewObjectContactOfUnoControl::getTemporaryControlForWindow( _rWindow, _inout_ControlContainer, *pUnoObject ); + } + + //-------------------------------------------------------------------- + ViewObjectContact& ViewContactOfUnoControl::CreateObjectSpecificViewObjectContact( ObjectContact& _rObjectContact ) + { + // print or print preview requires special handling + const OutputDevice* pDevice = _rObjectContact.TryToGetOutputDevice(); + bool bPrintOrPreview = ( pDevice != NULL ) && ( pDevice->GetOutDevType() == OUTDEV_PRINTER ); + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &_rObjectContact ); + bPrintOrPreview |= ( pPageViewContact != NULL ) && pPageViewContact->GetPageWindow().GetPageView().GetView().IsPrintPreview(); + + if ( bPrintOrPreview ) + return *new UnoControlPrintOrPreviewContact( *pPageViewContact, *this ); + + // all others are nowadays served by the same implementation + return *new ViewObjectContactOfUnoControl( _rObjectContact, *this ); + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfUnoControl::createViewIndependentPrimitive2DSequence() const + { + // create range. Use model data directly, not getBoundRect()/getSnapRect; these will use + // the primitive data themselves in the long run. Use SdrUnoObj's (which is a SdrRectObj) + // call to GetGeoRect() to access SdrTextObj::aRect directly and without executing anything + const Rectangle& rRectangle(GetSdrUnoObj().GetGeoRect()); + const basegfx::B2DRange aRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aTransform; + + aTransform.set(0, 0, aRange.getWidth()); + aTransform.set(1, 1, aRange.getHeight()); + aTransform.set(0, 2, aRange.getMinX()); + aTransform.set(1, 2, aRange.getMinY()); + + Reference< XControlModel > xControlModel = GetSdrUnoObj().GetUnoControlModel(); + + if(xControlModel.is()) + { + // create control primitive WITHOUT possibly existing XControl; this would be done in + // the VOC in createPrimitive2DSequence() + const drawinglayer::primitive2d::Primitive2DReference xRetval( + new drawinglayer::primitive2d::ControlPrimitive2D( + aTransform, + xControlModel)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + else + { + // always append an invisible outline for the cases where no visible content exists + const drawinglayer::primitive2d::Primitive2DReference xRetval( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aTransform)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + } + +//........................................................................ +} } // namespace sdr::contact +//........................................................................ diff --git a/svx/source/sdr/contact/viewcontactofvirtobj.cxx b/svx/source/sdr/contact/viewcontactofvirtobj.cxx new file mode 100644 index 000000000000..54d7e6ddae97 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofvirtobj.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * 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/viewcontactofvirtobj.hxx> +#include <svx/svdovirt.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <vcl/outdev.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + SdrVirtObj& ViewContactOfVirtObj::GetVirtObj() const + { + return (SdrVirtObj&)mrObject; + } + + ViewContactOfVirtObj::ViewContactOfVirtObj(SdrVirtObj& rObj) + : ViewContactOfSdrObj(rObj) + { + } + + ViewContactOfVirtObj::~ViewContactOfVirtObj() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfVirtObj::GetObjectCount() const + { + // Here, SdrVirtObj's need to return 0L to show that they have no + // sub-hierarchy, even when they are group objects. This is necessary + // to avoid that the same VOCs will be added to the draw hierarchy + // twice which leads to problems. + // + // This solution is only a first solution to get things running. Later + // this needs to be replaced with creating real VOCs for the objects + // referenced by virtual objects to avoid the 'trick' of setting the + // offset for painting at the destination OutputDevive. + // + // As can be seen, with primitives, the problem will be solved using + // a transformPrimitive, so this solution can stay with primitives. + return 0L; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfVirtObj::createViewIndependentPrimitive2DSequence() const + { + // create displacement transformation if we have content + basegfx::B2DHomMatrix aObjectMatrix; + Point aAnchor(GetVirtObj().GetAnchorPos()); + + if(aAnchor.X() || aAnchor.Y()) + { + aObjectMatrix.set(0, 2, aAnchor.X()); + aObjectMatrix.set(1, 2, aAnchor.Y()); + } + + // use method from referenced object to get the Primitive2DSequence + const drawinglayer::primitive2d::Primitive2DSequence xSequenceVirtual( + GetVirtObj().GetReferencedObj().GetViewContact().getViewIndependentPrimitive2DSequence()); + + if(xSequenceVirtual.hasElements()) + { + // create transform primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::TransformPrimitive2D( + aObjectMatrix, + xSequenceVirtual)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + else + { + // always append an invisible outline for the cases where no visible content exists + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectMatrix)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx new file mode 100644 index 000000000000..73e4c12e5066 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -0,0 +1,438 @@ +/************************************************************************* + * + * 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/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/region.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/animation/animationstate.hxx> +#include <svx/sdr/contact/viewobjectcontactredirector.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/primitive2d/animatedprimitive2d.hxx> +#include <drawinglayer/processor2d/baseprocessor2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/sdr/contact/viewobjectcontactredirector.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // animated extractor + + // Necessary to filter a sequence of animated primitives from + // a sequence of primitives to find out if animated or not. The decision for + // what to decompose is hard-coded and only done for knowingly animated primitives + // to not decompose too deeply and unnecessarily. This implies that the list + // which is view-specific needs to be expanded by hand when new animated objects + // are added. This may eventually be changed to a dynamically configurable approach + // if necessary. + class AnimatedExtractingProcessor2D : public drawinglayer::processor2d::BaseProcessor2D + { + protected: + // the found animated primitives + drawinglayer::primitive2d::Primitive2DSequence maPrimitive2DSequence; + + // bitfield + // text animation allowed? + unsigned mbTextAnimationAllowed : 1; + + // graphic animation allowed? + unsigned mbGraphicAnimationAllowed : 1; + + // as tooling, the process() implementation takes over API handling and calls this + // virtual render method when the primitive implementation is BasePrimitive2D-based. + virtual void processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate); + + public: + AnimatedExtractingProcessor2D( + const drawinglayer::geometry::ViewInformation2D& rViewInformation, + bool bTextAnimationAllowed, + bool bGraphicAnimationAllowed); + virtual ~AnimatedExtractingProcessor2D(); + + // data access + const drawinglayer::primitive2d::Primitive2DSequence& getPrimitive2DSequence() const { return maPrimitive2DSequence; } + bool isTextAnimationAllowed() const { return mbTextAnimationAllowed; } + bool isGraphicAnimationAllowed() const { return mbGraphicAnimationAllowed; } + }; + + AnimatedExtractingProcessor2D::AnimatedExtractingProcessor2D( + const drawinglayer::geometry::ViewInformation2D& rViewInformation, + bool bTextAnimationAllowed, + bool bGraphicAnimationAllowed) + : drawinglayer::processor2d::BaseProcessor2D(rViewInformation), + maPrimitive2DSequence(), + mbTextAnimationAllowed(bTextAnimationAllowed), + mbGraphicAnimationAllowed(bGraphicAnimationAllowed) + { + } + + AnimatedExtractingProcessor2D::~AnimatedExtractingProcessor2D() + { + } + + void AnimatedExtractingProcessor2D::processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate) + { + // known implementation, access directly + switch(rCandidate.getPrimitive2DID()) + { + // add and accept animated primitives directly, no need to decompose + case PRIMITIVE2D_ID_ANIMATEDSWITCHPRIMITIVE2D : + case PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D : + case PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D : + { + const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& rSwitchPrimitive = static_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& >(rCandidate); + + if((rSwitchPrimitive.isTextAnimation() && isTextAnimationAllowed()) + || (rSwitchPrimitive.isGraphicAnimation() && isGraphicAnimationAllowed())) + { + const drawinglayer::primitive2d::Primitive2DReference xReference(const_cast< drawinglayer::primitive2d::BasePrimitive2D* >(&rCandidate)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(maPrimitive2DSequence, xReference); + } + break; + } + + // decompose animated gifs where SdrGrafPrimitive2D produces a GraphicPrimitive2D + // which then produces the animation infos (all when used/needed) + case PRIMITIVE2D_ID_SDRGRAFPRIMITIVE2D : + case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D : + + // decompose SdrObjects with evtl. animated text + case PRIMITIVE2D_ID_SDRCAPTIONPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRCONNECTORPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRCUSTOMSHAPEPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRELLIPSEPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRELLIPSESEGMENTPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRMEASUREPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRPATHPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D : + + // decompose evtl. animated text contained in MaskPrimitive2D + // or group rimitives + case PRIMITIVE2D_ID_MASKPRIMITIVE2D : + case PRIMITIVE2D_ID_GROUPPRIMITIVE2D : + { + process(rCandidate.get2DDecomposition(getViewInformation2D())); + break; + } + + default : + { + // nothing to do for the rest + break; + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact) + : mrObjectContact(rObjectContact), + mrViewContact(rViewContact), + maObjectRange(), + mxPrimitive2DSequence(), + mpPrimitiveAnimation(0), + mbLazyInvalidate(false) + { + // make the ViewContact remember me + mrViewContact.AddViewObjectContact(*this); + + // make the ObjectContact remember me + mrObjectContact.AddViewObjectContact(*this); + } + + ViewObjectContact::~ViewObjectContact() + { + // invalidate in view + if(!maObjectRange.isEmpty()) + { + GetObjectContact().InvalidatePartOfView(maObjectRange); + } + + // delete PrimitiveAnimation + if(mpPrimitiveAnimation) + { + delete mpPrimitiveAnimation; + mpPrimitiveAnimation = 0; + } + + // take care of remebered ObjectContact. Remove from + // OC first. The VC removal (below) CAN trigger a StopGettingViewed() + // which (depending of it's implementation) may destroy other OCs. This + // can trigger the deletion of the helper OC of a page visualising object + // which IS the OC of this object. Eventually StopGettingViewed() needs + // to get asynchron later + GetObjectContact().RemoveViewObjectContact(*this); + + // take care of remebered ViewContact + GetViewContact().RemoveViewObjectContact(*this); + } + + const basegfx::B2DRange& ViewObjectContact::getObjectRange() const + { + if(maObjectRange.isEmpty()) + { + // if range is not computed (new or LazyInvalidate objects), force it + const DisplayInfo aDisplayInfo; + const drawinglayer::primitive2d::Primitive2DSequence xSequence(getPrimitive2DSequence(aDisplayInfo)); + + if(xSequence.hasElements()) + { + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const_cast< ViewObjectContact* >(this)->maObjectRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xSequence, rViewInformation2D); + } + } + + return maObjectRange; + } + + void ViewObjectContact::ActionChanged() + { + if(!mbLazyInvalidate) + { + // set local flag + mbLazyInvalidate = true; + + // force ObjectRange + getObjectRange(); + + if(!maObjectRange.isEmpty()) + { + // invalidate current valid range + GetObjectContact().InvalidatePartOfView(maObjectRange); + + // reset ObjectRange, it needs to be recalculated + maObjectRange.reset(); + } + + // register at OC for lazy invalidate + GetObjectContact().setLazyInvalidate(*this); + } + } + + void ViewObjectContact::triggerLazyInvalidate() + { + if(mbLazyInvalidate) + { + // reset flag + mbLazyInvalidate = false; + + // force ObjectRange + getObjectRange(); + + if(!maObjectRange.isEmpty()) + { + // invalidate current valid range + GetObjectContact().InvalidatePartOfView(maObjectRange); + } + } + } + + // Take some action when new objects are inserted + void ViewObjectContact::ActionChildInserted(ViewContact& rChild) + { + // force creation of the new VOC and trigger it's refresh, so it + // will take part in LazyInvalidate immediately + rChild.GetViewObjectContact(GetObjectContact()).ActionChanged(); + + // forward action to ObjectContact + // const ViewObjectContact& rChildVOC = rChild.GetViewObjectContact(GetObjectContact()); + // GetObjectContact().InvalidatePartOfView(rChildVOC.getObjectRange()); + } + + void ViewObjectContact::checkForPrimitive2DAnimations() + { + // remove old one + if(mpPrimitiveAnimation) + { + delete mpPrimitiveAnimation; + mpPrimitiveAnimation = 0; + } + + // check for animated primitives + if(mxPrimitive2DSequence.hasElements()) + { + const bool bTextAnimationAllowed(GetObjectContact().IsTextAnimationAllowed()); + const bool bGraphicAnimationAllowed(GetObjectContact().IsGraphicAnimationAllowed()); + + if(bTextAnimationAllowed || bGraphicAnimationAllowed) + { + AnimatedExtractingProcessor2D aAnimatedExtractor(GetObjectContact().getViewInformation2D(), + bTextAnimationAllowed, bGraphicAnimationAllowed); + aAnimatedExtractor.process(mxPrimitive2DSequence); + + if(aAnimatedExtractor.getPrimitive2DSequence().hasElements()) + { + // dervied primitiveList is animated, setup new PrimitiveAnimation + mpPrimitiveAnimation = new sdr::animation::PrimitiveAnimation(*this, aAnimatedExtractor.getPrimitive2DSequence()); + } + } + } + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // get the view-independent Primitive from the viewContact + drawinglayer::primitive2d::Primitive2DSequence xRetval(GetViewContact().getViewIndependentPrimitive2DSequence()); + + if(xRetval.hasElements()) + { + // handle GluePoint + if(!GetObjectContact().isOutputToPrinter() && GetObjectContact().AreGluePointsVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence xGlue(GetViewContact().createGluePointPrimitive2DSequence()); + + if(xGlue.hasElements()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xGlue); + } + } + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ModifiedColorPrimitive2D(xRetval, aBColorModifier)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xNewPrimitiveSequence; + + // take care of redirectors and create new list + ViewObjectContactRedirector* pRedirector = GetObjectContact().GetViewObjectContactRedirector(); + + if(pRedirector) + { + xNewPrimitiveSequence = pRedirector->createRedirectedPrimitive2DSequence(*this, rDisplayInfo); + } + else + { + xNewPrimitiveSequence = createPrimitive2DSequence(rDisplayInfo); + } + + // local up-to-date checks. New list different from local one? + if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxPrimitive2DSequence, xNewPrimitiveSequence)) + { + // has changed, copy content + const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = xNewPrimitiveSequence; + + // check for animated stuff + const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations(); + + // always update object range when PrimitiveSequence changes + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const_cast< ViewObjectContact* >(this)->maObjectRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(mxPrimitive2DSequence, rViewInformation2D); + } + + // return current Primitive2DSequence + return mxPrimitive2DSequence; + } + + bool ViewObjectContact::isPrimitiveVisible(const DisplayInfo& /*rDisplayInfo*/) const + { + // default: always visible + return true; + } + + bool ViewObjectContact::isPrimitiveGhosted(const DisplayInfo& rDisplayInfo) const + { + // default: standard check + return (GetObjectContact().DoVisualizeEnteredGroup() && !GetObjectContact().isOutputToPrinter() && rDisplayInfo.IsGhostedDrawModeActive()); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // check model-view visibility + if(isPrimitiveVisible(rDisplayInfo)) + { + xRetval = getPrimitive2DSequence(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& rDisplayInfo) const + { + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + drawinglayer::primitive2d::Primitive2DSequence xSeqRetval; + + for(sal_uInt32 a(0); a < nSubHierarchyCount; a++) + { + const ViewObjectContact& rCandidate(GetViewContact().GetViewContact(a).GetViewObjectContact(GetObjectContact())); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xSeqRetval, rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + } + + return xSeqRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofe3d.cxx b/svx/source/sdr/contact/viewobjectcontactofe3d.cxx new file mode 100644 index 000000000000..ec8cdb4ef5ba --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofe3d.cxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * 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/viewobjectcontactofe3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx> +#include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> + +////////////////////////////////////////////////////////////////////////////// +// predeclarations + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfE3d::ViewObjectContactOfE3d(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfE3d::~ViewObjectContactOfE3d() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewObjectContactOfE3d::createPrimitive3DSequence(const DisplayInfo& rDisplayInfo) const + { + // get the view-independent Primitive from the viewContact + const ViewContactOfE3d& rViewContactOfE3d(dynamic_cast< const ViewContactOfE3d& >(GetViewContact())); + drawinglayer::primitive3d::Primitive3DSequence xRetval(rViewContactOfE3d.getViewIndependentPrimitive3DSequence()); + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const ::basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const ::basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, ::basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::ModifiedColorPrimitive3D(xRetval, aBColorModifier)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3d::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + const ViewContactOfE3d& rViewContact = static_cast< const ViewContactOfE3d& >(GetViewContact()); + + // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator + return rViewContact.impCreateWithGivenPrimitive3DSequence(getPrimitive3DSequence(rDisplayInfo)); + } + + drawinglayer::primitive3d::Primitive3DSequence ViewObjectContactOfE3d::getPrimitive3DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive3d::Primitive3DSequence xNewPrimitive3DSeq(createPrimitive3DSequence(rDisplayInfo)); + + // local up-to-date checks. New list different from local one? + if(!drawinglayer::primitive3d::arePrimitive3DSequencesEqual(mxPrimitive3DSequence, xNewPrimitive3DSeq)) + { + // has changed, copy content + const_cast< ViewObjectContactOfE3d* >(this)->mxPrimitive3DSequence = xNewPrimitive3DSeq; + } + + // return current Primitive2DSequence + return mxPrimitive3DSequence; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx b/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx new file mode 100644 index 000000000000..a549b1db1233 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * 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/viewobjectcontactofe3dscene.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <basegfx/matrix/b3dhommatrix.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <basegfx/color/bcolormodifier.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3d.hxx> +#include <basegfx/tools/canvastools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // Helper method to recursively travel the DrawHierarchy for 3D objects contained in + // the 2D Scene. This will chreate all VOCs for the currenbt OC which are needed + // for ActionChanged() functionality + void impInternalSubHierarchyTraveller(const sdr::contact::ViewObjectContact& rVOC) + { + const sdr::contact::ViewContact& rVC = rVOC.GetViewContact(); + const sal_uInt32 nSubHierarchyCount(rVC.GetObjectCount()); + + for(sal_uInt32 a(0); a < nSubHierarchyCount; a++) + { + const sdr::contact::ViewObjectContact& rCandidate(rVC.GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact())); + impInternalSubHierarchyTraveller(rCandidate); + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfE3dScene::ViewObjectContactOfE3dScene(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfE3dScene::~ViewObjectContactOfE3dScene() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3dScene::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // handle ghosted, else the whole 3d group will be encapsulated to a ghosted primitive set (see below) + const bool bHandleGhostedDisplay(GetObjectContact().DoVisualizeEnteredGroup() && !GetObjectContact().isOutputToPrinter() && rDisplayInfo.IsGhostedDrawModeActive()); + const bool bIsActiveVC(bHandleGhostedDisplay && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bIsActiveVC) + { + // switch off ghosted, display contents normal + const_cast< DisplayInfo& >(rDisplayInfo).ClearGhostedDrawMode(); + } + + // create 2d primitive with content, use layer visibility test + // this uses no ghosted mode, so scenes in scenes and entering them will not + // support ghosted for now. This is no problem currently but would need to be + // added when sub-groups in 3d will be added one day. + const ViewContactOfE3dScene& rViewContact = dynamic_cast< ViewContactOfE3dScene& >(GetViewContact()); + const SetOfByte& rVisibleLayers = rDisplayInfo.GetProcessLayers(); + drawinglayer::primitive2d::Primitive2DSequence xRetval(rViewContact.createScenePrimitive2DSequence(&rVisibleLayers)); + + if(xRetval.hasElements()) + { + // handle GluePoint + if(!GetObjectContact().isOutputToPrinter() && GetObjectContact().AreGluePointsVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence xGlue(GetViewContact().createGluePointPrimitive2DSequence()); + + if(xGlue.hasElements()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xGlue); + } + } + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const ::basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const ::basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, ::basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ModifiedColorPrimitive2D(xRetval, aBColorModifier)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + if(bIsActiveVC) + { + // set back, display ghosted again + const_cast< DisplayInfo& >(rDisplayInfo).SetGhostedDrawMode(); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3dScene::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + // To get the VOCs for the contained 3D objects created to get the correct + // Draw hierarchy and ActionChanged() working properly, travel the DrawHierarchy + // using a local tooling method + impInternalSubHierarchyTraveller(*this); + + // call parent + return ViewObjectContactOfSdrObj::getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx new file mode 100644 index 000000000000..cd2d9670bf7c --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * 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/viewobjectcontactofgraphic.hxx> +#include <svx/sdr/contact/viewcontactofgraphic.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <svx/svdograf.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace event + { + class AsynchGraphicLoadingEvent : public BaseEvent + { + // the ViewContactOfGraphic to work with + sdr::contact::ViewObjectContactOfGraphic& mrVOCOfGraphic; + + public: + // basic constructor. + AsynchGraphicLoadingEvent(EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic); + + // destructor + virtual ~AsynchGraphicLoadingEvent(); + + // the called method if the event is triggered + virtual void ExecuteEvent(); + }; + + AsynchGraphicLoadingEvent::AsynchGraphicLoadingEvent( + EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic) + : BaseEvent(rEventHandler), + mrVOCOfGraphic(rVOCOfGraphic) + { + } + + AsynchGraphicLoadingEvent::~AsynchGraphicLoadingEvent() + { + mrVOCOfGraphic.forgetAsynchGraphicLoadingEvent(this); + } + + void AsynchGraphicLoadingEvent::ExecuteEvent() + { + mrVOCOfGraphic.doAsynchGraphicLoading(); + } + } // end of namespace event +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Test graphics state and eventually trigger a SwapIn event or an Asynchronous + // load event. Return value gives info if SwapIn was triggered or not + bool ViewObjectContactOfGraphic::impPrepareGraphicWithAsynchroniousLoading() + { + bool bRetval(false); + SdrGrafObj& rGrafObj = getSdrGrafObj(); + + if(rGrafObj.IsSwappedOut()) + { + if(rGrafObj.IsLinkedGraphic()) + { + // update graphic link + rGrafObj.ImpUpdateGraphicLink(); + } + else + { + // SwapIn needs to be done. Decide if it can be done asynchronious. + bool bSwapInAsynchronious(false); + ObjectContact& rObjectContact = GetObjectContact(); + + // only when allowed from configuration + if(rObjectContact.IsAsynchronGraphicsLoadingAllowed()) + { + // direct output or vdev output (PageView buffering) + if(rObjectContact.isOutputToWindow() || rObjectContact.isOutputToVirtualDevice()) + { + // only when no metafile recording + if(!rObjectContact.isOutputToRecordingMetaFile()) + { + // allow asynchronious loading + bSwapInAsynchronious = true; + } + } + } + + if(bSwapInAsynchronious) + { + // maybe it's on the way, then do nothing + if(!mpAsynchLoadEvent) + { + // Trigger asynchronious SwapIn. + sdr::event::TimerEventHandler& rEventHandler = rObjectContact.GetEventHandler(); + + mpAsynchLoadEvent = new sdr::event::AsynchGraphicLoadingEvent(rEventHandler, *this); + } + } + else + { + if(rObjectContact.isOutputToPrinter()) + { + // #i76395# preview mechanism is only active if + // swapin is called from inside paint preparation, so mbInsidePaint + // has to be false to be able to print with high resolution + rGrafObj.ForceSwapIn(); + } + else + { + // SwapIn direct + rGrafObj.mbInsidePaint = sal_True; + rGrafObj.ForceSwapIn(); + rGrafObj.mbInsidePaint = sal_False; + } + + bRetval = true; + } + } + } + else + { + // it is not swapped out, somehow it was loaded. In that case, forget + // about an existing triggered event + if(mpAsynchLoadEvent) + { + // just delete it, this will remove it from the EventHandler and + // will trigger forgetAsynchGraphicLoadingEvent from the destructor + delete mpAsynchLoadEvent; + } + } + + return bRetval; + } + + // Test graphics state and eventually trigger a SwapIn event. Return value + // gives info if SwapIn was triggered or not + bool ViewObjectContactOfGraphic::impPrepareGraphicWithSynchroniousLoading() + { + bool bRetval(false); + SdrGrafObj& rGrafObj = getSdrGrafObj(); + + if(rGrafObj.IsSwappedOut()) + { + if(rGrafObj.IsLinkedGraphic()) + { + // update graphic link + rGrafObj.ImpUpdateGraphicLink(); + } + else + { + ObjectContact& rObjectContact = GetObjectContact(); + + if(rObjectContact.isOutputToPrinter()) + { + // #i76395# preview mechanism is only active if + // swapin is called from inside paint preparation, so mbInsidePaint + // has to be false to be able to print with high resolution + rGrafObj.ForceSwapIn(); + } + else + { + // SwapIn direct + rGrafObj.mbInsidePaint = sal_True; + rGrafObj.ForceSwapIn(); + rGrafObj.mbInsidePaint = sal_False; + } + + bRetval = true; + } + } + + return bRetval; + } + + // This is the call from the asynch graphic loading. This may only be called from + // AsynchGraphicLoadingEvent::ExecuteEvent(). Do load the graphics. The event will + // be deleted (consumed) and forgetAsynchGraphicLoadingEvent will be called. + void ViewObjectContactOfGraphic::doAsynchGraphicLoading() + { + DBG_ASSERT(mpAsynchLoadEvent, "ViewObjectContactOfGraphic::doAsynchGraphicLoading: I did not trigger a event, why am i called (?)"); + + // swap it in + SdrGrafObj& rGrafObj = getSdrGrafObj(); + rGrafObj.ForceSwapIn(); + + // #i103720# forget event to avoid possible deletion by the following ActionChanged call + // which may use createPrimitive2DSequence/impPrepareGraphicWithAsynchroniousLoading again. + // Deletion is actally done by the scheduler who leaded to coming here + mpAsynchLoadEvent = 0; + + // Invalidate all paint areas and check existing animation (which may have changed). + GetViewContact().ActionChanged(); + } + + // This is the call from the destructor of the asynch graphic loading event. + // No one else has to call this. It is needed to let this object forget about + // the event. The parameter allows checking for the correct event. + void ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent* pEvent) + { + (void) pEvent; // suppress warning + + if(mpAsynchLoadEvent) + { + OSL_ENSURE(!pEvent || mpAsynchLoadEvent == pEvent, + "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)"); + + // forget event + mpAsynchLoadEvent = 0; + } + } + + SdrGrafObj& ViewObjectContactOfGraphic::getSdrGrafObj() + { + return static_cast< ViewContactOfGraphic& >(GetViewContact()).GetGrafObject(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfGraphic::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // prepare primitive generation with evtl. loading the graphic when it's swapped out + SdrGrafObj& rGrafObj = const_cast< ViewObjectContactOfGraphic* >(this)->getSdrGrafObj(); + bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics()); + static bool bSuppressAsynchLoading(false); + bool bSwapInDone(false); + + if(bDoAsynchronGraphicLoading + && rGrafObj.IsSwappedOut() + && rGrafObj.GetPage() + && rGrafObj.GetPage()->IsMasterPage()) + { + // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation + bDoAsynchronGraphicLoading = false; + } + + if(bDoAsynchronGraphicLoading && !bSuppressAsynchLoading) + { + bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithAsynchroniousLoading(); + } + else + { + bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithSynchroniousLoading(); + } + + // get return value by calling parent + drawinglayer::primitive2d::Primitive2DSequence xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo); + + if(xRetval.hasElements()) + { + // #i103255# suppress when graphic needs draft visualisation and output + // is for PDF export/Printer + const ViewContactOfGraphic& rVCOfGraphic = static_cast< const ViewContactOfGraphic& >(GetViewContact()); + + if(rVCOfGraphic.visualisationUsesDraft()) + { + const ObjectContact& rObjectContact = GetObjectContact(); + + if(rObjectContact.isOutputToPDFFile() || rObjectContact.isOutputToPrinter()) + { + xRetval = drawinglayer::primitive2d::Primitive2DSequence(); + } + } + } + + // if swap in was forced only for printing, swap out again + const bool bSwapInExclusiveForPrinting(bSwapInDone && GetObjectContact().isOutputToPrinter()); + + if(bSwapInExclusiveForPrinting) + { + rGrafObj.ForceSwapOut(); + } + + return xRetval; + } + + ViewObjectContactOfGraphic::ViewObjectContactOfGraphic(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact), + mpAsynchLoadEvent(0) + { + } + + ViewObjectContactOfGraphic::~ViewObjectContactOfGraphic() + { + // evtl. delete the asynch loading event + if(mpAsynchLoadEvent) + { + // just delete it, this will remove it from the EventHandler and + // will trigger forgetAsynchGraphicLoadingEvent from the destructor + delete mpAsynchLoadEvent; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofgroup.cxx b/svx/source/sdr/contact/viewobjectcontactofgroup.cxx new file mode 100644 index 000000000000..392b8e923212 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofgroup.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 <svx/sdr/contact/viewobjectcontactofgroup.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <svx/sdr/contact/viewcontact.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfGroup::ViewObjectContactOfGroup(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfGroup::~ViewObjectContactOfGroup() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfGroup::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // check model-view visibility + if(isPrimitiveVisible(rDisplayInfo)) + { + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + const sal_Bool bDoGhostedDisplaying( + GetObjectContact().DoVisualizeEnteredGroup() + && !GetObjectContact().isOutputToPrinter() + && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bDoGhostedDisplaying) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + + // create object hierarchy + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const ::basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + + if(bDoGhostedDisplaying) + { + rDisplayInfo.SetGhostedDrawMode(); + } + } + else + { + // draw replacement object for group. This will use ViewContactOfGroup::createViewIndependentPrimitive2DSequence + // which creates the replacement primitives for an empty group + xRetval = ViewObjectContactOfSdrObj::getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + } + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx new file mode 100644 index 000000000000..e779cac4151e --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.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/sdr/contact/viewobjectcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/viewcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/svdpage.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfMasterPageDescriptor::ViewObjectContactOfMasterPageDescriptor(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfMasterPageDescriptor::~ViewObjectContactOfMasterPageDescriptor() + { + } + + sdr::MasterPageDescriptor& ViewObjectContactOfMasterPageDescriptor::GetMasterPageDescriptor() const + { + return static_cast< ViewContactOfMasterPageDescriptor& >(GetViewContact()).GetMasterPageDescriptor(); + } + + bool ViewObjectContactOfMasterPageDescriptor::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(rDisplayInfo.GetControlLayerProcessingActive()) + { + return false; + } + + if(!rDisplayInfo.GetPageProcessingActive()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfMasterPageDescriptor::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + drawinglayer::primitive2d::Primitive2DSequence xMasterPageSequence; + const sdr::MasterPageDescriptor& rDescriptor = GetMasterPageDescriptor(); + + // used range (retval) is fixed here, it's the MasterPage fill range + const SdrPage& rOwnerPage = rDescriptor.GetOwnerPage(); + const basegfx::B2DRange aPageFillRange( + rOwnerPage.GetLftBorder(), rOwnerPage.GetUppBorder(), + rOwnerPage.GetWdt() - rOwnerPage.GetRgtBorder(), rOwnerPage.GetHgt() - rOwnerPage.GetLwrBorder()); + + // Modify DisplayInfo for MasterPageContent collection; remember original layers and + // set combined LayerSet; set MasterPagePaint flag + const SetOfByte aRememberedLayers(rDisplayInfo.GetProcessLayers()); + SetOfByte aPreprocessedLayers(aRememberedLayers); + aPreprocessedLayers &= rDescriptor.GetVisibleLayers(); + rDisplayInfo.SetProcessLayers(aPreprocessedLayers); + rDisplayInfo.SetSubContentActive(true); + + // check layer visibility (traditionally was member of layer 1) + if(aPreprocessedLayers.IsSet(1)) + { + // hide PageBackground for special DrawModes; historical reasons + if(!GetObjectContact().isDrawModeGray() && !GetObjectContact().isDrawModeHighContrast()) + { + // if visible, create the default background primitive sequence + xRetval = static_cast< ViewContactOfMasterPageDescriptor& >(GetViewContact()).getViewIndependentPrimitive2DSequence(); + } + } + + // hide MasterPage content? Test self here for hierarchy + if(isPrimitiveVisible(rDisplayInfo)) + { + // get the VOC of the Master-SdrPage and get it's object hierarchy + ViewContact& rViewContactOfMasterPage(rDescriptor.GetUsedPage().GetViewContact()); + ViewObjectContact& rVOCOfMasterPage(rViewContactOfMasterPage.GetViewObjectContact(GetObjectContact())); + + xMasterPageSequence = rVOCOfMasterPage.getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + + // reset DisplayInfo changes for MasterPage paint + rDisplayInfo.SetProcessLayers(aRememberedLayers); + rDisplayInfo.SetSubContentActive(false); + + if(xMasterPageSequence.hasElements()) + { + // get range of MasterPage sub hierarchy + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aSubHierarchyRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xMasterPageSequence, rViewInformation2D)); + + if(aPageFillRange.isInside(aSubHierarchyRange)) + { + // completely inside, just render MasterPage content. Add to target + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xMasterPageSequence); + } + else if(aPageFillRange.overlaps(aSubHierarchyRange)) + { + // overlapping, compute common area + basegfx::B2DRange aCommonArea(aPageFillRange); + aCommonArea.intersect(aSubHierarchyRange); + + // need to create a clip primitive, add clipped list to target + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::MaskPrimitive2D( + basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aCommonArea)), xMasterPageSequence)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + } + } + + // return grouped primitive + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx new file mode 100644 index 000000000000..34731f100b5d --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx @@ -0,0 +1,352 @@ +/************************************************************************* + * + * 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/viewobjectcontactofpageobj.hxx> +#include <svx/sdr/contact/viewcontactofpageobj.hxx> +#include <svx/svdopage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/svdpage.hxx> +#include <unoapi.hxx> +#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + class PagePrimitiveExtractor : public ObjectContactOfPagePainter, public Timer + { + private: + // the ViewObjectContactOfPageObj using this painter + ViewObjectContactOfPageObj& mrViewObjectContactOfPageObj; + + public: + // basic constructor/destructor + PagePrimitiveExtractor(ViewObjectContactOfPageObj& rVOC); + virtual ~PagePrimitiveExtractor(); + + // LazyInvalidate request. Supported here to not automatically + // invalidate the second interaction state all the time at the + // original OC + virtual void setLazyInvalidate(ViewObjectContact& rVOC); + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + virtual void Timeout(); + + // get primitive visualization + drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequenceForPage(const DisplayInfo& rDisplayInfo); + + // Own reaction on changes which will be forwarded to the OC of the owner-VOC + virtual void InvalidatePartOfView(const basegfx::B2DRange& rRange) const; + + // forward access to SdrPageView of ViewObjectContactOfPageObj + virtual bool isOutputToPrinter() const; + virtual bool isOutputToWindow() const; + virtual bool isOutputToVirtualDevice() const; + virtual bool isOutputToRecordingMetaFile() const; + virtual bool isOutputToPDFFile() const; + virtual bool isDrawModeGray() const; + virtual bool isDrawModeBlackWhite() const; + virtual bool isDrawModeHighContrast() const; + virtual SdrPageView* TryToGetSdrPageView() const; + virtual OutputDevice* TryToGetOutputDevice() const; + }; + + PagePrimitiveExtractor::PagePrimitiveExtractor( + ViewObjectContactOfPageObj& rVOC) + : ObjectContactOfPagePainter(0, rVOC.GetObjectContact()), + mrViewObjectContactOfPageObj(rVOC) + { + // make this renderer a preview renderer + setPreviewRenderer(true); + + // init timer + SetTimeout(1); + Stop(); + } + + PagePrimitiveExtractor::~PagePrimitiveExtractor() + { + // execute missing LazyInvalidates and stop timer + Timeout(); + } + + void PagePrimitiveExtractor::setLazyInvalidate(ViewObjectContact& /*rVOC*/) + { + // do NOT call parent, but remember that something is to do by + // starting the LazyInvalidateTimer + Start(); + } + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + void PagePrimitiveExtractor::Timeout() + { + // stop the timer + Stop(); + + // invalidate all LazyInvalidate VOCs new situations + const sal_uInt32 nVOCCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nVOCCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + pCandidate->triggerLazyInvalidate(); + } + } + + drawinglayer::primitive2d::Primitive2DSequence PagePrimitiveExtractor::createPrimitive2DSequenceForPage(const DisplayInfo& /*rDisplayInfo*/) + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPage* pStartPage = GetStartPage(); + + if(pStartPage) + { + // update own ViewInformation2D for visualized page + const drawinglayer::geometry::ViewInformation2D& rOriginalViewInformation = mrViewObjectContactOfPageObj.GetObjectContact().getViewInformation2D(); + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + rOriginalViewInformation.getObjectTransformation(), + rOriginalViewInformation.getViewTransformation(), + + // #i101075# use empty range for page content here to force + // the content not to be physically clipped in any way. This + // would be possible, but would require the internal transformation + // which maps between the page visualisation object and the page + // content, including the aspect ratios (for details see in + // PagePreviewPrimitive2D::create2DDecomposition) + basegfx::B2DRange(), + + GetXDrawPageForSdrPage(const_cast< SdrPage* >(pStartPage)), + 0.0, // no time; page previews are not animated + rOriginalViewInformation.getExtendedInformationSequence()); + updateViewInformation2D(aNewViewInformation2D); + + // create copy of DisplayInfo to set PagePainting + DisplayInfo aDisplayInfo; + + // get page's VOC + ViewObjectContact& rDrawPageVOContact = pStartPage->GetViewContact().GetViewObjectContact(*this); + + // get whole Primitive2DSequence + xRetval = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo); + } + + return xRetval; + } + + void PagePrimitiveExtractor::InvalidatePartOfView(const basegfx::B2DRange& rRange) const + { + // an invalidate is called at this view, this needs to be translated to an invalidate + // for the using VOC. Coordinates are in page coordinate system. + const SdrPage* pStartPage = GetStartPage(); + + if(pStartPage && !rRange.isEmpty()) + { + const basegfx::B2DRange aPageRange(0.0, 0.0, (double)pStartPage->GetWdt(), (double)pStartPage->GetHgt()); + + if(rRange.overlaps(aPageRange)) + { + // if object on the page is inside or overlapping with page, create ActionChanged() for + // involved VOC + mrViewObjectContactOfPageObj.ActionChanged(); + } + } + } + + // forward access to SdrPageView to VOCOfPageObj + bool PagePrimitiveExtractor::isOutputToPrinter() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPrinter(); } + bool PagePrimitiveExtractor::isOutputToWindow() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToWindow(); } + bool PagePrimitiveExtractor::isOutputToVirtualDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToVirtualDevice(); } + bool PagePrimitiveExtractor::isOutputToRecordingMetaFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToRecordingMetaFile(); } + bool PagePrimitiveExtractor::isOutputToPDFFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPDFFile(); } + bool PagePrimitiveExtractor::isDrawModeGray() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeGray(); } + bool PagePrimitiveExtractor::isDrawModeBlackWhite() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeBlackWhite(); } + bool PagePrimitiveExtractor::isDrawModeHighContrast() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeHighContrast(); } + SdrPageView* PagePrimitiveExtractor::TryToGetSdrPageView() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetSdrPageView(); } + OutputDevice* PagePrimitiveExtractor::TryToGetOutputDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetOutputDevice(); } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPageObj& rPageObject((static_cast< ViewContactOfPageObj& >(GetViewContact())).GetPageObj()); + const SdrPage* pPage = rPageObject.GetReferencedPage(); + const svtools::ColorConfig aColorConfig; + + // get PageObject's geometry + basegfx::B2DHomMatrix aPageObjectTransform; + { + const Rectangle aPageObjectModelData(rPageObject.GetLastBoundRect()); + const basegfx::B2DRange aPageObjectBound( + aPageObjectModelData.Left(), aPageObjectModelData.Top(), + aPageObjectModelData.Right(), aPageObjectModelData.Bottom()); + + aPageObjectTransform.set(0, 0, aPageObjectBound.getWidth()); + aPageObjectTransform.set(1, 1, aPageObjectBound.getHeight()); + aPageObjectTransform.set(0, 2, aPageObjectBound.getMinX()); + aPageObjectTransform.set(1, 2, aPageObjectBound.getMinY()); + } + + // #i102637# add gray frame also when printing and page exists (handout pages) + const bool bCreateGrayFrame(!GetObjectContact().isOutputToPrinter() || pPage); + + // get displayed page's content. This is the uscaled page content + if(mpExtractor && pPage) + { + // get displayed page's geometry + drawinglayer::primitive2d::Primitive2DSequence xPageContent; + const Size aPageSize(pPage->GetSize()); + const double fPageWidth(aPageSize.getWidth()); + const double fPageHeight(aPageSize.getHeight()); + + // The case that a PageObject contains another PageObject which visualizes the + // same page again would lead to a recursion. Limit that recursion depth to one + // by using a local static bool + static bool bInCreatePrimitive2D(false); + + if(bInCreatePrimitive2D) + { + // Recursion is possible. Create a replacement primitive + xPageContent.realloc(2); + const Color aDocColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + const Color aBorderColor(aColorConfig.GetColorValue(svtools::DOCBOUNDARIES).nColor); + const basegfx::B2DRange aPageBound(0.0, 0.0, fPageWidth, fPageHeight); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aPageBound)); + + // add replacement fill + xPageContent[0L] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aDocColor.getBColor())); + + // add replacement border + xPageContent[1L] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aBorderColor.getBColor())); + } + else + { + // set recursion flag + bInCreatePrimitive2D = true; + + // init extractor, guarantee existance, set page there + mpExtractor->SetStartPage(pPage); + + // #i105548# also need to copy the VOCRedirector for sub-content creation + mpExtractor->SetViewObjectContactRedirector(GetObjectContact().GetViewObjectContactRedirector()); + + // create page content + xPageContent = mpExtractor->createPrimitive2DSequenceForPage(rDisplayInfo); + + // #i105548# reset VOCRedirector to not accidentially have a pointer to a + // temporary class, so calls to it are avoided safely + mpExtractor->SetViewObjectContactRedirector(0); + + // reset recursion flag + bInCreatePrimitive2D = false; + } + + // prepare retval + if(xPageContent.hasElements()) + { + const uno::Reference< drawing::XDrawPage > xDrawPage(GetXDrawPageForSdrPage(const_cast< SdrPage*>(pPage))); + const drawinglayer::primitive2d::Primitive2DReference xPagePreview(new drawinglayer::primitive2d::PagePreviewPrimitive2D( + xDrawPage, aPageObjectTransform, fPageWidth, fPageHeight, xPageContent, true)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPagePreview, 1); + } + } + else if(bCreateGrayFrame) + { + // #i105146# no content, but frame display. To make hitting the page preview objects + // on the handout page more simple, add hidden fill geometry + const drawinglayer::primitive2d::Primitive2DReference xFrameHit( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, + aPageObjectTransform)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xFrameHit, 1); + } + + // add a gray outline frame, except not when printing + if(bCreateGrayFrame) + { + const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor); + basegfx::B2DPolygon aOwnOutline(basegfx::tools::createUnitPolygon()); + aOwnOutline.transform(aPageObjectTransform); + + const drawinglayer::primitive2d::Primitive2DReference xGrayFrame( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOwnOutline, aFrameColor.getBColor())); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xGrayFrame); + } + + return xRetval; + } + + ViewObjectContactOfPageObj::ViewObjectContactOfPageObj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact), + mpExtractor(new PagePrimitiveExtractor(*this)) + { + } + + ViewObjectContactOfPageObj::~ViewObjectContactOfPageObj() + { + // delete the helper OC + if(mpExtractor) + { + // remember candidate and reset own pointer to avoid action when createPrimitive2DSequence() + // would be called for any reason + PagePrimitiveExtractor* pCandidate = mpExtractor; + mpExtractor = 0; + + // also reset the StartPage to avoid ActionChanged() forwardings in the + // PagePrimitiveExtractor::InvalidatePartOfView() implementation + pCandidate->SetStartPage(0); + delete pCandidate; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx new file mode 100644 index 000000000000..ce8d0c79a5f9 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * 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/objectcontactofpageview.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdomedia.hxx> +#include <svx/svdpagv.hxx> +#include <vcl/outdev.hxx> +#include <vcl/window.hxx> +#include <avmedia/mediaitem.hxx> +#include "sdrmediawindow.hxx" +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr { namespace contact { + +// ---------------------------------- +// - ViewObjectContactOfSdrMediaObj - +// ---------------------------------- + +ViewObjectContactOfSdrMediaObj::ViewObjectContactOfSdrMediaObj( ObjectContact& rObjectContact, + ViewContact& rViewContact, + const ::avmedia::MediaItem& rMediaItem ) : + ViewObjectContactOfSdrObj( rObjectContact, rViewContact ), + mpMediaWindow( NULL ) +{ + Window* pWindow = getWindow(); + + if( pWindow ) + { + mpMediaWindow = new SdrMediaWindow( pWindow, *this ); + mpMediaWindow->hide(); + executeMediaItem( rMediaItem ); + } +} + +// ------------------------------------------------------------------------------ + +ViewObjectContactOfSdrMediaObj::~ViewObjectContactOfSdrMediaObj() +{ + delete mpMediaWindow; + mpMediaWindow = NULL; +} + +// ------------------------------------------------------------------------------ + +Window* ViewObjectContactOfSdrMediaObj::getWindow() const +{ + Window* pRetval = 0; + + const ObjectContactOfPageView* pObjectContactOfPageView = dynamic_cast< const ObjectContactOfPageView* >(&GetObjectContact()); + + if(pObjectContactOfPageView) + { + const SdrPageWindow& rPageWindow = pObjectContactOfPageView->GetPageWindow(); + const SdrPaintWindow* pPaintWindow = &rPageWindow.GetPaintWindow(); + + if(rPageWindow.GetOriginalPaintWindow()) + { + // #i83183# prefer OriginalPaintWindow if set; this is + // the real target device. GetPaintWindow() may return + // the current buffer device instead + pPaintWindow = rPageWindow.GetOriginalPaintWindow(); + } + + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + + if(OUTDEV_WINDOW == rOutDev.GetOutDevType()) + { + pRetval = static_cast< Window* >(&rOutDev); + } + } + + return pRetval; +} + +// ------------------------------------------------------------------------------ + +bool ViewObjectContactOfSdrMediaObj::hasPreferredSize() const +{ + return( mpMediaWindow != NULL && mpMediaWindow->hasPreferredSize() ); +} + +// ------------------------------------------------------------------------------ + +Size ViewObjectContactOfSdrMediaObj::getPreferredSize() const +{ + Size aRet; + + if( mpMediaWindow ) + aRet = mpMediaWindow->getPreferredSize(); + + return aRet; +} + +// ------------------------------------------------------------------------------ + +void ViewObjectContactOfSdrMediaObj::updateMediaItem( ::avmedia::MediaItem& rItem ) const +{ + if( mpMediaWindow ) + { + mpMediaWindow->updateMediaItem( rItem ); + + // show/hide is now dependent of play state + if(avmedia::MEDIASTATE_STOP == rItem.getState()) + { + mpMediaWindow->hide(); + } + else + { + basegfx::B2DRange aViewRange(getObjectRange()); + aViewRange.transform(GetObjectContact().getViewInformation2D().getViewTransformation()); + + const Rectangle aViewRectangle( + (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()), + (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY())); + + mpMediaWindow->setPosSize(aViewRectangle); + mpMediaWindow->show(); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewObjectContactOfSdrMediaObj::executeMediaItem( const ::avmedia::MediaItem& rItem ) +{ + if( mpMediaWindow ) + { + ::avmedia::MediaItem aUpdatedItem; + + mpMediaWindow->executeMediaItem( rItem ); + + // query new properties after trying to set the new properties + updateMediaItem( aUpdatedItem ); + static_cast< ViewContactOfSdrMediaObj& >( GetViewContact() ).mediaPropertiesChanged( aUpdatedItem ); + } +} + +// ------------------------------------------------------------------------------ + +}} // end of namespace sdr::contact + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx new file mode 100644 index 000000000000..485afe35f9c1 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * 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/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrobj.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdview.hxx> + +#include "fmobj.hxx" + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrObject& ViewObjectContactOfSdrObj::getSdrObject() const + { + return static_cast< ViewContactOfSdrObj& >(GetViewContact()).GetSdrObject(); + } + + ViewObjectContactOfSdrObj::ViewObjectContactOfSdrObj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrObj::~ViewObjectContactOfSdrObj() + { + } + + bool ViewObjectContactOfSdrObj::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + const SdrObject& rObject = getSdrObject(); + + // Test layer visibility + if(!rDisplayInfo.GetProcessLayers().IsSet(rObject.GetLayer())) + { + return false; + } + + if(GetObjectContact().isOutputToPrinter() ) + { + // Test if print output but not printable + if( !rObject.IsPrintable()) + return false; + } + else + { + // test is object is not visible on screen + if( !rObject.IsVisible() ) + return false; + } + + // Test for hidden object on MasterPage + if(rDisplayInfo.GetSubContentActive() && rObject.IsNotVisibleAsMaster()) + { + return false; + } + + // Test for Calc object hiding (for OLE and Graphic it's extra, see there) + const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pSdrPageView) + { + const SdrView& rSdrView = pSdrPageView->GetView(); + const bool bHideOle(rSdrView.getHideOle()); + const bool bHideChart(rSdrView.getHideChart()); + const bool bHideDraw(rSdrView.getHideDraw()); + const bool bHideFormControl(rSdrView.getHideFormControl()); + + if(bHideOle || bHideChart || bHideDraw || bHideFormControl) + { + if(OBJ_OLE2 == rObject.GetObjIdentifier()) + { + if(((SdrOle2Obj&)rObject).IsChart()) + { + // chart + if(bHideChart) + { + return false; + } + } + else + { + // OLE + if(bHideOle) + { + return false; + } + } + } + else if(OBJ_GRAF == rObject.GetObjIdentifier()) + { + // graphic handled like OLE + if(bHideOle) + { + return false; + } + } + else + { + const bool bIsFormControl = dynamic_cast< const FmFormObj * >( &rObject ) != 0; + if(bIsFormControl && bHideFormControl) + { + return false; + } + // any other draw object + if(!bIsFormControl && bHideDraw) + { + return false; + } + } + } + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx new file mode 100644 index 000000000000..b1a4826609f9 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * 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/viewobjectcontactofsdrole2obj.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrole2obj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdview.hxx> +#include <drawinglayer/primitive2d/chartprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <com/sun/star/embed/EmbedMisc.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrOle2Obj& ViewObjectContactOfSdrOle2Obj::getSdrOle2Object() const + { + return static_cast< ViewContactOfSdrOle2Obj& >(GetViewContact()).GetOle2Obj(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrOle2Obj::createPrimitive2DSequence( + const DisplayInfo& /*rDisplayInfo*/) const + { + // this method is overloaded to do some things the old SdrOle2Obj::DoPaintObject did. + // In the future, some of these may be solved different, but ATM try to stay compatible + // with the old behaviour + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrOle2Obj& rSdrOle2 = getSdrOle2Object(); + sal_Int32 nState(-1); + + { + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if ( xObjRef.is() ) + nState = xObjRef->getCurrentState(); + } + + const bool bIsOutplaceActive(nState == embed::EmbedStates::ACTIVE); + const bool bIsInplaceActive((nState == embed::EmbedStates::INPLACE_ACTIVE) || (nState == embed::EmbedStates::UI_ACTIVE)); + const bool bIsChart(rSdrOle2.IsChart()); + bool bDone(false); + + if(!bDone && bIsInplaceActive) + { + if( !GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile() ) + { + //no need to create a primitive sequence here as the OLE object does render itself + //in case of charts the superfluous creation of a metafile is strongly performance relevant! + bDone = true; + } + } + + if( !bDone ) + { + const Rectangle& rObjectRectangle(rSdrOle2.GetGeoRect()); + const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aObjectTransform; + aObjectTransform.set(0, 0, aObjectRange.getWidth()); + aObjectTransform.set(1, 1, aObjectRange.getHeight()); + aObjectTransform.set(0, 2, aObjectRange.getMinX()); + aObjectTransform.set(1, 2, aObjectRange.getMinY()); + + if(bIsChart) + { + //charts must be painted resolution dependent!! #i82893#, #i75867# + + // for chart, to not lose the current better quality visualisation which + // uses a direct paint, use a primtive wrapper for that exceptional case. The renderers + // will then ATM paint it to an OutputDevice directly. + // In later versions this should be replaced by getting the Primitive2DSequnce from + // the chart and using it. + // to be able to render something in non-VCL using renderers, the wrapper is a + // GroupPrimitive2D which automatically decomposes to the already created Metafile + // content. + // For being completely compatible, ATM Window and VDEV PrettyPrinting is suppressed. + // It works in the VCL renderers, though. So for activating again with VCL primitive + // renderers, change conditions here. + + // determine if embedding and PrettyPrinting shall be done at all + uno::Reference< frame::XModel > xChartModel; + bool bDoChartPrettyPrinting(true); + + // the original ChartPrettyPainter does not do it for Window + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToWindow()) + { + bDoChartPrettyPrinting = false; + } + + // the original ChartPrettyPainter does not do it for VDEV + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToVirtualDevice()) + { + if(GetObjectContact().isOutputToPDFFile()) + { + // #i97982# + // For PDF files, allow PrettyPrinting + } + else + { + bDoChartPrettyPrinting = false; + } + } + + // the chart model is needed. Check if it's available + if(bDoChartPrettyPrinting) + { + // get chart model + xChartModel = rSdrOle2.getXModel(); + + if(!xChartModel.is()) + { + bDoChartPrettyPrinting = false; + } + } + + if(bDoChartPrettyPrinting) + { + // embed MetaFile data in a specialized Wrapper Primitive which holds also the ChartModel needed + // for PrettyPrinting + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ChartPrimitive2D( + xChartModel, aObjectTransform, xRetval)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + bDone = true; + } + } + + if( !bDone ) + { + //old stuff that should be reworked + { + //if no replacement image is available load the OLE object + if(!rSdrOle2.GetGraphic()) //try to fetch the metafile - this can lead to the actual creation of the metafile what can be extremely expensive (e.g. for big charts)!!! #i101925# + { + // try to create embedded object + rSdrOle2.GetObjRef(); //this loads the OLE object if it is not loaded already + } + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if(xObjRef.is()) + { + const sal_Int64 nMiscStatus(xObjRef->getStatus(rSdrOle2.GetAspect())); + + // this hack (to change model data during PAINT argh(!)) should be reworked + if(!rSdrOle2.IsResizeProtect() && (nMiscStatus & embed::EmbedMisc::EMBED_NEVERRESIZE)) + { + const_cast< SdrOle2Obj* >(&rSdrOle2)->SetResizeProtect(true); + } + + SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + if(pPageView && (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE)) + { + // connect plugin object + pPageView->GetView().DoConnect(const_cast< SdrOle2Obj* >(&rSdrOle2)); + } + } + }//end old stuff to rework + + // create OLE primitive stuff directly at VC with HC as parameter + const ViewContactOfSdrOle2Obj& rVC = static_cast< const ViewContactOfSdrOle2Obj& >(GetViewContact()); + xRetval = rVC.createPrimitive2DSequenceWithParameters(GetObjectContact().isDrawModeHighContrast()); + } + + if(bIsOutplaceActive) + { + // do not shade when printing or PDF exporting + if(!GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile()) + { + // shade the representation if the object is activated outplace + basegfx::B2DPolygon aObjectOutline(basegfx::tools::createUnitPolygon()); + aObjectOutline.transform(aObjectTransform); + + // Use a FillHatchPrimitive2D with necessary attributes + const drawinglayer::attribute::FillHatchAttribute aFillHatch( + drawinglayer::attribute::HATCHSTYLE_SINGLE, // single hatch + 125.0, // 1.25 mm + 45.0 * F_PI180, // 45 degree diagonal + Color(COL_BLACK).getBColor(), // black color + false); // no filling + + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D( + basegfx::B2DPolyPolygon(aObjectOutline), + Color(COL_BLACK).getBColor(), + aFillHatch)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + } + } + + } + + return xRetval; + } + + ViewObjectContactOfSdrOle2Obj::ViewObjectContactOfSdrOle2Obj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrOle2Obj::~ViewObjectContactOfSdrOle2Obj() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx new file mode 100644 index 000000000000..c751ba2ada76 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx @@ -0,0 +1,723 @@ +/************************************************************************* + * + * 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/viewobjectcontactofsdrpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewcontactofsdrpage.hxx> +#include <svx/svdview.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/gridprimitive2d.hxx> +#include <drawinglayer/primitive2d/helplineprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrPage& ViewObjectContactOfPageSubObject::getPage() const + { + return static_cast< ViewContactOfPageSubObject& >(GetViewContact()).getPage(); + } + + ViewObjectContactOfPageSubObject::ViewObjectContactOfPageSubObject(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageSubObject::~ViewObjectContactOfPageSubObject() + { + } + + bool ViewObjectContactOfPageSubObject::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(rDisplayInfo.GetSubContentActive()) + { + return false; + } + + if(rDisplayInfo.GetControlLayerProcessingActive()) + { + return false; + } + + if(!rDisplayInfo.GetPageProcessingActive()) + { + return false; + } + + if(GetObjectContact().isOutputToPrinter()) + { + return false; + } + + if(!GetObjectContact().TryToGetSdrPageView()) + { + return false; + } + + return true; + } + + bool ViewObjectContactOfPageSubObject::isPrimitiveGhosted(const DisplayInfo& /*rDisplayInfo*/) const + { + // suppress ghosted for page parts + return false; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageBackground::ViewObjectContactOfPageBackground(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageBackground::~ViewObjectContactOfPageBackground() + { + } + + bool ViewObjectContactOfPageBackground::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + // no page background for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageBackground::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + // Initialize background. Dependent of IsPageVisible, use ApplicationBackgroundColor or ApplicationDocumentColor. Most + // old renderers for export (html, pdf, gallery, ...) set the page to not visible (SetPageVisible(false)). They expect the + // given OutputDevice to be initialized with the ApplicationDocumentColor then. + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrView& rView = pPageView->GetView(); + Color aInitColor; + + if(rView.IsPageVisible()) + { + aInitColor = pPageView->GetApplicationBackgroundColor(); + } + else + { + aInitColor = pPageView->GetApplicationDocumentColor(); + + if(Color(COL_AUTO) == aInitColor) + { + const svtools::ColorConfig aColorConfig; + aInitColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor; + } + } + + // init background with InitColor + xRetval.realloc(1); + const basegfx::BColor aRGBColor(aInitColor.getBColor()); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::BackgroundColorPrimitive2D(aRGBColor)); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfMasterPage::ViewObjectContactOfMasterPage(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfMasterPage::~ViewObjectContactOfMasterPage() + { + } + + bool ViewObjectContactOfMasterPage::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + // this object is only used for MasterPages. When not the MasterPage is + // displayed as a page, but another page is using it as sub-object, the + // geometry needs to be hidden + if(rDisplayInfo.GetSubContentActive()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageFill::ViewObjectContactOfPageFill(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageFill::~ViewObjectContactOfPageFill() + { + } + + bool ViewObjectContactOfPageFill::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsPageVisible()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageFill::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrPage& rPage = getPage(); + + const basegfx::B2DRange aPageFillRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + const basegfx::B2DPolygon aPageFillPolygon(basegfx::tools::createPolygonFromRect(aPageFillRange)); + Color aPageFillColor; + + if(pPageView->GetApplicationDocumentColor() != COL_AUTO) + { + aPageFillColor = pPageView->GetApplicationDocumentColor(); + } + else + { + const svtools::ColorConfig aColorConfig; + aPageFillColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor; + } + + // create and add primitive + xRetval.realloc(1); + const basegfx::BColor aRGBColor(aPageFillColor.getBColor()); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPageFillPolygon), aRGBColor)); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageShadow::ViewObjectContactOfPageShadow(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageShadow::~ViewObjectContactOfPageShadow() + { + } + + bool ViewObjectContactOfPageShadow::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsPageVisible()) + { + return false; + } + + // no page shadow for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfOuterPageBorder::ViewObjectContactOfOuterPageBorder(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfOuterPageBorder::~ViewObjectContactOfOuterPageBorder() + { + } + + bool ViewObjectContactOfOuterPageBorder::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsPageVisible() && rView.IsPageBorderVisible()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfInnerPageBorder::ViewObjectContactOfInnerPageBorder(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfInnerPageBorder::~ViewObjectContactOfInnerPageBorder() + { + } + + bool ViewObjectContactOfInnerPageBorder::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsBordVisible()) + { + return false; + } + + const SdrPage& rPage = getPage(); + + if(!rPage.GetLftBorder() && !rPage.GetUppBorder() && !rPage.GetRgtBorder() && !rPage.GetLwrBorder()) + { + return false; + } + + // no inner page border for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageHierarchy::ViewObjectContactOfPageHierarchy(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageHierarchy::~ViewObjectContactOfPageHierarchy() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageHierarchy::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // process local sub-hierarchy + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageGrid::ViewObjectContactOfPageGrid(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageGrid::~ViewObjectContactOfPageGrid() + { + } + + bool ViewObjectContactOfPageGrid::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsGridVisible()) + { + return false; + } + + // no page grid for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + if(static_cast< ViewContactOfGrid& >(GetViewContact()).getFront() != (bool)rView.IsGridFront()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageGrid::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrView& rView = pPageView->GetView(); + const SdrPage& rPage = getPage(); + const Color aGridColor(rView.GetGridColor()); + const basegfx::BColor aRGBGridColor(aGridColor.getBColor()); + + basegfx::B2DHomMatrix aGridMatrix; + aGridMatrix.set(0, 0, (double)(rPage.GetWdt() - (rPage.GetRgtBorder() + rPage.GetLftBorder()))); + aGridMatrix.set(1, 1, (double)(rPage.GetHgt() - (rPage.GetLwrBorder() + rPage.GetUppBorder()))); + aGridMatrix.set(0, 2, (double)rPage.GetLftBorder()); + aGridMatrix.set(1, 2, (double)rPage.GetUppBorder()); + + const Size aRaw(rView.GetGridCoarse()); + const Size aFine(rView.GetGridFine()); + const double fWidthX(aRaw.getWidth()); + const double fWidthY(aRaw.getHeight()); + const sal_uInt32 nSubdivisionsX(aFine.getWidth() ? aRaw.getWidth() / aFine.getWidth() : 0L); + const sal_uInt32 nSubdivisionsY(aFine.getHeight() ? aRaw.getHeight() / aFine.getHeight() : 0L); + + xRetval.realloc(1); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::GridPrimitive2D( + aGridMatrix, fWidthX, fWidthY, 10.0, 3.0, nSubdivisionsX, nSubdivisionsY, aRGBGridColor, + drawinglayer::primitive2d::createDefaultCross_3x3(aRGBGridColor))); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageHelplines::ViewObjectContactOfPageHelplines(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageHelplines::~ViewObjectContactOfPageHelplines() + { + } + + bool ViewObjectContactOfPageHelplines::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsHlplVisible()) + { + return false; + } + + // no helplines for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + if(static_cast< ViewContactOfHelplines& >(GetViewContact()).getFront() != (bool)rView.IsHlplFront()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageHelplines::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pPageView) + { + const SdrHelpLineList& rHelpLineList = pPageView->GetHelpLines(); + const sal_uInt32 nCount(rHelpLineList.GetCount()); + + if(nCount) + { + const basegfx::BColor aRGBColorA(1.0, 1.0, 1.0); + const basegfx::BColor aRGBColorB(0.0, 0.0, 0.0); + xRetval.realloc(nCount); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + const SdrHelpLine& rHelpLine = rHelpLineList[(sal_uInt16)a]; + const basegfx::B2DPoint aPosition((double)rHelpLine.GetPos().X(), (double)rHelpLine.GetPos().Y()); + const double fDiscreteDashLength(4.0); + + switch(rHelpLine.GetKind()) + { + default : // SDRHELPLINE_POINT + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(1.0, 0.0), drawinglayer::primitive2d::HELPLINESTYLE2D_POINT, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + case SDRHELPLINE_VERTICAL : + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(0.0, 1.0), drawinglayer::primitive2d::HELPLINESTYLE2D_LINE, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + case SDRHELPLINE_HORIZONTAL : + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(1.0, 0.0), drawinglayer::primitive2d::HELPLINESTYLE2D_LINE, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + } + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfSdrPage::ViewObjectContactOfSdrPage(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrPage::~ViewObjectContactOfSdrPage() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrPage::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // process local sub-hierarchy + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + const sal_Bool bDoGhostedDisplaying( + GetObjectContact().DoVisualizeEnteredGroup() + && !GetObjectContact().isOutputToPrinter() + && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bDoGhostedDisplaying) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + + // create object hierarchy + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + + if(bDoGhostedDisplaying) + { + rDisplayInfo.SetGhostedDrawMode(); + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx new file mode 100644 index 000000000000..1da80b6c245e --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -0,0 +1,1925 @@ +/************************************************************************* + * + * 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/viewobjectcontactofunocontrol.hxx> +#include <svx/sdr/contact/viewcontactofunocontrol.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/properties/properties.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdrpagewindow.hxx> +#include "sdrpaintwindow.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XView.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/awt/InvalidateStyle.hpp> +#include <com/sun/star/util/XModeChangeListener.hpp> +#include <com/sun/star/util/XModeChangeBroadcaster.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/container/XContainer.hpp> +/** === end UNO includes === **/ + +#include <toolkit/helper/formpdfexport.hxx> +#include <vcl/pdfextoutdevdata.hxx> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/scopeguard.hxx> +#include <cppuhelper/implbase4.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/controlprimitive2d.hxx> + +#include <boost/shared_ptr.hpp> +#include <boost/bind.hpp> + +/* + +Form controls (more precise: UNO Controls) in the drawing layer are ... prone to breakage, since they have some +specialities which the drawing layer currently doesn't capture too well. In particular, having a living VCL +window as child of the document window, and coupling this Window to a drawing layer object, makes things +difficult sometimes. + +Below is a list of issues which existed in the past. Whenever you change code here, you're encouraged to +verify those issues are still fixed. (Whenever you have some additional time, you're encouraged to write +an automatic test for one or more of those issues for which this is possible :) + +http://www.openoffice.org/issues/show_bug.cgi?id=105992 +zooming documents containg (alive) form controls improperly positions the controls + +http://www.openoffice.org/issues/show_bug.cgi?id=104362 +crash when copy a control + +http://www.openoffice.org/issues/show_bug.cgi?id=104544 +Gridcontrol duplicated after design view on/off + +http://www.openoffice.org/issues/show_bug.cgi?id=102089 +print preview shows control elements with property printable=false + +http://www.openoffice.org/issues/show_bug.cgi?id=102090 +problem with setVisible on TextControl + +http://www.openoffice.org/issues/show_bug.cgi?id=103138 +loop when insert a control in draw + +http://www.openoffice.org/issues/show_bug.cgi?id=101398 +initially-displaying a document with many controls is very slow + +http://www.openoffice.org/issues/show_bug.cgi?id=72429 +repaint error in form wizard in bugdoc database + +http://www.openoffice.org/issues/show_bug.cgi?id=72694 +form control artifacts when scrolling a text fast + + +issues in the old (Sun-internal) bug tracking system: + +#110592# +form controls being in redlining or in hidden section are visible in alive-mode + +*/ + +//........................................................................ +namespace sdr { namespace contact { +//........................................................................ + + /** === begin UNO using === **/ + using namespace ::com::sun::star::awt::InvalidateStyle; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::awt::XControl; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::awt::XControlModel; + using ::com::sun::star::awt::XControlContainer; + using ::com::sun::star::awt::XWindow; + using ::com::sun::star::awt::XWindow2; + using ::com::sun::star::awt::XWindowListener; + using ::com::sun::star::awt::PosSize::POSSIZE; + using ::com::sun::star::awt::XView; + using ::com::sun::star::awt::XGraphics; + using ::com::sun::star::awt::WindowEvent; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::beans::XPropertySetInfo; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::awt::XWindowPeer; + using ::com::sun::star::beans::XPropertyChangeListener; + using ::com::sun::star::util::XModeChangeListener; + using ::com::sun::star::util::XModeChangeBroadcaster; + using ::com::sun::star::util::ModeChangeEvent; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::beans::PropertyChangeEvent; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::container::XContainerListener; + using ::com::sun::star::container::XContainer; + using ::com::sun::star::container::ContainerEvent; + using ::com::sun::star::uno::Any; + /** === end UNO using === **/ + + //==================================================================== + //= ControlHolder + //==================================================================== + class ControlHolder + { + private: + Reference< XControl > m_xControl; + Reference< XWindow2 > m_xControlWindow; + Reference< XView > m_xControlView; + + public: + ControlHolder() + :m_xControl() + ,m_xControlWindow() + ,m_xControlView() + { + } + + explicit ControlHolder( const Reference< XControl >& _rxControl ) + :m_xControl() + ,m_xControlWindow() + ,m_xControlView() + { + *this = _rxControl; + } + + ControlHolder& operator=( const Reference< XControl >& _rxControl ) + { + clear(); + + m_xControl = _rxControl; + if ( m_xControl.is() ) + { + m_xControlWindow.set( m_xControl, UNO_QUERY ); + m_xControlView.set( m_xControl, UNO_QUERY ); + if ( !m_xControlWindow.is() || !m_xControlView.is() ) + { + OSL_ENSURE( false, "ControlHolder::operator=: invalid XControl, missing required interfaces!" ); + clear(); + } + } + + return *this; + } + + public: + inline bool is() const { return m_xControl.is() && m_xControlWindow.is() && m_xControlView.is(); } + inline void clear() { m_xControl.clear(); m_xControlWindow.clear(); m_xControlView.clear(); } + + // delegators for the methods of the UNO interfaces + // Note all those will crash if called for a NULL object. + inline bool isDesignMode() const { return m_xControl->isDesignMode(); } + inline void setDesignMode( const bool _bDesign ) const { m_xControl->setDesignMode( _bDesign ); } + inline bool isVisible() const { return m_xControlWindow->isVisible(); } + inline void setVisible( const bool _bVisible ) const { m_xControlWindow->setVisible( _bVisible ); } + inline Reference< XControlModel > + getModel() const { return m_xControl->getModel(); } + inline void setModel( const Reference< XControlModel >& _m ) const { m_xControl->setModel( _m ); } + inline bool isTransparent() const { return m_xControl->isTransparent(); } + inline Reference< XWindowPeer > + getPeer() const { return m_xControl->getPeer(); } + + inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); } + inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); } + void setPosSize( const Rectangle& _rPosSize ) const; + Rectangle + getPosSize() const; + void setZoom( const ::basegfx::B2DVector& _rScale ) const; + ::basegfx::B2DVector + getZoom() const; + + inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); } + inline Reference< XGraphics > + getGraphics() const { return m_xControlView->getGraphics(); } + inline void draw( const Point& _rTopLeft ) const { m_xControlView->draw( _rTopLeft.X(), _rTopLeft.Y() ); } + + void invalidate() const; + + public: + inline const Reference< XControl >& getControl() const { return m_xControl; } + }; + + //-------------------------------------------------------------------- + bool operator==( const ControlHolder& _rControl, const Reference< XInterface >& _rxCompare ) + { + return _rControl.getControl() == _rxCompare; + } + + //-------------------------------------------------------------------- + bool operator==( const Reference< XInterface >& _rxCompare, const ControlHolder& _rControl ) + { + return _rxCompare == _rControl.getControl(); + } + + //-------------------------------------------------------------------- + bool operator==( const ControlHolder& _rControl, const Any& _rxCompare ) + { + return _rControl == Reference< XInterface >( _rxCompare, UNO_QUERY ); + } + + //-------------------------------------------------------------------- + bool operator==( const Any& _rxCompare, const ControlHolder& _rControl ) + { + return Reference< XInterface >( _rxCompare, UNO_QUERY ) == _rControl; + } + + //-------------------------------------------------------------------- + void ControlHolder::setPosSize( const Rectangle& _rPosSize ) const + { + // no check whether we're valid, this is the responsibility of the caller + + // don't call setPosSize when pos/size did not change + // #i104181# / 2009-08-18 / frank.schoenheit@sun.com + ::Rectangle aCurrentRect( getPosSize() ); + if ( aCurrentRect != _rPosSize ) + { + m_xControlWindow->setPosSize( + _rPosSize.Left(), _rPosSize.Top(), _rPosSize.GetWidth(), _rPosSize.GetHeight(), + POSSIZE + ); + } + } + + //-------------------------------------------------------------------- + ::Rectangle ControlHolder::getPosSize() const + { + // no check whether we're valid, this is the responsibility of the caller + return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const + { + // no check whether we're valid, this is the responsibility of the caller + m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::invalidate() const + { + Reference< XWindowPeer > xPeer( m_xControl->getPeer() ); + if ( xPeer.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xPeer ); + OSL_ENSURE( pWindow, "ControlHolder::invalidate: no implementation access!" ); + if ( pWindow ) + pWindow->Invalidate(); + } + } + + //-------------------------------------------------------------------- + ::basegfx::B2DVector ControlHolder::getZoom() const + { + // no check whether we're valid, this is the responsibility of the caller + + // Argh. Why does XView have a setZoom only, but not a getZoom? + Window* pWindow = VCLUnoHelper::GetWindow( m_xControl->getPeer() ); + OSL_ENSURE( pWindow, "ControlHolder::getZoom: no implementation access!" ); + + ::basegfx::B2DVector aZoom( 1, 1 ); + if ( pWindow ) + { + const Fraction& rZoom( pWindow->GetZoom() ); + aZoom.setX( (double)rZoom ); + aZoom.setY( (double)rZoom ); + } + return aZoom; + } + + //==================================================================== + //= UnoControlContactHelper + //==================================================================== + class UnoControlContactHelper + { + public: + /** positions a control, and sets its zoom mode, using a given transformation and output device + */ + static void adjustControlGeometry_throw( + const ControlHolder& _rControl, + const Rectangle& _rLogicBoundingRect, + const ::basegfx::B2DHomMatrix& _rViewTransformation, + const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization + ); + + /** disposes the given control + */ + static void disposeAndClearControl_nothrow( + ControlHolder& _rControl + ); + + private: + UnoControlContactHelper(); // never implemented + UnoControlContactHelper( const UnoControlContactHelper& ); // never implemented + UnoControlContactHelper& operator=( const UnoControlContactHelper& ); // never implemented + }; + + //-------------------------------------------------------------------- + void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, + const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ) + { + OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" ); + if ( !_rControl.is() ) + return; + + #if OSL_DEBUG_LEVEL > 0 + ::basegfx::B2DTuple aViewScale, aViewTranslate; + double nViewRotate(0), nViewShearX(0); + _rViewTransformation.decompose( aViewScale, aViewTranslate, nViewRotate, nViewShearX ); + #endif + + // transform the logic bound rect, using the view transformation, to pixel coordinates + ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() ); + aTopLeft *= _rViewTransformation; + ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() ); + aBottomRight *= _rViewTransformation; + + const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() ); + _rControl.setPosSize( aPaintRectPixel ); + + // determine the scale from the current view transformation, and the normalization matrix + ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization ); + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX ); + _rControl.setZoom( aScale ); + } + + //-------------------------------------------------------------------- + void UnoControlContactHelper::disposeAndClearControl_nothrow( ControlHolder& _rControl ) + { + try + { + Reference< XComponent > xControlComp( _rControl.getControl(), UNO_QUERY ); + if ( xControlComp.is() ) + xControlComp->dispose(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + _rControl.clear(); + } + + //==================================================================== + //= IPageViewAccess + //==================================================================== + /** interface encapsulating access to an SdrPageView, stripped down to the methods we really need + */ + class IPageViewAccess + { + public: + /** determines whether the view is currently in design mode + */ + virtual bool isDesignMode() const = 0; + + /** retrieves the control container for a given output device + */ + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const = 0; + + /** determines whether a given layer is visible + */ + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const = 0; + }; + + //==================================================================== + //= SdrPageViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation based on a real ->SdrPageView instance + */ + class SdrPageViewAccess : public IPageViewAccess + { + const SdrPageView& m_rPageView; + public: + SdrPageViewAccess( const SdrPageView& _rPageView ) : m_rPageView( _rPageView ) { } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool SdrPageViewAccess::isDesignMode() const + { + return m_rPageView.GetView().IsDesignMode(); + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > SdrPageViewAccess::getControlContainer( const OutputDevice& _rDevice ) const + { + Reference< XControlContainer > xControlContainer = m_rPageView.GetControlContainer( _rDevice ); + DBG_ASSERT( xControlContainer.is() || NULL == m_rPageView.FindPageWindow( ( const_cast< OutputDevice& >( _rDevice ) ) ), + "SdrPageViewAccess::getControlContainer: the output device is known, but there is no control container for it?" ); + return xControlContainer; + } + + //-------------------------------------------------------------------- + bool SdrPageViewAccess::isLayerVisible( SdrLayerID _nLayerID ) const + { + return m_rPageView.GetVisibleLayers().IsSet( _nLayerID ); + } + + //==================================================================== + //= InvisibleControlViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation which can be used to create an invisble control for + an arbitrary window + */ + class InvisibleControlViewAccess : public IPageViewAccess + { + private: + Reference< XControlContainer >& m_rControlContainer; + public: + InvisibleControlViewAccess( Reference< XControlContainer >& _inout_ControlContainer ) + :m_rControlContainer( _inout_ControlContainer ) + { + } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool InvisibleControlViewAccess::isDesignMode() const + { + return true; + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > InvisibleControlViewAccess::getControlContainer( const OutputDevice& _rDevice ) const + { + if ( !m_rControlContainer.is() ) + { + const Window* pWindow = dynamic_cast< const Window* >( &_rDevice ); + OSL_ENSURE( pWindow, "InvisibleControlViewAccess::getControlContainer: expected to be called for a window only!" ); + if ( pWindow ) + m_rControlContainer = VCLUnoHelper::CreateControlContainer( const_cast< Window* >( pWindow ) ); + } + return m_rControlContainer; + } + + //-------------------------------------------------------------------- + bool InvisibleControlViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const + { + return false; + } + + //==================================================================== + //= DummyPageViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation which can be used to create a control for an arbitrary + non-Window device + + The implementation will report the "PageView" as being in design mode, all layers to be visible, + and will not return any ControlContainer, so all control container related features (notifications etc) + are not available. + */ + class DummyPageViewAccess : public IPageViewAccess + { + public: + DummyPageViewAccess() + { + } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool DummyPageViewAccess::isDesignMode() const + { + return true; + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const + { + return NULL; + } + + //-------------------------------------------------------------------- + bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const + { + return true; + } + + //==================================================================== + //= ViewObjectContactOfUnoControl_Impl + //==================================================================== + typedef ::cppu::WeakImplHelper4 < XWindowListener + , XPropertyChangeListener + , XContainerListener + , XModeChangeListener + > ViewObjectContactOfUnoControl_Impl_Base; + + class SVX_DLLPRIVATE ViewObjectContactOfUnoControl_Impl : public ViewObjectContactOfUnoControl_Impl_Base + { + private: + /// the instance whose IMPL we are + ViewObjectContactOfUnoControl* m_pAntiImpl; + + /// are we currently inside impl_ensureControl_nothrow? + bool m_bCreatingControl; + + /** thread safety + + (not really. ATM only our X* implementations are guarded with this, but not + the object as a whole.) + */ + mutable ::osl::Mutex m_aMutex; + + /// the control we're responsible for + ControlHolder m_aControl; + + /// the ControlContainer where we inserted our control + Reference< XContainer > m_xContainer; + + /// the output device for which the control was created + const OutputDevice* m_pOutputDeviceForWindow; + + /// flag indicating whether the control is currently visible + bool m_bControlIsVisible; + + /// are we currently listening at a design mode control? + bool m_bIsDesignModeListening; + + enum ViewControlMode + { + eDesign, + eAlive, + eUnknown + }; + /// is the control currently in design mode? + mutable ViewControlMode m_eControlDesignMode; + + ::basegfx::B2DHomMatrix m_aZoomLevelNormalization; + + public: + ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ); + + /** disposes the instance, which is nonfunctional afterwards + */ + void dispose(); + + /** determines whether the instance is disposed + */ + bool isDisposed() const { return impl_isDisposed_nofail(); } + + /** determines whether the instance is alive + */ + bool isAlive() const { return !isDisposed(); } + + /** returns the SdrUnoObject associated with the ViewContact + + @precond + We're not disposed. + */ + bool getUnoObject( SdrUnoObj*& _out_rpObject ) const; + + /** ensures that we have an ->XControl + + Must only be called if a control is needed when no DisplayInfo is present, yet. + + For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained + from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView, + this method fill fail. + + Failure of this method will be reported via an assertion in a non-product version. + */ + bool ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL ); + + /** returns our XControl, if it already has been created + + If you want to ensure that the control exists before accessing it, use ->ensureControl + */ + inline const ControlHolder& + getExistentControl() const { return m_aControl; } + + inline bool + hasControl() const { return m_aControl.is(); } + + /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given + transformation, and sets proper zoom settings according to our device + + @precond + ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/> + */ + void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const; + + /** determines whether or not our control is printable + + Effectively, this method returns the value of the "Printable" property + of the control's model. If we have no control, <FALSE/> is returned. + */ + bool isPrintableControl() const; + + /** sets the design mode on the control, or at least remembers the flag for the + time the control is created + */ + void setControlDesignMode( bool _bDesignMode ) const; + + /** determines whether our control is currently visible + @nofail + */ + bool isControlVisible() const { return impl_isControlVisible_nofail(); } + + /// creates an XControl for the given device and SdrUnoObj + static bool + createControlForDevice( + IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, + const SdrUnoObj& _rUnoObject, + const basegfx::B2DHomMatrix& _rInitialViewTransformation, + const basegfx::B2DHomMatrix& _rInitialZoomNormalization, + ControlHolder& _out_rControl + ); + + struct GuardAccess { friend class VOCGuard; private: GuardAccess() { } }; + ::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; } + + const ViewContactOfUnoControl& + getViewContact() const + { + ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" ); + return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() ); + } + + protected: + ~ViewObjectContactOfUnoControl_Impl(); + + // XEventListener + virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); + + // XWindowListener + virtual void SAL_CALL windowResized( const WindowEvent& e ) throw(RuntimeException); + virtual void SAL_CALL windowMoved( const WindowEvent& e ) throw(RuntimeException); + virtual void SAL_CALL windowShown( const EventObject& e ) throw(RuntimeException); + virtual void SAL_CALL windowHidden( const EventObject& e ) throw(RuntimeException); + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException); + + // XModeChangeListener + virtual void SAL_CALL modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException); + + // XContainerListener + virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + + private: + /** retrieves the SdrPageView which our associated SdrPageViewWindow belongs to + + @param out_rpPageView + a reference to a pointer holding, upon return, the desired SdrPageView + + @return + <TRUE/> if and only if a ->SdrPageView could be obtained + + @precond + We really belong to an SdrPageViewWindow. Perhaps (I'm not sure ATM :) + there are instance for which this might not be true, but those instances + should never have a need to call this method. + + @precond + We're not disposed. + + @postcond + The method expects success, if it returns with <FALSE/>, this will have been + asserted. + + @nothrow + */ + bool impl_getPageView_nothrow( SdrPageView*& _out_rpPageView ); + + /** adjusts the control visibility so it respects its layer's visibility + + @param _bForce + set to <TRUE/> if you want to force a ->XWindow::setVisible call, + no matter if the control visibility is already correct + + @precond + ->m_aControl is not <NULL/> + + @precond + We're not disposed. + + @precond + We really belong to an SdrPageViewWindow. There are instance for which this + might not be true, but those instances should never have a need to call + this method. + */ + void impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce ); + + /** adjusts the control visibility so it respects its layer's visibility + + The control must never be visibile if it's in design mode. + In alive mode, it must be visibility if and only it's on a visible layer. + + @param _rxControl + the control whose visibility is to be adjusted + + @param _rPageView + provides access to the attributes of the SdrPageView which the control finally belongs to + + @param _rUnoObject + our SdrUnoObj + + @param _bIsCurrentlyVisible + determines whether the control is currently visible. Note that this is only a shortcut for + querying _rxControl for the XWindow2 interface, and calling isVisible at this interface. + This shortcut has been chosen since the caller usually already has this information. + If _bForce is <TRUE/>, _bIsCurrentlyVisible is ignored. + + @param _bForce + set to <TRUE/> if you want to force a ->XWindow::setVisible call, + no matter if the control visibility is already correct + + @precond + We're not disposed. + */ + static void impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rxControl, const SdrUnoObj& _rUnoObject, + IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce ); + + /** starts or stops listening at various aspects of our control + + @precond + ->m_aControl is not <NULL/> + */ + void impl_switchControlListening_nothrow( bool _bStart ); + + /** starts or stops listening at our control container + + @precond + ->m_xContainer is not <NULL/> + */ + void impl_switchContainerListening_nothrow( bool _bStart ); + + /** starts or stops listening at the control for design-mode relevant facets + */ + void impl_switchDesignModeListening_nothrow( bool _bStart ); + + /** starts or stops listening for all properties at our control + + @param _bStart + determines whether to start or to stop listening + + @precond + ->m_aControl is not <NULL/> + */ + void impl_switchPropertyListening_nothrow( bool _bStart ); + + /** disposes the instance + @param _bAlsoDisposeControl + determines whether the XControl should be disposed, too + */ + void impl_dispose_nothrow( bool _bAlsoDisposeControl ); + + /** determines whether the instance is disposed + @nofail + */ + bool impl_isDisposed_nofail() const { return m_pAntiImpl == NULL; } + + /** determines whether our control is currently visible + @nofail + */ + bool impl_isControlVisible_nofail() const { return m_bControlIsVisible; } + + /** determines whether we are currently a listener at the control for desgin-mode relevant facets + @nofail + */ + bool impl_isDesignModeListening_nofail() const { return m_bIsDesignModeListening; } + + /** determines whether the control currently is in design mode + + @precond + The design mode must already be known. It is known when we first had access to + an SdrPageView (which carries this flag), or somebody explicitly set it from + outside. + */ + inline bool impl_isControlDesignMode_nothrow() const + { + DBG_ASSERT( m_eControlDesignMode != eUnknown, "ViewObjectContactOfUnoControl_Impl::impl_isControlDesignMode_nothrow: mode is still unknown!" ); + return m_eControlDesignMode == eDesign; + } + + /** ensures that we have a control for the given PageView/OutputDevice + */ + bool impl_ensureControl_nothrow( + IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, + const basegfx::B2DHomMatrix& _rInitialViewTransformation + ); + + /** retrieves the device which a PageView belongs to, starting from its ObjectContactOfPageView + + Since #i72752#, the PaintWindow (and thus the OutputDevice) associated with a PageView is not + constant over its lifetime. Instead, during some paint operations, the PaintWindow/OutputDevice + might be temporarily patched. + + This method cares for this, by retrieving the very original OutputDevice. + */ + static const OutputDevice& impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ); + + const OutputDevice& impl_getOutputDevice_throw() const; + + private: + ViewObjectContactOfUnoControl_Impl(); // never implemented + ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented + ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented + }; + + //==================================================================== + //= VOCGuard + //==================================================================== + /** class for guarding a ViewObjectContactOfUnoControl_Impl method + */ + class VOCGuard + { + private: + ::osl::MutexGuard m_aMutexGuard; + + public: + VOCGuard( const ViewObjectContactOfUnoControl_Impl& _rImpl ) + :m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) + { + } + }; + + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D + { + private: + typedef ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D BufferedDecompositionPrimitive2D; + + protected: + virtual ::drawinglayer::primitive2d::Primitive2DSequence + get2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::drawinglayer::primitive2d::Primitive2DSequence + create2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::basegfx::B2DRange + getB2DRange( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + public: + LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl ) + :m_pVOCImpl( _pVOCImpl ) + { + ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." ); + getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation ); + } + + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + // declare unique ID for this primitive class + DeclPrimitrive2DIDBlock() + + static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ); + + private: + void impl_positionAndZoomControl( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + if ( !_rViewInformation.getViewport().isEmpty() ) + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + } + + private: + ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl; + /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand + (since the data the calculation is based on might have changed then), but need to calc + it at construction time, and remember it. + */ + ::basegfx::B2DHomMatrix m_aTransformation; + }; + + //==================================================================== + //= ViewObjectContactOfUnoControl_Impl + //==================================================================== + DBG_NAME( ViewObjectContactOfUnoControl_Impl ) + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ) + :m_pAntiImpl( _pAntiImpl ) + ,m_bCreatingControl( false ) + ,m_pOutputDeviceForWindow( NULL ) + ,m_bControlIsVisible( false ) + ,m_bIsDesignModeListening( false ) + ,m_eControlDesignMode( eUnknown ) + ,m_aZoomLevelNormalization() + { + DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL ); + DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" ); + + const OutputDevice& rPageViewDevice( impl_getOutputDevice_throw() ); + m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation(); + + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + m_aZoomLevelNormalization.decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + + ::basegfx::B2DHomMatrix aScaleNormalization; + MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() ); + aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() ); + aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() ); + m_aZoomLevelNormalization *= aScaleNormalization; + } + + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl() + { + if ( !impl_isDisposed_nofail() ) + { + acquire(); + dispose(); + } + + DBG_DTOR( ViewObjectContactOfUnoControl_Impl, NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_dispose_nothrow( bool _bAlsoDisposeControl ) + { + if ( impl_isDisposed_nofail() ) + return; + + if ( m_aControl.is() ) + impl_switchControlListening_nothrow( false ); + + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( false ); + + // dispose the control + if ( _bAlsoDisposeControl ) + UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl ); + + m_aControl.clear(); + m_xContainer.clear(); + m_pOutputDeviceForWindow = NULL; + m_bControlIsVisible = false; + + m_pAntiImpl = NULL; + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::dispose() + { + VOCGuard aGuard( *this ); + impl_dispose_nothrow( true ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::getUnoObject( SdrUnoObj*& _out_rpObject ) const + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::getUnoObject: already disposed()" ); + if ( impl_isDisposed_nofail() ) + _out_rpObject = NULL; + else + { + _out_rpObject = dynamic_cast< SdrUnoObj* >( m_pAntiImpl->GetViewContact().TryToGetSdrObject() ); + DBG_ASSERT( _out_rpObject || !m_pAntiImpl->GetViewContact().TryToGetSdrObject(), + "ViewObjectContactOfUnoControl_Impl::getUnoObject: invalid SdrObject!" ); + } + return ( _out_rpObject != NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); + if ( !m_aControl.is() ) + return; + + try + { + SdrUnoObj* pUnoObject( NULL ); + if ( getUnoObject( pUnoObject ) ) + { + UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization ); + } + else + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL ) + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); + if ( impl_isDisposed_nofail() ) + return false; + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + { + SdrPageViewAccess aPVAccess( pPageViewContact->GetPageWindow().GetPageView() ); + const OutputDevice& rDevice( impl_getPageViewOutputDevice_nothrow( *pPageViewContact ) ); + return impl_ensureControl_nothrow( + aPVAccess, + rDevice, + _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation() + ); + } + + DummyPageViewAccess aNoPageView; + const OutputDevice& rDevice( impl_getOutputDevice_throw() ); + return impl_ensureControl_nothrow( + aNoPageView, + rDevice, + _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation() + ); + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getOutputDevice_throw() const + { + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + { + // do not use ObjectContact::TryToGetOutputDevice here, it would not care for the PageWindow's + // OriginalPaintWindow + return impl_getPageViewOutputDevice_nothrow( *pPageViewContact ); + } + + const OutputDevice* pDevice = m_pAntiImpl->GetObjectContact().TryToGetOutputDevice(); + ENSURE_OR_THROW( pDevice, "no output device -> no control" ); + return *pDevice; + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) + { + // if the PageWindow has a patched PaintWindow, use the original PaintWindow + // this ensures that our control is _not_ re-created just because somebody + // (temporarily) changed the window to paint onto. + // #i72429# / 2007-02-20 / frank.schoenheit@sun.com + SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); + if ( rPageWindow.GetOriginalPaintWindow() ) + return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice(); + + return rPageWindow.GetPaintWindow().GetOutputDevice(); + } + + namespace + { + static void lcl_resetFlag( bool& rbFlag ) + { + rbFlag = false; + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow( IPageViewAccess& _rPageView, const OutputDevice& _rDevice, + const basegfx::B2DHomMatrix& _rInitialViewTransformation ) + { + if ( m_bCreatingControl ) + { + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: reentrance is not really good here!" ); + // We once had a situation where this was called reentrantly, which lead to all kind of strange effects. All + // those affected the grid control, which is the only control so far which is visible in design mode (and + // not only in alive mode). + // Creating the control triggered an Window::Update on some of its child windows, which triggered a + // Paint on parent of the grid control (e.g. the SwEditWin), which triggered a reentrant call to this method, + // which it is not really prepared for. + // + // /me thinks that re-entrance should be caught on a higher level, i.e. the Drawing Layer should not allow + // reentrant paint requests. For the moment, until /me can discuss this with AW, catch it here. + // 2009-08-27 / #i104544# frank.schoenheit@sun.com + return false; + } + + m_bCreatingControl = true; + ::comphelper::ScopeGuard aGuard( ::boost::bind( lcl_resetFlag, ::boost::ref( m_bCreatingControl ) ) ); + + if ( m_aControl.is() ) + { + if ( m_pOutputDeviceForWindow == &_rDevice ) + return true; + + // Somebody requested a control for a new device, which means either of + // - our PageView's paint window changed since we were last here + // - we don't belong to a page view, and are simply painted onto different devices + // The first sounds strange (doens't it?), the second means we could perhaps + // optimize this in the future - there is no need to re-create the control every time, + // is it? + // #i74523# / 2007-02-15 / frank.schoenheit@sun.com + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( false ); + impl_switchControlListening_nothrow( false ); + UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl ); + } + + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return false; + + ControlHolder aControl; + if ( !createControlForDevice( _rPageView, _rDevice, *pUnoObject, _rInitialViewTransformation, m_aZoomLevelNormalization, aControl ) ) + return false; + + m_pOutputDeviceForWindow = &_rDevice; + m_aControl = aControl; + m_xContainer = m_xContainer.query( _rPageView.getControlContainer( _rDevice ) ); + DBG_ASSERT( ( m_xContainer.is() // either have a XControlContainer + || ( ( !_rPageView.getControlContainer( _rDevice ).is() ) // or don't have any container, + && ( dynamic_cast< const Window* >( &_rDevice ) == NULL ) // which is allowed for non-Window instances only + ) + ), + "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: no XContainer at the ControlContainer!" ); + + try + { + m_eControlDesignMode = m_aControl.isDesignMode() ? eDesign : eAlive; + m_bControlIsVisible = m_aControl.isVisible(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // start listening at all aspects of the control which are interesting to us ... + impl_switchControlListening_nothrow( true ); + + // start listening at the control container, in case somebody tampers with our control + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( true ); + + return m_aControl.is(); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::createControlForDevice( IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, const SdrUnoObj& _rUnoObject, const basegfx::B2DHomMatrix& _rInitialViewTransformation, + const basegfx::B2DHomMatrix& _rInitialZoomNormalization, ControlHolder& _out_rControl ) + { + _out_rControl.clear(); + + Reference< XControlModel > xControlModel( _rUnoObject.GetUnoControlModel() ); + DBG_ASSERT( xControlModel.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control model at the SdrUnoObject!?" ); + if ( !xControlModel.is() ) + return false; + + bool bSuccess = false; + try + { + const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); + + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW ); + + // knit the model and the control + _out_rControl.setModel( xControlModel ); + + // proper geometry + UnoControlContactHelper::adjustControlGeometry_throw( + _out_rControl, + _rUnoObject.GetLogicRect(), + _rInitialViewTransformation, + _rInitialZoomNormalization + ); + + // #107049# set design mode before peer is created, + // this is also needed for accessibility + _out_rControl.setDesignMode( _rPageView.isDesignMode() ); + + // adjust the initial visibility according to the visibility of the layer + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); + + // add the control to the respective control container + // #108327# do this last + Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); + if ( xControlContainer.is() ) + xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); + + bSuccess = true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( !bSuccess ) + { + // delete the control which might have been created already + UnoControlContactHelper::disposeAndClearControl_nothrow( _out_rControl ); + } + + return _out_rControl.is(); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow( SdrPageView*& _out_rpPageView ) + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: already disposed!" ); + + _out_rpPageView = NULL; + if ( impl_isDisposed_nofail() ) + return false; + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + _out_rpPageView = &pPageViewContact->GetPageWindow().GetPageView(); + + DBG_ASSERT( _out_rpPageView != NULL, "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: this method is expected to always have success!" ); + return ( _out_rpPageView != NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce ) + { + OSL_PRECOND( m_aControl.is(), + "ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw: only valid if we have a control!" ); + + SdrPageView* pPageView( NULL ); + if ( !impl_getPageView_nothrow( pPageView ) ) + return; + + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return; + + SdrPageViewAccess aPVAccess( *pPageView ); + impl_adjustControlVisibilityToLayerVisibility_throw( m_aControl, *pUnoObject, aPVAccess, impl_isControlVisible_nofail(), _bForce ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rControl, + const SdrUnoObj& _rUnoObject, IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce ) + { + // in design mode, there is no problem with the visibility: The XControl is hidden by + // default, and the Drawing Layer will simply not call our paint routine, if we're in + // a hidden layer. So, only alive mode matters. + if ( !_rControl.isDesignMode() ) + { + // the layer of our object + SdrLayerID nObjectLayer = _rUnoObject.GetLayer(); + // is the object we're residing in visible in this view? + bool bIsObjectVisible = _rUnoObject.IsVisible() && _rPageView.isLayerVisible( nObjectLayer ); + + if ( _bForce || ( bIsObjectVisible != _bIsCurrentlyVisible ) ) + { + _rControl.setVisible( bIsObjectVisible ); + } + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_xContainer.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow: no control container!" ); + if ( !m_xContainer.is() ) + return; + + try + { + if ( _bStart ) + m_xContainer->addContainerListener( this ); + else + m_xContainer->removeContainerListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow: invalid control!" ); + if ( !m_aControl.is() ) + return; + + try + { + // listen for visibility changes + if ( _bStart ) + m_aControl.addWindowListener( this ); + else + m_aControl.removeWindowListener( this ); + + // in design mode, listen for some more aspects + impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() && _bStart ); + + // listen for design mode changes + Reference< XModeChangeBroadcaster > xDesignModeChanges( m_aControl.getControl(), UNO_QUERY_THROW ); + if ( _bStart ) + xDesignModeChanges->addModeChangeListener( this ); + else + xDesignModeChanges->removeModeChangeListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchDesignModeListening_nothrow( bool _bStart ) + { + if ( impl_isDesignModeListening_nofail() != _bStart ) + { + m_bIsDesignModeListening = _bStart; + impl_switchPropertyListening_nothrow( _bStart ); + } + } + + //------------------------------------------------------------------------------ + void ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow: no control!" ); + if ( !m_aControl.is() ) + return; + + try + { + Reference< XPropertySet > xModelProperties( m_aControl.getModel(), UNO_QUERY_THROW ); + if ( _bStart ) + xModelProperties->addPropertyChangeListener( ::rtl::OUString(), this ); + else + xModelProperties->removePropertyChangeListener( ::rtl::OUString(), this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const + { + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return false; + + bool bIsPrintable = false; + try + { + Reference< XPropertySet > xModelProperties( pUnoObject->GetUnoControlModel(), UNO_QUERY_THROW ); + static const ::rtl::OUString s_sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ); + OSL_VERIFY( xModelProperties->getPropertyValue( s_sPrintablePropertyName ) >>= bIsPrintable ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bIsPrintable; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::disposing( const EventObject& Source ) throw(RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // some code below - in particular our disposal - might trigger actions which require the + // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control, + // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex - + // is the real bug. Toolkit really is infested with solar mutex usage ... :( + // #i82169# / 2007-11-14 / frank.schoenheit@sun.com + VOCGuard aGuard( *this ); + + if ( !m_aControl.is() ) + return; + + if ( ( m_aControl == Source.Source ) + || ( m_aControl.getModel() == Source.Source ) + ) + { + // the model or the control is dying ... hmm, not much sense in that we ourself continue + // living + impl_dispose_nothrow( false ); + return; + } + + DBG_ASSERT( Source.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::disposing: Who's this?" ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowResized( const WindowEvent& /*e*/ ) throw(RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowMoved( const WindowEvent& /*e*/ ) throw(RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowShown( const EventObject& /*e*/ ) throw(RuntimeException) + { + VOCGuard aGuard( *this ); + m_bControlIsVisible = true; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowHidden( const EventObject& /*e*/ ) throw(RuntimeException) + { + VOCGuard aGuard( *this ); + m_bControlIsVisible = false; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw(RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // (re)painting might require VCL operations, which need the SolarMutex + + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::propertyChange: already disposed()" ); + if ( impl_isDisposed_nofail() ) + return; + + VOCGuard aGuard( *this ); + DBG_ASSERT( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::propertyChange: " ); + if ( !m_aControl.is() ) + return; + + // a generic property changed. If we're in design mode, we need to repaint the control + if ( impl_isControlDesignMode_nothrow() ) + { + m_pAntiImpl->propertyChange(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException) + { + VOCGuard aGuard( *this ); + + DBG_ASSERT( _rSource.NewMode.equalsAscii( "design" ) || _rSource.NewMode.equalsAscii( "alive" ), + "ViewObjectContactOfUnoControl_Impl::modeChanged: unexpected mode!" ); + + m_eControlDesignMode = _rSource.NewMode.equalsAscii( "design" ) ? eDesign : eAlive; + + impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() ); + + try + { + // if the control is part of a invisible layer, we need to explicitly hide it in alive mode + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( false ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementInserted( const ContainerEvent& /*_Event*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // some code below - in particular our disposal - might trigger actions which require the + // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control, + // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex - + // is the real bug. Toolkit really is infested with solar mutex usage ... :( + // #i82169# / 2007-11-14 / frank.schoenheit@sun.com + VOCGuard aGuard( *this ); + DBG_ASSERT( Event.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::elementRemoved: where did this come from?" ); + + if ( m_aControl == Event.Element ) + impl_dispose_nothrow( false ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementReplaced( const ContainerEvent& Event ) throw (RuntimeException) + { + VOCGuard aGuard( *this ); + DBG_ASSERT( Event.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::elementReplaced: where did this come from?" ); + + if ( ! ( m_aControl == Event.ReplacedElement ) ) + return; + + Reference< XControl > xNewControl( Event.Element, UNO_QUERY ); + DBG_ASSERT( xNewControl.is(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: invalid new control!" ); + if ( !xNewControl.is() ) + return; + + ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." ); + + DBG_ASSERT( xNewControl->getModel() == m_aControl.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" ); + // another model should - in the drawing layer - also imply another SdrUnoObj, which + // should also result in new ViewContact, and thus in new ViewObjectContacts + + impl_switchControlListening_nothrow( false ); + + ControlHolder aNewControl( xNewControl ); + aNewControl.setZoom( m_aControl.getZoom() ); + aNewControl.setPosSize( m_aControl.getPosSize() ); + aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() ); + + m_aControl = xNewControl; + m_bControlIsVisible = m_aControl.isVisible(); + + impl_switchControlListening_nothrow( true ); + + m_pAntiImpl->onControlChangedOrModified( ViewObjectContactOfUnoControl::ImplAccess() ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::setControlDesignMode( bool _bDesignMode ) const + { + if ( ( m_eControlDesignMode != eUnknown ) && ( _bDesignMode == impl_isControlDesignMode_nothrow() ) ) + // nothing to do + return; + m_eControlDesignMode = _bDesignMode ? eDesign : eAlive; + + if ( !m_aControl.is() ) + // nothing to do, the setting will be respected as soon as the control + // is created + return; + + try + { + m_aControl.setDesignMode( _bDesignMode ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + //-------------------------------------------------------------------- + bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if ( !BufferedDecompositionPrimitive2D::operator==( rPrimitive ) ) + return false; + + const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive ); + if ( !pRHS ) + return false; + + if ( m_pVOCImpl != pRHS->m_pVOCImpl ) + return false; + + if ( m_aTransformation != pRHS->m_aTransformation ) + return false; + + return true; + } + + //-------------------------------------------------------------------- + void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ) + { + // Do use model data directly to create the correct geometry. Do NOT + // use getBoundRect()/getSnapRect() here; tese will use the sequence of + // primitives themselves in the long run. + const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + const basegfx::B2DRange aRange( + aSdrGeoData.Left(), + aSdrGeoData.Top(), + aSdrGeoData.Right(), + aSdrGeoData.Bottom() + ); + + _out_Transformation.identity(); + _out_Transformation.set( 0, 0, aRange.getWidth() ); + _out_Transformation.set( 1, 1, aRange.getHeight() ); + _out_Transformation.set( 0, 2, aRange.getMinX() ); + _out_Transformation.set( 1, 2, aRange.getMinY() ); + } + + //-------------------------------------------------------------------- + ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const + { + ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 ); + aRange.transform( m_aTransformation ); + return aRange; + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + if ( m_pVOCImpl->hasControl() ) + impl_positionAndZoomControl( _rViewInformation ); + return BufferedDecompositionPrimitive2D::get2DDecomposition( _rViewInformation ); + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::create2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + const bool bHadControl = m_pVOCImpl->getExistentControl().is(); + + // force control here to make it a VCL ChildWindow. Will be fetched + // and used below by getExistentControl() + m_pVOCImpl->ensureControl( &_rViewInformation.getObjectToViewTransformation() ); + impl_positionAndZoomControl( _rViewInformation ); + + // get needed data + const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() ); + Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() ); + const ControlHolder& rControl( m_pVOCImpl->getExistentControl() ); + + if ( !bHadControl && rControl.is() && rControl.isVisible() ) + rControl.invalidate(); + + if ( !bHadControl && rControl.is() && rControl.isVisible() ) + rControl.invalidate(); + + // check if we already have an XControl. + if ( !xControlModel.is() || !rControl.is() ) + // use the default mechanism. This will create a ControlPrimitive2D without + // handing over a XControl. If not even a XControlModel exists, it will + // create the SdrObject fallback visualisation + return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); + + // create a primitive and hand over the existing xControl. This will + // allow the primitive to not need to create another one on demand. + const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D( + m_aTransformation, xControlModel, rControl.getControl() ) ); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + + //-------------------------------------------------------------------- + ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D ) + + //==================================================================== + //= ViewObjectContactOfUnoControl + //==================================================================== + DBG_NAME( ViewObjectContactOfUnoControl ) + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl::ViewObjectContactOfUnoControl( ObjectContact& _rObjectContact, ViewContactOfUnoControl& _rViewContact ) + :ViewObjectContactOfSdrObj( _rObjectContact, _rViewContact ) + ,m_pImpl( new ViewObjectContactOfUnoControl_Impl( this ) ) + { + DBG_CTOR( ViewObjectContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl::~ViewObjectContactOfUnoControl() + { + m_pImpl->dispose(); + m_pImpl = NULL; + + DBG_DTOR( ViewObjectContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl::isControlVisible() const + { + VOCGuard aGuard( *m_pImpl ); + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + return rControl.is() && rControl.isVisible(); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewObjectContactOfUnoControl::getControl() + { + VOCGuard aGuard( *m_pImpl ); + m_pImpl->ensureControl( NULL ); + return m_pImpl->getExistentControl().getControl(); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewObjectContactOfUnoControl::getTemporaryControlForWindow( + const Window& _rWindow, Reference< XControlContainer >& _inout_ControlContainer, const SdrUnoObj& _rUnoObject ) + { + ControlHolder aControl; + + InvisibleControlViewAccess aSimulatePageView( _inout_ControlContainer ); + OSL_VERIFY( ViewObjectContactOfUnoControl_Impl::createControlForDevice( aSimulatePageView, _rWindow, _rUnoObject, + _rWindow.GetViewTransformation(), _rWindow.GetInverseViewTransformation(), aControl ) ); + return aControl.getControl(); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const + { + VOCGuard aGuard( *m_pImpl ); + + try + { + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + if ( !rControl.is() ) + return; + + // only need to care for alive mode + if ( rControl.isDesignMode() ) + return; + + // is the visibility correct? + if ( m_pImpl->isControlVisible() == _bVisible ) + return; + + // no -> adjust it + rControl.setVisible( _bVisible ); + DBG_ASSERT( m_pImpl->isControlVisible() == _bVisible, "ViewObjectContactOfUnoControl::ensureControlVisibility: this didn't work!" ); + // now this would mean that either isControlVisible is not reliable, + // or that showing/hiding the window did not work as intended. + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::setControlDesignMode( bool _bDesignMode ) const + { + VOCGuard aGuard( *m_pImpl ); + m_pImpl->setControlDesignMode( _bDesignMode ); + + if(!_bDesignMode) + { + // when live mode is switched on, a refresh is needed. The edit mode visualisation + // needs to be repainted and the now used VCL-Window needs to be positioned and + // sized. Both is done from the repant refresh. + const_cast< ViewObjectContactOfUnoControl* >(this)->ActionChanged(); + } + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + if ( m_pImpl->isDisposed() ) + // our control already died. + // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance + // disposed the control though it doesn't own it. So, /me thinks we should not bother here. + return drawinglayer::primitive2d::Primitive2DSequence(); + + // ignore existing controls which are in alive mode and manually switched to "invisible" + // #102090# / 2009-06-05 / frank.schoenheit@sun.com + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + if ( rControl.is() && !rControl.isDesignMode() && !rControl.isVisible() ) + return drawinglayer::primitive2d::Primitive2DSequence(); + + ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) ); + return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl::isPrimitiveVisible( const DisplayInfo& _rDisplayInfo ) const + { + VOCGuard aGuard( *m_pImpl ); + + if ( m_pImpl->hasControl() ) + { + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation( GetObjectContact().getViewInformation2D() ); + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + + if ( !rViewInformation.getViewport().isEmpty() ) + m_pImpl->positionAndZoomControl( rViewInformation.getObjectToViewTransformation() ); + } + + return ViewObjectContactOfSdrObj::isPrimitiveVisible( _rDisplayInfo ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::propertyChange() + { + impl_onControlChangedOrModified(); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::ActionChanged() + { + // call parent + ViewObjectContactOfSdrObj::ActionChanged(); + const ControlHolder& rControl(m_pImpl->getExistentControl()); + + if(rControl.is() && !rControl.isDesignMode()) + { + // #i93180# if layer visibility has changed and control is in live mode, it is necessary + // to correct visibility to make those control vanish on SdrObject LayerID changes + const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pSdrPageView) + { + const SdrObject& rObject = getSdrObject(); + const bool bIsLayerVisible( rObject.IsVisible() && pSdrPageView->GetVisibleLayers().IsSet(rObject.GetLayer())); + + if(rControl.isVisible() != bIsLayerVisible) + { + rControl.setVisible(bIsLayerVisible); + } + } + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::impl_onControlChangedOrModified() + { + // graphical invalidate at all views + ActionChanged(); + + // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel + // since e.g. background color has changed and existing decompositions are possibly no + // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator== + // since it only has a uno reference to the XControlModel + flushPrimitive2DSequence(); + } + + //==================================================================== + //= UnoControlPrintOrPreviewContact + //==================================================================== + DBG_NAME( UnoControlPrintOrPreviewContact ) + //-------------------------------------------------------------------- + UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView& _rObjectContact, ViewContactOfUnoControl& _rViewContact ) + :ViewObjectContactOfUnoControl( _rObjectContact, _rViewContact ) + { + DBG_CTOR( UnoControlPrintOrPreviewContact, NULL ); + } + + //-------------------------------------------------------------------- + UnoControlPrintOrPreviewContact::~UnoControlPrintOrPreviewContact() + { + DBG_DTOR( UnoControlPrintOrPreviewContact, NULL ); + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo ) const + { + if ( !m_pImpl->isPrintableControl() ) + return drawinglayer::primitive2d::Primitive2DSequence(); + return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo ); + } + +//........................................................................ +} } // namespace sdr::contact +//........................................................................ + diff --git a/svx/source/sdr/contact/viewobjectcontactredirector.cxx b/svx/source/sdr/contact/viewobjectcontactredirector.cxx new file mode 100644 index 000000000000..8d96b17f0a58 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactredirector.cxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * 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/viewobjectcontactredirector.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // basic constructor. + ViewObjectContactRedirector::ViewObjectContactRedirector() + { + } + + // The destructor. + ViewObjectContactRedirector::~ViewObjectContactRedirector() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( + const sdr::contact::ViewObjectContact& rOriginal, + const sdr::contact::DisplayInfo& rDisplayInfo) + { + return rOriginal.createPrimitive2DSequence(rDisplayInfo); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/event/eventhandler.cxx b/svx/source/sdr/event/eventhandler.cxx new file mode 100644 index 000000000000..967b6fefe949 --- /dev/null +++ b/svx/source/sdr/event/eventhandler.cxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * 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/event/eventhandler.hxx> + +// for SOLARIS compiler include of algorithm part of _STL is necesary to +// get access to basic algos like ::std::find +#include <algorithm> +#include <tools/debug.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace event + { + BaseEvent::BaseEvent(EventHandler& rEventHandler) + : mrEventHandler(rEventHandler) + { + mrEventHandler.AddEvent(*this); + } + + BaseEvent::~BaseEvent() + { + mrEventHandler.RemoveEvent(*this); + } + } // end of namespace mixer +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace event + { + void EventHandler::AddEvent(BaseEvent& rBaseEvent) + { + maVector.push_back(&rBaseEvent); + } + + void EventHandler::RemoveEvent(BaseEvent& rBaseEvent) + { + if(maVector.back() == &rBaseEvent) + { + // the one to remove is the last, pop + maVector.pop_back(); + } + else + { + const BaseEventVector::iterator aFindResult = ::std::find( + maVector.begin(), maVector.end(), &rBaseEvent); + DBG_ASSERT(aFindResult != maVector.end(), + "EventHandler::RemoveEvent: Event to be removed not found (!)"); + maVector.erase(aFindResult); + } + } + + BaseEvent* EventHandler::GetEvent() + { + if(maVector.size()) + { + // get the last event, that one is fastest to be removed + return maVector.back(); + } + else + { + return 0L; + } + } + + EventHandler::EventHandler() + { + } + + EventHandler::~EventHandler() + { + while(maVector.size()) + { + delete GetEvent(); + } + } + + // Trigger and consume the events + void EventHandler::ExecuteEvents() + { + for(;;) + { + BaseEvent* pEvent = GetEvent(); + if(pEvent == NULL) + break; + pEvent->ExecuteEvent(); + delete pEvent; + } + } + + // for control + sal_Bool EventHandler::IsEmpty() const + { + return (0L == maVector.size()); + } + } // end of namespace mixer +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace event + { + TimerEventHandler::TimerEventHandler(sal_uInt32 nTimeout) + { + SetTimeout(nTimeout); + Stop(); + } + + TimerEventHandler::~TimerEventHandler() + { + Stop(); + } + + // The timer when it is triggered; from class Timer + void TimerEventHandler::Timeout() + { + ExecuteEvents(); + } + + // reset the timer + void TimerEventHandler::Restart() + { + Start(); + } + } // end of namespace mixer +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/event/makefile.mk b/svx/source/sdr/event/makefile.mk new file mode 100644 index 000000000000..ff379af6be2a --- /dev/null +++ b/svx/source/sdr/event/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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=event +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/eventhandler.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/overlay/makefile.mk b/svx/source/sdr/overlay/makefile.mk new file mode 100644 index 000000000000..155053826f0d --- /dev/null +++ b/svx/source/sdr/overlay/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# 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=overlay +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/overlayanimatedbitmapex.obj \ + $(SLO)$/overlaybitmapex.obj \ + $(SLO)$/overlaycrosshair.obj \ + $(SLO)$/overlayhatchrect.obj \ + $(SLO)$/overlayhelpline.obj \ + $(SLO)$/overlayline.obj \ + $(SLO)$/overlaymanager.obj \ + $(SLO)$/overlaymanagerbuffered.obj \ + $(SLO)$/overlayobject.obj \ + $(SLO)$/overlayobjectcell.obj \ + $(SLO)$/overlayobjectlist.obj \ + $(SLO)$/overlaypolypolygon.obj \ + $(SLO)$/overlayprimitive2dsequenceobject.obj \ + $(SLO)$/overlayrollingrectangle.obj \ + $(SLO)$/overlayselection.obj \ + $(SLO)$/overlaytools.obj \ + $(SLO)$/overlaytriangle.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx b/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx new file mode 100644 index 000000000000..6fbd294a6559 --- /dev/null +++ b/svx/source/sdr/overlay/overlayanimatedbitmapex.cxx @@ -0,0 +1,217 @@ +/************************************************************************* + * + * 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/overlay/overlayanimatedbitmapex.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + // #i53216# check blink time value range + void OverlayAnimatedBitmapEx::impCheckBlinkTimeValueRange() + { + if(mnBlinkTime < 25) + { + mnBlinkTime = 25; + } + else if(mnBlinkTime > 10000) + { + mnBlinkTime = 10000; + } + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayAnimatedBitmapEx::createOverlayObjectPrimitive2DSequence() + { + if(mbOverlayState) + { + const drawinglayer::primitive2d::Primitive2DReference aPrimitive( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx1(), + getBasePosition(), + getCenterX1(), + getCenterY1())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aPrimitive, 1); + } + else + { + const drawinglayer::primitive2d::Primitive2DReference aPrimitive( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx2(), + getBasePosition(), + getCenterX2(), + getCenterY2())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aPrimitive, 1); + } + } + + OverlayAnimatedBitmapEx::OverlayAnimatedBitmapEx( + const basegfx::B2DPoint& rBasePos, + const BitmapEx& rBitmapEx1, + const BitmapEx& rBitmapEx2, + sal_uInt32 nBlinkTime, + sal_uInt16 nCenX1, + sal_uInt16 nCenY1, + sal_uInt16 nCenX2, + sal_uInt16 nCenY2) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_WHITE)), + maBitmapEx1(rBitmapEx1), + maBitmapEx2(rBitmapEx2), + mnCenterX1(nCenX1), mnCenterY1(nCenY1), + mnCenterX2(nCenX2), mnCenterY2(nCenY2), + mnBlinkTime(nBlinkTime), + mbOverlayState(false) + { + // set AllowsAnimation flag to mark this object as animation capable + mbAllowsAnimation = true; + + // #i53216# check blink time value range + impCheckBlinkTimeValueRange(); + } + + OverlayAnimatedBitmapEx::~OverlayAnimatedBitmapEx() + { + } + + void OverlayAnimatedBitmapEx::setBitmapEx1(const BitmapEx& rNew) + { + if(rNew != maBitmapEx1) + { + // remember new Bitmap + maBitmapEx1 = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setBitmapEx2(const BitmapEx& rNew) + { + if(rNew != maBitmapEx2) + { + // remember new Bitmap + maBitmapEx2 = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setCenterXY1(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX1 || nNewY != mnCenterY1) + { + // remember new values + if(nNewX != mnCenterX1) + { + mnCenterX1 = nNewX; + } + + if(nNewY != mnCenterY1) + { + mnCenterY1 = nNewY; + } + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setCenterXY2(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX2 || nNewY != mnCenterY2) + { + // remember new values + if(nNewX != mnCenterX2) + { + mnCenterX2 = nNewX; + } + + if(nNewY != mnCenterY2) + { + mnCenterY2 = nNewY; + } + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::setBlinkTime(sal_uInt32 nNew) + { + if(mnBlinkTime != nNew) + { + // remember new value + mnBlinkTime = nNew; + + // #i53216# check blink time value range + impCheckBlinkTimeValueRange(); + + // register change (after change) + objectChange(); + } + } + + void OverlayAnimatedBitmapEx::Trigger(sal_uInt32 nTime) + { + if(getOverlayManager()) + { + // #i53216# produce event after nTime + x + SetTime(nTime + mnBlinkTime); + + // switch state + if(mbOverlayState) + { + mbOverlayState = false; + } + else + { + mbOverlayState = true; + } + + // re-insert me as event + getOverlayManager()->InsertEvent(this); + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaybitmapex.cxx b/svx/source/sdr/overlay/overlaybitmapex.cxx new file mode 100644 index 000000000000..2a3a00b25b99 --- /dev/null +++ b/svx/source/sdr/overlay/overlaybitmapex.cxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * 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 <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <svx/sdr/overlay/overlaybitmapex.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayBitmapEx::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayBitmapExPrimitive( + getBitmapEx(), + getBasePosition(), + getCenterX(), + getCenterY())); + + if(basegfx::fTools::more(mfAlpha, 0.0)) + { + const drawinglayer::primitive2d::Primitive2DSequence aNewTransPrimitiveVector(&aReference, 1L); + aReference = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aNewTransPrimitiveVector, mfAlpha)); + } + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayBitmapEx::OverlayBitmapEx( + const basegfx::B2DPoint& rBasePos, + const BitmapEx& rBitmapEx, + sal_uInt16 nCenX, sal_uInt16 nCenY, double fAlpha) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_WHITE)), + maBitmapEx(rBitmapEx), + mnCenterX(nCenX), + mnCenterY(nCenY), + mfAlpha(fAlpha) + { + } + + OverlayBitmapEx::~OverlayBitmapEx() + { + } + + void OverlayBitmapEx::setBitmapEx(const BitmapEx& rNew) + { + if(rNew != maBitmapEx) + { + // remember new Bitmap + maBitmapEx = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayBitmapEx::setCenterXY(sal_uInt16 nNewX, sal_uInt16 nNewY) + { + if(nNewX != mnCenterX || nNewY != mnCenterY) + { + // remember new values + if(nNewX != mnCenterX) + { + mnCenterX = nNewX; + } + + if(nNewY != mnCenterY) + { + mnCenterY = nNewY; + } + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaycrosshair.cxx b/svx/source/sdr/overlay/overlaycrosshair.cxx new file mode 100644 index 000000000000..cf1c4c4a3c88 --- /dev/null +++ b/svx/source/sdr/overlay/overlaycrosshair.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * 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/overlay/overlaycrosshair.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayCrosshairStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayCrosshairPrimitive( + getBasePosition(), + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayCrosshairStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayCrosshairStriped::OverlayCrosshairStriped(const basegfx::B2DPoint& rBasePos) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)) + { + } + + OverlayCrosshairStriped::~OverlayCrosshairStriped() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayhatchrect.cxx b/svx/source/sdr/overlay/overlayhatchrect.cxx new file mode 100644 index 000000000000..64bd9e11b31f --- /dev/null +++ b/svx/source/sdr/overlay/overlayhatchrect.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * 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/overlay/overlayhatchrect.hxx> +#include <vcl/hatch.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayHatchRect::createOverlayObjectPrimitive2DSequence() + { + const basegfx::B2DRange aHatchRange(getBasePosition(), getSecondPosition()); + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayHatchRectanglePrimitive( + aHatchRange, + 3.0, + getHatchRotation(), + getBaseColor().getBColor(), + getDiscreteGrow(), + getDiscreteShrink(), + getRotation())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayHatchRect::OverlayHatchRect( + const basegfx::B2DPoint& rBasePosition, + const basegfx::B2DPoint& rSecondPosition, + const Color& rHatchColor, + double fDiscreteGrow, + double fDiscreteShrink, + double fHatchRotation, + double fRotation) + : OverlayObjectWithBasePosition(rBasePosition, rHatchColor), + maSecondPosition(rSecondPosition), + mfDiscreteGrow(fDiscreteGrow), + mfDiscreteShrink(fDiscreteShrink), + mfHatchRotation(fHatchRotation), + mfRotation(fRotation) + { + } + + void OverlayHatchRect::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayhelpline.cxx b/svx/source/sdr/overlay/overlayhelpline.cxx new file mode 100644 index 000000000000..3417cc4a651f --- /dev/null +++ b/svx/source/sdr/overlay/overlayhelpline.cxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * 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/overlay/overlayhelpline.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayHelplineStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + const drawinglayer::primitive2d::HelplineStyle aStyle( + SDRHELPLINE_POINT == getKind() ? drawinglayer::primitive2d::HELPLINESTYLE_POINT : + SDRHELPLINE_VERTICAL == getKind() ? drawinglayer::primitive2d::HELPLINESTYLE_VERTICAL : + drawinglayer::primitive2d::HELPLINESTYLE_HORIZONTAL); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayHelplineStripedPrimitive( + getBasePosition(), + aStyle, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayHelplineStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayHelplineStriped::OverlayHelplineStriped( + const basegfx::B2DPoint& rBasePos, + SdrHelpLineKind eNewKind) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + meKind(eNewKind) + { + } + + OverlayHelplineStriped::~OverlayHelplineStriped() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayline.cxx b/svx/source/sdr/overlay/overlayline.cxx new file mode 100644 index 000000000000..4d53ac480241 --- /dev/null +++ b/svx/source/sdr/overlay/overlayline.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * 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/overlay/overlayline.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayLineStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + basegfx::B2DPolygon aLine; + + aLine.append(getBasePosition()); + aLine.append(getSecondPosition()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( + aLine, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayLineStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayLineStriped::OverlayLineStriped( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + maSecondPosition(rSecondPos) + { + } + + OverlayLineStriped::~OverlayLineStriped() + { + } + + void OverlayLineStriped::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx new file mode 100644 index 000000000000..f52205d88e45 --- /dev/null +++ b/svx/source/sdr/overlay/overlaymanager.cxx @@ -0,0 +1,393 @@ +/************************************************************************* + * + * 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/overlay/overlaymanager.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <vcl/window.hxx> +#include <svx/sdr/overlay/overlayobject.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/processor2d/baseprocessor2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const + { + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing()); + const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing()); + + // create processor + drawinglayer::processor2d::BaseProcessor2D* pProcessor = ::sdr::contact::createBaseProcessor2DFromOutputDevice( + rDestinationDevice, + getCurrentViewInformation2D()); + + if(pProcessor) + { + for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + const OverlayObject& rCandidate = **aIter; + + if(rCandidate.isVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rCandidate.getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + if(rRange.overlaps(rCandidate.getBaseRange())) + { + if(bIsAntiAliasing && rCandidate.allowsAntiAliase()) + { + rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW); + } + else + { + rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW); + } + + pProcessor->process(rSequence); + } + } + } + } + + delete pProcessor; + } + + // restore AA settings + rDestinationDevice.SetAntialiasing(nOriginalAA); + } + } + + void OverlayManager::ImpStripeDefinitionChanged() + { + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + rCandidate.stripeDefinitionHasChanged(); + } + } + } + + double OverlayManager::getDiscreteOne() const + { + if(basegfx::fTools::equalZero(mfDiscreteOne)) + { + const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0)); + const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength(); + } + + return mfDiscreteOne; + } + + OverlayManager::OverlayManager( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager) + : Scheduler(), + rmOutputDevice(rOutputDevice), + maOverlayObjects(), + maStripeColorA(Color(COL_BLACK)), + maStripeColorB(Color(COL_WHITE)), + mnStripeLengthPixel(5), + maDrawinglayerOpt(), + maViewTransformation(), + maViewInformation2D(0), + mfDiscreteOne(0.0) + { + // set Property 'ReducedDisplayQuality' to true to allow simpler interaction + // visualisations + static bool bUseReducedDisplayQualityForDrag(true); + + if(bUseReducedDisplayQualityForDrag) + { + uno::Sequence< beans::PropertyValue > xProperties(1); + xProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality")); + xProperties[0].Value <<= true; + maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties); + } + + if(pOldOverlayManager) + { + // take over OverlayObjects from given OverlayManager. Copy + // the vector of pointers + maOverlayObjects = pOldOverlayManager->maOverlayObjects; + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + + // remove from old and add to new OverlayManager + pOldOverlayManager->impApplyRemoveActions(rCandidate); + impApplyAddActions(rCandidate); + } + + pOldOverlayManager->maOverlayObjects.clear(); + } + } + } + + const drawinglayer::geometry::ViewInformation2D OverlayManager::getCurrentViewInformation2D() const + { + if(getOutputDevice().GetViewTransformation() != maViewTransformation) + { + basegfx::B2DRange aViewRange(maViewInformation2D.getViewport()); + + if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) + { + const Size aOutputSizePixel(getOutputDevice().GetOutputSizePixel()); + aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + aViewRange.transform(getOutputDevice().GetInverseViewTransformation()); + } + + OverlayManager* pThis = const_cast< OverlayManager* >(this); + + pThis->maViewTransformation = getOutputDevice().GetViewTransformation(); + pThis->maViewInformation2D = drawinglayer::geometry::ViewInformation2D( + maViewInformation2D.getObjectTransformation(), + maViewTransformation, + aViewRange, + maViewInformation2D.getVisualizedPage(), + maViewInformation2D.getViewTime(), + maViewInformation2D.getExtendedInformationSequence()); + pThis->mfDiscreteOne = 0.0; + } + + return maViewInformation2D; + } + + void OverlayManager::impApplyRemoveActions(OverlayObject& rTarget) + { + // handle evtl. animation + if(rTarget.allowsAnimation()) + { + // remove from event chain + RemoveEvent(&rTarget); + } + + // make invisible + invalidateRange(rTarget.getBaseRange()); + + // clear manager + rTarget.mpOverlayManager = 0; + } + + void OverlayManager::impApplyAddActions(OverlayObject& rTarget) + { + // set manager + rTarget.mpOverlayManager = this; + + // make visible + invalidateRange(rTarget.getBaseRange()); + + // handle evtl. animation + if(rTarget.allowsAnimation()) + { + // Trigger at current time to get alive. This will do the + // object-specific next time calculation and hand over adding + // again to the scheduler to the animated object, too. This works for + // a paused or non-paused animator. + rTarget.Trigger(GetTime()); + } + } + + OverlayManager::~OverlayManager() + { + // The OverlayManager is not the owner of the OverlayObjects + // and thus will not delete them, but remove them. Profit here + // from knowing that all will be removed + const sal_uInt32 nSize(maOverlayObjects.size()); + + if(nSize) + { + for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); aIter++) + { + OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)"); + OverlayObject& rCandidate = **aIter; + impApplyRemoveActions(rCandidate); + } + + // erase vector + maOverlayObjects.clear(); + } + } + + void OverlayManager::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const + { + if(!rRegion.IsEmpty() && maOverlayObjects.size()) + { + // check for changed MapModes. That may influence the + // logical size of pixel based OverlayObjects (like BitmapHandles) + //ImpCheckMapModeChange(); + + // paint members + const Rectangle aRegionBoundRect(rRegion.GetBoundRect()); + const basegfx::B2DRange aRegionRange( + aRegionBoundRect.Left(), aRegionBoundRect.Top(), + aRegionBoundRect.Right(), aRegionBoundRect.Bottom()); + + OutputDevice& rTarget = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice(); + ImpDrawMembers(aRegionRange, rTarget); + } + } + + void OverlayManager::flush() + { + // default has nothing to do + } + + // #i68597# part of content gets copied, react on it + void OverlayManager::copyArea(const Point& /*rDestPt*/, const Point& /*rSrcPt*/, const Size& /*rSrcSize*/) + { + // unbuffered versions do nothing here + } + + void OverlayManager::restoreBackground(const Region& /*rRegion*/) const + { + // unbuffered versions do nothing here + } + + void OverlayManager::add(OverlayObject& rOverlayObject) + { + OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)"); + + // add to the end of chain to preserve display order in paint + maOverlayObjects.push_back(&rOverlayObject); + + // execute add actions + impApplyAddActions(rOverlayObject); + } + + void OverlayManager::remove(OverlayObject& rOverlayObject) + { + OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)"); + + // execute remove actions + impApplyRemoveActions(rOverlayObject); + + // remove from vector + const OverlayObjectVector::iterator aFindResult = ::std::find(maOverlayObjects.begin(), maOverlayObjects.end(), &rOverlayObject); + const bool bFound(aFindResult != maOverlayObjects.end()); + OSL_ENSURE(bFound, "OverlayObject NOT found at OverlayManager (!)"); + + if(bFound) + { + maOverlayObjects.erase(aFindResult); + } + } + + void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange) + { + if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType()) + { + if(getDrawinglayerOpt().IsAntiAliasing()) + { + // assume AA needs one pixel more and invalidate one pixel more + const double fDiscreteOne(getDiscreteOne()); + const Rectangle aInvalidateRectangle( + (sal_Int32)floor(rRange.getMinX() - fDiscreteOne), + (sal_Int32)floor(rRange.getMinY() - fDiscreteOne), + (sal_Int32)ceil(rRange.getMaxX() + fDiscreteOne), + (sal_Int32)ceil(rRange.getMaxY() + fDiscreteOne)); + + // simply invalidate + ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE); + } + else + { + // #i77674# transform to rectangle. Use floor/ceil to get all covered + // discrete pixels, see #i75163# and OverlayManagerBuffered::invalidateRange + const Rectangle aInvalidateRectangle( + (sal_Int32)floor(rRange.getMinX()), (sal_Int32)floor(rRange.getMinY()), + (sal_Int32)ceil(rRange.getMaxX()), (sal_Int32)ceil(rRange.getMaxY())); + + // simply invalidate + ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE); + } + } + } + + // stripe support ColA + void OverlayManager::setStripeColorA(Color aNew) + { + if(aNew != maStripeColorA) + { + maStripeColorA = aNew; + ImpStripeDefinitionChanged(); + } + } + + // stripe support ColB + void OverlayManager::setStripeColorB(Color aNew) + { + if(aNew != maStripeColorB) + { + maStripeColorB = aNew; + ImpStripeDefinitionChanged(); + } + } + + // stripe support StripeLengthPixel + void OverlayManager::setStripeLengthPixel(sal_uInt32 nNew) + { + if(nNew != mnStripeLengthPixel) + { + mnStripeLengthPixel = nNew; + ImpStripeDefinitionChanged(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaymanagerbuffered.cxx b/svx/source/sdr/overlay/overlaymanagerbuffered.cxx new file mode 100644 index 000000000000..dcbf12991d30 --- /dev/null +++ b/svx/source/sdr/overlay/overlaymanagerbuffered.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 <svx/sdr/overlay/overlaymanagerbuffered.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/window.hxx> +#include <vcl/bitmap.hxx> +#include <tools/stream.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <vcl/cursor.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayManagerBuffered::ImpPrepareBufferDevice() + { + // compare size of maBufferDevice with size of visible area + if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel()) + { + // set new buffer size, copy as much content as possible (use bool parameter for vcl). + // Newly uncovered regions will be repainted. + maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false); + } + + // compare the MapModes for zoom/scroll changes + if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode()) + { + const bool bZoomed( + maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX() + || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY()); + + if(!bZoomed) + { + const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin(); + const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin(); + const bool bScrolled(rOriginOld != rOriginNew); + + if(bScrolled) + { + // get pixel bounds + const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld)); + const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew)); + const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel()); + + // remember and switch off MapMode + const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); + + // scroll internally buffered stuff + const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel); + maBufferDevice.DrawOutDev( + aDestinationOffsetPixel, aOutputSizePixel, // destination + Point(), aOutputSizePixel); // source + + // restore MapMode + maBufferDevice.EnableMapMode(bMapModeWasEnabled); + + // scroll remembered region, too. + if(!maBufferRememberedRangePixel.isEmpty()) + { + const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y()); + const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel); + const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel); + maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum); + } + } + } + + // copy new MapMode + maBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); + } + + // #i29186# + maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode()); + maBufferDevice.SetSettings(getOutputDevice().GetSettings()); + maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing()); + } + + void OverlayManagerBuffered::ImpRestoreBackground() const + { + const Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + const Region aRegionPixel(aRegionRectanglePixel); + + ImpRestoreBackground(aRegionPixel); + } + + void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const + { + // local region + Region aRegionPixel(rRegionPixel); + RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects()); + Rectangle aRegionRectanglePixel; + + // MapModes off + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false); + + while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) + { +#ifdef DBG_UTIL + // #i72754# possible graphical region test only with non-pro + static bool bDoPaintForVisualControl(false); + if(bDoPaintForVisualControl) + { + getOutputDevice().SetLineColor(COL_LIGHTGREEN); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(aRegionRectanglePixel); + } +#endif + + // restore the area + const Point aTopLeft(aRegionRectanglePixel.TopLeft()); + const Size aSize(aRegionRectanglePixel.GetSize()); + + getOutputDevice().DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maBufferDevice); + } + + aRegionPixel.EndEnumRects(aRegionHandle); + + // restore MapModes + getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); + ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); + } + + void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice) + { + // prepare source + OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice(); + + // Ensure buffer is valid + ImpPrepareBufferDevice(); + + // build region which needs to be copied + Region aRegion(rSource.LogicToPixel(rRegion)); + + // limit to PaintRegion if it's a window. This will be evtl. the expanded one, + // but always the exact redraw area + if(OUTDEV_WINDOW == rSource.GetOutDevType()) + { + Window& rWindow = (Window&)rSource; + Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion()); + aRegion.Intersect(aPaintRegionPixel); + + // #i72754# Make sure content is completetly rendered, the window + // will be used as source of a DrawOutDev soon + rWindow.Flush(); + } + + // also limit to buffer size + const Rectangle aBufferDeviceRectanglePixel = Rectangle(Point(), maBufferDevice.GetOutputSizePixel()); + aRegion.Intersect(aBufferDeviceRectanglePixel); + + // prepare to iterate over the rectangles from the region in pixels + RegionHandle aRegionHandle(aRegion.BeginEnumRects()); + Rectangle aRegionRectanglePixel; + + // MapModes off + const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled()); + const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); + rSource.EnableMapMode(false); + maBufferDevice.EnableMapMode(false); + + while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) + { + // for each rectangle, save the area + Point aTopLeft(aRegionRectanglePixel.TopLeft()); + Size aSize(aRegionRectanglePixel.GetSize()); + + maBufferDevice.DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + rSource); + +#ifdef DBG_UTIL + // #i72754# possible graphical region test only with non-pro + static bool bDoPaintForVisualControl(false); + if(bDoPaintForVisualControl) + { + const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + getOutputDevice().SetLineColor(COL_LIGHTRED); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(aRegionRectanglePixel); + getOutputDevice().EnableMapMode(bMapModeWasEnabledTest); + } + + static bool bDoSaveForVisualControl(false); + if(bDoSaveForVisualControl) + { + const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize)); + SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); + aNew << aBitmap; + } +#endif + } + + aRegion.EndEnumRects(aRegionHandle); + + // restore MapModes + rSource.EnableMapMode(bMapModeWasEnabledDest); + maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); + } + + IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/) + { + // stop timer + maBufferTimer.Stop(); + + if(!maBufferRememberedRangePixel.isEmpty()) + { + // logic size for impDrawMember call + basegfx::B2DRange aBufferRememberedRangeLogic( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation()); + + // prepare cursor handling + const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType()); + bool bCursorWasEnabled(false); + + // #i80730# switch off VCL cursor during overlay refresh + if(bTargetIsWindow) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + Cursor* pCursor = rWindow.GetCursor(); + + if(pCursor && pCursor->IsVisible()) + { + pCursor->Hide(); + bCursorWasEnabled = true; + } + } + + if(DoRefreshWithPreRendering()) + { + // #i73602# ensure valid and sized maOutputBufferDevice + const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel()); + const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel()); + + if(aDestinationSizePixel != aOutputBufferSizePixel) + { + maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel); + } + + maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); + maOutputBufferDevice.EnableMapMode(false); + maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode()); + maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings()); + maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing()); + + // calculate sizes + Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + + // truncate aRegionRectanglePixel to destination pixel size, more does + // not need to be prepared since destination is a buffer for a window. So, + // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel() + if(aRegionRectanglePixel.Left() < 0L) + { + aRegionRectanglePixel.Left() = 0L; + } + + if(aRegionRectanglePixel.Top() < 0L) + { + aRegionRectanglePixel.Top() = 0L; + } + + if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth()) + { + aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth(); + } + + if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight()) + { + aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight(); + } + + // get sizes + const Point aTopLeft(aRegionRectanglePixel.TopLeft()); + const Size aSize(aRegionRectanglePixel.GetSize()); + + { + const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled()); + maBufferDevice.EnableMapMode(false); + + maOutputBufferDevice.DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maBufferDevice); + + // restore MapModes + maBufferDevice.EnableMapMode(bMapModeWasEnabledDest); + } + + // paint overlay content for remembered region, use + // method from base class directly + maOutputBufferDevice.EnableMapMode(true); + OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice); + maOutputBufferDevice.EnableMapMode(false); + + // copy to output + { + const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); + getOutputDevice().EnableMapMode(false); + + getOutputDevice().DrawOutDev( + aTopLeft, aSize, // destination + aTopLeft, aSize, // source + maOutputBufferDevice); + + // debug + /*getOutputDevice().SetLineColor(COL_RED); + getOutputDevice().SetFillColor(); + getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/ + + // restore MapModes + getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); + } + } + else + { + // Restore all rectangles for remembered region from buffer + ImpRestoreBackground(); + + // paint overlay content for remembered region, use + // method from base class directly + OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice()); + } + + // VCL hack for transparent child windows + // Problem is e.g. a radiobuttion form control in life mode. The used window + // is a transparence vcl childwindow. This flag only allows the parent window to + // paint into the child windows area, but there is no mechanism which takes + // care for a repaint of the child window. A transparent child window is NOT + // a window which always keeps it's content consistent over the parent, but it's + // more like just a paint flag for the parent. + // To get the update, the windows in question are updated manulally here. + if(bTargetIsWindow) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + + if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount()) + { + const Rectangle aRegionRectanglePixel( + maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), + maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); + + for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++) + { + Window* pCandidate = rWindow.GetChild(a); + + if(pCandidate && pCandidate->IsPaintTransparent()) + { + const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel()); + + if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel)) + { + pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN); + pCandidate->Update(); + } + } + } + } + } + + // #i80730# restore visibility of VCL cursor + if(bCursorWasEnabled) + { + Window& rWindow = static_cast< Window& >(rmOutputDevice); + Cursor* pCursor = rWindow.GetCursor(); + + if(pCursor) + { + // check if cursor still exists. It may have been deleted from someone + pCursor->Show(); + } + } + + // forget remembered Region + maBufferRememberedRangePixel.reset(); + } + + return 0; + } + + OverlayManagerBuffered::OverlayManagerBuffered( + OutputDevice& rOutputDevice, + OverlayManager* pOldOverlayManager, + bool bRefreshWithPreRendering) + : OverlayManager(rOutputDevice, pOldOverlayManager), + mbRefreshWithPreRendering(bRefreshWithPreRendering) + { + // Init timer + maBufferTimer.SetTimeout(1); + maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler)); + } + + OverlayManagerBuffered::~OverlayManagerBuffered() + { + // Clear timer + maBufferTimer.Stop(); + + if(!maBufferRememberedRangePixel.isEmpty()) + { + // Restore all rectangles for remembered region from buffer + ImpRestoreBackground(); + } + } + + void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const + { + if(!rRegion.IsEmpty()) + { + // save new background + ((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice); + } + + // call parent + OverlayManager::completeRedraw(rRegion, pPreRenderDevice); + } + + void OverlayManagerBuffered::flush() + { + // call timer handler direct + ImpBufferTimerHandler(0); + } + + // #i68597# part of content gets copied, react on it + void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize) + { + // scroll local buffered area + maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize); + } + + void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const + { + // restore + const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion)); + ImpRestoreBackground(aRegionPixel); + + // call parent + OverlayManager::restoreBackground(rRegion); + } + + void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange) + { + if(!rRange.isEmpty()) + { + // buffered output, do not invalidate but use the timer + // to trigger a timer event for refresh + maBufferTimer.Start(); + + // add the discrete range to the remembered region + // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even + // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel + // since it just transforms the top left and bottom right points equally without taking + // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated + // to an also empty discrete pixel rectangle - what is wrong. + basegfx::B2DRange aDiscreteRange(rRange); + aDiscreteRange.transform(getOutputDevice().GetViewTransformation()); + + if(maDrawinglayerOpt.IsAntiAliasing()) + { + // assume AA needs one pixel more and invalidate one pixel more + const double fDiscreteOne(getDiscreteOne()); + const basegfx::B2IPoint aTopLeft( + (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne), + (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne)); + const basegfx::B2IPoint aBottomRight( + (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne), + (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne)); + + maBufferRememberedRangePixel.expand(aTopLeft); + maBufferRememberedRangePixel.expand(aBottomRight); + } + else + { + const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY())); + const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY())); + + maBufferRememberedRangePixel.expand(aTopLeft); + maBufferRememberedRangePixel.expand(aBottomRight); + } + } + } + + void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew) + { + if((bool)mbRefreshWithPreRendering != bNew) + { + mbRefreshWithPreRendering = bNew; + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobject.cxx b/svx/source/sdr/overlay/overlayobject.cxx new file mode 100644 index 000000000000..049dfe2ecc4c --- /dev/null +++ b/svx/source/sdr/overlay/overlayobject.cxx @@ -0,0 +1,216 @@ +/************************************************************************* + * + * 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/overlay/overlayobject.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <tools/debug.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/vector/b2dvector.hxx> +#include <vcl/outdev.hxx> +#include <vcl/salbtype.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + void OverlayObject::objectChange() + { + const basegfx::B2DRange aPreviousRange(maBaseRange); + maBaseRange.reset(); + setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); + + if(getOverlayManager() && !aPreviousRange.isEmpty()) + { + getOverlayManager()->invalidateRange(aPreviousRange); + } + + const basegfx::B2DRange& rCurrentRange = getBaseRange(); + + if(getOverlayManager() && rCurrentRange != aPreviousRange && !rCurrentRange.isEmpty()) + { + getOverlayManager()->invalidateRange(rCurrentRange); + } + } + + // OverlayObject implementations. + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::createOverlayObjectPrimitive2DSequence() + { + // Default implementation has to assert a missing implementation. It cannot + // be useful to have overlay object derivations which have no visualisation + // at all + OSL_ENSURE(false, "OverlayObject derivation without visualisation definition (missing createOverlayObjectPrimitive2DSequence implementation) (!)"); + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + void OverlayObject::allowAntiAliase(bool bNew) + { + if(bNew != (bool)mbAllowsAntiAliase) + { + // remember new value + mbAllowsAntiAliase = bNew; + + // register change (after change) + objectChange(); + } + } + + OverlayObject::OverlayObject(Color aBaseColor) + : Event(0), + mpOverlayManager(0), + maBaseColor(aBaseColor), + mbIsVisible(true), + mbIsHittable(true), + mbAllowsAnimation(false), + mbAllowsAntiAliase(true) + { + } + + OverlayObject::~OverlayObject() + { + OSL_ENSURE(0 == getOverlayManager(), "OverlayObject is destructed which is still registered at OverlayManager (!)"); + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayObject::getOverlayObjectPrimitive2DSequence() const + { + if(!getPrimitive2DSequence().hasElements()) + { + // no existing sequence; create one + const_cast< OverlayObject* >(this)->setPrimitive2DSequence( + const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence()); + } + + return getPrimitive2DSequence(); + } + + const basegfx::B2DRange& OverlayObject::getBaseRange() const + { + if(getOverlayManager() && maBaseRange.isEmpty()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(getOverlayManager()->getCurrentViewInformation2D()); + + const_cast< sdr::overlay::OverlayObject* >(this)->maBaseRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(rSequence, aViewInformation2D); + } + } + + return maBaseRange; + } + + void OverlayObject::setVisible(bool bNew) + { + if(bNew != (bool)mbIsVisible) + { + // remember new value + mbIsVisible = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::setHittable(bool bNew) + { + if(bNew != (bool)mbIsHittable) + { + // remember new value + mbIsHittable = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::setBaseColor(Color aNew) + { + if(aNew != maBaseColor) + { + // remember new value + maBaseColor = aNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayObject::Trigger(sal_uInt32 /*nTime*/) + { + // default does not register again + } + + void OverlayObject::stripeDefinitionHasChanged() + { + // default does not need to do anything + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + OverlayObjectWithBasePosition::OverlayObjectWithBasePosition(const basegfx::B2DPoint& rBasePos, Color aBaseColor) + : OverlayObject(aBaseColor), + maBasePosition(rBasePos) + { + } + + OverlayObjectWithBasePosition::~OverlayObjectWithBasePosition() + { + } + + void OverlayObjectWithBasePosition::setBasePosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maBasePosition) + { + // remember new value + maBasePosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobjectcell.cxx b/svx/source/sdr/overlay/overlayobjectcell.cxx new file mode 100644 index 000000000000..dbf38a8cd0f1 --- /dev/null +++ b/svx/source/sdr/overlay/overlayobjectcell.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * 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/numeric/ftools.hxx> +#include <vcl/outdev.hxx> +#include <vcl/hatch.hxx> +#include <svx/sdr/overlay/overlayobjectcell.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> + +using namespace ::basegfx; + +// #114409# +namespace sdr +{ + namespace overlay + { + OverlayObjectCell::OverlayObjectCell( CellOverlayType eType, const Color& rColor, const RangeVector& rRects ) + : OverlayObject( rColor ), + mePaintType( eType ), + maRectangles( rRects ) + { + // no AA for selection overlays + allowAntiAliase(false); + } + + OverlayObjectCell::~OverlayObjectCell() + { + } + + drawinglayer::primitive2d::Primitive2DSequence OverlayObjectCell::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + const sal_uInt32 nCount(maRectangles.size()); + + if(nCount) + { + const basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); + + // create primitives for all ranges + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DRange& rRange(maRectangles[a]); + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(rRange)); + + aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + aRGBColor)); + } + + + if(mePaintType == CELL_OVERLAY_TRANSPARENT) + { + // embed in 50% transparent paint + const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + aRetval, + 0.5)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); + } + else // CELL_OVERLAY_INVERT + { + // embed in invert primitive + const drawinglayer::primitive2d::Primitive2DReference aInvert( + new drawinglayer::primitive2d::InvertPrimitive2D( + aRetval)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); + } + } + + return aRetval; + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayobjectlist.cxx b/svx/source/sdr/overlay/overlayobjectlist.cxx new file mode 100644 index 000000000000..e9464bdee09b --- /dev/null +++ b/svx/source/sdr/overlay/overlayobjectlist.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * 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/overlay/overlayobjectlist.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <tools/debug.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> + +// for SOLARIS compiler include of algorithm part of _STL is necesary to +// get access to basic algos like ::std::find +#include <algorithm> + +#include <drawinglayer/processor2d/hittestprocessor2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + OverlayObjectList::~OverlayObjectList() + { + clear(); + } + + void OverlayObjectList::clear() + { + OverlayObjectVector::iterator aStart(maVector.begin()); + + for(; aStart != maVector.end(); aStart++) + { + ::sdr::overlay::OverlayObject* pCandidate = *aStart; + + if(pCandidate->getOverlayManager()) + { + pCandidate->getOverlayManager()->remove(*pCandidate); + } + + delete pCandidate; + } + + maVector.clear(); + } + + void OverlayObjectList::remove(OverlayObject& rOverlayObject) + { + const OverlayObjectVector::iterator aFindResult = ::std::find(maVector.begin(), maVector.end(), &rOverlayObject); + const bool bFound(aFindResult != maVector.end()); + OSL_ENSURE(bFound, "Could not find given object in list (!)"); + + if(bFound) + { + maVector.erase(aFindResult); + } + } + + bool OverlayObjectList::isHitLogic(const basegfx::B2DPoint& rLogicPosition, double fLogicTolerance) const + { + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + sdr::overlay::OverlayObject* pFirst = *aStart; + OSL_ENSURE(pFirst, "Corrupt OverlayObjectList (!)"); + OverlayManager* pManager = pFirst->getOverlayManager(); + + if(pManager) + { + if(0.0 == fLogicTolerance) + { + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic( + Size(DEFAULT_VALUE_FOR_HITTEST_PIXEL, DEFAULT_VALUE_FOR_HITTEST_PIXEL))); + fLogicTolerance = aSizeLogic.Width(); + } + + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(pManager->getCurrentViewInformation2D()); + drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( + aViewInformation2D, + rLogicPosition, + fLogicTolerance, + false); + + for(; aStart != maVector.end(); aStart++) + { + sdr::overlay::OverlayObject* pCandidate = *aStart; + OSL_ENSURE(pCandidate, "Corrupt OverlayObjectList (!)"); + + if(pCandidate->isHittable()) + { + const drawinglayer::primitive2d::Primitive2DSequence& rSequence = pCandidate->getOverlayObjectPrimitive2DSequence(); + + if(rSequence.hasElements()) + { + aHitTestProcessor2D.process(rSequence); + + if(aHitTestProcessor2D.getHit()) + { + return true; + } + } + } + } + } + } + + return false; + } + + bool OverlayObjectList::isHitPixel(const Point& rDiscretePosition, sal_uInt32 nDiscreteTolerance) const + { + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + sdr::overlay::OverlayObject* pCandidate = *aStart; + OverlayManager* pManager = pCandidate->getOverlayManager(); + + if(pManager) + { + const Point aPosLogic(pManager->getOutputDevice().PixelToLogic(rDiscretePosition)); + const basegfx::B2DPoint aPosition(aPosLogic.X(), aPosLogic.Y()); + + if(nDiscreteTolerance) + { + const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(Size(nDiscreteTolerance, nDiscreteTolerance))); + return isHitLogic(aPosition, (double)aSizeLogic.Width()); + } + else + { + return isHitLogic(aPosition); + } + } + } + + return false; + } + + basegfx::B2DRange OverlayObjectList::getBaseRange() const + { + basegfx::B2DRange aRetval; + + if(maVector.size()) + { + OverlayObjectVector::const_iterator aStart(maVector.begin()); + + for(; aStart != maVector.end(); aStart++) + { + ::sdr::overlay::OverlayObject* pCandidate = *aStart; + aRetval.expand(pCandidate->getBaseRange()); + } + } + + return aRetval; + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaypolypolygon.cxx b/svx/source/sdr/overlay/overlaypolypolygon.cxx new file mode 100644 index 000000000000..a8476854ae13 --- /dev/null +++ b/svx/source/sdr/overlay/overlaypolypolygon.cxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * 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/overlay/overlaypolypolygon.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayPolyPolygonStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager()) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolyPolygonMarkerPrimitive2D( + getPolyPolygon(), + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + return aRetval; + } + + void OverlayPolyPolygonStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayPolyPolygonStriped::OverlayPolyPolygonStriped( + const basegfx::B2DPolyPolygon& rPolyPolygon) + : OverlayObject(Color(COL_BLACK)), + maPolyPolygon(rPolyPolygon) + { + } + + OverlayPolyPolygonStriped::~OverlayPolyPolygonStriped() + { + } + + void OverlayPolyPolygonStriped::setPolyPolygon(const basegfx::B2DPolyPolygon& rNew) + { + if(rNew != maPolyPolygon) + { + // remember new value + maPolyPolygon = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx new file mode 100644 index 000000000000..52f43084c664 --- /dev/null +++ b/svx/source/sdr/overlay/overlayprimitive2dsequenceobject.cxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * 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/overlay/overlayprimitive2dsequenceobject.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayPrimitive2DSequenceObject::createOverlayObjectPrimitive2DSequence() + { + return getSequence(); + } + + OverlayPrimitive2DSequenceObject::OverlayPrimitive2DSequenceObject(const drawinglayer::primitive2d::Primitive2DSequence& rSequence) + : OverlayObjectWithBasePosition(basegfx::B2DPoint(), Color(COL_BLACK)), + maSequence(rSequence) + { + } + + OverlayPrimitive2DSequenceObject::~OverlayPrimitive2DSequenceObject() + { + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayrollingrectangle.cxx b/svx/source/sdr/overlay/overlayrollingrectangle.cxx new file mode 100644 index 000000000000..1b09df2ca60e --- /dev/null +++ b/svx/source/sdr/overlay/overlayrollingrectangle.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * 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/overlay/overlayrollingrectangle.hxx> +#include <tools/gen.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlaytools.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayRollingRectangleStriped::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + + if(getOverlayManager() && (getShowBounds() || getExtendedLines())) + { + const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor()); + const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor()); + const double fStripeLengthPixel(getOverlayManager()->getStripeLengthPixel()); + const basegfx::B2DRange aRollingRectangle(getBasePosition(), getSecondPosition()); + + if(getShowBounds()) + { + // view-independent part, create directly + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRollingRectangle)); + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolygonMarkerPrimitive2D( + aPolygon, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aReference); + } + + if(getExtendedLines()) + { + // view-dependent part, use helper primitive + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::OverlayRollingRectanglePrimitive( + aRollingRectangle, + aRGBColorA, + aRGBColorB, + fStripeLengthPixel)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aReference); + } + } + + return aRetval; + } + + void OverlayRollingRectangleStriped::stripeDefinitionHasChanged() + { + // react on OverlayManager's stripe definition change + objectChange(); + } + + OverlayRollingRectangleStriped::OverlayRollingRectangleStriped( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos, + bool bExtendedLines, + bool bShowBounds) + : OverlayObjectWithBasePosition(rBasePos, Color(COL_BLACK)), + maSecondPosition(rSecondPos), + mbExtendedLines(bExtendedLines), + mbShowBounds(bShowBounds) + { + } + + OverlayRollingRectangleStriped::~OverlayRollingRectangleStriped() + { + } + + void OverlayRollingRectangleStriped::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayRollingRectangleStriped::setExtendedLines(bool bNew) + { + if(bNew != (bool)mbExtendedLines) + { + // remember new value + mbExtendedLines = bNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayRollingRectangleStriped::setShowBounds(bool bNew) + { + if(bNew != (bool)mbShowBounds) + { + // remember new value + mbShowBounds = bNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlayselection.cxx b/svx/source/sdr/overlay/overlayselection.cxx new file mode 100644 index 000000000000..2115d3c63120 --- /dev/null +++ b/svx/source/sdr/overlay/overlayselection.cxx @@ -0,0 +1,237 @@ +/************************************************************************* + * + * 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/overlay/overlayselection.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <svtools/optionsdrawinglayer.hxx> +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <drawinglayer/primitive2d/invertprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + // combine rages geometrically to a single, ORed polygon + basegfx::B2DPolyPolygon impCombineRangesToPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges) + { + const sal_uInt32 nCount(rRanges.size()); + basegfx::B2DPolyPolygon aRetval; + + for(sal_uInt32 a(0); a < nCount; a++) + { + const basegfx::B2DPolygon aDiscretePolygon(basegfx::tools::createPolygonFromRect(rRanges[a])); + + if(0 == a) + { + aRetval.append(aDiscretePolygon); + } + else + { + aRetval = basegfx::tools::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon)); + } + } + + return aRetval; + } + + // check if wanted type OVERLAY_TRANSPARENT or OVERLAY_SOLID + // is possible. If not, fallback to invert mode (classic mode) + OverlayType impCheckPossibleOverlayType(OverlayType aOverlayType) + { + if(OVERLAY_INVERT != aOverlayType) + { + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + + if(!aSvtOptionsDrawinglayer.IsTransparentSelection()) + { + // not possible when switched off by user + return OVERLAY_INVERT; + } + else + { + const OutputDevice *pOut = Application::GetDefaultDevice(); + + if(pOut->GetSettings().GetStyleSettings().GetHighContrastMode()) + { + // not possible when in high contrast mode + return OVERLAY_INVERT; + } + + if(!pOut->supportsOperation(OutDevSupport_TransparentRect)) + { + // not possible when no fast transparence paint is supported on the system + return OVERLAY_INVERT; + } + } + } + + return aOverlayType; + } + + drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::createOverlayObjectPrimitive2DSequence() + { + drawinglayer::primitive2d::Primitive2DSequence aRetval; + const sal_uInt32 nCount(getRanges().size()); + + if(nCount) + { + // create range primitives + const bool bInvert(OVERLAY_INVERT == maLastOverlayType); + basegfx::BColor aRGBColor(getBaseColor().getBColor()); + aRetval.realloc(nCount); + + if(bInvert) + { + // force color to white for invert to get a full invert + aRGBColor = basegfx::BColor(1.0, 1.0, 1.0); + } + + for(sal_uInt32 a(0);a < nCount; a++) + { + const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(maRanges[a])); + aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + aRGBColor)); + } + + if(bInvert) + { + // embed all in invert primitive + const drawinglayer::primitive2d::Primitive2DReference aInvert( + new drawinglayer::primitive2d::InvertPrimitive2D( + aRetval)); + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); + } + else if(OVERLAY_TRANSPARENT == maLastOverlayType) + { + // embed all rectangles in transparent paint + const double fTransparence(mnLastTransparence / 100.0); + const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + aRetval, + fTransparence)); + + if(getBorder()) + { + const basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges())); + const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline( + new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( + aPolyPolygon, + aRGBColor)); + + // add both to result + aRetval.realloc(2); + aRetval[0] = aUnifiedTransparence; + aRetval[1] = aSelectionOutline; + } + else + { + // just add transparent part + aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); + } + } + } + + return aRetval; + } + + OverlaySelection::OverlaySelection( + OverlayType eType, + const Color& rColor, + const std::vector< basegfx::B2DRange >& rRanges, + bool bBorder) + : OverlayObject(rColor), + meOverlayType(eType), + maRanges(rRanges), + maLastOverlayType(eType), + mnLastTransparence(0), + mbBorder(bBorder) + { + // no AA for selection overlays + allowAntiAliase(false); + } + + OverlaySelection::~OverlaySelection() + { + if(getOverlayManager()) + { + getOverlayManager()->remove(*this); + } + } + + drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::getOverlayObjectPrimitive2DSequence() const + { + // get current values + const OverlayType aNewOverlayType(impCheckPossibleOverlayType(meOverlayType)); + const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + const sal_uInt16 nNewTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()); + + if(getPrimitive2DSequence().hasElements()) + { + if(aNewOverlayType != maLastOverlayType + || nNewTransparence != mnLastTransparence) + { + // conditions of last local decomposition have changed, delete + const_cast< OverlaySelection* >(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); + } + } + + if(!getPrimitive2DSequence().hasElements()) + { + // remember new values + const_cast< OverlaySelection* >(this)->maLastOverlayType = aNewOverlayType; + const_cast< OverlaySelection* >(this)->mnLastTransparence = nNewTransparence; + } + + // call base implementation + return OverlayObject::getOverlayObjectPrimitive2DSequence(); + } + + void OverlaySelection::setRanges(const std::vector< basegfx::B2DRange >& rNew) + { + if(rNew != maRanges) + { + maRanges = rNew; + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaytools.cxx b/svx/source/sdr/overlay/overlaytools.cxx new file mode 100644 index 000000000000..215b8484d5bf --- /dev/null +++ b/svx/source/sdr/overlay/overlaytools.cxx @@ -0,0 +1,493 @@ +/************************************************************************* + * + * 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/overlay/overlaytools.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayBitmapExPrimitive::OverlayBitmapExPrimitive( + const BitmapEx& rBitmapEx, + const basegfx::B2DPoint& rBasePosition, + sal_uInt16 nCenterX, + sal_uInt16 nCenterY) + : DiscreteMetricDependentPrimitive2D(), + maBitmapEx(rBitmapEx), + maBasePosition(rBasePosition), + mnCenterX(nCenterX), + mnCenterY(nCenterY) + {} + + Primitive2DSequence OverlayBitmapExPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + const Size aBitmapSize(getBitmapEx().GetSizePixel()); + + if(aBitmapSize.Width() && aBitmapSize.Height() && basegfx::fTools::more(getDiscreteUnit(), 0.0)) + { + // calculate back from internal bitmap's extreme coordinates (the edges) + // to logical coordinates. Only use a unified scaling value (getDiscreteUnit(), + // the prepared one which expresses how many logic units form a discrete unit) + // for this step. This primitive is to be displayed always unscaled (in it's pixel size) + // and unrotated, more like a marker + const double fLeft(((0.0 - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); + const double fTop(((0.0 - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); + const double fRight((((aBitmapSize.getWidth() - 1.0) - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); + const double fBottom((((aBitmapSize.getHeight() - 1.0) - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); + + // create a BitmapPrimitive2D using those positions + basegfx::B2DHomMatrix aTransform; + + aTransform.set(0, 0, fRight - fLeft); + aTransform.set(1, 1, fBottom - fTop); + aTransform.set(0, 2, fLeft); + aTransform.set(1, 2, fTop); + + const Primitive2DReference aPrimitive(new BitmapPrimitive2D(getBitmapEx(), aTransform)); + aRetval = Primitive2DSequence(&aPrimitive, 1); + } + + return aRetval; + } + + bool OverlayBitmapExPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayBitmapExPrimitive& rCompare = static_cast< const OverlayBitmapExPrimitive& >(rPrimitive); + + return (getBitmapEx() == rCompare.getBitmapEx() + && getBasePosition() == rCompare.getBasePosition() + && getCenterX() == rCompare.getCenterX() + && getCenterY() == rCompare.getCenterY()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayBitmapExPrimitive, PRIMITIVE2D_ID_OVERLAYBITMAPEXPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayCrosshairPrimitive::OverlayCrosshairPrimitive( + const basegfx::B2DPoint& rBasePosition, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maBasePosition(rBasePosition), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayCrosshairPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + aRetval.realloc(2); + basegfx::B2DPolygon aPolygon; + + aPolygon.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); + aPolygon.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aPolygon, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + aPolygon.clear(); + aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); + aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); + + aRetval[1] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aPolygon, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + } + + return aRetval; + } + + bool OverlayCrosshairPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayCrosshairPrimitive& rCompare = static_cast< const OverlayCrosshairPrimitive& >(rPrimitive); + + return (getBasePosition() == rCompare.getBasePosition() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayCrosshairPrimitive, PRIMITIVE2D_ID_OVERLAYCROSSHAIRPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayHatchRectanglePrimitive::OverlayHatchRectanglePrimitive( + const basegfx::B2DRange& rObjectRange, + double fDiscreteHatchDistance, + double fHatchRotation, + const basegfx::BColor& rHatchColor, + double fDiscreteGrow, + double fDiscreteShrink, + double fRotation) + : DiscreteMetricDependentPrimitive2D(), + maObjectRange(rObjectRange), + mfDiscreteHatchDistance(fDiscreteHatchDistance), + mfHatchRotation(fHatchRotation), + maHatchColor(rHatchColor), + mfDiscreteGrow(fDiscreteGrow), + mfDiscreteShrink(fDiscreteShrink), + mfRotation(fRotation) + {} + + Primitive2DSequence OverlayHatchRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + Primitive2DSequence aRetval; + + if(basegfx::fTools::more(getDiscreteUnit(), 0.0)) + { + basegfx::B2DRange aInnerRange(getObjectRange()); + basegfx::B2DRange aOuterRange(getObjectRange()); + basegfx::B2DPolyPolygon aHatchPolyPolygon; + + aOuterRange.grow(getDiscreteUnit() * getDiscreteGrow()); + aInnerRange.grow(getDiscreteUnit() * -getDiscreteShrink()); + + aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aOuterRange)); + + if(!aInnerRange.isEmpty()) + { + aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aInnerRange)); + } + + if(!basegfx::fTools::equalZero(getRotation())) + { + const basegfx::B2DHomMatrix aTransform(basegfx::tools::createRotateAroundPoint( + getObjectRange().getMinX(), getObjectRange().getMinY(), getRotation())); + + aHatchPolyPolygon.transform(aTransform); + } + + const basegfx::BColor aEmptyColor(0.0, 0.0, 0.0); + const drawinglayer::attribute::FillHatchAttribute aFillHatchAttribute( + drawinglayer::attribute::HATCHSTYLE_SINGLE, + getDiscreteHatchDistance() * getDiscreteUnit(), + getHatchRotation() - getRotation(), + getHatchColor(), + false); + const Primitive2DReference aPrimitive( + new PolyPolygonHatchPrimitive2D( + aHatchPolyPolygon, + aEmptyColor, + aFillHatchAttribute)); + + aRetval = Primitive2DSequence(&aPrimitive, 1); + } + + return aRetval; + } + + bool OverlayHatchRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayHatchRectanglePrimitive& rCompare = static_cast< const OverlayHatchRectanglePrimitive& >(rPrimitive); + + return (getObjectRange() == rCompare.getObjectRange() + && getDiscreteHatchDistance() == rCompare.getDiscreteHatchDistance() + && getHatchRotation() == rCompare.getHatchRotation() + && getHatchColor() == rCompare.getHatchColor() + && getDiscreteGrow() == rCompare.getDiscreteGrow() + && getDiscreteShrink() == rCompare.getDiscreteShrink() + && getRotation() == rCompare.getRotation()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayHatchRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYHATCHRECTANGLEPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayHelplineStripedPrimitive::OverlayHelplineStripedPrimitive( + const basegfx::B2DPoint& rBasePosition, + HelplineStyle eStyle, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maBasePosition(rBasePosition), + meStyle(eStyle), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayHelplineStripedPrimitive::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + switch(getStyle()) + { + case HELPLINESTYLE_VERTICAL : + { + aRetval.realloc(1); + basegfx::B2DPolygon aLine; + + aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLine, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + break; + } + + case HELPLINESTYLE_HORIZONTAL : + { + aRetval.realloc(1); + basegfx::B2DPolygon aLine; + + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLine, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + break; + } + + default: // case HELPLINESTYLE_POINT : + { + const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); + aRetval.realloc(2); + basegfx::B2DPolygon aLineA, aLineB; + + aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() - fDiscreteUnit)); + aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() + fDiscreteUnit)); + + aRetval[0] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLineA, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + aLineB.append(basegfx::B2DPoint(getBasePosition().getX() - fDiscreteUnit, getBasePosition().getY())); + aLineB.append(basegfx::B2DPoint(getBasePosition().getX() + fDiscreteUnit, getBasePosition().getY())); + + aRetval[1] = Primitive2DReference( + new PolygonMarkerPrimitive2D( + aLineB, + getRGBColorA(), + getRGBColorB(), + getDiscreteDashLength())); + + break; + } + } + } + + return aRetval; + } + + bool OverlayHelplineStripedPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayHelplineStripedPrimitive& rCompare = static_cast< const OverlayHelplineStripedPrimitive& >(rPrimitive); + + return (getBasePosition() == rCompare.getBasePosition() + && getStyle() == rCompare.getStyle() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayHelplineStripedPrimitive, PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + OverlayRollingRectanglePrimitive::OverlayRollingRectanglePrimitive( + const basegfx::B2DRange& aRollingRectangle, + const basegfx::BColor& rRGBColorA, + const basegfx::BColor& rRGBColorB, + double fDiscreteDashLength) + : ViewportDependentPrimitive2D(), + maRollingRectangle(aRollingRectangle), + maRGBColorA(rRGBColorA), + maRGBColorB(rRGBColorB), + mfDiscreteDashLength(fDiscreteDashLength) + {} + + Primitive2DSequence OverlayRollingRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + // use the prepared Viewport information accessible using getViewport() + Primitive2DSequence aRetval; + + if(!getViewport().isEmpty()) + { + basegfx::B2DPolygon aLine; + aRetval.realloc(8); + + // Left lines + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); + aRetval[0] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); + aRetval[1] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Right lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMinY())); + aRetval[2] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMaxY())); + aRetval[3] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Top lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); + aRetval[4] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMinY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); + aRetval[5] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + // Bottom lines + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMaxY())); + aRetval[6] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + + aLine.clear(); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); + aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMaxY())); + aRetval[7] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); + } + + return aRetval; + } + + bool OverlayRollingRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const + { + if(ViewportDependentPrimitive2D::operator==(rPrimitive)) + { + const OverlayRollingRectanglePrimitive& rCompare = static_cast< const OverlayRollingRectanglePrimitive& >(rPrimitive); + + return (getRollingRectangle() == rCompare.getRollingRectangle() + && getRGBColorA() == rCompare.getRGBColorA() + && getRGBColorB() == rCompare.getRGBColorB() + && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); + } + + return false; + } + + ImplPrimitrive2DIDBlock(OverlayRollingRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/overlay/overlaytriangle.cxx b/svx/source/sdr/overlay/overlaytriangle.cxx new file mode 100644 index 000000000000..ecf1cf5866e5 --- /dev/null +++ b/svx/source/sdr/overlay/overlaytriangle.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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/overlay/overlaytriangle.hxx> +#include <tools/poly.hxx> +#include <vcl/salbtype.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/overlay/overlaymanager.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace overlay + { + drawinglayer::primitive2d::Primitive2DSequence OverlayTriangle::createOverlayObjectPrimitive2DSequence() + { + basegfx::B2DPolygon aPolygon; + + aPolygon.append(getBasePosition()); + aPolygon.append(getSecondPosition()); + aPolygon.append(getThirdPosition()); + aPolygon.setClosed(true); + + const drawinglayer::primitive2d::Primitive2DReference aReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPolygon), + getBaseColor().getBColor())); + + return drawinglayer::primitive2d::Primitive2DSequence(&aReference, 1); + } + + OverlayTriangle::OverlayTriangle( + const basegfx::B2DPoint& rBasePos, + const basegfx::B2DPoint& rSecondPos, + const basegfx::B2DPoint& rThirdPos, + Color aTriangleColor) + : OverlayObjectWithBasePosition(rBasePos, aTriangleColor), + maSecondPosition(rSecondPos), + maThirdPosition(rThirdPos) + { + } + + OverlayTriangle::~OverlayTriangle() + { + } + + void OverlayTriangle::setSecondPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maSecondPosition) + { + // remember new value + maSecondPosition = rNew; + + // register change (after change) + objectChange(); + } + } + + void OverlayTriangle::setThirdPosition(const basegfx::B2DPoint& rNew) + { + if(rNew != maThirdPosition) + { + // remember new value + maThirdPosition = rNew; + + // register change (after change) + objectChange(); + } + } + } // end of namespace overlay +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/makefile.mk b/svx/source/sdr/primitive2d/makefile.mk new file mode 100644 index 000000000000..078bc4bc977e --- /dev/null +++ b/svx/source/sdr/primitive2d/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# 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=primitive2d +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/primitivefactory2d.obj \ + $(SLO)$/sdrdecompositiontools.obj \ + $(SLO)$/sdrattributecreator.obj \ + $(SLO)$/sdrellipseprimitive2d.obj \ + $(SLO)$/sdrrectangleprimitive2d.obj \ + $(SLO)$/sdrcustomshapeprimitive2d.obj \ + $(SLO)$/sdrcaptionprimitive2d.obj \ + $(SLO)$/sdrgrafprimitive2d.obj \ + $(SLO)$/sdrole2primitive2d.obj \ + $(SLO)$/sdrolecontentprimitive2d.obj \ + $(SLO)$/sdrpathprimitive2d.obj \ + $(SLO)$/sdrprimitivetools.obj \ + $(SLO)$/sdrmeasureprimitive2d.obj \ + $(SLO)$/sdrconnectorprimitive2d.obj \ + $(SLO)$/sdrtextprimitive2d.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/primitive2d/primitivefactory2d.cxx b/svx/source/sdr/primitive2d/primitivefactory2d.cxx new file mode 100644 index 000000000000..d6a6867b819e --- /dev/null +++ b/svx/source/sdr/primitive2d/primitivefactory2d.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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/primitiveFactory2d.hxx> +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpage.hxx> +#include <unoapi.hxx> +#include <svx/sdr/contact/viewcontact.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// +// UNO API helper methods + +namespace drawinglayer +{ + namespace primitive2d + { + uno::Reference< uno::XInterface > SAL_CALL XPrimitiveFactory2DProvider_createInstance( + const uno::Reference< lang::XMultiServiceFactory >& /*rSMgr*/) throw( uno::Exception ) + { + return *(new PrimitiveFactory2D()); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// UNO API helper methods + +namespace drawinglayer +{ + namespace primitive2d + { + PrimitiveFactory2D::PrimitiveFactory2D() + : PrimitiveFactory2DImplBase(m_aMutex) + { + } + + Primitive2DSequence SAL_CALL PrimitiveFactory2D::createPrimitivesFromXShape( + const uno::Reference< drawing::XShape >& xShape, + const uno::Sequence< beans::PropertyValue >& /*aParms*/ ) throw (uno::RuntimeException) + { + Primitive2DSequence aRetval; + + if(xShape.is()) + { + SdrObject* pSource = GetSdrObjectFromXShape(xShape); + + if(pSource) + { + const sdr::contact::ViewContact& rSource(pSource->GetViewContact()); + aRetval = rSource.getViewIndependentPrimitive2DSequence(); + } + } + + return aRetval; + } + + Primitive2DSequence SAL_CALL PrimitiveFactory2D::createPrimitivesFromXDrawPage( + const uno::Reference< drawing::XDrawPage >& xDrawPage, + const uno::Sequence< beans::PropertyValue >& /*aParms*/ ) throw (uno::RuntimeException) + { + Primitive2DSequence aRetval; + + if(xDrawPage.is()) + { + SdrPage* pSource = GetSdrPageFromXDrawPage(xDrawPage); + + if(pSource) + { + const sdr::contact::ViewContact& rSource(pSource->GetViewContact()); + + aRetval = rSource.getViewIndependentPrimitive2DSequence(); + } + } + + return aRetval; + } + + rtl::OUString PrimitiveFactory2D::getImplementationName_Static() + { + static rtl::OUString aRetval(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.graphic.PrimitiveFactory2D")); + return aRetval; + } + + uno::Sequence< rtl::OUString > PrimitiveFactory2D::getSupportedServiceNames_Static() + { + static uno::Sequence< rtl::OUString > aSeq; + osl::Mutex aMutex; + osl::MutexGuard aGuard( aMutex ); + + if(!aSeq.getLength()) + { + aSeq.realloc(1L); + aSeq.getArray()[0L] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.PrimitiveFactory2D")); + } + + return aSeq; + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx new file mode 100644 index 000000000000..4ff335a04125 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrattributecreator.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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svl/itemset.hxx> +#include <svx/xdef.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/xlineit0.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xlntrit.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlinjoit.hxx> +#include <svx/xlnclit.hxx> +#include <svx/xlnstwit.hxx> +#include <svx/xlnedwit.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnstcit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnedcit.hxx> +#include <svx/xdash.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xflclit.hxx> +#include <svx/xgrscit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xflbckit.hxx> +#include <svx/sdshitm.hxx> +#include <svx/sdsxyitm.hxx> +#include <svx/sdshcitm.hxx> +#include <svx/sdshtitm.hxx> +#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx> +#include <basegfx/polygon/b2dlinegeometry.hxx> +#include <svx/svdotext.hxx> +#include <drawinglayer/attribute/fillbitmapattribute.hxx> +#include <svx/sdr/attribute/sdrtextattribute.hxx> +#include <svx/xbtmpit.hxx> +#include <svl/itempool.hxx> +#include <vcl/svapp.hxx> +#include <basegfx/range/b2drange.hxx> +#include <svx/svx3ditems.hxx> +#include <com/sun/star/drawing/ProjectionMode.hpp> +#include <com/sun/star/drawing/ShadeMode.hpp> +#include <drawinglayer/attribute/sdrallattribute3d.hxx> +#include <svx/rectenum.hxx> +#include <svx/sdtfchim.hxx> +#include <svx/svdoutl.hxx> +#include <svx/svdmodel.hxx> +#include <editeng/editstat.hxx> +#include <drawinglayer/attribute/fillhatchattribute.hxx> +#include <drawinglayer/attribute/fillgradientattribute.hxx> +#include <svx/sdr/attribute/sdrshadowtextattribute.hxx> +#include <svx/sdr/attribute/sdrlineshadowtextattribute.hxx> +#include <svx/sdr/attribute/sdrformtextattribute.hxx> +#include <svx/sdr/attribute/sdrlinefillshadowtextattribute.hxx> +#include <drawinglayer/attribute/sdrsceneattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightingattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightattribute3d.hxx> +#include <svx/sdr/attribute/sdrfilltextattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace + { + attribute::GradientStyle XGradientStyleToGradientStyle(XGradientStyle eStyle) + { + switch(eStyle) + { + case XGRAD_LINEAR : + { + return attribute::GRADIENTSTYLE_LINEAR; + } + case XGRAD_AXIAL : + { + return attribute::GRADIENTSTYLE_AXIAL; + } + case XGRAD_RADIAL : + { + return attribute::GRADIENTSTYLE_RADIAL; + } + case XGRAD_ELLIPTICAL : + { + return attribute::GRADIENTSTYLE_ELLIPTICAL; + } + case XGRAD_SQUARE : + { + return attribute::GRADIENTSTYLE_SQUARE; + } + default : + { + return attribute::GRADIENTSTYLE_RECT; // XGRAD_RECT + } + } + } + + attribute::HatchStyle XHatchStyleToHatchStyle(XHatchStyle eStyle) + { + switch(eStyle) + { + case XHATCH_SINGLE : + { + return attribute::HATCHSTYLE_SINGLE; + } + case XHATCH_DOUBLE : + { + return attribute::HATCHSTYLE_DOUBLE; + } + default : + { + return attribute::HATCHSTYLE_TRIPLE; // XHATCH_TRIPLE + } + } + } + + basegfx::B2DLineJoin XLineJointtoB2DLineJoin(XLineJoint eLineJoint) + { + switch(eLineJoint) + { + case XLINEJOINT_MIDDLE : + { + return basegfx::B2DLINEJOIN_MIDDLE; + } + case XLINEJOINT_BEVEL : + { + return basegfx::B2DLINEJOIN_BEVEL; + } + case XLINEJOINT_MITER : + { + return basegfx::B2DLINEJOIN_MITER; + } + case XLINEJOINT_ROUND : + { + return basegfx::B2DLINEJOIN_ROUND; + } + default : + { + return basegfx::B2DLINEJOIN_NONE; // XLINEJOINT_NONE + } + } + } + + basegfx::B2DVector RectPointToB2DVector(RECT_POINT eRectPoint) + { + basegfx::B2DVector aRetval(0.0, 0.0); + + // position changes X + switch(eRectPoint) + { + case RP_LT: case RP_LM: case RP_LB: + { + aRetval.setX(-1.0); + break; + } + + case RP_RT: case RP_RM: case RP_RB: + { + aRetval.setX(1.0); + break; + } + + default : + { + break; + } + } + + // position changes Y + switch(eRectPoint) + { + case RP_LT: case RP_MT: case RP_RT: + { + aRetval.setY(-1.0); + break; + } + + case RP_LB: case RP_MB: case RP_RB: + { + aRetval.setY(1.0); + break; + } + + default : + { + break; + } + } + + return aRetval; + } + } // end of anonymous namespace +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + attribute::SdrLineAttribute createNewSdrLineAttribute(const SfxItemSet& rSet) + { + const XLineStyle eStyle(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue()); + + if(XLINE_NONE != eStyle) + { + sal_uInt16 nTransparence(((const XLineTransparenceItem&)(rSet.Get(XATTR_LINETRANSPARENCE))).GetValue()); + + if(nTransparence > 100) + { + nTransparence = 100; + } + + if(100 != nTransparence) + { + const sal_uInt32 nWidth(((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue()); + const Color aColor(((const XLineColorItem&)(rSet.Get(XATTR_LINECOLOR))).GetColorValue()); + const XLineJoint eJoint(((const XLineJointItem&)(rSet.Get(XATTR_LINEJOINT))).GetValue()); + ::std::vector< double > aDotDashArray; + double fFullDotDashLen(0.0); + + if(XLINE_DASH == eStyle) + { + const XDash& rDash = ((const XLineDashItem&)(rSet.Get(XATTR_LINEDASH))).GetDashValue(); + + if(rDash.GetDots() || rDash.GetDashes()) + { + fFullDotDashLen = rDash.CreateDotDashArray(aDotDashArray, (double)nWidth); + } + } + + return attribute::SdrLineAttribute( + XLineJointtoB2DLineJoin(eJoint), + (double)nWidth, + (double)nTransparence * 0.01, + aColor.getBColor(), + aDotDashArray, + fFullDotDashLen); + } + } + + return attribute::SdrLineAttribute(); + } + + attribute::SdrLineStartEndAttribute createNewSdrLineStartEndAttribute( + const SfxItemSet& rSet, + double fWidth) + { + const sal_Int32 nTempStartWidth(((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue()); + const sal_Int32 nTempEndWidth(((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue()); + basegfx::B2DPolyPolygon aStartPolyPolygon; + basegfx::B2DPolyPolygon aEndPolyPolygon; + double fStartWidth(0.0); + double fEndWidth(0.0); + bool bStartActive(false); + bool bEndActive(false); + bool bStartCentered(true); + bool bEndCentered(true); + + if(nTempStartWidth) + { + if(nTempStartWidth < 0L) + { + fStartWidth = ((double)(-nTempStartWidth) * fWidth) * 0.01; + } + else + { + fStartWidth = (double)nTempStartWidth; + } + + if(0.0 != fStartWidth) + { + aStartPolyPolygon = basegfx::B2DPolyPolygon(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue()); + + if(aStartPolyPolygon.count() && aStartPolyPolygon.getB2DPolygon(0L).count()) + { + bStartActive = true; + bStartCentered = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue(); + } + } + } + + if(nTempEndWidth) + { + if(nTempEndWidth < 0L) + { + fEndWidth = ((double)(-nTempEndWidth) * fWidth) * 0.01; + } + else + { + fEndWidth = (double)nTempEndWidth; + } + + if(0.0 != fEndWidth) + { + aEndPolyPolygon = basegfx::B2DPolyPolygon(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue()); + + if(aEndPolyPolygon.count() && aEndPolyPolygon.getB2DPolygon(0L).count()) + { + bEndActive = true; + bEndCentered = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue(); + } + } + } + + if(bStartActive || bEndActive) + { + return attribute::SdrLineStartEndAttribute( + aStartPolyPolygon, aEndPolyPolygon, fStartWidth, fEndWidth, + bStartActive, bEndActive, bStartCentered, bEndCentered); + } + + return attribute::SdrLineStartEndAttribute(); + } + + attribute::SdrShadowAttribute createNewSdrShadowAttribute(const SfxItemSet& rSet) + { + const bool bShadow(((SdrShadowItem&)rSet.Get(SDRATTR_SHADOW)).GetValue()); + + if(bShadow) + { + sal_uInt16 nTransparence(((SdrShadowTransparenceItem&)(rSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); + + if(nTransparence > 100) + { + nTransparence = 100; + } + + if(nTransparence) + { + sal_uInt16 nFillTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue()); + + if(nFillTransparence > 100) + { + nFillTransparence = 100; + } + + if(nTransparence == nFillTransparence) + { + // shadow does not really have an own transparence, but the application + // sets the shadow transparence equal to the object transparence for + // convenience. This is not useful for primitive creation, so take + // this as no shadow transparence + nTransparence = 0; + } + } + + if(100 != nTransparence) + { + const basegfx::B2DVector aOffset( + (double)((SdrShadowXDistItem&)(rSet.Get(SDRATTR_SHADOWXDIST))).GetValue(), + (double)((SdrShadowYDistItem&)(rSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); + const Color aColor(((SdrShadowColorItem&)(rSet.Get(SDRATTR_SHADOWCOLOR))).GetColorValue()); + + return attribute::SdrShadowAttribute(aOffset, (double)nTransparence * 0.01, aColor.getBColor()); + } + } + + return attribute::SdrShadowAttribute(); + } + + attribute::SdrFillAttribute createNewSdrFillAttribute(const SfxItemSet& rSet) + { + const XFillStyle eStyle(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue()); + + if(XFILL_NONE != eStyle) + { + sal_uInt16 nTransparence(((const XFillTransparenceItem&)(rSet.Get(XATTR_FILLTRANSPARENCE))).GetValue()); + + if(nTransparence > 100) + { + nTransparence = 100; + } + + if(100 != nTransparence) + { + const Color aColor(((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue()); + attribute::FillGradientAttribute aGradient; + attribute::FillHatchAttribute aHatch; + attribute::SdrFillBitmapAttribute aBitmap; + + switch(eStyle) + { + case XFILL_NONE : // for warnings + case XFILL_SOLID : + { + // nothing to do, color is defined + break; + } + case XFILL_GRADIENT : + { + XGradient aXGradient(((XFillGradientItem&)(rSet.Get(XATTR_FILLGRADIENT))).GetGradientValue()); + + const Color aStartColor(aXGradient.GetStartColor()); + const sal_uInt16 nStartIntens(aXGradient.GetStartIntens()); + basegfx::BColor aStart(aStartColor.getBColor()); + + if(nStartIntens != 100) + { + const basegfx::BColor aBlack; + aStart = interpolate(aBlack, aStart, (double)nStartIntens * 0.01); + } + + const Color aEndColor(aXGradient.GetEndColor()); + const sal_uInt16 nEndIntens(aXGradient.GetEndIntens()); + basegfx::BColor aEnd(aEndColor.getBColor()); + + if(nEndIntens != 100) + { + const basegfx::BColor aBlack; + aEnd = interpolate(aBlack, aEnd, (double)nEndIntens * 0.01); + } + + aGradient = attribute::FillGradientAttribute( + XGradientStyleToGradientStyle(aXGradient.GetGradientStyle()), + (double)aXGradient.GetBorder() * 0.01, + (double)aXGradient.GetXOffset() * 0.01, + (double)aXGradient.GetYOffset() * 0.01, + (double)aXGradient.GetAngle() * F_PI1800, + aStart, + aEnd, + ((const XGradientStepCountItem&)rSet.Get(XATTR_GRADIENTSTEPCOUNT)).GetValue()); + + break; + } + case XFILL_HATCH : + { + const XHatch& rHatch(((XFillHatchItem&)(rSet.Get(XATTR_FILLHATCH))).GetHatchValue()); + const Color aColorB(rHatch.GetColor()); + + aHatch = attribute::FillHatchAttribute( + XHatchStyleToHatchStyle(rHatch.GetHatchStyle()), + (double)rHatch.GetDistance(), + (double)rHatch.GetAngle() * F_PI1800, + aColorB.getBColor(), + ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue()); + + break; + } + case XFILL_BITMAP : + { + aBitmap = createNewSdrFillBitmapAttribute(rSet); + break; + } + } + + return attribute::SdrFillAttribute( + (double)nTransparence * 0.01, + aColor.getBColor(), + aGradient, + aHatch, + aBitmap); + } + } + + return attribute::SdrFillAttribute(); + } + + // #i101508# Support handing over given text-to-border distances + attribute::SdrTextAttribute createNewSdrTextAttribute( + const SfxItemSet& rSet, + const SdrText& rText, + const sal_Int32* pLeft, + const sal_Int32* pUpper, + const sal_Int32* pRight, + const sal_Int32* pLower) + { + const SdrTextObj& rTextObj = rText.GetObject(); + + if(rText.GetOutlinerParaObject() && rText.GetModel()) + { + // added TextEdit text suppression + bool bInEditMode(false); + + if(rText.GetObject().getTextCount() > 1) + { + bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText; + } + else + { + bInEditMode = rTextObj.IsInEditMode(); + } + + OutlinerParaObject aOutlinerParaObject(*rText.GetOutlinerParaObject()); + + if(bInEditMode) + { + OutlinerParaObject* pTempObj = rTextObj.GetEditOutlinerParaObject(); + + if(pTempObj) + { + aOutlinerParaObject = *pTempObj; + delete pTempObj; + } + else + { + // #i100537# + // GetEditOutlinerParaObject() returning no object does not mean that + // text edit mode is not active. Do not reset the flag here + // bInEditMode = false; + } + } + + const SdrFitToSizeType eFit(rTextObj.GetFitToSize()); + const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind()); + + // #i107346# + const SdrOutliner& rDrawTextOutliner = rText.GetModel()->GetDrawOutliner(&rTextObj); + const bool bWrongSpell(rDrawTextOutliner.GetControlWord() & EE_CNTRL_ONLINESPELLING); + + return attribute::SdrTextAttribute( + rText, + aOutlinerParaObject, + ((const XFormTextStyleItem&)rSet.Get(XATTR_FORMTXTSTYLE)).GetValue(), + pLeft ? *pLeft : rTextObj.GetTextLeftDistance(), + pUpper ? *pUpper : rTextObj.GetTextUpperDistance(), + pRight ? *pRight : rTextObj.GetTextRightDistance(), + pLower ? *pLower : rTextObj.GetTextLowerDistance(), + rTextObj.GetTextHorizontalAdjust(rSet), + rTextObj.GetTextVerticalAdjust(rSet), + ((const SdrTextContourFrameItem&)rSet.Get(SDRATTR_TEXT_CONTOURFRAME)).GetValue(), + (SDRTEXTFIT_PROPORTIONAL == eFit || SDRTEXTFIT_ALLLINES == eFit), + ((const XFormTextHideFormItem&)rSet.Get(XATTR_FORMTXTHIDEFORM)).GetValue(), + SDRTEXTANI_BLINK == eAniKind, + SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind, + bInEditMode, + ((const SdrTextFixedCellHeightItem&)rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue(), + bWrongSpell); + } + + return attribute::SdrTextAttribute(); + } + + attribute::FillGradientAttribute createNewTransparenceGradientAttribute(const SfxItemSet& rSet) + { + const SfxPoolItem* pGradientItem; + + if(SFX_ITEM_SET == rSet.GetItemState(XATTR_FILLFLOATTRANSPARENCE, TRUE, &pGradientItem) + && ((XFillFloatTransparenceItem*)pGradientItem)->IsEnabled()) + { + // test if float transparence is completely transparent + const XGradient& rGradient = ((XFillFloatTransparenceItem*)pGradientItem)->GetGradientValue(); + const sal_uInt8 nStartLuminance(rGradient.GetStartColor().GetLuminance()); + const sal_uInt8 nEndLuminance(rGradient.GetEndColor().GetLuminance()); + const bool bCompletelyTransparent(0xff == nStartLuminance && 0xff == nEndLuminance); + + if(!bCompletelyTransparent) + { + const double fStartLum(nStartLuminance / 255.0); + const double fEndLum(nEndLuminance / 255.0); + + return attribute::FillGradientAttribute( + XGradientStyleToGradientStyle(rGradient.GetGradientStyle()), + (double)rGradient.GetBorder() * 0.01, + (double)rGradient.GetXOffset() * 0.01, + (double)rGradient.GetYOffset() * 0.01, + (double)rGradient.GetAngle() * F_PI1800, + basegfx::BColor(fStartLum, fStartLum, fStartLum), + basegfx::BColor(fEndLum, fEndLum, fEndLum), + 0); + } + } + + return attribute::FillGradientAttribute(); + } + + attribute::SdrFillBitmapAttribute createNewSdrFillBitmapAttribute(const SfxItemSet& rSet) + { + Bitmap aBitmap((((const XFillBitmapItem&)(rSet.Get(XATTR_FILLBITMAP))).GetBitmapValue()).GetBitmap()); + + // make sure it's not empty, use default instead + if(aBitmap.IsEmpty()) + { + aBitmap = Bitmap(Size(4,4), 8); + } + + // if there is no logical size, create a size from pixel size and set MapMode accordingly + if(0L == aBitmap.GetPrefSize().Width() || 0L == aBitmap.GetPrefSize().Height()) + { + aBitmap.SetPrefSize(aBitmap.GetSizePixel()); + aBitmap.SetPrefMapMode(MAP_PIXEL); + } + + // convert size and MapMode to destination logical size and MapMode. The created + // bitmap must have a valid logical size (PrefSize) + const MapUnit aDestinationMapUnit((MapUnit)rSet.GetPool()->GetMetric(0)); + + if(aBitmap.GetPrefMapMode() != aDestinationMapUnit) + { + // #i100360# for MAP_PIXEL, LogicToLogic will not work properly, + // so fallback to Application::GetDefaultDevice() + if(MAP_PIXEL == aBitmap.GetPrefMapMode().GetMapUnit()) + { + aBitmap.SetPrefSize(Application::GetDefaultDevice()->PixelToLogic( + aBitmap.GetPrefSize(), aDestinationMapUnit)); + } + else + { + aBitmap.SetPrefSize(OutputDevice::LogicToLogic( + aBitmap.GetPrefSize(), aBitmap.GetPrefMapMode(), aDestinationMapUnit)); + } + } + + // get size + const basegfx::B2DVector aSize( + (double)((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEX))).GetValue(), + (double)((const SfxMetricItem&)(rSet.Get(XATTR_FILLBMP_SIZEY))).GetValue()); + const basegfx::B2DVector aOffset( + (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETX))).GetValue(), + (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_TILEOFFSETY))).GetValue()); + const basegfx::B2DVector aOffsetPosition( + (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETX))).GetValue(), + (double)((const SfxUInt16Item&) (rSet.Get(XATTR_FILLBMP_POSOFFSETY))).GetValue()); + + return attribute::SdrFillBitmapAttribute( + aBitmap, + aSize, + aOffset, + aOffsetPosition, + RectPointToB2DVector((RECT_POINT)((const SfxEnumItem&)(rSet.Get(XATTR_FILLBMP_POS))).GetValue()), + ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_TILE))).GetValue(), + ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_STRETCH))).GetValue(), + ((const SfxBoolItem&) (rSet.Get(XATTR_FILLBMP_SIZELOG))).GetValue()); + } + + attribute::SdrShadowTextAttribute createNewSdrShadowTextAttribute( + const SfxItemSet& rSet, + const SdrText* pText, + bool bSuppressText) + { + attribute::SdrTextAttribute aText; + + // #i98072# added option to suppress text + // look for text first + if(!bSuppressText && pText) + { + aText = createNewSdrTextAttribute(rSet, *pText); + } + + // try shadow + const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); + + return attribute::SdrShadowTextAttribute(aShadow, aText); + } + + attribute::SdrLineShadowTextAttribute createNewSdrLineShadowTextAttribute( + const SfxItemSet& rSet, + const SdrText* pText) + { + attribute::SdrLineAttribute aLine; + attribute::SdrLineStartEndAttribute aLineStartEnd; + attribute::SdrTextAttribute aText; + bool bFontworkHideContour(false); + + // look for text first + if(pText) + { + aText = createNewSdrTextAttribute(rSet, *pText); + + // when object has text and text is fontwork and hide contour is set for fontwork, force + // line and fill style to empty + if(!aText.isDefault() + && !aText.getSdrFormTextAttribute().isDefault() + && aText.isHideContour()) + { + bFontworkHideContour = true; + } + } + + // try line style + if(!bFontworkHideContour) + { + aLine = createNewSdrLineAttribute(rSet); + + if(!aLine.isDefault()) + { + // try LineStartEnd + aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); + } + } + + if(!aLine.isDefault() || !aText.isDefault()) + { + // try shadow + const attribute::SdrShadowAttribute aShadow(createNewSdrShadowAttribute(rSet)); + + return attribute::SdrLineShadowTextAttribute(aLine, aLineStartEnd, aShadow, aText); + } + + return attribute::SdrLineShadowTextAttribute(); + } + + attribute::SdrLineFillShadowTextAttribute createNewSdrLineFillShadowTextAttribute( + const SfxItemSet& rSet, + const SdrText* pText) + { + attribute::SdrLineAttribute aLine; + attribute::SdrFillAttribute aFill; + attribute::SdrLineStartEndAttribute aLineStartEnd; + attribute::SdrShadowAttribute aShadow; + attribute::FillGradientAttribute aFillFloatTransGradient; + attribute::SdrTextAttribute aText; + bool bFontworkHideContour(false); + + // look for text first + if(pText) + { + aText = createNewSdrTextAttribute(rSet, *pText); + + // when object has text and text is fontwork and hide contour is set for fontwork, force + // line and fill style to empty + if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour()) + { + bFontworkHideContour = true; + } + } + + if(!bFontworkHideContour) + { + // try line style + aLine = createNewSdrLineAttribute(rSet); + + if(!aLine.isDefault()) + { + // try LineStartEnd + aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); + } + + // try fill style + aFill = createNewSdrFillAttribute(rSet); + + if(!aFill.isDefault()) + { + // try fillfloattransparence + aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); + } + } + + if(!aLine.isDefault() || !aFill.isDefault() || !aText.isDefault()) + { + // try shadow + aShadow = createNewSdrShadowAttribute(rSet); + + return attribute::SdrLineFillShadowTextAttribute( + aLine, aFill, aLineStartEnd, aShadow, aFillFloatTransGradient, aText); + } + + return attribute::SdrLineFillShadowTextAttribute(); + } + + attribute::SdrLineFillShadowAttribute3D createNewSdrLineFillShadowAttribute(const SfxItemSet& rSet, bool bSuppressFill) + { + attribute::SdrFillAttribute aFill; + attribute::SdrLineStartEndAttribute aLineStartEnd; + attribute::SdrShadowAttribute aShadow; + attribute::FillGradientAttribute aFillFloatTransGradient; + + // try line style + const attribute::SdrLineAttribute aLine(createNewSdrLineAttribute(rSet)); + + if(!aLine.isDefault()) + { + // try LineStartEnd + aLineStartEnd = createNewSdrLineStartEndAttribute(rSet, aLine.getWidth()); + } + + // try fill style + if(!bSuppressFill) + { + aFill = createNewSdrFillAttribute(rSet); + + if(!aFill.isDefault()) + { + // try fillfloattransparence + aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); + } + } + + if(!aLine.isDefault() || !aFill.isDefault()) + { + // try shadow + aShadow = createNewSdrShadowAttribute(rSet); + + return attribute::SdrLineFillShadowAttribute3D( + aLine, aFill, aLineStartEnd, aShadow, aFillFloatTransGradient); + } + + return attribute::SdrLineFillShadowAttribute3D(); + } + + attribute::SdrSceneAttribute createNewSdrSceneAttribute(const SfxItemSet& rSet) + { + // get perspective + ::com::sun::star::drawing::ProjectionMode aProjectionMode(::com::sun::star::drawing::ProjectionMode_PARALLEL); + const sal_uInt16 nProjectionValue(((const Svx3DPerspectiveItem&)rSet.Get(SDRATTR_3DSCENE_PERSPECTIVE)).GetValue()); + + if(1L == nProjectionValue) + { + aProjectionMode = ::com::sun::star::drawing::ProjectionMode_PERSPECTIVE; + } + + // get distance + const double fDistance(((const Svx3DDistanceItem&)rSet.Get(SDRATTR_3DSCENE_DISTANCE)).GetValue()); + + // get shadow slant + const double fShadowSlant(F_PI180 * ((const Svx3DShadowSlantItem&)rSet.Get(SDRATTR_3DSCENE_SHADOW_SLANT)).GetValue()); + + // get shade mode + ::com::sun::star::drawing::ShadeMode aShadeMode(::com::sun::star::drawing::ShadeMode_FLAT); + const sal_uInt16 nShadeValue(((const Svx3DShadeModeItem&)rSet.Get(SDRATTR_3DSCENE_SHADE_MODE)).GetValue()); + + if(1L == nShadeValue) + { + aShadeMode = ::com::sun::star::drawing::ShadeMode_PHONG; + } + else if(2L == nShadeValue) + { + aShadeMode = ::com::sun::star::drawing::ShadeMode_SMOOTH; + } + else if(3L == nShadeValue) + { + aShadeMode = ::com::sun::star::drawing::ShadeMode_DRAFT; + } + + // get two sided lighting + const bool bTwoSidedLighting(((const Svx3DTwoSidedLightingItem&)rSet.Get(SDRATTR_3DSCENE_TWO_SIDED_LIGHTING)).GetValue()); + + return attribute::SdrSceneAttribute(fDistance, fShadowSlant, aProjectionMode, aShadeMode, bTwoSidedLighting); + } + + attribute::SdrLightingAttribute createNewSdrLightingAttribute(const SfxItemSet& rSet) + { + // extract lights from given SfxItemSet (from scene) + ::std::vector< attribute::Sdr3DLightAttribute > aLightVector; + + if(((const Svx3DLightOnOff1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_1)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection1Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, true)); + } + + if(((const Svx3DLightOnOff2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_2)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection2Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_3)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection3Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_4)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection4Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_5)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection5Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_6)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection6Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_7)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection7Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + if(((const Svx3DLightOnOff8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTON_8)).GetValue()) + { + const basegfx::BColor aColor(((const Svx3DLightcolor8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8)).GetValue().getBColor()); + const basegfx::B3DVector aDirection(((const Svx3DLightDirection8Item&)rSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8)).GetValue()); + aLightVector.push_back(attribute::Sdr3DLightAttribute(aColor, aDirection, false)); + } + + // get ambient color + const Color aAmbientValue(((const Svx3DAmbientcolorItem&)rSet.Get(SDRATTR_3DSCENE_AMBIENTCOLOR)).GetValue()); + const basegfx::BColor aAmbientLight(aAmbientValue.getBColor()); + + return attribute::SdrLightingAttribute(aAmbientLight, aLightVector); + } + + void calculateRelativeCornerRadius(sal_Int32 nRadius, const basegfx::B2DRange& rObjectRange, double& rfCornerRadiusX, double& rfCornerRadiusY) + { + rfCornerRadiusX = rfCornerRadiusY = (double)nRadius; + + if(0.0 != rfCornerRadiusX) + { + const double fHalfObjectWidth(rObjectRange.getWidth() * 0.5); + + if(0.0 != fHalfObjectWidth) + { + if(rfCornerRadiusX < 0.0) + { + rfCornerRadiusX = 0.0; + } + + if(rfCornerRadiusX > fHalfObjectWidth) + { + rfCornerRadiusX = fHalfObjectWidth; + } + + rfCornerRadiusX /= fHalfObjectWidth; + } + else + { + rfCornerRadiusX = 0.0; + } + } + + if(0.0 != rfCornerRadiusY) + { + const double fHalfObjectHeight(rObjectRange.getHeight() * 0.5); + + if(0.0 != fHalfObjectHeight) + { + if(rfCornerRadiusY < 0.0) + { + rfCornerRadiusY = 0.0; + } + + if(rfCornerRadiusY > fHalfObjectHeight) + { + rfCornerRadiusY = fHalfObjectHeight; + } + + rfCornerRadiusY /= fHalfObjectHeight; + } + else + { + rfCornerRadiusY = 0.0; + } + } + } + + // #i101508# Support handing over given text-to-border distances + attribute::SdrFillTextAttribute createNewSdrFillTextAttribute( + const SfxItemSet& rSet, + const SdrText* pText, + const sal_Int32* pLeft, + const sal_Int32* pUpper, + const sal_Int32* pRight, + const sal_Int32* pLower) + { + attribute::SdrFillAttribute aFill; + attribute::FillGradientAttribute aFillFloatTransGradient; + attribute::SdrTextAttribute aText; + bool bFontworkHideContour(false); + + // look for text first + if(pText) + { + aText = createNewSdrTextAttribute(rSet, *pText, pLeft, pUpper, pRight, pLower); + + // when object has text and text is fontwork and hide contour is set for fontwork, force + // fill style to empty + if(!aText.getSdrFormTextAttribute().isDefault() && aText.isHideContour()) + { + bFontworkHideContour = true; + } + } + + if(!bFontworkHideContour) + { + // try fill style + aFill = createNewSdrFillAttribute(rSet); + + if(!aFill.isDefault()) + { + // try fillfloattransparence + aFillFloatTransGradient = createNewTransparenceGradientAttribute(rSet); + } + } + + if(!aFill.isDefault() || !aText.isDefault()) + { + return attribute::SdrFillTextAttribute(aFill, aFillFloatTransGradient, aText); + } + + return attribute::SdrFillTextAttribute(); + } + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx new file mode 100644 index 000000000000..3757d60a3d27 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrcaptionprimitive2d.cxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrcaptionprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrCaptionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // create unit outline polygon + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), + getCornerRadiusX(), + getCornerRadiusY())); + + // add fill + if(getSdrLFSTAttribute().getFill().isDefault()) + { + // create invisible fill for HitTest + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + true, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + if(getSdrLFSTAttribute().getLine().isDefault()) + { + // create invisible line for HitTest/BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(getTail()), + getTransform())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + getTail(), + getTransform(), + getSdrLFSTAttribute().getLine(), + getSdrLFSTAttribute().getLineStartEnd())); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive(aRetval, getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrCaptionPrimitive2D::SdrCaptionPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, + const basegfx::B2DPolygon& rTail, + double fCornerRadiusX, + double fCornerRadiusY) + : BufferedDecompositionPrimitive2D(), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute), + maTail(rTail), + mfCornerRadiusX(fCornerRadiusX), + mfCornerRadiusY(fCornerRadiusY) + { + // transform maTail to unit polygon + if(getTail().count()) + { + basegfx::B2DHomMatrix aInverse(getTransform()); + aInverse.invert(); + maTail.transform(aInverse); + } + } + + bool SdrCaptionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrCaptionPrimitive2D& rCompare = (SdrCaptionPrimitive2D&)rPrimitive; + + return (getCornerRadiusX() == rCompare.getCornerRadiusX() + && getCornerRadiusY() == rCompare.getCornerRadiusY() + && getTail() == rCompare.getTail() + && getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrCaptionPrimitive2D, PRIMITIVE2D_ID_SDRCAPTIONPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx new file mode 100644 index 000000000000..6b52837c3eca --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrconnectorprimitive2d.cxx @@ -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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrconnectorprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrConnectorPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // add line + if(getSdrLSTAttribute().getLine().isDefault()) + { + // create invisible line for HitTest/BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(getUnitPolygon()))); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + getUnitPolygon(), + basegfx::B2DHomMatrix(), + getSdrLSTAttribute().getLine(), + getSdrLSTAttribute().getLineStartEnd())); + } + + // add text + if(!getSdrLSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(getUnitPolygon()), + basegfx::B2DHomMatrix(), + getSdrLSTAttribute().getText(), + getSdrLSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrConnectorPrimitive2D::SdrConnectorPrimitive2D( + const attribute::SdrLineShadowTextAttribute& rSdrLSTAttribute, + const ::basegfx::B2DPolygon& rUnitPolygon) + : BufferedDecompositionPrimitive2D(), + maSdrLSTAttribute(rSdrLSTAttribute), + maUnitPolygon(rUnitPolygon) + { + } + + bool SdrConnectorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrConnectorPrimitive2D& rCompare = (SdrConnectorPrimitive2D&)rPrimitive; + + return (getUnitPolygon() == rCompare.getUnitPolygon() + && getSdrLSTAttribute() == rCompare.getSdrLSTAttribute()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrConnectorPrimitive2D, PRIMITIVE2D_ID_SDRCONNECTORPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx new file mode 100644 index 000000000000..710beeb444f2 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrcustomshapeprimitive2d.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/attribute/sdrlineattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrCustomShapePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval(getSubPrimitives()); + + // add text + if(!getSdrSTAttribute().getText().isDefault()) + { + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createUnitPolygon()); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTextBox(), + getSdrSTAttribute().getText(), + attribute::SdrLineAttribute(), + false, + getWordWrap(), + isForceTextClipToTextRange())); + } + + // add shadow + if(aRetval.hasElements() && !getSdrSTAttribute().getShadow().isDefault()) + { + // #i105323# add generic shadow only for 2D shapes. For + // 3D shapes shadow will be set at the individual created + // visualisation objects and be visualized by the 3d renderer + // as a single shadow. + // + // The shadow for AutoShapes could be handled uniformely by not setting any + // shadow items at the helper model objects and only adding shadow here for + // 2D and 3D (and it works, too), but this would lead to two 3D scenes for + // the 3D object; one for the shadow aond one for the content. The one for the + // shadow will be correct (using ColorModifierStack), but expensive. + if(!get3DShape()) + { + aRetval = createEmbeddedShadowPrimitive(aRetval, getSdrSTAttribute().getShadow()); + } + } + + return aRetval; + } + + SdrCustomShapePrimitive2D::SdrCustomShapePrimitive2D( + const attribute::SdrShadowTextAttribute& rSdrSTAttribute, + const Primitive2DSequence& rSubPrimitives, + const basegfx::B2DHomMatrix& rTextBox, + bool bWordWrap, + bool b3DShape, + bool bForceTextClipToTextRange) + : BufferedDecompositionPrimitive2D(), + maSdrSTAttribute(rSdrSTAttribute), + maSubPrimitives(rSubPrimitives), + maTextBox(rTextBox), + mbWordWrap(bWordWrap), + mb3DShape(b3DShape), + mbForceTextClipToTextRange(bForceTextClipToTextRange) + { + } + + bool SdrCustomShapePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrCustomShapePrimitive2D& rCompare = (SdrCustomShapePrimitive2D&)rPrimitive; + + return (getSdrSTAttribute() == rCompare.getSdrSTAttribute() + && getSubPrimitives() == rCompare.getSubPrimitives() + && getTextBox() == rCompare.getTextBox() + && getWordWrap() == rCompare.getWordWrap() + && get3DShape() == rCompare.get3DShape() + && isForceTextClipToTextRange() == rCompare.isForceTextClipToTextRange()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrCustomShapePrimitive2D, PRIMITIVE2D_ID_SDRCUSTOMSHAPEPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx new file mode 100644 index 000000000000..76e6d81bb252 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -0,0 +1,486 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/baseprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> +#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> +#include <drawinglayer/attribute/strokeattribute.hxx> +#include <drawinglayer/attribute/linestartendattribute.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/attribute/sdrfillbitmapattribute.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/shadowprimitive2d.hxx> +#include <svx/sdr/attribute/sdrtextattribute.hxx> +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <svx/svdotext.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/animatedprimitive2d.hxx> +#include <drawinglayer/animation/animationtiming.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> +#include <drawinglayer/attribute/sdrfillattribute.hxx> +#include <drawinglayer/attribute/sdrlineattribute.hxx> +#include <drawinglayer/attribute/sdrlinestartendattribute.hxx> +#include <drawinglayer/attribute/sdrshadowattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DReference createPolyPolygonFillPrimitive( + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, + const attribute::SdrFillAttribute& rFill, + const attribute::FillGradientAttribute& rFillGradient) + { + // prepare fully scaled polygon + basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); + aScaledPolyPolygon.transform(rObjectTransform); + BasePrimitive2D* pNewFillPrimitive = 0; + + if(!rFill.getGradient().isDefault()) + { + pNewFillPrimitive = new PolyPolygonGradientPrimitive2D(aScaledPolyPolygon, rFill.getGradient()); + } + else if(!rFill.getHatch().isDefault()) + { + pNewFillPrimitive = new PolyPolygonHatchPrimitive2D(aScaledPolyPolygon, rFill.getColor(), rFill.getHatch()); + } + else if(!rFill.getBitmap().isDefault()) + { + const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon)); + pNewFillPrimitive = new PolyPolygonBitmapPrimitive2D(aScaledPolyPolygon, rFill.getBitmap().getFillBitmapAttribute(aRange)); + } + else + { + pNewFillPrimitive = new PolyPolygonColorPrimitive2D(aScaledPolyPolygon, rFill.getColor()); + } + + if(0.0 != rFill.getTransparence()) + { + // create simpleTransparencePrimitive, add created fill primitive + const Primitive2DReference xRefA(pNewFillPrimitive); + const Primitive2DSequence aContent(&xRefA, 1L); + return Primitive2DReference(new UnifiedTransparencePrimitive2D(aContent, rFill.getTransparence())); + } + else if(!rFillGradient.isDefault()) + { + // create sequence with created fill primitive + const Primitive2DReference xRefA(pNewFillPrimitive); + const Primitive2DSequence aContent(&xRefA, 1L); + + // create FillGradientPrimitive2D for transparence and add to new sequence + // fillGradientPrimitive is enough here (compared to PolyPolygonGradientPrimitive2D) since float transparence will be masked anyways + const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon)); + const Primitive2DReference xRefB(new FillGradientPrimitive2D(aRange, rFillGradient)); + const Primitive2DSequence aAlpha(&xRefB, 1L); + + // create TransparencePrimitive2D using alpha and content + return Primitive2DReference(new TransparencePrimitive2D(aContent, aAlpha)); + } + else + { + // add to decomposition + return Primitive2DReference(pNewFillPrimitive); + } + } + + Primitive2DReference createPolygonLinePrimitive( + const basegfx::B2DPolygon& rUnitPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, + const attribute::SdrLineAttribute& rLine, + const attribute::SdrLineStartEndAttribute& rStroke) + { + // prepare fully scaled polygon + basegfx::B2DPolygon aScaledPolygon(rUnitPolygon); + aScaledPolygon.transform(rObjectTransform); + + // create line and stroke attribute + const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin()); + const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen()); + BasePrimitive2D* pNewLinePrimitive = 0L; + + if(!rUnitPolygon.isClosed() && !rStroke.isDefault()) + { + attribute::LineStartEndAttribute aStart(rStroke.getStartWidth(), rStroke.getStartPolyPolygon(), rStroke.isStartCentered()); + attribute::LineStartEndAttribute aEnd(rStroke.getEndWidth(), rStroke.getEndPolyPolygon(), rStroke.isEndCentered()); + + // create data + pNewLinePrimitive = new PolygonStrokeArrowPrimitive2D(aScaledPolygon, aLineAttribute, aStrokeAttribute, aStart, aEnd); + } + else + { + // create data + pNewLinePrimitive = new PolygonStrokePrimitive2D(aScaledPolygon, aLineAttribute, aStrokeAttribute); + } + + if(0.0 != rLine.getTransparence()) + { + // create simpleTransparencePrimitive, add created fill primitive + const Primitive2DReference xRefA(pNewLinePrimitive); + const Primitive2DSequence aContent(&xRefA, 1L); + return Primitive2DReference(new UnifiedTransparencePrimitive2D(aContent, rLine.getTransparence())); + } + else + { + // add to decomposition + return Primitive2DReference(pNewLinePrimitive); + } + } + + Primitive2DReference createTextPrimitive( + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform, + const attribute::SdrTextAttribute& rText, + const attribute::SdrLineAttribute& rStroke, + bool bCellText, + bool bWordWrap, + bool bClipOnBounds) + { + basegfx::B2DHomMatrix aAnchorTransform(rObjectTransform); + SdrTextPrimitive2D* pNew = 0; + + if(rText.isContour()) + { + // contour text + if(!rStroke.isDefault() && 0.0 != rStroke.getWidth()) + { + // take line width into account and shrink contour polygon accordingly + // decompose to get scale + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + // scale outline to object's size to allow growing with value relative to that size + // and also to keep aspect ratio + basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); + aScaledUnitPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix( + fabs(aScale.getX()), fabs(aScale.getY()))); + + // grow the polygon. To shrink, use negative value (half width) + aScaledUnitPolyPolygon = basegfx::tools::growInNormalDirection(aScaledUnitPolyPolygon, -(rStroke.getWidth() * 0.5)); + + // scale back to unit polygon + aScaledUnitPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix( + 0.0 != aScale.getX() ? 1.0 / aScale.getX() : 1.0, + 0.0 != aScale.getY() ? 1.0 / aScale.getY() : 1.0)); + + // create with unit polygon + pNew = new SdrContourTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aScaledUnitPolyPolygon, + rObjectTransform); + } + else + { + // create with unit polygon + pNew = new SdrContourTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + rUnitPolyPolygon, + rObjectTransform); + } + } + else if(!rText.getSdrFormTextAttribute().isDefault()) + { + // text on path, use scaled polygon + basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); + aScaledPolyPolygon.transform(rObjectTransform); + pNew = new SdrPathTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aScaledPolyPolygon, + rText.getSdrFormTextAttribute()); + } + else + { + // rObjectTransform is the whole SdrObject transformation from unit rectangle + // to it's size and position. Decompose to allow working with single values. + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + // extract mirroring + const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0)); + const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0)); + aScale = basegfx::absolute(aScale); + + // Get the real size, since polygon ountline and scale + // from the object transformation may vary (e.g. ellipse segments) + basegfx::B2DHomMatrix aJustScaleTransform; + aJustScaleTransform.set(0, 0, aScale.getX()); + aJustScaleTransform.set(1, 1, aScale.getY()); + basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); + aScaledUnitPolyPolygon.transform(aJustScaleTransform); + const basegfx::B2DRange aSnapRange(basegfx::tools::getRange(aScaledUnitPolyPolygon)); + + // create a range describing the wanted text position and size (aTextAnchorRange). This + // means to use the text distance values here + const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + rText.getTextLeftDistance(), aSnapRange.getMinY() + rText.getTextUpperDistance()); + const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - rText.getTextRightDistance(), aSnapRange.getMaxY() - rText.getTextLowerDistance()); + basegfx::B2DRange aTextAnchorRange; + aTextAnchorRange.expand(aTopLeft); + aTextAnchorRange.expand(aBottomRight); + + // now create a transformation from this basic range (aTextAnchorRange) + aAnchorTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( + aTextAnchorRange.getWidth(), aTextAnchorRange.getHeight(), + aTextAnchorRange.getMinX(), aTextAnchorRange.getMinY()); + + // apply mirroring + aAnchorTransform.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0); + + // apply object's other transforms + aAnchorTransform = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate) + * aAnchorTransform; + + if(rText.isFitToSize()) + { + // streched text in range + pNew = new SdrStretchTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aAnchorTransform, + rText.isFixedCellHeight()); + } + else // text in range + { + // build new primitive + pNew = new SdrBlockTextPrimitive2D( + &rText.getSdrText(), + rText.getOutlinerParaObject(), + aAnchorTransform, + rText.getSdrTextHorzAdjust(), + rText.getSdrTextVertAdjust(), + rText.isFixedCellHeight(), + rText.isScroll(), + bCellText, + bWordWrap, + bClipOnBounds); + } + } + + OSL_ENSURE(pNew != 0, "createTextPrimitive: no text primitive created (!)"); + + if(rText.isBlink()) + { + // prepare animation and primitive list + drawinglayer::animation::AnimationEntryList aAnimationList; + rText.getBlinkTextTiming(aAnimationList); + + if(0.0 != aAnimationList.getDuration()) + { + // create content sequence + const Primitive2DReference xRefA(pNew); + const Primitive2DSequence aContent(&xRefA, 1L); + + // create and add animated switch primitive + return Primitive2DReference(new AnimatedBlinkPrimitive2D(aAnimationList, aContent, true)); + } + else + { + // add to decomposition + return Primitive2DReference(pNew); + } + } + + if(rText.isScroll()) + { + // suppress scroll when FontWork + if(rText.getSdrFormTextAttribute().isDefault()) + { + // get scroll direction + const SdrTextAniDirection eDirection(rText.getSdrText().GetObject().GetTextAniDirection()); + const bool bHorizontal(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection); + + // decompose to get separated values for the scroll box + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aAnchorTransform.decompose(aScale, aTranslate, fRotate, fShearX); + + // build transform from scaled only to full AnchorTransform and inverse + const basegfx::B2DHomMatrix aSRT(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( + fShearX, fRotate, aTranslate)); + basegfx::B2DHomMatrix aISRT(aSRT); + aISRT.invert(); + + // bring the primitive back to scaled only and get scaled range, create new clone for this + SdrTextPrimitive2D* pNew2 = pNew->createTransformedClone(aISRT); + OSL_ENSURE(pNew2, "createTextPrimitive: Could not create transformed clone of text primitive (!)"); + delete pNew; + pNew = pNew2; + + // create neutral geometry::ViewInformation2D for local range and decompose calls. This is okay + // since the decompose is view-independent + const uno::Sequence< beans::PropertyValue > xViewParameters; + geometry::ViewInformation2D aViewInformation2D(xViewParameters); + + // get range + const basegfx::B2DRange aScaledRange(pNew->getB2DRange(aViewInformation2D)); + + // create left outside and right outside transformations. Also take care + // of the clip rectangle + basegfx::B2DHomMatrix aLeft, aRight; + basegfx::B2DPoint aClipTopLeft(0.0, 0.0); + basegfx::B2DPoint aClipBottomRight(aScale.getX(), aScale.getY()); + + if(bHorizontal) + { + aClipTopLeft.setY(aScaledRange.getMinY()); + aClipBottomRight.setY(aScaledRange.getMaxY()); + aLeft.translate(-aScaledRange.getMaxX(), 0.0); + aRight.translate(aScale.getX() - aScaledRange.getMinX(), 0.0); + } + else + { + aClipTopLeft.setX(aScaledRange.getMinX()); + aClipBottomRight.setX(aScaledRange.getMaxX()); + aLeft.translate(0.0, -aScaledRange.getMaxY()); + aRight.translate(0.0, aScale.getY() - aScaledRange.getMinY()); + } + + aLeft *= aSRT; + aRight *= aSRT; + + // prepare animation list + drawinglayer::animation::AnimationEntryList aAnimationList; + + if(bHorizontal) + { + rText.getScrollTextTiming(aAnimationList, aScale.getX(), aScaledRange.getWidth()); + } + else + { + rText.getScrollTextTiming(aAnimationList, aScale.getY(), aScaledRange.getHeight()); + } + + if(0.0 != aAnimationList.getDuration()) + { + // create a new Primitive2DSequence containing the animated text in it's scaled only state. + // use the decomposition to force to simple text primitives, those will no longer + // need the outliner for formatting (alternatively it is also possible to just add + // pNew to aNewPrimitiveSequence) + Primitive2DSequence aAnimSequence(pNew->get2DDecomposition(aViewInformation2D)); + delete pNew; + + // create a new animatedInterpolatePrimitive and add it + std::vector< basegfx::B2DHomMatrix > aMatrixStack; + aMatrixStack.push_back(aLeft); + aMatrixStack.push_back(aRight); + const Primitive2DReference xRefA(new AnimatedInterpolatePrimitive2D(aMatrixStack, aAnimationList, aAnimSequence, true)); + const Primitive2DSequence aContent(&xRefA, 1L); + + // scrolling needs an encapsulating clipping primitive + const basegfx::B2DRange aClipRange(aClipTopLeft, aClipBottomRight); + basegfx::B2DPolygon aClipPolygon(basegfx::tools::createPolygonFromRect(aClipRange)); + aClipPolygon.transform(aSRT); + return Primitive2DReference(new MaskPrimitive2D(basegfx::B2DPolyPolygon(aClipPolygon), aContent)); + } + else + { + // add to decomposition + return Primitive2DReference(pNew); + } + } + } + + if(rText.isInEditMode()) + { + // #i97628# + // encapsulate with TextHierarchyEditPrimitive2D to allow renderers + // to suppress actively edited content if needed + const Primitive2DReference xRefA(pNew); + const Primitive2DSequence aContent(&xRefA, 1L); + + // create and add TextHierarchyEditPrimitive2D primitive + return Primitive2DReference(new TextHierarchyEditPrimitive2D(aContent)); + } + else + { + // add to decomposition + return Primitive2DReference(pNew); + } + } + + Primitive2DSequence createEmbeddedShadowPrimitive( + const Primitive2DSequence& rContent, + const attribute::SdrShadowAttribute& rShadow) + { + if(rContent.hasElements()) + { + Primitive2DSequence aRetval(2); + basegfx::B2DHomMatrix aShadowOffset; + + // prepare shadow offset + aShadowOffset.set(0, 2, rShadow.getOffset().getX()); + aShadowOffset.set(1, 2, rShadow.getOffset().getY()); + + // create shadow primitive and add content + aRetval[0] = Primitive2DReference( + new ShadowPrimitive2D( + aShadowOffset, + rShadow.getColor(), + rContent)); + + if(0.0 != rShadow.getTransparence()) + { + // create SimpleTransparencePrimitive2D + const Primitive2DSequence aTempContent(&aRetval[0], 1); + + aRetval[0] = Primitive2DReference( + new UnifiedTransparencePrimitive2D( + aTempContent, + rShadow.getTransparence())); + } + + aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent)); + return aRetval; + } + else + { + return rContent; + } + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx new file mode 100644 index 000000000000..02de307bee77 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrellipseprimitive2d.cxx @@ -0,0 +1,278 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrellipseprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <basegfx/color/bcolor.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrEllipsePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // create unit outline polygon + // Do use createPolygonFromUnitCircle, but let create from first quadrant to mimic old geometry creation. + // This is needed to have the same look when stroke is used since the polygon start point defines the + // stroke start, too. + basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromUnitCircle(1)); + + // scale and move UnitEllipse to UnitObject (-1,-1 1,1) -> (0,0 1,1) + const basegfx::B2DHomMatrix aUnitCorrectionMatrix( + basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5)); + + // apply to the geometry + aUnitOutline.transform(aUnitCorrectionMatrix); + + // add fill + if(!getSdrLFSTAttribute().getFill().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + if(getSdrLFSTAttribute().getLine().isDefault()) + { + // create invisible line for HitTest/BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrEllipsePrimitive2D::SdrEllipsePrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute) + : BufferedDecompositionPrimitive2D(), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute) + { + } + + bool SdrEllipsePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrEllipsePrimitive2D& rCompare = (SdrEllipsePrimitive2D&)rPrimitive; + + return (getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrEllipsePrimitive2D, PRIMITIVE2D_ID_SDRELLIPSEPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrEllipseSegmentPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // create unit outline polygon + basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromUnitEllipseSegment(mfStartAngle, mfEndAngle)); + + if(mbCloseSegment) + { + if(mbCloseUsingCenter) + { + // for compatibility, insert the center point at polygon start to get the same + // line stroking pattern as the old painting mechanisms. + aUnitOutline.insert(0L, basegfx::B2DPoint(0.0, 0.0)); + } + + aUnitOutline.setClosed(true); + } + + // move and scale UnitEllipse to UnitObject (-1,-1 1,1) -> (0,0 1,1) + const basegfx::B2DHomMatrix aUnitCorrectionMatrix( + basegfx::tools::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5)); + + // apply to the geometry + aUnitOutline.transform(aUnitCorrectionMatrix); + + // add fill + if(!getSdrLFSTAttribute().getFill().isDefault() && aUnitOutline.isClosed()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + if(getSdrLFSTAttribute().getLine().isDefault()) + { + // create invisible line for HitTest/BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + getSdrLFSTAttribute().getLineStartEnd())); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrEllipseSegmentPrimitive2D::SdrEllipseSegmentPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, + double fStartAngle, + double fEndAngle, + bool bCloseSegment, + bool bCloseUsingCenter) + : SdrEllipsePrimitive2D(rTransform, rSdrLFSTAttribute), + mfStartAngle(fStartAngle), + mfEndAngle(fEndAngle), + mbCloseSegment(bCloseSegment), + mbCloseUsingCenter(bCloseUsingCenter) + { + } + + bool SdrEllipseSegmentPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(SdrEllipsePrimitive2D::operator==(rPrimitive)) + { + const SdrEllipseSegmentPrimitive2D& rCompare = (SdrEllipseSegmentPrimitive2D&)rPrimitive; + + if( mfStartAngle == rCompare.mfStartAngle + && mfEndAngle == rCompare.mfEndAngle + && mbCloseSegment == rCompare.mbCloseSegment + && mbCloseUsingCenter == rCompare.mbCloseUsingCenter) + { + return true; + } + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrEllipseSegmentPrimitive2D, PRIMITIVE2D_ID_SDRELLIPSESEGMENTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx new file mode 100644 index 000000000000..e981af91896b --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrgrafprimitive2d.cxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrgrafprimitive2d.hxx> +#include <drawinglayer/primitive2d/graphicprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrGrafPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // create unit outline polygon + basegfx::B2DPolygon aUnitOutline(basegfx::tools::createUnitPolygon()); + + // add fill, but only when graphic ist transparent + if(!getSdrLFSTAttribute().getFill().isDefault() && isTransparent()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + if(!getSdrLFSTAttribute().getLine().isDefault()) + { + // if line width is given, polygon needs to be grown by half of it to make the + // outline to be outside of the bitmap + if(0.0 != getSdrLFSTAttribute().getLine().getWidth()) + { + // decompose to get scale + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getTransform().decompose(aScale, aTranslate, fRotate, fShearX); + + // create expanded range (add relative half line width to unit rectangle) + double fHalfLineWidth(getSdrLFSTAttribute().getLine().getWidth() * 0.5); + double fScaleX(0.0 != aScale.getX() ? fHalfLineWidth / fabs(aScale.getX()) : 1.0); + double fScaleY(0.0 != aScale.getY() ? fHalfLineWidth / fabs(aScale.getY()) : 1.0); + const basegfx::B2DRange aExpandedRange(-fScaleX, -fScaleY, 1.0 + fScaleX, 1.0 + fScaleY); + basegfx::B2DPolygon aExpandedUnitOutline(basegfx::tools::createPolygonFromRect(aExpandedRange)); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aExpandedUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + } + + // add graphic content + if(255L != getGraphicAttr().GetTransparency()) + { + const Primitive2DReference xGraphicContentPrimitive( + new GraphicPrimitive2D( + getTransform(), + getGraphicObject(), + getGraphicAttr())); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xGraphicContentPrimitive); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrGrafPrimitive2D::SdrGrafPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, + const GraphicObject& rGraphicObject, + const GraphicAttr& rGraphicAttr) + : BufferedDecompositionPrimitive2D(), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute), + maGraphicObject(rGraphicObject), + maGraphicAttr(rGraphicAttr) + { + // reset some values from GraphicAttr which are part of transformation already + maGraphicAttr.SetRotation(0L); + } + + bool SdrGrafPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrGrafPrimitive2D& rCompare = (SdrGrafPrimitive2D&)rPrimitive; + + return (getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute() + && getGraphicObject() == rCompare.getGraphicObject() + && getGraphicAttr() == rCompare.getGraphicAttr()); + } + + return false; + } + + bool SdrGrafPrimitive2D::isTransparent() const + { + return ((0L != getGraphicAttr().GetTransparency()) || (getGraphicObject().IsTransparent())); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrGrafPrimitive2D, PRIMITIVE2D_ID_SDRGRAFPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx new file mode 100644 index 000000000000..e4403cd6df49 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrmeasureprimitive2d.cxx @@ -0,0 +1,510 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrmeasureprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <svx/sdr/attribute/sdrtextattribute.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DReference SdrMeasurePrimitive2D::impCreatePart( + const attribute::SdrLineAttribute& rLineAttribute, + const basegfx::B2DHomMatrix& rObjectMatrix, + const basegfx::B2DPoint& rStart, + const basegfx::B2DPoint& rEnd, + bool bLeftActive, + bool bRightActive) const + { + const attribute::SdrLineStartEndAttribute& rLineStartEnd = getSdrLSTAttribute().getLineStartEnd(); + basegfx::B2DPolygon aPolygon; + + aPolygon.append(rStart); + aPolygon.append(rEnd); + + if(rLineStartEnd.isDefault() || (!bLeftActive && !bRightActive)) + { + return createPolygonLinePrimitive( + aPolygon, + rObjectMatrix, + rLineAttribute, + attribute::SdrLineStartEndAttribute()); + } + + if(bLeftActive && bRightActive) + { + return createPolygonLinePrimitive( + aPolygon, + rObjectMatrix, + rLineAttribute, + rLineStartEnd); + } + + const basegfx::B2DPolyPolygon aEmpty; + const attribute::SdrLineStartEndAttribute aLineStartEnd( + bLeftActive ? rLineStartEnd.getStartPolyPolygon() : aEmpty, bRightActive ? rLineStartEnd.getEndPolyPolygon() : aEmpty, + bLeftActive ? rLineStartEnd.getStartWidth() : 0.0, bRightActive ? rLineStartEnd.getEndWidth() : 0.0, + bLeftActive ? rLineStartEnd.isStartActive() : false, bRightActive ? rLineStartEnd.isEndActive() : false, + bLeftActive ? rLineStartEnd.isStartCentered() : false, bRightActive? rLineStartEnd.isEndCentered() : false); + + return createPolygonLinePrimitive(aPolygon, rObjectMatrix, rLineAttribute, aLineStartEnd); + } + + Primitive2DSequence SdrMeasurePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const + { + Primitive2DSequence aRetval; + SdrBlockTextPrimitive2D* pBlockText = 0; + basegfx::B2DRange aTextRange; + double fTextX((getStart().getX() + getEnd().getX()) * 0.5); + double fTextY((getStart().getX() + getEnd().getX()) * 0.5); + const basegfx::B2DVector aLine(getEnd() - getStart()); + const double fDistance(aLine.getLength()); + const double fAngle(atan2(aLine.getY(), aLine.getX())); + bool bAutoUpsideDown(false); + const attribute::SdrTextAttribute rTextAttribute = getSdrLSTAttribute().getText(); + const basegfx::B2DHomMatrix aObjectMatrix( + basegfx::tools::createShearXRotateTranslateB2DHomMatrix(0.0, fAngle, getStart())); + + // preapare text, but do not add yet; it needs to be aligned to + // the line geometry + if(!rTextAttribute.isDefault()) + { + basegfx::B2DHomMatrix aTextMatrix; + double fTestAngle(fAngle); + + if(getTextRotation()) + { + aTextMatrix.rotate(-90.0 * F_PI180); + fTestAngle -= (90.0 * F_PI180); + + if(getTextAutoAngle() && fTestAngle < -F_PI) + { + fTestAngle += F_2PI; + } + } + + if(getTextAutoAngle()) + { + if(fTestAngle > (F_PI / 4.0) || fTestAngle < (-F_PI * (3.0 / 4.0))) + { + bAutoUpsideDown = true; + } + } + + // create primitive and get text range + pBlockText = new SdrBlockTextPrimitive2D( + &rTextAttribute.getSdrText(), + rTextAttribute.getOutlinerParaObject(), + aTextMatrix, + SDRTEXTHORZADJUST_CENTER, + SDRTEXTVERTADJUST_CENTER, + rTextAttribute.isScroll(), + false, + false, + false, + false); + + aTextRange = pBlockText->getB2DRange(aViewInformation); + } + + // prepare line attribute and result + { + const attribute::SdrLineAttribute rLineAttribute(getSdrLSTAttribute().getLine()); + bool bArrowsOutside(false); + bool bMainLineSplitted(false); + const attribute::SdrLineStartEndAttribute& rLineStartEnd = getSdrLSTAttribute().getLineStartEnd(); + double fStartArrowW(0.0); + double fStartArrowH(0.0); + double fEndArrowW(0.0); + double fEndArrowH(0.0); + + if(!rLineStartEnd.isDefault()) + { + if(rLineStartEnd.isStartActive()) + { + const basegfx::B2DRange aArrowRange(basegfx::tools::getRange(rLineStartEnd.getStartPolyPolygon())); + fStartArrowW = rLineStartEnd.getStartWidth(); + fStartArrowH = aArrowRange.getHeight() * fStartArrowW / aArrowRange.getWidth(); + + if(rLineStartEnd.isStartCentered()) + { + fStartArrowH *= 0.5; + } + } + + if(rLineStartEnd.isEndActive()) + { + const basegfx::B2DRange aArrowRange(basegfx::tools::getRange(rLineStartEnd.getEndPolyPolygon())); + fEndArrowW = rLineStartEnd.getEndWidth(); + fEndArrowH = aArrowRange.getHeight() * fEndArrowW / aArrowRange.getWidth(); + + if(rLineStartEnd.isEndCentered()) + { + fEndArrowH *= 0.5; + } + } + } + + const double fSpaceNeededByArrows(fStartArrowH + fEndArrowH + ((fStartArrowW + fEndArrowW) * 0.5)); + const double fArrowsOutsideLen((fStartArrowH + fEndArrowH + fStartArrowW + fEndArrowW) * 0.5); + const double fHalfLineWidth(rLineAttribute.getWidth() * 0.5); + + if(fSpaceNeededByArrows > fDistance) + { + bArrowsOutside = true; + } + + MeasureTextPosition eHorizontal(getHorizontal()); + MeasureTextPosition eVertical(getVertical()); + + if(MEASURETEXTPOSITION_AUTOMATIC == eVertical) + { + eVertical = MEASURETEXTPOSITION_NEGATIVE; + } + + if(MEASURETEXTPOSITION_CENTERED == eVertical) + { + bMainLineSplitted = true; + } + + if(MEASURETEXTPOSITION_AUTOMATIC == eHorizontal) + { + if(aTextRange.getWidth() > fDistance) + { + eHorizontal = MEASURETEXTPOSITION_NEGATIVE; + } + else + { + eHorizontal = MEASURETEXTPOSITION_CENTERED; + } + + if(bMainLineSplitted) + { + if(aTextRange.getWidth() + fSpaceNeededByArrows > fDistance) + { + bArrowsOutside = true; + } + } + else + { + const double fSmallArrowNeed(fStartArrowH + fEndArrowH + ((fStartArrowW + fEndArrowW) * 0.125)); + + if(aTextRange.getWidth() + fSmallArrowNeed > fDistance) + { + bArrowsOutside = true; + } + } + } + + if(MEASURETEXTPOSITION_CENTERED != eHorizontal) + { + bArrowsOutside = true; + } + + // switch text above/below? + if(getBelow() || (bAutoUpsideDown && !getTextRotation())) + { + if(MEASURETEXTPOSITION_NEGATIVE == eVertical) + { + eVertical = MEASURETEXTPOSITION_POSITIVE; + } + else if(MEASURETEXTPOSITION_POSITIVE == eVertical) + { + eVertical = MEASURETEXTPOSITION_NEGATIVE; + } + } + + const double fMainLineOffset(getBelow() ? getDistance() : -getDistance()); + const basegfx::B2DPoint aMainLeft(0.0, fMainLineOffset); + const basegfx::B2DPoint aMainRight(fDistance, fMainLineOffset); + + // main line + if(bArrowsOutside) + { + double fLenLeft(fArrowsOutsideLen); + double fLenRight(fArrowsOutsideLen); + + if(!bMainLineSplitted) + { + if(MEASURETEXTPOSITION_NEGATIVE == eHorizontal) + { + fLenLeft = fStartArrowH + aTextRange.getWidth(); + } + else if(MEASURETEXTPOSITION_POSITIVE == eHorizontal) + { + fLenRight = fEndArrowH + aTextRange.getWidth(); + } + } + + const basegfx::B2DPoint aMainLeftLeft(aMainLeft.getX() - fLenLeft, aMainLeft.getY()); + const basegfx::B2DPoint aMainRightRight(aMainRight.getX() + fLenRight, aMainRight.getY()); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainLeftLeft, aMainLeft, false, true)); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainRight, aMainRightRight, true, false)); + + if(!bMainLineSplitted || MEASURETEXTPOSITION_CENTERED != eHorizontal) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainLeft, aMainRight, false, false)); + } + } + else + { + if(bMainLineSplitted) + { + const double fHalfLength((fDistance - (aTextRange.getWidth() + (fStartArrowH + fEndArrowH) * 0.25)) * 0.5); + const basegfx::B2DPoint aMainInnerLeft(aMainLeft.getX() + fHalfLength, aMainLeft.getY()); + const basegfx::B2DPoint aMainInnerRight(aMainRight.getX() - fHalfLength, aMainRight.getY()); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainLeft, aMainInnerLeft, true, false)); + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainInnerRight, aMainRight, false, true)); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aMainLeft, aMainRight, true, true)); + } + } + + // left/right help line value preparation + const double fTopEdge(getBelow() ? getUpper() + getDistance() : -getUpper() - getDistance()); + const double fBottomLeft(getBelow() ? getLower() - getLeftDelta() : getLeftDelta() - getLower()); + const double fBottomRight(getBelow() ? getLower() - getRightDelta() : getRightDelta() - getLower()); + + // left help line + const basegfx::B2DPoint aLeftUp(0.0, fTopEdge); + const basegfx::B2DPoint aLeftDown(0.0, fBottomLeft); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aLeftDown, aLeftUp, false, false)); + + // right help line + const basegfx::B2DPoint aRightUp(fDistance, fTopEdge); + const basegfx::B2DPoint aRightDown(fDistance, fBottomRight); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, impCreatePart(rLineAttribute, aObjectMatrix, aRightDown, aRightUp, false, false)); + + // text horizontal position + if(MEASURETEXTPOSITION_NEGATIVE == eHorizontal) + { + // left + const double fSmall(fArrowsOutsideLen * 0.18); + fTextX = aMainLeft.getX() - (fStartArrowH + aTextRange.getWidth() + fSmall + fHalfLineWidth); + + if(bMainLineSplitted) + { + fTextX -= (fArrowsOutsideLen - fStartArrowH); + } + + if(!rTextAttribute.isDefault()) + { + fTextX -= rTextAttribute.getTextRightDistance(); + } + } + else if(MEASURETEXTPOSITION_POSITIVE == eHorizontal) + { + // right + const double fSmall(fArrowsOutsideLen * 0.18); + fTextX = aMainRight.getX() + (fEndArrowH + fSmall + fHalfLineWidth); + + if(bMainLineSplitted) + { + fTextX += (fArrowsOutsideLen - fEndArrowH); + } + + if(!rTextAttribute.isDefault()) + { + fTextX += rTextAttribute.getTextLeftDistance(); + } + } + else // MEASURETEXTPOSITION_CENTERED + { + // centered + fTextX = aMainLeft.getX() + ((fDistance - aTextRange.getWidth()) * 0.5); + + if(!rTextAttribute.isDefault()) + { + fTextX += (rTextAttribute.getTextLeftDistance() - rTextAttribute.getTextRightDistance()) / 2L; + } + } + + // text vertical position + if(MEASURETEXTPOSITION_NEGATIVE == eVertical) + { + // top + const double fSmall(fArrowsOutsideLen * 0.10); + fTextY = aMainLeft.getY() - (aTextRange.getHeight() + fSmall + fHalfLineWidth); + + if(!rTextAttribute.isDefault()) + { + fTextY -= rTextAttribute.getTextLowerDistance(); + } + } + else if(MEASURETEXTPOSITION_POSITIVE == eVertical) + { + // bottom + const double fSmall(fArrowsOutsideLen * 0.10); + fTextY = aMainLeft.getY() + (fSmall + fHalfLineWidth); + + if(!rTextAttribute.isDefault()) + { + fTextY += rTextAttribute.getTextUpperDistance(); + } + } + else // MEASURETEXTPOSITION_CENTERED + { + // centered + fTextY = aMainLeft.getY() - (aTextRange.getHeight() * 0.5); + + if(!rTextAttribute.isDefault()) + { + fTextY += (rTextAttribute.getTextUpperDistance() - rTextAttribute.getTextLowerDistance()) / 2L; + } + } + } + + if(getSdrLSTAttribute().getLine().isDefault()) + { + // embed line geometry to invisible (100% transparent) line group for HitTest + const Primitive2DReference xHiddenLines(new HiddenGeometryPrimitive2D(aRetval)); + + aRetval = Primitive2DSequence(&xHiddenLines, 1); + } + + if(pBlockText) + { + // create transformation to text primitive end position + basegfx::B2DHomMatrix aChange; + + // handle auto text rotation + if(bAutoUpsideDown) + { + aChange.rotate(F_PI); + } + + // move from aTextRange.TopLeft to fTextX, fTextY + aChange.translate(fTextX - aTextRange.getMinX(), fTextY - aTextRange.getMinY()); + + // apply object matrix + aChange *= aObjectMatrix; + + // apply to existing text primitive + SdrTextPrimitive2D* pNewBlockText = pBlockText->createTransformedClone(aChange); + OSL_ENSURE(pNewBlockText, "SdrMeasurePrimitive2D::create2DDecomposition: Could not create transformed clone of text primitive (!)"); + delete pBlockText; + + // add to local primitives + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, Primitive2DReference(pNewBlockText)); + } + + // add shadow + if(!getSdrLSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrMeasurePrimitive2D::SdrMeasurePrimitive2D( + const attribute::SdrLineShadowTextAttribute& rSdrLSTAttribute, + const basegfx::B2DPoint& rStart, + const basegfx::B2DPoint& rEnd, + MeasureTextPosition eHorizontal, + MeasureTextPosition eVertical, + double fDistance, + double fUpper, + double fLower, + double fLeftDelta, + double fRightDelta, + bool bBelow, + bool bTextRotation, + bool bTextAutoAngle) + : BufferedDecompositionPrimitive2D(), + maSdrLSTAttribute(rSdrLSTAttribute), + maStart(rStart), + maEnd(rEnd), + meHorizontal(eHorizontal), + meVertical(eVertical), + mfDistance(fDistance), + mfUpper(fUpper), + mfLower(fLower), + mfLeftDelta(fLeftDelta), + mfRightDelta(fRightDelta), + mbBelow(bBelow), + mbTextRotation(bTextRotation), + mbTextAutoAngle(bTextAutoAngle) + { + } + + bool SdrMeasurePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrMeasurePrimitive2D& rCompare = (SdrMeasurePrimitive2D&)rPrimitive; + + return (getStart() == rCompare.getStart() + && getEnd() == rCompare.getEnd() + && getHorizontal() == rCompare.getHorizontal() + && getVertical() == rCompare.getVertical() + && getDistance() == rCompare.getDistance() + && getUpper() == rCompare.getUpper() + && getLower() == rCompare.getLower() + && getLeftDelta() == rCompare.getLeftDelta() + && getRightDelta() == rCompare.getRightDelta() + && getBelow() == rCompare.getBelow() + && getTextRotation() == rCompare.getTextRotation() + && getTextAutoAngle() == rCompare.getTextAutoAngle() + && getSdrLSTAttribute() == rCompare.getSdrLSTAttribute()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrMeasurePrimitive2D, PRIMITIVE2D_ID_SDRMEASUREPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx b/svx/source/sdr/primitive2d/sdrole2primitive2d.cxx new file mode 100644 index 000000000000..43e3cf72ffbb --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrole2primitive2d.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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrole2primitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + SdrOle2Primitive2D::SdrOle2Primitive2D( + const Primitive2DSequence& rOLEContent, + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute) + : BasePrimitive2D(), + maOLEContent(rOLEContent), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute) + { + } + + bool SdrOle2Primitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BasePrimitive2D::operator==(rPrimitive)) + { + const SdrOle2Primitive2D& rCompare = (SdrOle2Primitive2D&)rPrimitive; + + // #i108636# The standard operator== on two UNO sequences did not work as i + // would have expected; it just checks the .is() states and the data type + // of the sequence. What i need here is detection of equality of the whole + // sequence content, thus i need to use the arePrimitive2DSequencesEqual helper + // here instead of the operator== which lead to always returning false and thus + // always re-decompositions of the subcontent. + if(arePrimitive2DSequencesEqual(getOLEContent(), rCompare.getOLEContent()) + && getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()) + { + return true; + } + } + + return false; + } + + Primitive2DSequence SdrOle2Primitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + // to take care of getSdrLFSTAttribute() later, the same as in SdrGrafPrimitive2D::create2DDecomposition + // should happen. For the moment we only need the OLE itself + // Added complete primitive preparation using getSdrLFSTAttribute() now. To not do stuff which is not needed now, it + // may be supressed by using a static bool. The paint version only supported text. + static bool bBehaveCompatibleToPaintVersion(true); + Primitive2DSequence aRetval; + + // create unit outline polygon + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createUnitPolygon()); + + // add fill + if(!bBehaveCompatibleToPaintVersion + && !getSdrLFSTAttribute().getFill().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + // #i97981# condition was inverse to purpose. When being compatible to paint version, + // border needs to be suppressed + if(!bBehaveCompatibleToPaintVersion + && !getSdrLFSTAttribute().getLine().isDefault()) + { + // if line width is given, polygon needs to be grown by half of it to make the + // outline to be outside of the bitmap + if(0.0 != getSdrLFSTAttribute().getLine().getWidth()) + { + // decompose to get scale + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getTransform().decompose(aScale, aTranslate, fRotate, fShearX); + + // create expanded range (add relative half line width to unit rectangle) + double fHalfLineWidth(getSdrLFSTAttribute().getLine().getWidth() * 0.5); + double fScaleX(0.0 != aScale.getX() ? fHalfLineWidth / fabs(aScale.getX()) : 1.0); + double fScaleY(0.0 != aScale.getY() ? fHalfLineWidth / fabs(aScale.getY()) : 1.0); + const basegfx::B2DRange aExpandedRange(-fScaleX, -fScaleY, 1.0 + fScaleX, 1.0 + fScaleY); + basegfx::B2DPolygon aExpandedUnitOutline(basegfx::tools::createPolygonFromRect(aExpandedRange)); + + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aExpandedUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + else + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + } + else + { + // if initially no line is defined, create one for HitTest and BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + + // add graphic content + appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, getOLEContent()); + + // add text, no need to supress to stay compatible since text was + // always supported by the old paints, too + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!bBehaveCompatibleToPaintVersion + && !getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrOle2Primitive2D, PRIMITIVE2D_ID_SDROLE2PRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx new file mode 100644 index 000000000000..70c1feda75a8 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrolecontentprimitive2d.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrolecontentprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/svdoole2.hxx> +#include <vcl/svapp.hxx> +#include <drawinglayer/primitive2d/graphicprimitive2d.hxx> +#include <svtools/colorcfg.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrOleContentPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + const SdrOle2Obj* pSource = (mpSdrOle2Obj.is() ? static_cast< SdrOle2Obj* >(mpSdrOle2Obj.get()) : 0); + bool bScaleContent(false); + Graphic aGraphic; + + if(pSource) + { + Graphic* pOLEGraphic = (getHighContrast()) + ? pSource->getEmbeddedObjectRef().GetHCGraphic() + : pSource->GetGraphic(); + + if(pOLEGraphic) + { + aGraphic = *pOLEGraphic; + bScaleContent = pSource->IsEmptyPresObj(); + } + } + + if(GRAPHIC_NONE == aGraphic.GetType()) + { + // no source, use fallback ressource emty OLE graphic + const Bitmap aEmptyOLEBitmap(SdrOle2Obj::GetEmtyOLEReplacementBitmap()); + aGraphic = Graphic(aEmptyOLEBitmap); + bScaleContent = true; + } + + if(GRAPHIC_NONE != aGraphic.GetType()) + { + const GraphicObject aGraphicObject(aGraphic); + const GraphicAttr aGraphicAttr; + drawinglayer::primitive2d::Primitive2DSequence xOLEContent; + + if(bScaleContent) + { + // get transformation atoms + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + getObjectTransform().decompose(aScale, aTranslate, fRotate, fShearX); + + // get PrefSize from the graphic in 100th mm + Size aPrefSize(aGraphic.GetPrefSize()); + + if(MAP_PIXEL == aGraphic.GetPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aGraphic.GetPrefMapMode(), MAP_100TH_MM); + } + + const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0); + const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0); + + if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) + { + // if content fits into frame, create it + basegfx::B2DHomMatrix aInnerObjectMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix( + aPrefSize.getWidth(), aPrefSize.getHeight(), fOffsetX, fOffsetY)); + aInnerObjectMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate) + * aInnerObjectMatrix; + + const drawinglayer::primitive2d::Primitive2DReference aGraphicPrimitive( + new drawinglayer::primitive2d::GraphicPrimitive2D( + aInnerObjectMatrix, + aGraphicObject, + aGraphicAttr)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aGraphicPrimitive); + } + } + else + { + // create graphic primitive for content + const drawinglayer::primitive2d::Primitive2DReference aGraphicPrimitive( + new drawinglayer::primitive2d::GraphicPrimitive2D( + getObjectTransform(), + aGraphicObject, + aGraphicAttr)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aGraphicPrimitive); + } + + // a standard gray outline is created for scaled content + if(bScaleContent) + { + const svtools::ColorConfig aColorConfig; + const svtools::ColorConfigValue aColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES)); + + if(aColor.bIsVisible) + { + basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon()); + const Color aVclColor(aColor.nColor); + aOutline.transform(getObjectTransform()); + const drawinglayer::primitive2d::Primitive2DReference xOutline( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aVclColor.getBColor())); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xOutline); + } + } + } + + // get graphic and check scale content state + return aRetval; + } + + SdrOleContentPrimitive2D::SdrOleContentPrimitive2D( + const SdrOle2Obj& rSdrOle2Obj, + const basegfx::B2DHomMatrix& rObjectTransform, + sal_uInt32 nGraphicVersion, + bool bHighContrast) + : BufferedDecompositionPrimitive2D(), + mpSdrOle2Obj(const_cast< SdrOle2Obj* >(&rSdrOle2Obj)), + maObjectTransform(rObjectTransform), + mnGraphicVersion(nGraphicVersion), + mbHighContrast(bHighContrast) + { + } + + bool SdrOleContentPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrOleContentPrimitive2D& rCompare = (SdrOleContentPrimitive2D&)rPrimitive; + const bool bBothNot(!mpSdrOle2Obj.is() && !rCompare.mpSdrOle2Obj.is()); + const bool bBothAndEqual(mpSdrOle2Obj.is() && rCompare.mpSdrOle2Obj.is() + && mpSdrOle2Obj.get() == rCompare.mpSdrOle2Obj.get()); + + return ((bBothNot || bBothAndEqual) + && getObjectTransform() == rCompare.getObjectTransform() + + // #i104867# to find out if the Graphic content of the + // OLE has changed, use GraphicVersion number + && getGraphicVersion() == rCompare.getGraphicVersion() + + && getHighContrast() == rCompare.getHighContrast()); + } + + return false; + } + + basegfx::B2DRange SdrOleContentPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const + { + basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0); + aRange.transform(getObjectTransform()); + + return aRange; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrOleContentPrimitive2D, PRIMITIVE2D_ID_SDROLECONTENTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx new file mode 100644 index 000000000000..2ceea2c69b7d --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrpathprimitive2d.cxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrPathPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // add fill + if(!getSdrLFSTAttribute().getFill().isDefault() + && getUnitPolyPolygon().isClosed()) + { + // #i108255# no need to use correctOrientations here; target is + // straight visualisation + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + getUnitPolyPolygon(), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + + // add line + if(getSdrLFSTAttribute().getLine().isDefault()) + { + // if initially no line is defined, create one for HitTest and BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + getUnitPolyPolygon(), + getTransform())); + } + else + { + Primitive2DSequence aTemp(getUnitPolyPolygon().count()); + + for(sal_uInt32 a(0); a < getUnitPolyPolygon().count(); a++) + { + aTemp[a] = createPolygonLinePrimitive( + getUnitPolyPolygon().getB2DPolygon(a), + getTransform(), + getSdrLFSTAttribute().getLine(), + getSdrLFSTAttribute().getLineStartEnd()); + } + + appendPrimitive2DSequenceToPrimitive2DSequence(aRetval, aTemp); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + getUnitPolyPolygon(), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrPathPrimitive2D::SdrPathPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, + const basegfx::B2DPolyPolygon& rUnitPolyPolygon) + : BufferedDecompositionPrimitive2D(), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute), + maUnitPolyPolygon(rUnitPolyPolygon) + { + } + + bool SdrPathPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrPathPrimitive2D& rCompare = (SdrPathPrimitive2D&)rPrimitive; + + return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() + && getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrPathPrimitive2D, PRIMITIVE2D_ID_SDRPATHPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrprimitivetools.cxx b/svx/source/sdr/primitive2d/sdrprimitivetools.cxx new file mode 100644 index 000000000000..8f188e9fcf6f --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrprimitivetools.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> +#include <vcl/bmpacc.hxx> +#include <osl/mutex.hxx> +#include <vcl/lazydelete.hxx> + +////////////////////////////////////////////////////////////////////////////// +// helper methods + +namespace drawinglayer +{ + namespace primitive2d + { + BitmapEx createDefaultCross_3x3(const basegfx::BColor& rBColor) + { + static vcl::DeleteOnDeinit< BitmapEx > aRetVal(0); + static basegfx::BColor aColor; + ::osl::Mutex m_mutex; + + if(!aRetVal.get() || rBColor != aColor) + { + // copy values + aColor = rBColor; + + // create bitmap + Bitmap aContent(Size(3, 3), 24); + Bitmap aMask(Size(3, 3), 1); + BitmapWriteAccess* pWContent = aContent.AcquireWriteAccess(); + BitmapWriteAccess* pWMask = aMask.AcquireWriteAccess(); + OSL_ENSURE(pWContent && pWMask, "No WriteAccess to bitmap (!)"); + const Color aVCLColor(aColor); + const BitmapColor aPixColor(aVCLColor); + const BitmapColor aMaskColor(0x01); + + // Y,X unusual order (!) + pWContent->SetPixel(0, 1, aPixColor); + pWContent->SetPixel(1, 0, aPixColor); + pWContent->SetPixel(1, 1, aPixColor); + pWContent->SetPixel(1, 2, aPixColor); + pWContent->SetPixel(2, 1, aPixColor); + + pWMask->SetPixel(0, 0, aMaskColor); + pWMask->SetPixel(0, 2, aMaskColor); + pWMask->SetPixel(2, 0, aMaskColor); + pWMask->SetPixel(2, 2, aMaskColor); + + aContent.ReleaseAccess(pWContent); + aMask.ReleaseAccess(pWMask); + + // create and exchange at aRetVal + delete aRetVal.set(new BitmapEx(aContent, aMask)); + } + + return aRetVal.get() ? *aRetVal.get() : BitmapEx(); + } + + BitmapEx createDefaultGluepoint_7x7(const basegfx::BColor& rBColorA, const basegfx::BColor& rBColorB) + { + static vcl::DeleteOnDeinit< BitmapEx > aRetVal(0); + static basegfx::BColor aColorA; + static basegfx::BColor aColorB; + ::osl::Mutex m_mutex; + + if(!aRetVal.get() || rBColorA != aColorA || rBColorB != aColorB) + { + // copy values + aColorA = rBColorA; + aColorB = rBColorB; + + // create bitmap + Bitmap aContent(Size(7, 7), 24); + Bitmap aMask(Size(7, 7), 1); + BitmapWriteAccess* pWContent = aContent.AcquireWriteAccess(); + BitmapWriteAccess* pWMask = aMask.AcquireWriteAccess(); + OSL_ENSURE(pWContent && pWMask, "No WriteAccess to bitmap (!)"); + const Color aColA(aColorA); + const Color aColB(aColorB); + const BitmapColor aPixColorA(aColA); + const BitmapColor aPixColorB(aColB); + const BitmapColor aMaskColor(0x01); + + // Y,X unusual order (!) + pWContent->SetPixel(0, 1, aPixColorA); + pWContent->SetPixel(0, 5, aPixColorA); + pWContent->SetPixel(1, 0, aPixColorA); + pWContent->SetPixel(1, 2, aPixColorA); + pWContent->SetPixel(1, 4, aPixColorA); + pWContent->SetPixel(1, 6, aPixColorA); + pWContent->SetPixel(2, 1, aPixColorA); + pWContent->SetPixel(2, 3, aPixColorA); + pWContent->SetPixel(2, 5, aPixColorA); + pWContent->SetPixel(3, 2, aPixColorA); + pWContent->SetPixel(3, 4, aPixColorA); + pWContent->SetPixel(4, 1, aPixColorA); + pWContent->SetPixel(4, 3, aPixColorA); + pWContent->SetPixel(4, 5, aPixColorA); + pWContent->SetPixel(5, 0, aPixColorA); + pWContent->SetPixel(5, 2, aPixColorA); + pWContent->SetPixel(5, 4, aPixColorA); + pWContent->SetPixel(5, 6, aPixColorA); + pWContent->SetPixel(6, 1, aPixColorA); + pWContent->SetPixel(6, 5, aPixColorA); + + pWContent->SetPixel(1, 1, aPixColorB); + pWContent->SetPixel(1, 5, aPixColorB); + pWContent->SetPixel(2, 2, aPixColorB); + pWContent->SetPixel(2, 4, aPixColorB); + pWContent->SetPixel(3, 3, aPixColorB); + pWContent->SetPixel(4, 2, aPixColorB); + pWContent->SetPixel(4, 4, aPixColorB); + pWContent->SetPixel(5, 1, aPixColorB); + pWContent->SetPixel(5, 5, aPixColorB); + + pWMask->SetPixel(0, 0, aMaskColor); + pWMask->SetPixel(0, 2, aMaskColor); + pWMask->SetPixel(0, 3, aMaskColor); + pWMask->SetPixel(0, 4, aMaskColor); + pWMask->SetPixel(0, 6, aMaskColor); + pWMask->SetPixel(1, 3, aMaskColor); + pWMask->SetPixel(2, 0, aMaskColor); + pWMask->SetPixel(2, 6, aMaskColor); + pWMask->SetPixel(3, 0, aMaskColor); + pWMask->SetPixel(3, 1, aMaskColor); + pWMask->SetPixel(3, 5, aMaskColor); + pWMask->SetPixel(3, 6, aMaskColor); + pWMask->SetPixel(4, 0, aMaskColor); + pWMask->SetPixel(4, 6, aMaskColor); + pWMask->SetPixel(5, 3, aMaskColor); + pWMask->SetPixel(6, 0, aMaskColor); + pWMask->SetPixel(6, 2, aMaskColor); + pWMask->SetPixel(6, 3, aMaskColor); + pWMask->SetPixel(6, 4, aMaskColor); + pWMask->SetPixel(6, 6, aMaskColor); + + aContent.ReleaseAccess(pWContent); + aMask.ReleaseAccess(pWMask); + + // create and exchange at aRetVal + delete aRetVal.set(new BitmapEx(aContent, aMask)); + } + + return aRetVal.get() ? *aRetVal.get() : BitmapEx(); + } + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx new file mode 100644 index 000000000000..60b8ca1c7817 --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrRectanglePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const + { + Primitive2DSequence aRetval; + + // create unit outline polygon + const basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), + getCornerRadiusX(), + getCornerRadiusY())); + + // add fill + if(!getSdrLFSTAttribute().getFill().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getFill(), + getSdrLFSTAttribute().getFillFloatTransGradient())); + } + else if(getForceFillForHitTest()) + { + // if no fill and it's a text frame, create a fill for HitTest and + // BoundRect fallback + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + true, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + + // add line + if(!getSdrLFSTAttribute().getLine().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createPolygonLinePrimitive( + aUnitOutline, + getTransform(), + getSdrLFSTAttribute().getLine(), + attribute::SdrLineStartEndAttribute())); + } + else if(!getForceFillForHitTest()) + { + // if initially no line is defined and it's not a text frame, create + // a line for HitTest and BoundRect + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createHiddenGeometryPrimitives2D( + false, + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform())); + } + + // add text + if(!getSdrLFSTAttribute().getText().isDefault()) + { + appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, + createTextPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + getTransform(), + getSdrLFSTAttribute().getText(), + getSdrLFSTAttribute().getLine(), + false, + false, + false)); + } + + // add shadow + if(!getSdrLFSTAttribute().getShadow().isDefault()) + { + aRetval = createEmbeddedShadowPrimitive( + aRetval, + getSdrLFSTAttribute().getShadow()); + } + + return aRetval; + } + + SdrRectanglePrimitive2D::SdrRectanglePrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const attribute::SdrLineFillShadowTextAttribute& rSdrLFSTAttribute, + double fCornerRadiusX, + double fCornerRadiusY, + bool bForceFillForHitTest) + : BufferedDecompositionPrimitive2D(), + maTransform(rTransform), + maSdrLFSTAttribute(rSdrLFSTAttribute), + mfCornerRadiusX(fCornerRadiusX), + mfCornerRadiusY(fCornerRadiusY), + mbForceFillForHitTest(bForceFillForHitTest) + { + } + + bool SdrRectanglePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrRectanglePrimitive2D& rCompare = (SdrRectanglePrimitive2D&)rPrimitive; + + return (getCornerRadiusX() == rCompare.getCornerRadiusX() + && getCornerRadiusY() == rCompare.getCornerRadiusY() + && getTransform() == rCompare.getTransform() + && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute() + && getForceFillForHitTest() == rCompare.getForceFillForHitTest()); + } + + return false; + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrRectanglePrimitive2D, PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx new file mode 100644 index 000000000000..089f75aa8ade --- /dev/null +++ b/svx/source/sdr/primitive2d/sdrtextprimitive2d.cxx @@ -0,0 +1,497 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "precompiled_svx.hxx" +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <svx/svdotext.hxx> +#include <basegfx/color/bcolor.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/editobj.hxx> +#include <editeng/flditem.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <unoapi.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdoutl.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + sal_Int16 getPageNumber(const uno::Reference< drawing::XDrawPage >& rxDrawPage) + { + sal_Int16 nRetval(0); + uno::Reference< beans::XPropertySet > xSet(rxDrawPage, uno::UNO_QUERY); + + if (xSet.is()) + { + try + { + const uno::Any aNumber(xSet->getPropertyValue(::rtl::OUString::createFromAscii("Number"))); + aNumber >>= nRetval; + } + catch(const uno::Exception&) + { + OSL_ASSERT(false); + } + } + + return nRetval; + } + + sal_Int16 getPageCount(const uno::Reference< drawing::XDrawPage >& rxDrawPage) + { + sal_Int16 nRetval(0); + SdrPage* pPage = GetSdrPageFromXDrawPage(rxDrawPage); + + if(pPage && pPage->GetModel()) + { + if( (pPage->GetPageNum() == 0) && !pPage->IsMasterPage() ) + { + // handout page! + return pPage->GetModel()->getHandoutPageCount(); + } + else + { + const sal_uInt16 nPageCount(pPage->GetModel()->GetPageCount()); + nRetval = ((sal_Int16)nPageCount - 1) / 2; + } + } + + return nRetval; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + // support for XTEXT_PAINTSHAPE_BEGIN/XTEXT_PAINTSHAPE_END Metafile comments + // for slideshow. This uses TextHierarchyBlockPrimitive2D to mark a text block. + // ATM there is only one text block per SdrObject, this may get more in the future + Primitive2DSequence SdrTextPrimitive2D::encapsulateWithTextHierarchyBlockPrimitive2D(const Primitive2DSequence& rCandidate) const + { + Primitive2DReference xReference(new TextHierarchyBlockPrimitive2D(rCandidate)); + Primitive2DSequence xRetval(&xReference, 1); + + return xRetval; + } + + SdrTextPrimitive2D::SdrTextPrimitive2D( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject) + : BufferedDecompositionPrimitive2D(), + mrSdrText(const_cast< SdrText* >(pSdrText)), + maOutlinerParaObject(rOutlinerParaObject), + mxLastVisualizingPage(), + mnLastPageNumber(0), + mnLastPageCount(0), + maLastTextBackgroundColor(), + mbContainsPageField(false), + mbContainsPageCountField(false), + mbContainsOtherFields(false) + { + const EditTextObject& rETO = maOutlinerParaObject.GetTextObject(); + + mbContainsPageField = rETO.HasField(SvxPageField::StaticType()); + mbContainsPageCountField = rETO.HasField(SvxPagesField::StaticType()); + mbContainsOtherFields = rETO.HasField(SvxHeaderField::StaticType()) + || rETO.HasField(SvxFooterField::StaticType()) + || rETO.HasField(SvxDateTimeField::StaticType()) + || rETO.HasField(SvxAuthorField::StaticType()); + } + + bool SdrTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) + { + const SdrTextPrimitive2D& rCompare = (SdrTextPrimitive2D&)rPrimitive; + + return ( + + // compare OPO and content, but not WrongList + getOutlinerParaObject() == rCompare.getOutlinerParaObject() + + // also compare WrongList (not-persistent data, but visualized) + && getOutlinerParaObject().isWrongListEqual(rCompare.getOutlinerParaObject())); + } + + return false; + } + + Primitive2DSequence SdrTextPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const + { + uno::Reference< drawing::XDrawPage > xCurrentlyVisualizingPage; + bool bCurrentlyVisualizingPageIsSet(false); + Color aNewTextBackgroundColor; + bool bNewTextBackgroundColorIsSet(false); + sal_Int16 nCurrentlyValidPageNumber(0); + sal_Int16 nCurrentlyValidPageCount(0); + + if(getBuffered2DDecomposition().hasElements()) + { + bool bDoDelete(false); + + // check visualized page + if(mbContainsPageField || mbContainsPageCountField || mbContainsOtherFields) + { + // get visualized page and remember + xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); + bCurrentlyVisualizingPageIsSet = true; + + if(xCurrentlyVisualizingPage != mxLastVisualizingPage) + { + bDoDelete = true; + } + + // #i98870# check visualized PageNumber + if(!bDoDelete && mbContainsPageField) + { + nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); + + if(nCurrentlyValidPageNumber != mnLastPageNumber) + { + bDoDelete = true; + } + } + + // #i98870# check visualized PageCount, too + if(!bDoDelete && mbContainsPageCountField) + { + nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); + + if(nCurrentlyValidPageCount != mnLastPageCount) + { + bDoDelete = true; + } + } + } + + // #i101443# check change of TextBackgroundolor + if(!bDoDelete && getSdrText() && getSdrText()->GetModel()) + { + SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); + aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); + bNewTextBackgroundColorIsSet = true; + + if(aNewTextBackgroundColor != maLastTextBackgroundColor) + { + bDoDelete = true; + } + } + + if(bDoDelete) + { + const_cast< SdrTextPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); + } + } + + if(!getBuffered2DDecomposition().hasElements()) + { + if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField) + { + xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); + } + + if(!nCurrentlyValidPageNumber && mbContainsPageField) + { + nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); + } + + if(!nCurrentlyValidPageCount && mbContainsPageCountField) + { + nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); + } + + if(!bNewTextBackgroundColorIsSet && getSdrText() && getSdrText()->GetModel()) + { + SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); + aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); + } + + const_cast< SdrTextPrimitive2D* >(this)->mxLastVisualizingPage = xCurrentlyVisualizingPage; + const_cast< SdrTextPrimitive2D* >(this)->mnLastPageNumber = nCurrentlyValidPageNumber; + const_cast< SdrTextPrimitive2D* >(this)->mnLastPageCount = nCurrentlyValidPageCount; + const_cast< SdrTextPrimitive2D* >(this)->maLastTextBackgroundColor = aNewTextBackgroundColor; + } + + // call parent + return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); + } + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrContourTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const + { + Primitive2DSequence aRetval; + getSdrText()->GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation); + + return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); + } + + SdrContourTextPrimitive2D::SdrContourTextPrimitive2D( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject, + const basegfx::B2DPolyPolygon& rUnitPolyPolygon, + const basegfx::B2DHomMatrix& rObjectTransform) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), + maUnitPolyPolygon(rUnitPolyPolygon), + maObjectTransform(rObjectTransform) + { + } + + bool SdrContourTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(SdrTextPrimitive2D::operator==(rPrimitive)) + { + const SdrContourTextPrimitive2D& rCompare = (SdrContourTextPrimitive2D&)rPrimitive; + + return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() + && getObjectTransform() == rCompare.getObjectTransform()); + } + + return false; + } + + SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const + { + return new SdrContourTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + getUnitPolyPolygon(), + rTransform * getObjectTransform()); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrContourTextPrimitive2D, PRIMITIVE2D_ID_SDRCONTOURTEXTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrPathTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const + { + Primitive2DSequence aRetval; + getSdrText()->GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation); + + return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); + } + + SdrPathTextPrimitive2D::SdrPathTextPrimitive2D( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject, + const basegfx::B2DPolyPolygon& rPathPolyPolygon, + const attribute::SdrFormTextAttribute& rSdrFormTextAttribute) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), + maPathPolyPolygon(rPathPolyPolygon), + maSdrFormTextAttribute(rSdrFormTextAttribute) + { + } + + bool SdrPathTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(SdrTextPrimitive2D::operator==(rPrimitive)) + { + const SdrPathTextPrimitive2D& rCompare = (SdrPathTextPrimitive2D&)rPrimitive; + + return (getPathPolyPolygon() == rCompare.getPathPolyPolygon() + && getSdrFormTextAttribute() == rCompare.getSdrFormTextAttribute()); + } + + return false; + } + + SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const + { + basegfx::B2DPolyPolygon aNewPolyPolygon(getPathPolyPolygon()); + aNewPolyPolygon.transform(rTransform); + + return new SdrPathTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + aNewPolyPolygon, + getSdrFormTextAttribute()); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrPathTextPrimitive2D, PRIMITIVE2D_ID_SDRPATHTEXTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrBlockTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const + { + Primitive2DSequence aRetval; + getSdrText()->GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation); + + return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); + } + + SdrBlockTextPrimitive2D::SdrBlockTextPrimitive2D( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject, + const basegfx::B2DHomMatrix& rTextRangeTransform, + SdrTextHorzAdjust aSdrTextHorzAdjust, + SdrTextVertAdjust aSdrTextVertAdjust, + bool bFixedCellHeight, + bool bUnlimitedPage, + bool bCellText, + bool bWordWrap, + bool bClipOnBounds) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), + maTextRangeTransform(rTextRangeTransform), + maSdrTextHorzAdjust(aSdrTextHorzAdjust), + maSdrTextVertAdjust(aSdrTextVertAdjust), + mbFixedCellHeight(bFixedCellHeight), + mbUnlimitedPage(bUnlimitedPage), + mbCellText(bCellText), + mbWordWrap(bWordWrap), + mbClipOnBounds(bClipOnBounds) + { + } + + bool SdrBlockTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(SdrTextPrimitive2D::operator==(rPrimitive)) + { + const SdrBlockTextPrimitive2D& rCompare = (SdrBlockTextPrimitive2D&)rPrimitive; + + return (getTextRangeTransform() == rCompare.getTextRangeTransform() + && getSdrTextHorzAdjust() == rCompare.getSdrTextHorzAdjust() + && getSdrTextVertAdjust() == rCompare.getSdrTextVertAdjust() + && isFixedCellHeight() == rCompare.isFixedCellHeight() + && getUnlimitedPage() == rCompare.getUnlimitedPage() + && getCellText() == rCompare.getCellText() + && getWordWrap() == rCompare.getWordWrap() + && getClipOnBounds() == rCompare.getClipOnBounds()); + } + + return false; + } + + SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const + { + return new SdrBlockTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + rTransform * getTextRangeTransform(), + getSdrTextHorzAdjust(), + getSdrTextVertAdjust(), + isFixedCellHeight(), + getUnlimitedPage(), + getCellText(), + getWordWrap(), + getClipOnBounds()); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrBlockTextPrimitive2D, PRIMITIVE2D_ID_SDRBLOCKTEXTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + Primitive2DSequence SdrStretchTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const + { + Primitive2DSequence aRetval; + getSdrText()->GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation); + + return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); + } + + SdrStretchTextPrimitive2D::SdrStretchTextPrimitive2D( + const SdrText* pSdrText, + const OutlinerParaObject& rOutlinerParaObject, + const basegfx::B2DHomMatrix& rTextRangeTransform, + bool bFixedCellHeight) + : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), + maTextRangeTransform(rTextRangeTransform), + mbFixedCellHeight(bFixedCellHeight) + { + } + + bool SdrStretchTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if(SdrTextPrimitive2D::operator==(rPrimitive)) + { + const SdrStretchTextPrimitive2D& rCompare = (SdrStretchTextPrimitive2D&)rPrimitive; + + return (getTextRangeTransform() == rCompare.getTextRangeTransform() + && isFixedCellHeight() == rCompare.isFixedCellHeight()); + } + + return false; + } + + SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const + { + return new SdrStretchTextPrimitive2D( + getSdrText(), + getOutlinerParaObject(), + rTransform * getTextRangeTransform(), + isFixedCellHeight()); + } + + // provide unique ID + ImplPrimitrive2DIDBlock(SdrStretchTextPrimitive2D, PRIMITIVE2D_ID_SDRSTRETCHTEXTPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/primitive3d/makefile.mk b/svx/source/sdr/primitive3d/makefile.mk new file mode 100644 index 000000000000..c845cadc90a4 --- /dev/null +++ b/svx/source/sdr/primitive3d/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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=primitive3d +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/sdrattributecreator3d.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/primitive3d/sdrattributecreator3d.cxx b/svx/source/sdr/primitive3d/sdrattributecreator3d.cxx new file mode 100644 index 000000000000..3a15c3a392d9 --- /dev/null +++ b/svx/source/sdr/primitive3d/sdrattributecreator3d.cxx @@ -0,0 +1,158 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <svx/svx3ditems.hxx> +#include <svl/itemset.hxx> +#include <com/sun/star/drawing/NormalsKind.hpp> +#include <com/sun/star/drawing/TextureProjectionMode.hpp> +#include <com/sun/star/drawing/TextureKind2.hpp> +#include <com/sun/star/drawing/TextureMode.hpp> +#include <svx/xflclit.hxx> +#include <drawinglayer/attribute/materialattribute3d.hxx> +#include <drawinglayer/attribute/sdrobjectattribute3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + attribute::Sdr3DObjectAttribute* createNewSdr3DObjectAttribute(const SfxItemSet& rSet) + { + // get NormalsKind + ::com::sun::star::drawing::NormalsKind aNormalsKind(::com::sun::star::drawing::NormalsKind_SPECIFIC); + const sal_uInt16 nNormalsValue(((const Svx3DNormalsKindItem&)rSet.Get(SDRATTR_3DOBJ_NORMALS_KIND)).GetValue()); + + if(1L == nNormalsValue) + { + aNormalsKind = ::com::sun::star::drawing::NormalsKind_FLAT; + } + else if(2L == nNormalsValue) + { + aNormalsKind = ::com::sun::star::drawing::NormalsKind_SPHERE; + } + + // get NoermalsInvert flag + const bool bInvertNormals(((const Svx3DNormalsInvertItem&)rSet.Get(SDRATTR_3DOBJ_NORMALS_INVERT)).GetValue()); + + // get TextureProjectionX + ::com::sun::star::drawing::TextureProjectionMode aTextureProjectionX(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC); + const sal_uInt16 nTextureValueX(((const Svx3DTextureProjectionXItem&)rSet.Get(SDRATTR_3DOBJ_TEXTURE_PROJ_X)).GetValue()); + + if(1L == nTextureValueX) + { + aTextureProjectionX = ::com::sun::star::drawing::TextureProjectionMode_PARALLEL; + } + else if(2L == nTextureValueX) + { + aTextureProjectionX = ::com::sun::star::drawing::TextureProjectionMode_SPHERE; + } + + // get TextureProjectionY + ::com::sun::star::drawing::TextureProjectionMode aTextureProjectionY(::com::sun::star::drawing::TextureProjectionMode_OBJECTSPECIFIC); + const sal_uInt16 nTextureValueY(((const Svx3DTextureProjectionYItem&)rSet.Get(SDRATTR_3DOBJ_TEXTURE_PROJ_Y)).GetValue()); + + if(1L == nTextureValueY) + { + aTextureProjectionY = ::com::sun::star::drawing::TextureProjectionMode_PARALLEL; + } + else if(2L == nTextureValueY) + { + aTextureProjectionY = ::com::sun::star::drawing::TextureProjectionMode_SPHERE; + } + + // get DoubleSided flag + const bool bDoubleSided(((const Svx3DDoubleSidedItem&)rSet.Get(SDRATTR_3DOBJ_DOUBLE_SIDED)).GetValue()); + + // get Shadow3D flag + const bool bShadow3D(((const Svx3DShadow3DItem&)rSet.Get(SDRATTR_3DOBJ_SHADOW_3D)).GetValue()); + + // get TextureFilter flag + const bool bTextureFilter(((const Svx3DTextureFilterItem&)rSet.Get(SDRATTR_3DOBJ_TEXTURE_FILTER)).GetValue()); + + // get texture kind + // TextureKind: 1 == Base3DTextureLuminance, 2 == Base3DTextureIntensity, 3 == Base3DTextureColor + ::com::sun::star::drawing::TextureKind2 aTextureKind(::com::sun::star::drawing::TextureKind2_LUMINANCE); + const sal_uInt16 nTextureKind(((const Svx3DTextureKindItem&)rSet.Get(SDRATTR_3DOBJ_TEXTURE_KIND)).GetValue()); + + if(2 == nTextureKind) + { + aTextureKind = ::com::sun::star::drawing::TextureKind2_INTENSITY; + } + else if(3 == nTextureKind) + { + aTextureKind = ::com::sun::star::drawing::TextureKind2_COLOR; + } + + // get texture mode + // TextureMode: 1 == Base3DTextureReplace, 2 == Base3DTextureModulate, 3 == Base3DTextureBlend + ::com::sun::star::drawing::TextureMode aTextureMode(::com::sun::star::drawing::TextureMode_REPLACE); + const sal_uInt16 nTextureMode(((const Svx3DTextureModeItem&)rSet.Get(SDRATTR_3DOBJ_TEXTURE_MODE)).GetValue()); + + if(2 == nTextureMode) + { + aTextureMode = ::com::sun::star::drawing::TextureMode_MODULATE; + } + else if(3 == nTextureMode) + { + aTextureMode = ::com::sun::star::drawing::TextureMode_BLEND; + } + + // get object color + const ::basegfx::BColor aObjectColor(((const XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue().getBColor()); + + // get specular color + const ::basegfx::BColor aSpecular(((const Svx3DMaterialSpecularItem&)rSet.Get(SDRATTR_3DOBJ_MAT_SPECULAR)).GetValue().getBColor()); + + // get emissive color + const ::basegfx::BColor aEmission(((const Svx3DMaterialEmissionItem&)rSet.Get(SDRATTR_3DOBJ_MAT_EMISSION)).GetValue().getBColor()); + + // get specular intensity + sal_uInt16 nSpecularIntensity(((const Svx3DMaterialSpecularIntensityItem&)rSet.Get(SDRATTR_3DOBJ_MAT_SPECULAR_INTENSITY)).GetValue()); + + if(nSpecularIntensity > 128) + { + nSpecularIntensity = 128; + } + + // get reduced line geometry + const bool bReducedLineGeometry(((const Svx3DReducedLineGeometryItem&)rSet.Get(SDRATTR_3DOBJ_REDUCED_LINE_GEOMETRY)).GetValue()); + + // prepare material + attribute::MaterialAttribute3D aMaterial(aObjectColor, aSpecular, aEmission, nSpecularIntensity); + + return new attribute::Sdr3DObjectAttribute( + aNormalsKind, aTextureProjectionX, aTextureProjectionY, + aTextureKind, aTextureMode, aMaterial, + bInvertNormals, bDoubleSided, bShadow3D, bTextureFilter, bReducedLineGeometry); + } + } // end of namespace primitive2d +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/attributeproperties.cxx b/svx/source/sdr/properties/attributeproperties.cxx new file mode 100644 index 000000000000..0f3325a0027e --- /dev/null +++ b/svx/source/sdr/properties/attributeproperties.cxx @@ -0,0 +1,628 @@ +/************************************************************************* + * + * 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/properties/attributeproperties.hxx> +#include <svx/sdr/properties/itemsettools.hxx> +#include <tools/debug.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svl/whiter.hxx> +#include <svl/poolitem.hxx> +#include <svx/svdobj.hxx> +#include <svx/svddef.hxx> +#include <svx/xit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xlnasit.hxx> +#include <svx/xflasit.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdtrans.hxx> +#include <svx/svdpage.hxx> + +// #114265# +#include <svl/smplhint.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + void AttributeProperties::ImpAddStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + // test if old StyleSheet is cleared, else it would be lost + // after this method -> memory leak (!) + DBG_ASSERT(!mpStyleSheet, "Old style sheet not deleted before setting new one (!)"); + + if(pNewStyleSheet) + { + mpStyleSheet = pNewStyleSheet; + + // local ItemSet is needed here, force it + GetObjectItemSet(); + + // register as listener + StartListening(pNewStyleSheet->GetPool()); + StartListening(*pNewStyleSheet); + + // Delete hard attributes where items are set in the style sheet + if(!bDontRemoveHardAttr) + { + const SfxItemSet& rStyle = pNewStyleSheet->GetItemSet(); + SfxWhichIter aIter(rStyle); + sal_uInt16 nWhich = aIter.FirstWhich(); + + while(nWhich) + { + if(SFX_ITEM_SET == rStyle.GetItemState(nWhich)) + { + mpItemSet->ClearItem(nWhich); + } + + nWhich = aIter.NextWhich(); + } + } + + // set new stylesheet as parent + mpItemSet->SetParent(&pNewStyleSheet->GetItemSet()); + } + } + + void AttributeProperties::ImpRemoveStyleSheet() + { + // Check type since it is destroyed when the type is deleted + if(GetStyleSheet() && HAS_BASE(SfxStyleSheet, mpStyleSheet)) + { + EndListening(*mpStyleSheet); + EndListening(mpStyleSheet->GetPool()); + + // reset parent of ItemSet + if(mpItemSet) + { + mpItemSet->SetParent(0L); + } + + SdrObject& rObj = GetSdrObject(); + rObj.SetBoundRectDirty(); + rObj.SetRectsDirty(sal_True); + } + + mpStyleSheet = 0L; + } + + // create a new itemset + SfxItemSet& AttributeProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // ranges from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // end + 0, 0)); + } + + AttributeProperties::AttributeProperties(SdrObject& rObj) + : DefaultProperties(rObj), + mpStyleSheet(0L) + { + } + + AttributeProperties::AttributeProperties(const AttributeProperties& rProps, SdrObject& rObj) + : DefaultProperties(rProps, rObj), + mpStyleSheet(0L) + { + if(rProps.GetStyleSheet()) + { + ImpAddStyleSheet(rProps.GetStyleSheet(), sal_True); + } + } + + AttributeProperties::~AttributeProperties() + { + ImpRemoveStyleSheet(); + } + + BaseProperties& AttributeProperties::Clone(SdrObject& rObj) const + { + return *(new AttributeProperties(*this, rObj)); + } + + void AttributeProperties::ItemSetChanged(const SfxItemSet& /*rSet*/) + { + // own modifications + SdrObject& rObj = GetSdrObject(); + + rObj.SetBoundRectDirty(); + rObj.SetRectsDirty(sal_True); + rObj.SetChanged(); + } + + void AttributeProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) + { + if(pNewItem) + { + const SfxPoolItem* pItem = pNewItem; + SdrModel* pModel = GetSdrObject().GetModel(); + + switch( nWhich ) + { + case XATTR_FILLBITMAP: + { + pItem = ((XFillBitmapItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_LINEDASH: + { + pItem = ((XLineDashItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_LINESTART: + { + pItem = ((XLineStartItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_LINEEND: + { + pItem = ((XLineEndItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_FILLGRADIENT: + { + pItem = ((XFillGradientItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_FILLFLOATTRANSPARENCE: + { + // #85953# allow all kinds of XFillFloatTransparenceItem to be set + pItem = ((XFillFloatTransparenceItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + case XATTR_FILLHATCH: + { + pItem = ((XFillHatchItem*)pItem)->checkForUniqueItem( pModel ); + break; + } + } + + // set item + if(pItem) + { + // force ItemSet + GetObjectItemSet(); + mpItemSet->Put(*pItem); + + // delete item if it was a generated one + if(pItem != pNewItem) + { + delete (SfxPoolItem*)pItem; + } + } + } + else + { + // clear item if ItemSet exists + if(mpItemSet) + { + mpItemSet->ClearItem(nWhich); + } + } + } + + void AttributeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + ImpRemoveStyleSheet(); + ImpAddStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + SdrObject& rObj = GetSdrObject(); + rObj.SetBoundRectDirty(); + rObj.SetRectsDirty(sal_True); + } + + SfxStyleSheet* AttributeProperties::GetStyleSheet() const + { + return mpStyleSheet; + } + + void AttributeProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel) + { + OSL_ASSERT(pNewModel!=NULL); + + if(pSrcPool && pDestPool && (pSrcPool != pDestPool)) + { + if(mpItemSet) + { + // migrate ItemSet to new pool. Scaling is NOT necessary + // because this functionality is used by UNDO only. Thus + // objects and ItemSets would be moved back to their original + // pool before usage. + SfxItemSet* pOldSet = mpItemSet; + SfxStyleSheet* pStySheet = GetStyleSheet(); + + if(pStySheet) + { + ImpRemoveStyleSheet(); + } + + mpItemSet = mpItemSet->Clone(FALSE, pDestPool); + GetSdrObject().GetModel()->MigrateItemSet(pOldSet, mpItemSet, pNewModel); + + // set stylesheet (if used) + if(pStySheet) + { + // #i109515# + SfxItemPool* pStyleSheetPool = &pStySheet->GetPool().GetPool(); + + if(pStyleSheetPool == pDestPool) + { + // just re-set stylesheet + ImpAddStyleSheet(pStySheet, sal_True); + } + else + { + // StyleSheet is NOT from the correct pool. + // Look one up in the right pool with the same + // name or use the default. + + // Look up the style in the new document. + OSL_ASSERT(pNewModel->GetStyleSheetPool() != NULL); + SfxStyleSheet* pNewStyleSheet = dynamic_cast<SfxStyleSheet*>( + pNewModel->GetStyleSheetPool()->Find( + pStySheet->GetName(), + SFX_STYLE_FAMILY_ALL)); + if (pNewStyleSheet == NULL + || &pNewStyleSheet->GetPool().GetPool() != pDestPool) + { + // There is no copy of the style in the new + // document. Use the default as a fallback. + pNewStyleSheet = pNewModel->GetDefaultStyleSheet(); + } + ImpAddStyleSheet(pNewStyleSheet, sal_True); + } + } + + delete pOldSet; + } + } + } + + void AttributeProperties::SetModel(SdrModel* pOldModel, SdrModel* pNewModel) + { + if(pOldModel != pNewModel && pNewModel && !pNewModel->IsLoading()) + { + // For a living model move the items from one pool to the other + if(pOldModel) + { + // If metric has changed, scale items. + MapUnit aOldUnit(pOldModel->GetScaleUnit()); + MapUnit aNewUnit(pNewModel->GetScaleUnit()); + sal_Bool bScaleUnitChanged(aNewUnit != aOldUnit); + Fraction aMetricFactor; + + if(bScaleUnitChanged) + { + aMetricFactor = GetMapFactor(aOldUnit, aNewUnit).X(); + Scale(aMetricFactor); + } + + // Move all styles which are used by the object to the new + // StyleSheet pool + SfxStyleSheet* pOldStyleSheet = GetStyleSheet(); + + if(pOldStyleSheet) + { + SfxStyleSheetBase* pSheet = pOldStyleSheet; + SfxStyleSheetBasePool* pOldPool = pOldModel->GetStyleSheetPool(); + SfxStyleSheetBasePool* pNewPool = pNewModel->GetStyleSheetPool(); + DBG_ASSERT(pOldPool, "Properties::SetModel(): Object has StyleSheet but no StyleSheetPool (!)"); + + if(pOldPool && pNewPool) + { + // build a list of to-be-copied Styles + List aList; + SfxStyleSheetBase* pAnchor = 0L; + + while(pSheet) + { + pAnchor = pNewPool->Find(pSheet->GetName(), pSheet->GetFamily()); + + if(!pAnchor) + { + aList.Insert(pSheet, LIST_APPEND); + pSheet = pOldPool->Find(pSheet->GetParent(), pSheet->GetFamily()); + } + else + { + // the style does exist + pSheet = 0L; + } + } + + // copy and set the parents + pSheet = (SfxStyleSheetBase*)aList.First(); + SfxStyleSheetBase* pNewSheet = 0L; + SfxStyleSheetBase* pLastSheet = 0L; + SfxStyleSheetBase* pForThisObject = 0L; + + while(pSheet) + { + pNewSheet = &pNewPool->Make(pSheet->GetName(), pSheet->GetFamily(), pSheet->GetMask()); + pNewSheet->GetItemSet().Put(pSheet->GetItemSet(), FALSE); + + if(bScaleUnitChanged) + { + sdr::properties::ScaleItemSet(pNewSheet->GetItemSet(), aMetricFactor); + } + + if(pLastSheet) + { + pLastSheet->SetParent(pNewSheet->GetName()); + } + + if(!pForThisObject) + { + pForThisObject = pNewSheet; + } + + pLastSheet = pNewSheet; + pSheet = (SfxStyleSheetBase*)aList.Next(); + } + + // Set link to the Style found in the Pool + if(pAnchor && pLastSheet) + { + pLastSheet->SetParent(pAnchor->GetName()); + } + + // if list was empty (all Styles exist in destination pool) + // pForThisObject is not yet set + if(!pForThisObject && pAnchor) + { + pForThisObject = pAnchor; + } + + // De-register at old and register at new Style + if(GetStyleSheet() != pForThisObject) + { + ImpRemoveStyleSheet(); + ImpAddStyleSheet((SfxStyleSheet*)pForThisObject, sal_True); + } + } + else + { + // there is no StyleSheetPool in the new model, thus set + // all items as hard items in the object + List aList; + const SfxItemSet* pItemSet = &pOldStyleSheet->GetItemSet(); + + while(pItemSet) + { + aList.Insert((void*)pItemSet, CONTAINER_APPEND); + pItemSet = pItemSet->GetParent(); + } + + SfxItemSet* pNewSet = &CreateObjectSpecificItemSet(pNewModel->GetItemPool()); + pItemSet = (SfxItemSet*)aList.Last(); + + while(pItemSet) + { + pNewSet->Put(*pItemSet); + pItemSet = (SfxItemSet*)aList.Prev(); + } + + // Items which were hard attributes before need to stay + if(mpItemSet) + { + SfxWhichIter aIter(*mpItemSet); + sal_uInt16 nWhich = aIter.FirstWhich(); + + while(nWhich) + { + if(mpItemSet->GetItemState(nWhich, FALSE) == SFX_ITEM_SET) + { + pNewSet->Put(mpItemSet->Get(nWhich)); + } + + nWhich = aIter.NextWhich(); + } + } + + if(bScaleUnitChanged) + { + ScaleItemSet(*pNewSet, aMetricFactor); + } + + if(mpItemSet) + { + if(GetStyleSheet()) + { + ImpRemoveStyleSheet(); + } + + delete mpItemSet; + mpItemSet = 0L; + } + + mpItemSet = pNewSet; + } + } + } + + // each object gets the default Style if there is none set yet. + if(mpItemSet && !GetStyleSheet() && pNewModel && !pNewModel->IsLoading()) + { + SetStyleSheet(pNewModel->GetDefaultStyleSheet(), sal_True); + } + } + } + + void AttributeProperties::ForceStyleToHardAttributes() + { + if(GetStyleSheet() && HAS_BASE(SfxStyleSheet, mpStyleSheet)) + { + // prepare copied, new itemset, but WITHOUT parent + GetObjectItemSet(); + SfxItemSet* pDestItemSet = new SfxItemSet(*mpItemSet); + pDestItemSet->SetParent(0L); + + // pepare forgetting the current stylesheet like in RemoveStyleSheet() + EndListening(*mpStyleSheet); + EndListening(mpStyleSheet->GetPool()); + + // prepare the iter; use the mpObjectItemSet which may have less + // WhichIDs than the style. + SfxWhichIter aIter(*pDestItemSet); + sal_uInt16 nWhich(aIter.FirstWhich()); + const SfxPoolItem *pItem = NULL; + + // now set all hard attributes of the current at the new itemset + while(nWhich) + { + // #i61284# use mpItemSet with parents, makes things easier and reduces to + // one loop + if(SFX_ITEM_SET == mpItemSet->GetItemState(nWhich, true, &pItem)) + { + pDestItemSet->Put(*pItem); + } + + nWhich = aIter.NextWhich(); + } + + // replace itemsets + delete mpItemSet; + mpItemSet = pDestItemSet; + + // set necessary changes like in RemoveStyleSheet() + GetSdrObject().SetBoundRectDirty(); + GetSdrObject().SetRectsDirty(sal_True); + + mpStyleSheet = NULL; + } + } + + void AttributeProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) + { + sal_Bool bHintUsed(sal_False); + + SfxStyleSheetHint *pStyleHint = PTR_CAST(SfxStyleSheetHint, &rHint); + + if(pStyleHint && pStyleHint->GetStyleSheet() == GetStyleSheet()) + { + SdrObject& rObj = GetSdrObject(); + //SdrPage* pPage = rObj.GetPage(); + + switch(pStyleHint->GetHint()) + { + case SFX_STYLESHEET_CREATED : + { + // cannot happen, nothing to do + break; + } + case SFX_STYLESHEET_MODIFIED : + case SFX_STYLESHEET_CHANGED : + { + // notify change + break; + } + case SFX_STYLESHEET_ERASED : + case SFX_STYLESHEET_INDESTRUCTION : + { + // Style needs to be exchanged + SfxStyleSheet* pNewStSh = 0L; + SdrModel* pModel = rObj.GetModel(); + + // #111111# + // Do nothing if object is in destruction, else a StyleSheet may be found from + // a StyleSheetPool which is just being deleted itself. and thus it would be fatal + // to register as listener to that new StyleSheet. + if(pModel && !rObj.IsInDestruction()) + { + if(HAS_BASE(SfxStyleSheet, GetStyleSheet())) + { + pNewStSh = (SfxStyleSheet*)pModel->GetStyleSheetPool()->Find( + GetStyleSheet()->GetParent(), GetStyleSheet()->GetFamily()); + } + + if(!pNewStSh) + { + pNewStSh = pModel->GetDefaultStyleSheet(); + } + } + + // remove used style, it's erased or in destruction + ImpRemoveStyleSheet(); + + if(pNewStSh) + { + ImpAddStyleSheet(pNewStSh, sal_True); + } + + break; + } + } + + // Get old BoundRect. Do this after the style change is handled + // in the ItemSet parts because GetBoundRect() may calculate a new + Rectangle aBoundRect = rObj.GetLastBoundRect(); + + rObj.SetRectsDirty(sal_True); + + // tell the object about the change + rObj.SetChanged(); + rObj.BroadcastObjectChange(); + + //if(pPage && pPage->IsInserted()) + //{ + // rObj.BroadcastObjectChange(); + //} + + rObj.SendUserCall(SDRUSERCALL_CHGATTR, aBoundRect); + + bHintUsed = sal_True; + } + + if(!bHintUsed) + { + // forward to SdrObject ATM. Not sure if this will be necessary + // in the future. + GetSdrObject().Notify(rBC, rHint); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/captionproperties.cxx b/svx/source/sdr/properties/captionproperties.cxx new file mode 100644 index 000000000000..e08bf5516f03 --- /dev/null +++ b/svx/source/sdr/properties/captionproperties.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * 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/properties/captionproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdocapt.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& CaptionProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrCaptionObj + SDRATTR_CAPTION_FIRST, SDRATTR_CAPTION_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + CaptionProperties::CaptionProperties(SdrObject& rObj) + : RectangleProperties(rObj) + { + } + + CaptionProperties::CaptionProperties(const CaptionProperties& rProps, SdrObject& rObj) + : RectangleProperties(rProps, rObj) + { + } + + CaptionProperties::~CaptionProperties() + { + } + + BaseProperties& CaptionProperties::Clone(SdrObject& rObj) const + { + return *(new CaptionProperties(*this, rObj)); + } + + void CaptionProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrCaptionObj& rObj = (SdrCaptionObj&)GetSdrObject(); + + // local changes + rObj.ImpRecalcTail(); + + // call parent + RectangleProperties::ItemSetChanged(rSet); + } + + void CaptionProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrCaptionObj& rObj = (SdrCaptionObj&)GetSdrObject(); + + // call parent + RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // local changes + rObj.ImpRecalcTail(); + } + + void CaptionProperties::ForceDefaultAttributes() + { + // call parent + RectangleProperties::ForceDefaultAttributes(); + + // force ItemSet + GetObjectItemSet(); + + // this was set by TextProperties::ForceDefaultAttributes(), + // retet to default + mpItemSet->ClearItem(XATTR_LINESTYLE); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/circleproperties.cxx b/svx/source/sdr/properties/circleproperties.cxx new file mode 100644 index 000000000000..9dc37cb6b760 --- /dev/null +++ b/svx/source/sdr/properties/circleproperties.cxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * 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/properties/circleproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdocirc.hxx> +#include <svx/sxcikitm.hxx> +#include <svx/sxciaitm.hxx> +#include <svx/sxciaitm.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& CircleProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrCircObj + SDRATTR_CIRC_FIRST, SDRATTR_CIRC_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + CircleProperties::CircleProperties(SdrObject& rObj) + : RectangleProperties(rObj) + { + } + + CircleProperties::CircleProperties(const CircleProperties& rProps, SdrObject& rObj) + : RectangleProperties(rProps, rObj) + { + } + + CircleProperties::~CircleProperties() + { + } + + BaseProperties& CircleProperties::Clone(SdrObject& rObj) const + { + return *(new CircleProperties(*this, rObj)); + } + + void CircleProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrCircObj& rObj = (SdrCircObj&)GetSdrObject(); + + // call parent + RectangleProperties::ItemSetChanged(rSet); + + // local changes + rObj.ImpSetAttrToCircInfo(); + } + + void CircleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrCircObj& rObj = (SdrCircObj&)GetSdrObject(); + + // local changes + rObj.SetXPolyDirty(); + + // call parent + RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // local changes + rObj.ImpSetAttrToCircInfo(); + } + + void CircleProperties::ForceDefaultAttributes() + { + SdrCircObj& rObj = (SdrCircObj&)GetSdrObject(); + SdrCircKind eKindA = SDRCIRC_FULL; + SdrObjKind eKind = rObj.GetCircleKind(); + + if(eKind == OBJ_SECT) + { + eKindA = SDRCIRC_SECT; + } + else if(eKind == OBJ_CARC) + { + eKindA = SDRCIRC_ARC; + } + else if(eKind == OBJ_CCUT) + { + eKindA = SDRCIRC_CUT; + } + + if(eKindA != SDRCIRC_FULL) + { + // force ItemSet + GetObjectItemSet(); + + mpItemSet->Put(SdrCircKindItem(eKindA)); + + if(rObj.GetStartWink()) + { + mpItemSet->Put(SdrCircStartAngleItem(rObj.GetStartWink())); + } + + if(rObj.GetEndWink() != 36000) + { + mpItemSet->Put(SdrCircEndAngleItem(rObj.GetEndWink())); + } + } + + // call parent after SetObjectItem(SdrCircKindItem()) + // because ForceDefaultAttr() will call + // ImpSetAttrToCircInfo() which needs a correct + // SdrCircKindItem + RectangleProperties::ForceDefaultAttributes(); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/connectorproperties.cxx b/svx/source/sdr/properties/connectorproperties.cxx new file mode 100644 index 000000000000..963a541a73c1 --- /dev/null +++ b/svx/source/sdr/properties/connectorproperties.cxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * 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/properties/connectorproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdoedge.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& ConnectorProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrEdgeObj + SDRATTR_EDGE_FIRST, SDRATTR_EDGE_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + ConnectorProperties::ConnectorProperties(SdrObject& rObj) + : TextProperties(rObj) + { + } + + ConnectorProperties::ConnectorProperties(const ConnectorProperties& rProps, SdrObject& rObj) + : TextProperties(rProps, rObj) + { + } + + ConnectorProperties::~ConnectorProperties() + { + } + + BaseProperties& ConnectorProperties::Clone(SdrObject& rObj) const + { + return *(new ConnectorProperties(*this, rObj)); + } + + void ConnectorProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrEdgeObj& rObj = (SdrEdgeObj&)GetSdrObject(); + + // call parent + TextProperties::ItemSetChanged(rSet); + + // local changes + rObj.ImpSetAttrToEdgeInfo(); + } + + void ConnectorProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrEdgeObj& rObj = (SdrEdgeObj&)GetSdrObject(); + + // call parent + TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // local changes + rObj.ImpSetAttrToEdgeInfo(); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/customshapeproperties.cxx b/svx/source/sdr/properties/customshapeproperties.cxx new file mode 100644 index 000000000000..6146dc66e417 --- /dev/null +++ b/svx/source/sdr/properties/customshapeproperties.cxx @@ -0,0 +1,239 @@ +/************************************************************************* + * + * 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/properties/customshapeproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svdoashp.hxx> +#include <editeng/eeitem.hxx> +#include <svx/sdtagitm.hxx> +#include <svl/whiter.hxx> +#include <svl/itemset.hxx> +#include <svl/smplhint.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + void CustomShapeProperties::UpdateTextFrameStatus() + { + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + SdrTextAutoGrowHeightItem& rAutoGrowHeightItem = + (SdrTextAutoGrowHeightItem&)rObj.GetMergedItem( SDRATTR_TEXT_AUTOGROWHEIGHT ); + rObj.bTextFrame = rAutoGrowHeightItem.GetValue() != 0; + + if ( rObj.bTextFrame ) + rObj.NbcAdjustTextFrameWidthAndHeight(); + } + + SfxItemSet& CustomShapeProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // ranges from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // Graphic Attributes + SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, + + // 3d Properties + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, + + // CustomShape properties + SDRATTR_CUSTOMSHAPE_FIRST, SDRATTR_CUSTOMSHAPE_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + sal_Bool CustomShapeProperties::AllowItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem ) const + { + sal_Bool bAllowItemChange = sal_True; + if ( !pNewItem ) + { + if ( ( nWhich >= SDRATTR_CUSTOMSHAPE_FIRST ) && ( nWhich <= SDRATTR_CUSTOMSHAPE_LAST ) ) + bAllowItemChange = sal_False; + } + if ( bAllowItemChange ) + bAllowItemChange = TextProperties::AllowItemChange( nWhich, pNewItem ); + return bAllowItemChange; + } + void CustomShapeProperties::ClearObjectItem(const sal_uInt16 nWhich) + { + if ( !nWhich ) + { + SfxWhichIter aIter( *mpItemSet ); + sal_uInt16 nWhich2 = aIter.FirstWhich(); + while( nWhich2 ) + { + TextProperties::ClearObjectItemDirect( nWhich2 ); + nWhich2 = aIter.NextWhich(); + } + SfxItemSet aSet((SfxItemPool&)(*GetSdrObject().GetObjectItemPool())); + ItemSetChanged(aSet); + } + else + TextProperties::ClearObjectItem( nWhich ); + } + void CustomShapeProperties::ClearObjectItemDirect(const sal_uInt16 nWhich) + { + if ( !nWhich ) + { + SfxWhichIter aIter( *mpItemSet ); + sal_uInt16 nWhich2 = aIter.FirstWhich(); + while( nWhich2 ) + { + TextProperties::ClearObjectItemDirect( nWhich2 ); + nWhich2 = aIter.NextWhich(); + } + } + else + TextProperties::ClearObjectItemDirect( nWhich ); + } + void CustomShapeProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrObjCustomShape& rObj = (SdrObjCustomShape&)GetSdrObject(); + + if( SFX_ITEM_SET == rSet.GetItemState( SDRATTR_TEXT_AUTOGROWHEIGHT ) ) + { + rObj.bTextFrame = ((SdrTextAutoGrowHeightItem&)rSet.Get( SDRATTR_TEXT_AUTOGROWHEIGHT )).GetValue() != 0; + } + + // call parent + TextProperties::ItemSetChanged(rSet); + + // local changes, removing cached objects + rObj.InvalidateRenderGeometry(); + } + void CustomShapeProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) + { + SdrObjCustomShape& rObj = (SdrObjCustomShape&)GetSdrObject(); + //OutlinerParaObject* pParaObj = rObj.GetOutlinerParaObject(); + + if( pNewItem && ( SDRATTR_TEXT_AUTOGROWHEIGHT == nWhich ) ) + { + rObj.bTextFrame = ((SdrTextAutoGrowHeightItem*)pNewItem)->GetValue() != 0; + } + // call parent + TextProperties::ItemChange( nWhich, pNewItem ); + + rObj.InvalidateRenderGeometry(); + } + void CustomShapeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + TextProperties::SetStyleSheet( pNewStyleSheet, bDontRemoveHardAttr ); + UpdateTextFrameStatus(); + } + void CustomShapeProperties::ForceDefaultAttributes() + { + UpdateTextFrameStatus(); + +/* SJ: Following is no good if creating customshapes, leading to objects that are white after loading via xml + + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + sal_Bool bTextFrame(rObj.IsTextFrame()); + + // force ItemSet + GetObjectItemSet(); + + if(bTextFrame) + { + mpItemSet->Put(XLineStyleItem(XLINE_NONE)); + mpItemSet->Put(XFillColorItem(String(), Color(COL_WHITE))); + mpItemSet->Put(XFillStyleItem(XFILL_NONE)); + } + else + { + mpItemSet->Put(SvxAdjustItem(SVX_ADJUST_CENTER)); + mpItemSet->Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); + mpItemSet->Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); + } +*/ + } + CustomShapeProperties::CustomShapeProperties(SdrObject& rObj) + : TextProperties(rObj) + { + } + + CustomShapeProperties::CustomShapeProperties(const CustomShapeProperties& rProps, SdrObject& rObj) + : TextProperties(rProps, rObj) + { + } + + CustomShapeProperties::~CustomShapeProperties() + { + } + + BaseProperties& CustomShapeProperties::Clone(SdrObject& rObj) const + { + return *(new CustomShapeProperties(*this, rObj)); + } + void CustomShapeProperties::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) + { + TextProperties::Notify( rBC, rHint ); + + sal_Bool bRemoveRenderGeometry = sal_False; + + const SfxStyleSheetHint *pStyleHint = PTR_CAST( SfxStyleSheetHint, &rHint ); + const SfxSimpleHint *pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint ); + if ( pStyleHint && pStyleHint->GetStyleSheet() == GetStyleSheet() ) + { + switch( pStyleHint->GetHint() ) + { + case SFX_STYLESHEET_MODIFIED : + case SFX_STYLESHEET_CHANGED : + bRemoveRenderGeometry = sal_True; + break; + }; + } + else if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DATACHANGED ) + { + bRemoveRenderGeometry = sal_True; + } + if ( bRemoveRenderGeometry ) + { + UpdateTextFrameStatus(); + + // local changes, removing cached objects + SdrObjCustomShape& rObj = (SdrObjCustomShape&)GetSdrObject(); + rObj.InvalidateRenderGeometry(); + } + + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/defaultproperties.cxx b/svx/source/sdr/properties/defaultproperties.cxx new file mode 100644 index 000000000000..005ba0b19789 --- /dev/null +++ b/svx/source/sdr/properties/defaultproperties.cxx @@ -0,0 +1,237 @@ +/************************************************************************* + * + * 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/properties/defaultproperties.hxx> +#include <svx/sdr/properties/itemsettools.hxx> +#include <svl/itemset.hxx> +#include <svl/whiter.hxx> + +#include <vector> +#include <svx/svdobj.hxx> +#include <svx/svddef.hxx> +#include <svx/svdpool.hxx> +#include <editeng/eeitem.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + SfxItemSet& DefaultProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + // Basic implementation; Basic object has NO attributes + return *(new SfxItemSet(rPool)); + } + + DefaultProperties::DefaultProperties(SdrObject& rObj) + : BaseProperties(rObj), + mpItemSet(0L) + { + } + + DefaultProperties::DefaultProperties(const DefaultProperties& rProps, SdrObject& rObj) + : BaseProperties(rObj), + mpItemSet(0L) + { + if(rProps.mpItemSet) + { + mpItemSet = rProps.mpItemSet->Clone(TRUE); + + // do not keep parent info, this may be changed by later construrtors. + // This class just copies the ItemSet, ignore parent. + if(mpItemSet && mpItemSet->GetParent()) + { + mpItemSet->SetParent(0L); + } + } + } + + BaseProperties& DefaultProperties::Clone(SdrObject& rObj) const + { + return *(new DefaultProperties(*this, rObj)); + } + + DefaultProperties::~DefaultProperties() + { + if(mpItemSet) + { + delete mpItemSet; + mpItemSet = 0L; + } + } + + const SfxItemSet& DefaultProperties::GetObjectItemSet() const + { + if(!mpItemSet) + { + ((DefaultProperties*)this)->mpItemSet = &(((DefaultProperties*)this)->CreateObjectSpecificItemSet(*GetSdrObject().GetObjectItemPool())); + ((DefaultProperties*)this)->ForceDefaultAttributes(); + } + + DBG_ASSERT(mpItemSet, "Could not create an SfxItemSet(!)"); + + return *mpItemSet; + } + + void DefaultProperties::SetObjectItem(const SfxPoolItem& rItem) + { + const sal_uInt16 nWhichID(rItem.Which()); + + if(AllowItemChange(nWhichID, &rItem)) + { + ItemChange(nWhichID, &rItem); + PostItemChange(nWhichID); + + SfxItemSet aSet(*GetSdrObject().GetObjectItemPool(), nWhichID, nWhichID); + aSet.Put(rItem); + ItemSetChanged(aSet); + } + } + + void DefaultProperties::SetObjectItemDirect(const SfxPoolItem& rItem) + { + const sal_uInt16 nWhichID(rItem.Which()); + + if(AllowItemChange(nWhichID, &rItem)) + { + ItemChange(nWhichID, &rItem); + } + } + + void DefaultProperties::ClearObjectItem(const sal_uInt16 nWhich) + { + if(AllowItemChange(nWhich)) + { + ItemChange(nWhich); + PostItemChange(nWhich); + + if(nWhich) + { + SfxItemSet aSet(*GetSdrObject().GetObjectItemPool(), nWhich, nWhich, 0, 0); + ItemSetChanged(aSet); + } + } + } + + void DefaultProperties::ClearObjectItemDirect(const sal_uInt16 nWhich) + { + if(AllowItemChange(nWhich)) + { + ItemChange(nWhich); + } + } + + void DefaultProperties::SetObjectItemSet(const SfxItemSet& rSet) + { + SfxWhichIter aWhichIter(rSet); + sal_uInt16 nWhich(aWhichIter.FirstWhich()); + const SfxPoolItem *pPoolItem; + std::vector< sal_uInt16 > aPostItemChangeList; + sal_Bool bDidChange(sal_False); + SfxItemSet aSet(*GetSdrObject().GetObjectItemPool(), SDRATTR_START, EE_ITEMS_END, 0, 0); + + // give a hint to STL_Vector + aPostItemChangeList.reserve(rSet.Count()); + + while(nWhich) + { + if(SFX_ITEM_SET == rSet.GetItemState(nWhich, FALSE, &pPoolItem)) + { + if(AllowItemChange(nWhich, pPoolItem)) + { + bDidChange = sal_True; + ItemChange(nWhich, pPoolItem); + aPostItemChangeList.push_back( nWhich ); + aSet.Put(*pPoolItem); + } + } + + nWhich = aWhichIter.NextWhich(); + } + + if(bDidChange) + { + std::vector< sal_uInt16 >::iterator aIter = aPostItemChangeList.begin(); + const std::vector< sal_uInt16 >::iterator aEnd = aPostItemChangeList.end(); + + while(aIter != aEnd) + { + PostItemChange(*aIter); + aIter++; + } + + ItemSetChanged(aSet); + } + } + + void DefaultProperties::ItemSetChanged(const SfxItemSet& /*rSet*/) + { + } + + sal_Bool DefaultProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const + { + return sal_True; + } + + void DefaultProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) + { + } + + void DefaultProperties::PostItemChange(const sal_uInt16 /*nWhich*/) + { + } + + void DefaultProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, sal_Bool /*bDontRemoveHardAttr*/) + { + // no StyleSheet in DefaultProperties + } + + SfxStyleSheet* DefaultProperties::GetStyleSheet() const + { + // no StyleSheet in DefaultProperties + return 0L; + } + + void DefaultProperties::ForceDefaultAttributes() + { + } + + void DefaultProperties::Scale(const Fraction& rScale) + { + if(mpItemSet) + { + ScaleItemSet(*mpItemSet, rScale); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dcompoundproperties.cxx b/svx/source/sdr/properties/e3dcompoundproperties.cxx new file mode 100644 index 000000000000..a939ed664a8d --- /dev/null +++ b/svx/source/sdr/properties/e3dcompoundproperties.cxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * 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/properties/e3dcompoundproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/obj3d.hxx> +#include <svx/scene3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + E3dCompoundProperties::E3dCompoundProperties(SdrObject& rObj) + : E3dProperties(rObj) + { + } + + E3dCompoundProperties::E3dCompoundProperties(const E3dCompoundProperties& rProps, SdrObject& rObj) + : E3dProperties(rProps, rObj) + { + } + + E3dCompoundProperties::~E3dCompoundProperties() + { + } + + BaseProperties& E3dCompoundProperties::Clone(SdrObject& rObj) const + { + return *(new E3dCompoundProperties(*this, rObj)); + } + + const SfxItemSet& E3dCompoundProperties::GetObjectItemSet() const + { + //DBG_ASSERT(sal_False, "E3dCompoundProperties::GetObjectItemSet() maybe the wrong call (!)"); + return E3dProperties::GetObjectItemSet(); + } + + const SfxItemSet& E3dCompoundProperties::GetMergedItemSet() const + { + // include Items of scene this object belongs to + E3dCompoundObject& rObj = (E3dCompoundObject&)GetSdrObject(); + E3dScene* pScene = rObj.GetScene(); + + if(pScene) + { + // force ItemSet + GetObjectItemSet(); + + // add filtered scene properties (SDRATTR_3DSCENE_) to local itemset + SfxItemSet aSet(*mpItemSet->GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST); + aSet.Put(pScene->GetProperties().GetObjectItemSet()); + mpItemSet->Put(aSet); + } + + // call parent + return E3dProperties::GetMergedItemSet(); + } + + void E3dCompoundProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems) + { + // Set scene specific items at scene + E3dCompoundObject& rObj = (E3dCompoundObject&)GetSdrObject(); + E3dScene* pScene = rObj.GetScene(); + + if(pScene) + { + // force ItemSet + GetObjectItemSet(); + + // Generate filtered scene properties (SDRATTR_3DSCENE_) itemset + SfxItemSet aSet(*mpItemSet->GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST); + aSet.Put(rSet); + + if(bClearAllItems) + { + pScene->GetProperties().ClearObjectItem(); + } + + if(aSet.Count()) + { + pScene->GetProperties().SetObjectItemSet(aSet); + } + } + + // call parent. This will set items on local object, too. + E3dProperties::SetMergedItemSet(rSet, bClearAllItems); + } + + void E3dCompoundProperties::PostItemChange(const sal_uInt16 nWhich) + { + // call parent + E3dProperties::PostItemChange(nWhich); + + // handle value change + E3dCompoundObject& rObj = (E3dCompoundObject&)GetSdrObject(); + + switch(nWhich) + { + // #i28528# + // Added extra Item (Bool) for chart2 to be able to show reduced line geometry + case SDRATTR_3DOBJ_REDUCED_LINE_GEOMETRY: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_DOUBLE_SIDED: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_NORMALS_KIND: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_NORMALS_INVERT: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_TEXTURE_PROJ_X: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_TEXTURE_PROJ_Y: + { + rObj.ActionChanged(); + break; + } + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dextrudeproperties.cxx b/svx/source/sdr/properties/e3dextrudeproperties.cxx new file mode 100644 index 000000000000..91b86551339c --- /dev/null +++ b/svx/source/sdr/properties/e3dextrudeproperties.cxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * 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/properties/e3dextrudeproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/extrud3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + E3dExtrudeProperties::E3dExtrudeProperties(SdrObject& rObj) + : E3dCompoundProperties(rObj) + { + } + + E3dExtrudeProperties::E3dExtrudeProperties(const E3dExtrudeProperties& rProps, SdrObject& rObj) + : E3dCompoundProperties(rProps, rObj) + { + } + + E3dExtrudeProperties::~E3dExtrudeProperties() + { + } + + BaseProperties& E3dExtrudeProperties::Clone(SdrObject& rObj) const + { + return *(new E3dExtrudeProperties(*this, rObj)); + } + + void E3dExtrudeProperties::PostItemChange(const sal_uInt16 nWhich) + { + // call parent + E3dCompoundProperties::PostItemChange(nWhich); + + // handle value change + E3dExtrudeObj& rObj = (E3dExtrudeObj&)GetSdrObject(); + + switch(nWhich) + { + case SDRATTR_3DOBJ_PERCENT_DIAGONAL: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_BACKSCALE: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_DEPTH: + { + rObj.ActionChanged(); + break; + } + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dlatheproperties.cxx b/svx/source/sdr/properties/e3dlatheproperties.cxx new file mode 100644 index 000000000000..135104abab32 --- /dev/null +++ b/svx/source/sdr/properties/e3dlatheproperties.cxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * 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/properties/e3dlatheproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/lathe3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + E3dLatheProperties::E3dLatheProperties(SdrObject& rObj) + : E3dCompoundProperties(rObj) + { + } + + E3dLatheProperties::E3dLatheProperties(const E3dLatheProperties& rProps, SdrObject& rObj) + : E3dCompoundProperties(rProps, rObj) + { + } + + E3dLatheProperties::~E3dLatheProperties() + { + } + + BaseProperties& E3dLatheProperties::Clone(SdrObject& rObj) const + { + return *(new E3dLatheProperties(*this, rObj)); + } + + void E3dLatheProperties::PostItemChange(const sal_uInt16 nWhich) + { + // call parent + E3dCompoundProperties::PostItemChange(nWhich); + + // handle value change + E3dLatheObj& rObj = (E3dLatheObj&)GetSdrObject(); + + switch(nWhich) + { + case SDRATTR_3DOBJ_HORZ_SEGS: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_VERT_SEGS: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_PERCENT_DIAGONAL: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_BACKSCALE: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_END_ANGLE: + { + rObj.ActionChanged(); + break; + } + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dproperties.cxx b/svx/source/sdr/properties/e3dproperties.cxx new file mode 100644 index 000000000000..9ae3e2565a78 --- /dev/null +++ b/svx/source/sdr/properties/e3dproperties.cxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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/properties/e3dproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/svddef.hxx> +#include <svx/obj3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& E3dProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // ranges from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // ranges from E3dObject, contains object and scene because of GetMergedItemSet() + SDRATTR_3D_FIRST, SDRATTR_3D_LAST, + + // end + 0, 0)); + } + + E3dProperties::E3dProperties(SdrObject& rObj) + : AttributeProperties(rObj) + { + } + + E3dProperties::E3dProperties(const E3dProperties& rProps, SdrObject& rObj) + : AttributeProperties(rProps, rObj) + { + } + + E3dProperties::~E3dProperties() + { + } + + BaseProperties& E3dProperties::Clone(SdrObject& rObj) const + { + return *(new E3dProperties(*this, rObj)); + } + + void E3dProperties::ItemSetChanged(const SfxItemSet& rSet) + { + E3dObject& rObj = (E3dObject&)GetSdrObject(); + + // call parent + AttributeProperties::ItemSetChanged(rSet); + + // local changes + rObj.StructureChanged(); + } + + void E3dProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + // call parent + AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // propagate call to contained objects + const SdrObjList* pSub = ((const E3dObject&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->GetProperties().SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dsceneproperties.cxx b/svx/source/sdr/properties/e3dsceneproperties.cxx new file mode 100644 index 000000000000..41a3294b2a01 --- /dev/null +++ b/svx/source/sdr/properties/e3dsceneproperties.cxx @@ -0,0 +1,334 @@ +/************************************************************************* + * + * 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/properties/e3dsceneproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/whiter.hxx> +#include <svx/svddef.hxx> +#include <svx/scene3d.hxx> +#include <svditer.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + E3dSceneProperties::E3dSceneProperties(SdrObject& rObj) + : E3dProperties(rObj) + { + } + + E3dSceneProperties::E3dSceneProperties(const E3dSceneProperties& rProps, SdrObject& rObj) + : E3dProperties(rProps, rObj) + { + } + + E3dSceneProperties::~E3dSceneProperties() + { + } + + BaseProperties& E3dSceneProperties::Clone(SdrObject& rObj) const + { + return *(new E3dSceneProperties(*this, rObj)); + } + + const SfxItemSet& E3dSceneProperties::GetObjectItemSet() const + { + //DBG_ASSERT(sal_False, "E3dSceneProperties::GetObjectItemSet() maybe the wrong call (!)"); + return E3dProperties::GetObjectItemSet(); + } + + const SfxItemSet& E3dSceneProperties::GetMergedItemSet() const + { + // prepare ItemSet + if(mpItemSet) + { + // filter for SDRATTR_3DSCENE_ items, only keep those items + SfxItemSet aNew(*mpItemSet->GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST); + aNew.Put(*mpItemSet); + mpItemSet->ClearItem(); + mpItemSet->Put(aNew); + } + else + { + // No ItemSet yet, force local ItemSet + GetObjectItemSet(); + } + + // collect all ItemSets of contained 3d objects + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + SdrObject* pObj = pSub->GetObj(a); + + if(pObj && pObj->ISA(E3dCompoundObject)) + { + const SfxItemSet& rSet = pObj->GetMergedItemSet(); + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich(aIter.FirstWhich()); + + while(nWhich) + { + // Leave out the SDRATTR_3DSCENE_ range, this would only be double + // and always equal. + if(nWhich <= SDRATTR_3DSCENE_FIRST || nWhich >= SDRATTR_3DSCENE_LAST) + { + if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE)) + { + mpItemSet->InvalidateItem(nWhich); + } + else + { + mpItemSet->MergeValue(rSet.Get(nWhich), TRUE); + } + } + + nWhich = aIter.NextWhich(); + } + } + } + + // call parent + return E3dProperties::GetMergedItemSet(); + } + + void E3dSceneProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems) + { + // Set SDRATTR_3DOBJ_ range at contained objects. + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + if(nCount) + { + // Generate filtered ItemSet which contains all but the SDRATTR_3DSCENE items. + // #i50808# Leak fix, Clone produces a new instance and we get ownership here + SfxItemSet* pNewSet = rSet.Clone(TRUE); + DBG_ASSERT(pNewSet, "E3dSceneProperties::SetMergedItemSet(): Could not clone ItemSet (!)"); + + for(sal_uInt16 b(SDRATTR_3DSCENE_FIRST); b <= SDRATTR_3DSCENE_LAST; b++) + { + pNewSet->ClearItem(b); + } + + if(pNewSet->Count()) + { + for(sal_uInt32 a(0L); a < nCount; a++) + { + SdrObject* pObj = pSub->GetObj(a); + + if(pObj && pObj->ISA(E3dCompoundObject)) + { + // set merged ItemSet at contained 3d object. + pObj->SetMergedItemSet(*pNewSet, bClearAllItems); + } + } + } + + delete pNewSet; + } + + // call parent. This will set items on local object, too. + E3dProperties::SetMergedItemSet(rSet, bClearAllItems); + } + + void E3dSceneProperties::SetMergedItem(const SfxPoolItem& rItem) + { + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->SetMergedItem(rItem); + } + + // #i43809# call parent. This will set items on local object, too. + E3dProperties::SetMergedItem(rItem); + } + + void E3dSceneProperties::ClearMergedItem(const sal_uInt16 nWhich) + { + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->ClearMergedItem(nWhich); + } + + // #i43809# call parent. This will clear items on local object, too. + E3dProperties::ClearMergedItem(nWhich); + } + + void E3dSceneProperties::PostItemChange(const sal_uInt16 nWhich) + { + // call parent + E3dProperties::PostItemChange(nWhich); + + // local changes + E3dScene& rObj = (E3dScene&)GetSdrObject(); + rObj.StructureChanged(); + + switch(nWhich) + { + case SDRATTR_3DSCENE_PERSPECTIVE : + case SDRATTR_3DSCENE_DISTANCE : + case SDRATTR_3DSCENE_FOCAL_LENGTH : + { + // #83387#, #83391# + // one common function for the camera attributes + // since SetCamera() sets all three back to the ItemSet + Camera3D aSceneCam(rObj.GetCamera()); + sal_Bool bChange(sal_False); + + // for SDRATTR_3DSCENE_PERSPECTIVE: + if(aSceneCam.GetProjection() != rObj.GetPerspective()) + { + aSceneCam.SetProjection(rObj.GetPerspective()); + bChange = sal_True; + } + + // for SDRATTR_3DSCENE_DISTANCE: + basegfx::B3DPoint aActualPosition(aSceneCam.GetPosition()); + double fNew = rObj.GetDistance(); + + if(fNew != aActualPosition.getZ()) + { + aSceneCam.SetPosition(basegfx::B3DPoint(aActualPosition.getX(), aActualPosition.getY(), fNew)); + bChange = sal_True; + } + + // for SDRATTR_3DSCENE_FOCAL_LENGTH: + fNew = rObj.GetFocalLength() / 100.0; + + if(aSceneCam.GetFocalLength() != fNew) + { + aSceneCam.SetFocalLength(fNew); + bChange = sal_True; + } + + // for all + if(bChange) + { + rObj.SetCamera(aSceneCam); + } + + break; + } + } + } + + void E3dSceneProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + } + } + + SfxStyleSheet* E3dSceneProperties::GetStyleSheet() const + { + SfxStyleSheet* pRetval = 0L; + + const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet(); + + if(pRetval) + { + if(pCandidate != pRetval) + { + // different StyleSheelts, return none + return 0L; + } + } + else + { + pRetval = pCandidate; + } + } + + return pRetval; + } + + void E3dSceneProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel) + { + if(pSrcPool && pDestPool && (pSrcPool != pDestPool)) + { + // call parent + E3dProperties::MoveToItemPool(pSrcPool, pDestPool, pNewModel); + + // own reaction, but only with outmost scene + E3dScene& rObj = (E3dScene&)GetSdrObject(); + const SdrObjList* pSubList = rObj.GetSubList(); + + if(pSubList && rObj.GetScene() == &rObj) + { + SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS); + + while(a3DIterator.IsMore()) + { + E3dObject* pObj = (E3dObject*)a3DIterator.Next(); + DBG_ASSERT(pObj->ISA(E3dObject), "In scenes there are only 3D objects allowed (!)"); + pObj->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel); + } + } + } + } + + void E3dSceneProperties::SetSceneItemsFromCamera() + { + // force ItemSet + GetObjectItemSet(); + + E3dScene& rObj = (E3dScene&)GetSdrObject(); + Camera3D aSceneCam(rObj.GetCamera()); + + // ProjectionType + mpItemSet->Put(Svx3DPerspectiveItem((UINT16)aSceneCam.GetProjection())); + + // CamPos + mpItemSet->Put(Svx3DDistanceItem((UINT32)(aSceneCam.GetPosition().getZ() + 0.5))); + + // FocalLength + mpItemSet->Put(Svx3DFocalLengthItem((UINT32)((aSceneCam.GetFocalLength() * 100.0) + 0.5))); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/e3dsphereproperties.cxx b/svx/source/sdr/properties/e3dsphereproperties.cxx new file mode 100644 index 000000000000..589a5e639d0a --- /dev/null +++ b/svx/source/sdr/properties/e3dsphereproperties.cxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * 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/properties/e3dsphereproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/sphere3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + E3dSphereProperties::E3dSphereProperties(SdrObject& rObj) + : E3dCompoundProperties(rObj) + { + } + + E3dSphereProperties::E3dSphereProperties(const E3dSphereProperties& rProps, SdrObject& rObj) + : E3dCompoundProperties(rProps, rObj) + { + } + + E3dSphereProperties::~E3dSphereProperties() + { + } + + BaseProperties& E3dSphereProperties::Clone(SdrObject& rObj) const + { + return *(new E3dSphereProperties(*this, rObj)); + } + + void E3dSphereProperties::PostItemChange(const sal_uInt16 nWhich) + { + // call parent + E3dCompoundProperties::PostItemChange(nWhich); + + // handle value change + E3dSphereObj& rObj = (E3dSphereObj&)GetSdrObject(); + + switch(nWhich) + { + case SDRATTR_3DOBJ_HORZ_SEGS: + { + rObj.ActionChanged(); + break; + } + case SDRATTR_3DOBJ_VERT_SEGS: + { + rObj.ActionChanged(); + break; + } + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/emptyproperties.cxx b/svx/source/sdr/properties/emptyproperties.cxx new file mode 100644 index 000000000000..a33d5b23f84d --- /dev/null +++ b/svx/source/sdr/properties/emptyproperties.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/sdr/properties/emptyproperties.hxx> +#include <tools/debug.hxx> +#include <svl/itemset.hxx> +#include <svx/svddef.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpool.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& EmptyProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + // Basic implementation; Basic object has NO attributes + DBG_ASSERT(sal_False, "EmptyProperties::CreateObjectSpecificItemSet() should never be called"); + return *(new SfxItemSet(rPool)); + } + + EmptyProperties::EmptyProperties(SdrObject& rObj) + : BaseProperties(rObj), + mpEmptyItemSet(0L) + { + } + + EmptyProperties::EmptyProperties(const EmptyProperties& rProps, SdrObject& rObj) + : BaseProperties(rProps, rObj), + mpEmptyItemSet(0L) + { + // #115593# + // do not gererate an assert, else derivations like PageProperties will generate an assert + // using the Clone() operator path. + } + + EmptyProperties::~EmptyProperties() + { + if(mpEmptyItemSet) + { + delete mpEmptyItemSet; + mpEmptyItemSet = 0L; + } + } + + BaseProperties& EmptyProperties::Clone(SdrObject& rObj) const + { + return *(new EmptyProperties(*this, rObj)); + } + + const SfxItemSet& EmptyProperties::GetObjectItemSet() const + { + if(!mpEmptyItemSet) + { + ((EmptyProperties*)this)->mpEmptyItemSet = &(((EmptyProperties*)this)->CreateObjectSpecificItemSet(*GetSdrObject().GetObjectItemPool())); + } + + DBG_ASSERT(mpEmptyItemSet, "Could not create an SfxItemSet(!)"); + DBG_ASSERT(sal_False, "EmptyProperties::GetObjectItemSet() should never be called (!)"); + + return *mpEmptyItemSet; + } + + void EmptyProperties::SetObjectItem(const SfxPoolItem& /*rItem*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItem() should never be called (!)"); + } + + void EmptyProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemDirect() should never be called (!)"); + } + + void EmptyProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItem() should never be called (!)"); + } + + void EmptyProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::ClearObjectItemDirect() should never be called (!)"); + } + + void EmptyProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::SetObjectItemSet() should never be called (!)"); + } + + void EmptyProperties::ItemSetChanged(const SfxItemSet& /*rSet*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::ItemSetChanged() should never be called (!)"); + } + + sal_Bool EmptyProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const + { + DBG_ASSERT(sal_False, "EmptyProperties::AllowItemChange() should never be called (!)"); + return sal_True; + } + + void EmptyProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::ItemChange() should never be called (!)"); + } + + void EmptyProperties::PostItemChange(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::PostItemChange() should never be called (!)"); + } + + void EmptyProperties::SetStyleSheet(SfxStyleSheet* /*pNewStyleSheet*/, sal_Bool /*bDontRemoveHardAttr*/) + { + DBG_ASSERT(sal_False, "EmptyProperties::SetStyleSheet() should never be called (!)"); + } + + SfxStyleSheet* EmptyProperties::GetStyleSheet() const + { + DBG_ASSERT(sal_False, "EmptyProperties::GetStyleSheet() should never be called (!)"); + return 0L; + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/graphicproperties.cxx b/svx/source/sdr/properties/graphicproperties.cxx new file mode 100644 index 000000000000..76eacd537c27 --- /dev/null +++ b/svx/source/sdr/properties/graphicproperties.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * 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/properties/graphicproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdograf.hxx> +#include <svx/sdgcpitm.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& GraphicProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrGrafObj + SDRATTR_GRAF_FIRST, SDRATTR_GRAF_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + GraphicProperties::GraphicProperties(SdrObject& rObj) + : RectangleProperties(rObj) + { + } + + GraphicProperties::GraphicProperties(const GraphicProperties& rProps, SdrObject& rObj) + : RectangleProperties(rProps, rObj) + { + } + + GraphicProperties::~GraphicProperties() + { + } + + BaseProperties& GraphicProperties::Clone(SdrObject& rObj) const + { + return *(new GraphicProperties(*this, rObj)); + } + + void GraphicProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrGrafObj& rObj = (SdrGrafObj&)GetSdrObject(); + + // local changes + rObj.SetXPolyDirty(); + + // #i29367# Update GraphicAttr, too. This was formerly + // triggered by SdrGrafObj::Notify, which is no longer + // called nowadays. BTW: strictly speaking, the whole + // ImpSetAttrToGrafInfo/ImpSetGrafInfoToAttr stuff could + // be dumped, when SdrGrafObj::aGrafInfo is removed and + // always created on the fly for repaint. + rObj.ImpSetAttrToGrafInfo(); + + // call parent + RectangleProperties::ItemSetChanged(rSet); + } + + void GraphicProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrGrafObj& rObj = (SdrGrafObj&)GetSdrObject(); + + // local changes + rObj.SetXPolyDirty(); + + // call parent + RectangleProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // local changes + rObj.ImpSetAttrToGrafInfo(); + } + + void GraphicProperties::ForceDefaultAttributes() + { + // call parent + RectangleProperties::ForceDefaultAttributes(); + + // force ItemSet + GetObjectItemSet(); + + mpItemSet->Put( SdrGrafLuminanceItem( 0 ) ); + mpItemSet->Put( SdrGrafContrastItem( 0 ) ); + mpItemSet->Put( SdrGrafRedItem( 0 ) ); + mpItemSet->Put( SdrGrafGreenItem( 0 ) ); + mpItemSet->Put( SdrGrafBlueItem( 0 ) ); + mpItemSet->Put( SdrGrafGamma100Item( 100 ) ); + mpItemSet->Put( SdrGrafTransparenceItem( 0 ) ); + mpItemSet->Put( SdrGrafInvertItem( FALSE ) ); + mpItemSet->Put( SdrGrafModeItem( GRAPHICDRAWMODE_STANDARD ) ); + mpItemSet->Put( SdrGrafCropItem( 0, 0, 0, 0 ) ); + + // #i25616# + mpItemSet->Put( XFillStyleItem(XFILL_NONE) ); + mpItemSet->Put( XLineStyleItem(XLINE_NONE) ); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/groupproperties.cxx b/svx/source/sdr/properties/groupproperties.cxx new file mode 100644 index 000000000000..9761946d15b3 --- /dev/null +++ b/svx/source/sdr/properties/groupproperties.cxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * 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/properties/groupproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/whiter.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdpool.hxx> +#include <svx/svdpage.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& GroupProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + // Groups have in principle no ItemSet. To support methods like + // GetMergedItemSet() the local one is used. Thus, all items in the pool + // may be used and a pool itemset is created. + return *(new SfxItemSet(rPool)); + } + + GroupProperties::GroupProperties(SdrObject& rObj) + : DefaultProperties(rObj) + { + } + + GroupProperties::GroupProperties(const GroupProperties& rProps, SdrObject& rObj) + : DefaultProperties(rProps, rObj) + { + } + + GroupProperties::~GroupProperties() + { + } + + BaseProperties& GroupProperties::Clone(SdrObject& rObj) const + { + return *(new GroupProperties(*this, rObj)); + } + + const SfxItemSet& GroupProperties::GetObjectItemSet() const + { + DBG_ASSERT(sal_False, "GroupProperties::GetObjectItemSet() should never be called (!)"); + return DefaultProperties::GetObjectItemSet(); + } + + const SfxItemSet& GroupProperties::GetMergedItemSet() const + { + // prepare ItemSet + if(mpItemSet) + { + // clear local itemset for merge + mpItemSet->ClearItem(); + } + else + { + // force local itemset + DefaultProperties::GetObjectItemSet(); + } + + // collect all ItemSets in mpItemSet + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + const SfxItemSet& rSet = pSub->GetObj(a)->GetMergedItemSet(); + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich(aIter.FirstWhich()); + + while(nWhich) + { + if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, FALSE)) + { + mpItemSet->InvalidateItem(nWhich); + } + else + { + mpItemSet->MergeValue(rSet.Get(nWhich), TRUE); + } + + nWhich = aIter.NextWhich(); + } + } + + // For group proerties, do not call parent since groups do + // not have local ItemSets. + return *mpItemSet; + } + + void GroupProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems) + { + // iterate over contained SdrObjects + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + SdrObject* pObj = pSub->GetObj(a); + + if(pObj) + { + // Set merged ItemSet at contained object + pObj->SetMergedItemSet(rSet, bClearAllItems); + } + } + + // Do not call parent here. Group objects do not have local ItemSets + // where items need to be set. + // DefaultProperties::SetMergedItemSet(rSet, bClearAllItems); + } + + void GroupProperties::SetObjectItem(const SfxPoolItem& /*rItem*/) + { + DBG_ASSERT(sal_False, "GroupProperties::SetObjectItem() should never be called (!)"); + } + + void GroupProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/) + { + DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemDirect() should never be called (!)"); + } + + void GroupProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItem() should never be called (!)"); + } + + void GroupProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "GroupProperties::ClearObjectItemDirect() should never be called (!)"); + } + + void GroupProperties::SetMergedItem(const SfxPoolItem& rItem) + { + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->GetProperties().SetMergedItem(rItem); + } + } + + void GroupProperties::ClearMergedItem(const sal_uInt16 nWhich) + { + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->GetProperties().ClearMergedItem(nWhich); + } + } + + void GroupProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/) + { + DBG_ASSERT(sal_False, "GroupProperties::SetObjectItemSet() should never be called (!)"); + } + + void GroupProperties::ItemSetChanged(const SfxItemSet& /*rSet*/) + { + DBG_ASSERT(sal_False, "GroupProperties::ItemSetChanged() should never be called (!)"); + } + + sal_Bool GroupProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const + { + DBG_ASSERT(sal_False, "GroupProperties::AllowItemChange() should never be called (!)"); + return sal_False; + } + + void GroupProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) + { + DBG_ASSERT(sal_False, "GroupProperties::ItemChange() should never be called (!)"); + } + + void GroupProperties::PostItemChange(const sal_uInt16 /*nWhich*/) + { + DBG_ASSERT(sal_False, "GroupProperties::PostItemChange() should never be called (!)"); + } + + SfxStyleSheet* GroupProperties::GetStyleSheet() const + { + SfxStyleSheet* pRetval = 0L; + + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet(); + + if(pRetval) + { + if(pCandidate != pRetval) + { + // different StyleSheelts, return none + return 0L; + } + } + else + { + pRetval = pCandidate; + } + } + + return pRetval; + } + + void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + } + } + + void GroupProperties::ForceDefaultAttributes() + { + // nothing to do here, groups have no items and thus no default items, too. + } + + void GroupProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel) + { + if(pSrcPool && pDestPool && (pSrcPool != pDestPool)) + { + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel); + } + + // also clear local ItemSet, it's only temporary for group objects anyways. + if(mpItemSet) + { + // #121905# + // copy/paste is still using clone operators and MoveToItemPool functionality. + // Since SfxItemSet contains a pool pointer, ClearItem is not enough here. + // The ItemSet for merge is constructed on demand, so it's enough here to + // just delete it and set to 0L. + // mpItemSet->ClearItem(); + delete mpItemSet; + mpItemSet = 0L; + } + } + } + + void GroupProperties::ForceStyleToHardAttributes() + { + const SdrObjList* pSub = ((const SdrObjGroup&)GetSdrObject()).GetSubList(); + const sal_uInt32 nCount(pSub->GetObjCount()); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + pSub->GetObj(a)->GetProperties().ForceStyleToHardAttributes(); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/itemsettools.cxx b/svx/source/sdr/properties/itemsettools.cxx new file mode 100644 index 000000000000..eab977681490 --- /dev/null +++ b/svx/source/sdr/properties/itemsettools.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * 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/properties/itemsettools.hxx> +#include <tools/debug.hxx> +#include <svl/itemset.hxx> +#include <svl/whiter.hxx> + +#include <vector> +#include <svx/svdogrp.hxx> +#include <svditer.hxx> + +////////////////////////////////////////////////////////////////////////////// +// class to remember broadcast start positions + +namespace sdr +{ + namespace properties + { + // helper vector to remember rectangles + typedef ::std::vector< Rectangle > RectangleVector; + + ItemChangeBroadcaster::ItemChangeBroadcaster(const SdrObject& rObj) + { + if(rObj.ISA(SdrObjGroup)) + { + SdrObjListIter aIter((const SdrObjGroup&)rObj, IM_DEEPNOGROUPS); + mpData = new RectangleVector; + DBG_ASSERT(mpData, "ItemChangeBroadcaster: No memory (!)"); + ((RectangleVector*)mpData)->reserve(aIter.Count()); + + while(aIter.IsMore()) + { + SdrObject* pObj = aIter.Next(); + + if(pObj) + { + ((RectangleVector*)mpData)->push_back(pObj->GetLastBoundRect()); + } + } + + mnCount = ((RectangleVector*)mpData)->size(); + } + else + { + mpData = new Rectangle(rObj.GetLastBoundRect()); + mnCount = 1L; + } + } + + ItemChangeBroadcaster::~ItemChangeBroadcaster() + { + if(mnCount > 1) + { + delete ((RectangleVector*)mpData); + } + else + { + delete ((Rectangle*)mpData); + } + } + + sal_uInt32 ItemChangeBroadcaster::GetRectangleCount() const + { + return mnCount; + } + + const Rectangle& ItemChangeBroadcaster::GetRectangle(sal_uInt32 nIndex) const + { + if(mnCount > 1) + { + return (*((RectangleVector*)mpData))[nIndex]; + } + else + { + return *((Rectangle*)mpData); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + void ScaleItemSet(SfxItemSet& rSet, const Fraction& rScale) + { + sal_Int32 nMul(rScale.GetNumerator()); + sal_Int32 nDiv(rScale.GetDenominator()); + + if(!rScale.IsValid() || !nDiv) + { + return; + } + + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich(aIter.FirstWhich()); + const SfxPoolItem *pItem = NULL; + + while(nWhich) + { + if(SFX_ITEM_SET == rSet.GetItemState(nWhich, FALSE, &pItem)) + { + if(pItem->HasMetrics()) + { + SfxPoolItem* pNewItem = pItem->Clone(); + pNewItem->ScaleMetrics(nMul, nDiv); + rSet.Put(*pNewItem); + } + } + nWhich = aIter.NextWhich(); + } + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/makefile.mk b/svx/source/sdr/properties/makefile.mk new file mode 100644 index 000000000000..5296765769b1 --- /dev/null +++ b/svx/source/sdr/properties/makefile.mk @@ -0,0 +1,65 @@ +#************************************************************************* +# +# 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=properties +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES=\ + $(SLO)$/properties.obj \ + $(SLO)$/emptyproperties.obj \ + $(SLO)$/pageproperties.obj \ + $(SLO)$/defaultproperties.obj \ + $(SLO)$/attributeproperties.obj \ + $(SLO)$/textproperties.obj \ + $(SLO)$/customshapeproperties.obj \ + $(SLO)$/rectangleproperties.obj \ + $(SLO)$/oleproperties.obj \ + $(SLO)$/captionproperties.obj \ + $(SLO)$/circleproperties.obj \ + $(SLO)$/connectorproperties.obj \ + $(SLO)$/e3dproperties.obj \ + $(SLO)$/e3dcompoundproperties.obj \ + $(SLO)$/e3dextrudeproperties.obj \ + $(SLO)$/e3dlatheproperties.obj \ + $(SLO)$/e3dsceneproperties.obj \ + $(SLO)$/e3dsphereproperties.obj \ + $(SLO)$/graphicproperties.obj \ + $(SLO)$/groupproperties.obj \ + $(SLO)$/measureproperties.obj \ + $(SLO)$/itemsettools.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/properties/measureproperties.cxx b/svx/source/sdr/properties/measureproperties.cxx new file mode 100644 index 000000000000..8c935c2700f0 --- /dev/null +++ b/svx/source/sdr/properties/measureproperties.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * 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/properties/measureproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svx/svddef.hxx> +#include <editeng/eeitem.hxx> +#include <svx/svdomeas.hxx> +#include <svx/sxmsuitm.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnstwit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnedwit.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& MeasureProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrMeasureObj + SDRATTR_MEASURE_FIRST, SDRATTR_MEASURE_LAST, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + MeasureProperties::MeasureProperties(SdrObject& rObj) + : TextProperties(rObj) + { + } + + MeasureProperties::MeasureProperties(const MeasureProperties& rProps, SdrObject& rObj) + : TextProperties(rProps, rObj) + { + } + + MeasureProperties::~MeasureProperties() + { + } + + BaseProperties& MeasureProperties::Clone(SdrObject& rObj) const + { + return *(new MeasureProperties(*this, rObj)); + } + + void MeasureProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrMeasureObj& rObj = (SdrMeasureObj&)GetSdrObject(); + + // call parent + TextProperties::ItemSetChanged(rSet); + + // local changes + rObj.SetTextDirty(); + } + + void MeasureProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrMeasureObj& rObj = (SdrMeasureObj&)GetSdrObject(); + + // local changes + rObj.SetTextDirty(); + + // call parent + TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + } + + void MeasureProperties::ForceDefaultAttributes() + { + // call parent + TextProperties::ForceDefaultAttributes(); + + // force ItemSet + GetObjectItemSet(); + + //#71958# by default, the show units Bool-Item is set as hard + // attribute to TRUE to aviod confusion when copying SdrMeasureObj's + // from one application to another + mpItemSet->Put(SdrMeasureShowUnitItem(TRUE)); + + basegfx::B2DPolygon aNewPolygon; + aNewPolygon.append(basegfx::B2DPoint(100.0, 0.0)); + aNewPolygon.append(basegfx::B2DPoint(200.0, 400.0)); + aNewPolygon.append(basegfx::B2DPoint(0.0, 400.0)); + aNewPolygon.setClosed(true); + + mpItemSet->Put(XLineStartItem(String(), basegfx::B2DPolyPolygon(aNewPolygon))); + mpItemSet->Put(XLineStartWidthItem(200)); + mpItemSet->Put(XLineEndItem(String(), basegfx::B2DPolyPolygon(aNewPolygon))); + mpItemSet->Put(XLineEndWidthItem(200)); + mpItemSet->Put(XLineStyleItem(XLINE_SOLID)); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +// eof diff --git a/svx/source/sdr/properties/oleproperties.cxx b/svx/source/sdr/properties/oleproperties.cxx new file mode 100644 index 000000000000..b2a103bd8cfc --- /dev/null +++ b/svx/source/sdr/properties/oleproperties.cxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: graphicproperties.cxx,v $ + * $Revision: 1.12.76.1 $ + * + * 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/properties/oleproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xlineit0.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + OleProperties::OleProperties(SdrObject& rObj) + : RectangleProperties(rObj) + { + } + + OleProperties::OleProperties(const OleProperties& rProps, SdrObject& rObj) + : RectangleProperties(rProps, rObj) + { + } + + OleProperties::~OleProperties() + { + } + + BaseProperties& OleProperties::Clone(SdrObject& rObj) const + { + return *(new OleProperties(*this, rObj)); + } + + void OleProperties::ForceDefaultAttributes() + { + // call parent + RectangleProperties::ForceDefaultAttributes(); + + // force ItemSet + GetObjectItemSet(); + + // #i108221# + mpItemSet->Put( XFillStyleItem(XFILL_NONE) ); + mpItemSet->Put( XLineStyleItem(XLINE_NONE) ); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/pageproperties.cxx b/svx/source/sdr/properties/pageproperties.cxx new file mode 100644 index 000000000000..2fc92633b953 --- /dev/null +++ b/svx/source/sdr/properties/pageproperties.cxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * 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/properties/pageproperties.hxx> +#include <svl/itemset.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpool.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + // create a new itemset + SfxItemSet& PageProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + // overloaded to legally return a valid ItemSet + return *(new SfxItemSet(rPool)); + } + + PageProperties::PageProperties(SdrObject& rObj) + : EmptyProperties(rObj) + { + } + + PageProperties::PageProperties(const PageProperties& rProps, SdrObject& rObj) + : EmptyProperties(rProps, rObj) + { + } + + PageProperties::~PageProperties() + { + } + + BaseProperties& PageProperties::Clone(SdrObject& rObj) const + { + return *(new PageProperties(*this, rObj)); + } + + // get itemset. Overloaded here to allow creating the empty itemset + // without asserting + const SfxItemSet& PageProperties::GetObjectItemSet() const + { + if(!mpEmptyItemSet) + { + ((PageProperties*)this)->mpEmptyItemSet = &(((PageProperties*)this)->CreateObjectSpecificItemSet(*GetSdrObject().GetObjectItemPool())); + } + + DBG_ASSERT(mpEmptyItemSet, "Could not create an SfxItemSet(!)"); + + return *mpEmptyItemSet; + } + + void PageProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) + { + // #86481# simply ignore item setting on page objects + } + + SfxStyleSheet* PageProperties::GetStyleSheet() const + { + // overloaded to legally return a 0L pointer here + return 0L; + } + + void PageProperties::ClearObjectItem(const sal_uInt16 /*nWhich*/) + { + // simply ignore item clearing on page objects + } + } // end of namespace properties +} // end of namespace sdr + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// eof diff --git a/svx/source/sdr/properties/properties.cxx b/svx/source/sdr/properties/properties.cxx new file mode 100644 index 000000000000..576f9745e167 --- /dev/null +++ b/svx/source/sdr/properties/properties.cxx @@ -0,0 +1,189 @@ +/************************************************************************* + * + * 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/properties/properties.hxx> +#include <svx/sdr/properties/itemsettools.hxx> +#include <svl/itemset.hxx> +#include <svx/svdogrp.hxx> +#include <svditer.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + BaseProperties::BaseProperties(SdrObject& rObj) + : mrObject(rObj) + { + } + + BaseProperties::BaseProperties(const BaseProperties& /*rProps*/, SdrObject& rObj) + : mrObject(rObj) + { + } + + BaseProperties::~BaseProperties() + { + } + + const SfxItemSet& BaseProperties::GetMergedItemSet() const + { + // default implementation falls back to GetObjectItemSet() + return GetObjectItemSet(); + } + + void BaseProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems) + { + // clear items if requested + if(bClearAllItems) + { + ClearObjectItem(); + } + + // default implementation falls back to SetObjectItemSet() + SetObjectItemSet(rSet); + } + + void BaseProperties::SetMergedItem(const SfxPoolItem& rItem) + { + // default implementation falls back to SetObjectItem() + SetObjectItem(rItem); + } + + void BaseProperties::ClearMergedItem(const sal_uInt16 nWhich) + { + // default implementation falls back to ClearObjectItem() + ClearObjectItem(nWhich); + } + + void BaseProperties::Scale(const Fraction& /*rScale*/) + { + // default implementation does nothing; overload where + // an ItemSet is implemented. + } + + void BaseProperties::MoveToItemPool(SfxItemPool* /*pSrcPool*/, SfxItemPool* /*pDestPool*/, SdrModel* /*pNewModel*/) + { + // Move properties to a new ItemPool. Default implementation does nothing. + // Overload where an ItemSet is implemented. + } + + void BaseProperties::SetModel(SdrModel* /*pOldModel*/, SdrModel* /*pNewModel*/) + { + // Set new model. Default implementation does nothing. + // Overload where an ItemSet is implemented. + } + + void BaseProperties::ForceStyleToHardAttributes() + { + // force all attributes which come from styles to hard attributes + // to be able to live without the style. Default implementation does nothing. + // Overload where an ItemSet is implemented. + } + + //void BaseProperties::SetItemAndBroadcast(const SfxPoolItem& rItem) + //{ + // ItemChangeBroadcaster aC(GetSdrObject()); + // SetObjectItem(rItem); + // BroadcastItemChange(aC); + //} + + //void BaseProperties::ClearItemAndBroadcast(const sal_uInt16 nWhich) + //{ + // ItemChangeBroadcaster aC(GetSdrObject()); + // ClearObjectItem(nWhich); + // BroadcastItemChange(aC); + //} + + void BaseProperties::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, sal_Bool bClearAllItems) + { + ItemChangeBroadcaster aC(GetSdrObject()); + + if(bClearAllItems) + { + ClearObjectItem(); + } + + SetMergedItemSet(rSet); + BroadcastItemChange(aC); + } + + const SfxPoolItem& BaseProperties::GetItem(const sal_uInt16 nWhich) const + { + return GetObjectItemSet().Get(nWhich); + } + + void BaseProperties::BroadcastItemChange(const ItemChangeBroadcaster& rChange) + { + const sal_uInt32 nCount(rChange.GetRectangleCount()); + + // #110094#-14 Reduce to do only second change + //// invalidate all remembered rectangles + //for(sal_uInt32 a(0); a < nCount; a++) + //{ + // GetSdrObject().BroadcastObjectChange(rChange.GetRectangle(a)); + //} + + // invalidate all new rectangles + if(GetSdrObject().ISA(SdrObjGroup)) + { + SdrObjListIter aIter((SdrObjGroup&)GetSdrObject(), IM_DEEPNOGROUPS); + + while(aIter.IsMore()) + { + SdrObject* pObj = aIter.Next(); + // This is done with ItemSetChanged + // pObj->SetChanged(); + pObj->BroadcastObjectChange(); + } + } + else + { + // This is done with ItemSetChanged + // GetSdrObject().SetChanged(); + GetSdrObject().BroadcastObjectChange(); + } + + // also send the user calls + for(sal_uInt32 a(0L); a < nCount; a++) + { + GetSdrObject().SendUserCall(SDRUSERCALL_CHGATTR, rChange.GetRectangle(a)); + } + } + + sal_uInt32 BaseProperties::getVersion() const + { + return 0; + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/rectangleproperties.cxx b/svx/source/sdr/properties/rectangleproperties.cxx new file mode 100644 index 000000000000..21907df0018d --- /dev/null +++ b/svx/source/sdr/properties/rectangleproperties.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * 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/properties/rectangleproperties.hxx> +#include <svx/svdorect.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + RectangleProperties::RectangleProperties(SdrObject& rObj) + : TextProperties(rObj) + { + } + + RectangleProperties::RectangleProperties(const RectangleProperties& rProps, SdrObject& rObj) + : TextProperties(rProps, rObj) + { + } + + RectangleProperties::~RectangleProperties() + { + } + + BaseProperties& RectangleProperties::Clone(SdrObject& rObj) const + { + return *(new RectangleProperties(*this, rObj)); + } + + void RectangleProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrRectObj& rObj = (SdrRectObj&)GetSdrObject(); + + // call parent + TextProperties::ItemSetChanged(rSet); + + // local changes + rObj.SetXPolyDirty(); + } + + // set a new StyleSheet and broadcast + void RectangleProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrRectObj& rObj = (SdrRectObj&)GetSdrObject(); + + // call parent + TextProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // local changes + rObj.SetXPolyDirty(); + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/properties/textproperties.cxx b/svx/source/sdr/properties/textproperties.cxx new file mode 100644 index 000000000000..091656e1f261 --- /dev/null +++ b/svx/source/sdr/properties/textproperties.cxx @@ -0,0 +1,638 @@ +/************************************************************************* + * + * 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/properties/textproperties.hxx> +#include <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svl/itemiter.hxx> +#include <svl/smplhint.hxx> +#include <svx/svddef.hxx> +#include <svx/svdotext.hxx> +#include <svx/svdoutl.hxx> +#include <editeng/writingmodeitem.hxx> +#include <svx/svdmodel.hxx> +#include <editeng/outlobj.hxx> +#include <svx/xflclit.hxx> +#include <editeng/adjitem.hxx> +#include <svx/svdetc.hxx> +#include <editeng/editeng.hxx> +#include <editeng/flditem.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/svdpool.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace properties + { + SfxItemSet& TextProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) + { + return *(new SfxItemSet(rPool, + + // range from SdrAttrObj + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, + + // range from SdrTextObj + EE_ITEMS_START, EE_ITEMS_END, + + // end + 0, 0)); + } + + TextProperties::TextProperties(SdrObject& rObj) + : AttributeProperties(rObj), + maVersion(0) + { + } + + TextProperties::TextProperties(const TextProperties& rProps, SdrObject& rObj) + : AttributeProperties(rProps, rObj), + maVersion(rProps.getVersion()) + { + } + + TextProperties::~TextProperties() + { + } + + BaseProperties& TextProperties::Clone(SdrObject& rObj) const + { + return *(new TextProperties(*this, rObj)); + } + + void TextProperties::ItemSetChanged(const SfxItemSet& rSet) + { + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + sal_Int32 nText = rObj.getTextCount(); + + // #i101556# ItemSet has changed -> new version + maVersion++; + + while( --nText >= 0 ) + { + SdrText* pText = rObj.getText( nText ); + + OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; + + if(pParaObj) + { + const bool bTextEdit = rObj.IsTextEditActive() && (rObj.getActiveText() == pText); + + // handle outliner attributes + GetObjectItemSet(); + Outliner* pOutliner = rObj.GetTextEditOutliner(); + + if(!bTextEdit) + { + pOutliner = &rObj.ImpGetDrawOutliner(); + pOutliner->SetText(*pParaObj); + } + + sal_uInt32 nParaCount(pOutliner->GetParagraphCount()); + + for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) + { + SfxItemSet aSet(pOutliner->GetParaAttribs(nPara)); + aSet.Put(rSet); + pOutliner->SetParaAttribs(nPara, aSet); + } + + if(!bTextEdit) + { + if(nParaCount) + { + // force ItemSet + GetObjectItemSet(); + + SfxItemSet aNewSet(pOutliner->GetParaAttribs(0L)); + mpItemSet->Put(aNewSet); + } + + OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount); + pOutliner->Clear(); + + rObj.NbcSetOutlinerParaObjectForText(pTemp,pText); + } + } + } + + // Extra-Repaint for radical layout changes (#43139#) + if(SFX_ITEM_SET == rSet.GetItemState(SDRATTR_TEXT_CONTOURFRAME)) + { + // Here only repaint wanted + rObj.ActionChanged(); + //rObj.BroadcastObjectChange(); + } + + // call parent + AttributeProperties::ItemSetChanged(rSet); + } + + void TextProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) + { + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + + // #i25616# + sal_Int32 nOldLineWidth(0L); + + if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange()) + { + nOldLineWidth = ((const XLineWidthItem&)GetItem(XATTR_LINEWIDTH)).GetValue(); + } + + if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich)) + { + sal_Bool bVertical(com::sun::star::text::WritingMode_TB_RL == ((SvxWritingModeItem*)pNewItem)->GetValue()); + rObj.SetVerticalWriting(bVertical); + } + + // #95501# reset to default + if(!pNewItem && !nWhich && rObj.HasText() ) + { + SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); + + sal_Int32 nCount = rObj.getTextCount(); + while( nCount-- ) + { + SdrText* pText = rObj.getText( nCount ); + OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject(); + if( pParaObj ) + { + rOutliner.SetText(*pParaObj); + sal_uInt32 nParaCount(rOutliner.GetParagraphCount()); + + if(nParaCount) + { + ESelection aSelection( 0, 0, EE_PARA_ALL, EE_PARA_ALL); + rOutliner.RemoveAttribs(aSelection, sal_True, 0); + + OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount); + rOutliner.Clear(); + + rObj.NbcSetOutlinerParaObjectForText( pTemp, pText ); + } + } + } + } + + // call parent + AttributeProperties::ItemChange( nWhich, pNewItem ); + + // #i25616# + if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange()) + { + const sal_Int32 nNewLineWidth(((const XLineWidthItem&)GetItem(XATTR_LINEWIDTH)).GetValue()); + const sal_Int32 nDifference((nNewLineWidth - nOldLineWidth) / 2); + + if(nDifference) + { + const sal_Bool bLineVisible(XLINE_NONE != ((const XLineStyleItem&)(GetItem(XATTR_LINESTYLE))).GetValue()); + + if(bLineVisible) + { + const sal_Int32 nLeftDist(((const SdrTextLeftDistItem&)GetItem(SDRATTR_TEXT_LEFTDIST)).GetValue()); + const sal_Int32 nRightDist(((const SdrTextRightDistItem&)GetItem(SDRATTR_TEXT_RIGHTDIST)).GetValue()); + const sal_Int32 nUpperDist(((const SdrTextUpperDistItem&)GetItem(SDRATTR_TEXT_UPPERDIST)).GetValue()); + const sal_Int32 nLowerDist(((const SdrTextLowerDistItem&)GetItem(SDRATTR_TEXT_LOWERDIST)).GetValue()); + + SetObjectItemDirect(SdrTextLeftDistItem(nLeftDist + nDifference)); + SetObjectItemDirect(SdrTextRightDistItem(nRightDist + nDifference)); + SetObjectItemDirect(SdrTextUpperDistItem(nUpperDist + nDifference)); + SetObjectItemDirect(SdrTextLowerDistItem(nLowerDist + nDifference)); + } + } + } + } + + void TextProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) + { + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + + // call parent + AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); + + // #i101556# StyleSheet has changed -> new version + maVersion++; + + if( rObj.GetModel() /*&& !rObj.IsTextEditActive()*/ && !rObj.IsLinkedText() ) + { + SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); + + sal_Int32 nText = rObj.getTextCount(); + + while( --nText >= 0 ) + { + SdrText* pText = rObj.getText( nText ); + + OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; + if( !pParaObj ) + continue; + + // apply StyleSheet to all paragraphs + rOutliner.SetText(*pParaObj); + sal_uInt32 nParaCount(rOutliner.GetParagraphCount()); + + if(nParaCount) + { + for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) + { + SfxItemSet* pTempSet = 0L; + + // since setting the stylesheet removes all para attributes + if(bDontRemoveHardAttr) + { + // we need to remember them if we want to keep them + pTempSet = new SfxItemSet(rOutliner.GetParaAttribs(nPara)); + } + + if(GetStyleSheet()) + { + if((OBJ_OUTLINETEXT == rObj.GetTextKind()) && (SdrInventor == rObj.GetObjInventor())) + { + String aNewStyleSheetName(GetStyleSheet()->GetName()); + aNewStyleSheetName.Erase(aNewStyleSheetName.Len() - 1, 1); + sal_Int16 nDepth = rOutliner.GetDepth((sal_uInt16)nPara); + aNewStyleSheetName += String::CreateFromInt32( nDepth <= 0 ? 1 : nDepth + 1); + + SdrModel* pModel = rObj.GetModel(); + SfxStyleSheetBasePool* pStylePool = (pModel != NULL) ? pModel->GetStyleSheetPool() : 0L; + SfxStyleSheet* pNewStyle = (SfxStyleSheet*)pStylePool->Find(aNewStyleSheetName, GetStyleSheet()->GetFamily()); + DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" ); + + if(pNewStyle) + { + rOutliner.SetStyleSheet(nPara, pNewStyle); + } + } + else + { + rOutliner.SetStyleSheet(nPara, GetStyleSheet()); + } + } + else + { + // remove StyleSheet + rOutliner.SetStyleSheet(nPara, 0L); + } + + if(bDontRemoveHardAttr) + { + if(pTempSet) + { + // restore para attributes + rOutliner.SetParaAttribs(nPara, *pTempSet); + } + } + else + { + if(pNewStyleSheet) + { + // remove all hard paragraph attributes + // which occur in StyleSheet, take care of + // parents (!) + SfxItemIter aIter(pNewStyleSheet->GetItemSet()); + const SfxPoolItem* pItem = aIter.FirstItem(); + + while(pItem) + { + if(!IsInvalidItem(pItem)) + { + sal_uInt16 nW(pItem->Which()); + + if(nW >= EE_ITEMS_START && nW <= EE_ITEMS_END) + { + rOutliner.QuickRemoveCharAttribs((sal_uInt16)nPara, nW); + } + } + pItem = aIter.NextItem(); + } + } + } + + if(pTempSet) + { + delete pTempSet; + } + } + + OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount); + rOutliner.Clear(); + rObj.NbcSetOutlinerParaObjectForText(pTemp, pText); + } + } + } + + if(rObj.IsTextFrame()) + { + rObj.NbcAdjustTextFrameWidthAndHeight(); + } + } + + void TextProperties::ForceDefaultAttributes() + { + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + + if( rObj.GetObjInventor() == SdrInventor ) + { + const sal_uInt16 nSdrObjKind = rObj.GetObjIdentifier(); + + if( nSdrObjKind == OBJ_TITLETEXT || nSdrObjKind == OBJ_OUTLINETEXT ) + return; // no defaults for presentation objects + } + + bool bTextFrame(rObj.IsTextFrame()); + + // force ItemSet + GetObjectItemSet(); + + if(bTextFrame) + { + mpItemSet->Put(XLineStyleItem(XLINE_NONE)); + mpItemSet->Put(XFillColorItem(String(), Color(COL_WHITE))); + mpItemSet->Put(XFillStyleItem(XFILL_NONE)); + } + else + { + mpItemSet->Put(SvxAdjustItem(SVX_ADJUST_CENTER, EE_PARA_JUST)); + mpItemSet->Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); + mpItemSet->Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); + } + } + + void TextProperties::ForceStyleToHardAttributes() + { + // #i61284# call parent first to get the hard ObjectItemSet + AttributeProperties::ForceStyleToHardAttributes(); + + // #i61284# push hard ObjectItemSet to OutlinerParaObject attributes + // using existing functionality + GetObjectItemSet(); // force ItemSet + ItemSetChanged(*mpItemSet); + + // now the standard TextProperties stuff + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + + if(rObj.GetModel() + && !rObj.IsTextEditActive() + && !rObj.IsLinkedText()) + { + Outliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_OUTLINEOBJECT, rObj.GetModel()); + sal_Int32 nText = rObj.getTextCount(); + + while( --nText >= 0 ) + { + SdrText* pText = rObj.getText( nText ); + + OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; + if( !pParaObj ) + continue; + + pOutliner->SetText(*pParaObj); + + sal_uInt32 nParaCount(pOutliner->GetParagraphCount()); + + if(nParaCount) + { + sal_Bool bBurnIn(sal_False); + + for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) + { + SfxStyleSheet* pSheet = pOutliner->GetStyleSheet(nPara); + + if(pSheet) + { + SfxItemSet aParaSet(pOutliner->GetParaAttribs(nPara)); + SfxItemSet aSet(*aParaSet.GetPool()); + aSet.Put(pSheet->GetItemSet()); + + /** the next code handles a special case for paragraphs that contain a + url field. The color for URL fields is either the system color for + urls or the char color attribute that formats the portion in which the + url field is contained. + When we set a char color attribute to the paragraphs item set from the + styles item set, we would have this char color attribute as an attribute + that is spanned over the complete paragraph after xml import due to some + problems in the xml import (using a XCursor on import so it does not know + the paragraphs and can't set char attributes to paragraphs ). + + To avoid this, as soon as we try to set a char color attribute from the style + we + 1. check if we have at least one url field in this paragraph + 2. if we found at least one url field, we span the char color attribute over + all portions that are not url fields and remove the char color attribute + from the paragraphs item set + */ + + sal_Bool bHasURL(sal_False); + + if(aSet.GetItemState(EE_CHAR_COLOR) == SFX_ITEM_SET) + { + EditEngine* pEditEngine = const_cast<EditEngine*>(&(pOutliner->GetEditEngine())); + EECharAttribArray aAttribs; + pEditEngine->GetCharAttribs((sal_uInt16)nPara, aAttribs); + sal_uInt16 nAttrib; + + for(nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++) + { + struct EECharAttrib aAttrib(aAttribs.GetObject(nAttrib)); + + if(EE_FEATURE_FIELD == aAttrib.pAttr->Which()) + { + if(aAttrib.pAttr) + { + SvxFieldItem* pFieldItem = (SvxFieldItem*)aAttrib.pAttr; + + if(pFieldItem) + { + const SvxFieldData* pData = pFieldItem->GetField(); + + if(pData && pData->ISA(SvxURLField)) + { + bHasURL = sal_True; + break; + } + } + } + } + } + + if(bHasURL) + { + SfxItemSet aColorSet(*aSet.GetPool(), EE_CHAR_COLOR, EE_CHAR_COLOR ); + aColorSet.Put(aSet, FALSE); + + ESelection aSel((sal_uInt16)nPara, 0); + + for(nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++) + { + struct EECharAttrib aAttrib(aAttribs.GetObject(nAttrib)); + + if(EE_FEATURE_FIELD == aAttrib.pAttr->Which()) + { + aSel.nEndPos = aAttrib.nStart; + + if(aSel.nStartPos != aSel.nEndPos) + { + pEditEngine->QuickSetAttribs(aColorSet, aSel); + } + + aSel.nStartPos = aAttrib.nEnd; + } + } + + aSel.nEndPos = pEditEngine->GetTextLen((sal_uInt16)nPara); + + if(aSel.nStartPos != aSel.nEndPos) + { + pEditEngine->QuickSetAttribs( aColorSet, aSel ); + } + } + + } + + aSet.Put(aParaSet, FALSE); + + if(bHasURL) + { + aSet.ClearItem(EE_CHAR_COLOR); + } + + pOutliner->SetParaAttribs(nPara, aSet); + bBurnIn = sal_True; // #i51163# Flag was set wrong + } + } + + if(bBurnIn) + { + OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount); + rObj.NbcSetOutlinerParaObjectForText(pTemp,pText); + } + } + + pOutliner->Clear(); + } + delete pOutliner; + } + } + + void TextProperties::SetObjectItemNoBroadcast(const SfxPoolItem& rItem) + { + GetObjectItemSet(); + mpItemSet->Put(rItem); + } + + + void TextProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) + { + // call parent + AttributeProperties::Notify(rBC, rHint); + + SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); + if(rObj.HasText()) + { + if(HAS_BASE(SfxStyleSheet, &rBC)) + { + SfxSimpleHint* pSimple = PTR_CAST(SfxSimpleHint, &rHint); + sal_uInt32 nId(pSimple ? pSimple->GetId() : 0L); + + if(SFX_HINT_DATACHANGED == nId) + { + rObj.SetPortionInfoChecked(sal_False); + + sal_Int32 nText = rObj.getTextCount(); + while( --nText > 0 ) + { + OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); + if( pParaObj ) + pParaObj->ClearPortionInfo(); + } + rObj.SetTextSizeDirty(); + + if(rObj.IsTextFrame() && rObj.NbcAdjustTextFrameWidthAndHeight()) + { + // here only repaint wanted + rObj.ActionChanged(); + //rObj.BroadcastObjectChange(); + } + + // #i101556# content of StyleSheet has changed -> new version + maVersion++; + } + + if(SFX_HINT_DYING == nId) + { + rObj.SetPortionInfoChecked(sal_False); + sal_Int32 nText = rObj.getTextCount(); + while( --nText > 0 ) + { + OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); + if( pParaObj ) + pParaObj->ClearPortionInfo(); + } + } + } + else if(HAS_BASE(SfxStyleSheetBasePool, &rBC)) + { + SfxStyleSheetHintExtended* pExtendedHint = PTR_CAST(SfxStyleSheetHintExtended, &rHint); + + if(pExtendedHint + && SFX_STYLESHEET_MODIFIED == pExtendedHint->GetHint()) + { + String aOldName(pExtendedHint->GetOldName()); + String aNewName(pExtendedHint->GetStyleSheet()->GetName()); + SfxStyleFamily eFamily = pExtendedHint->GetStyleSheet()->GetFamily(); + + if(!aOldName.Equals(aNewName)) + { + sal_Int32 nText = rObj.getTextCount(); + while( --nText > 0 ) + { + OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); + if( pParaObj ) + pParaObj->ChangeStyleSheetName(eFamily, aOldName, aNewName); + } + } + } + } + } + } + + // #i101556# Handout version information + sal_uInt32 TextProperties::getVersion() const + { + return maVersion; + } + } // end of namespace properties +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof |