/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/** CL, OD 2005-07-19 #i52126# - this is initially 0 and set when * a SvxShape::Create() call is executed. It is then set to the created * SdrObject so a multiple call to SvxShape::Create() with same SdrObject * is prohibited.
*/
::unotools::WeakReference< SdrObject > mxCreatedObj;
// for xComponent
::comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> maDisposeListeners;
::comphelper::OMultiTypeInterfaceContainerHelperVar4<OUString, css::beans::XPropertyChangeListener> maPropertyChangeListeners;
/// Calculates what scaling factor will be used for autofit text scaling of this shape.
SdrTextObj* getTextObjectWithFitToSize(SdrObject* pObject)
{
SdrTextObj* pTextObj = DynCastSdrTextObj(pObject); if (!pTextObj)
{ return nullptr;
}
void SvxShape::impl_initFromSdrObject()
{
DBG_TESTSOLARMUTEX();
OSL_PRECOND( HasSdrObject(), "SvxShape::impl_initFromSdrObject: not to be called without SdrObject!" ); if ( !HasSdrObject() ) return;
// #i40944# // Do not simply return when no model but do the type corrections // following below. const SdrInventor nInventor = GetSdrObject()->GetObjInventor();
// is it one of ours (svx) ? if( !(nInventor == SdrInventor::Default || nInventor == SdrInventor::E3d || nInventor == SdrInventor::FmForm) ) return;
switch(mpImpl->mnObjId)
{ case SdrObjKind::CircleCut: // segment of circle case SdrObjKind::CircleArc: // arc of circle case SdrObjKind::CircleSection: // sector
mpImpl->mnObjId = SdrObjKind::CircleOrEllipse; break; default: ;
}
}
assert( pNewObj && "SvxShape::Create: invalid new object!" ); if ( !pNewObj ) return;
rtl::Reference<SdrObject> pCreatedObj = mpImpl->mxCreatedObj.get();
assert( ( !pCreatedObj || ( pCreatedObj == pNewObj ) ) && "SvxShape::Create: the same shape used for two different objects?! Strange ..." );
OSL_ENSURE( !mbIsMultiPropertyCall, "SvxShape::Create: hmm?" ); // this was previously set in impl_initFromSdrObject, but I think it was superfluous // (it definitely was in the other context where it was called, but I strongly suppose // it was also superfluous when called from here)
impl_initFromSdrObject();
ObtainSettingsFromPropertySet( *mpPropSet );
// save user call
SdrObjUserCall* pUser = GetSdrObject()->GetUserCall();
GetSdrObject()->SetUserCall(nullptr);
setPosition( maPosition );
setSize( maSize );
// restore user call after we set the initial size
GetSdrObject()->SetUserCall( pUser );
// if this shape was already named, use this name if( !maShapeName.isEmpty() )
{
GetSdrObject()->SetName( maShapeName );
maShapeName.clear();
}
}
// tdf#118662 Emulate old behaviour of XclObjComment (see there) const SdrCaptionObj* pSdrCaptionObj(dynamic_cast<SdrCaptionObj*>(GetSdrObject())); if(nullptr != pSdrCaptionObj && pSdrCaptionObj->isSuppressGetBitmap())
{ return aAny;
}
// tdf#119180 If we do not ask for Metafile and we access a SdrGrafObj, // and content exists and is a Bitmap, take the shortcut. // Do *not* do this for Metafile - as can be seen, requested in that case // is a byte-sequence of a saved WMF format file (see below) if(!bMetaFile)
{ const SdrGrafObj* pSdrGrafObj(dynamic_cast<SdrGrafObj*>(GetSdrObject()));
// tdf#118662 instead of creating an E3dView instance every time to paint // a single SdrObject, use the existing SdrObject::SingleObjectPainter to // use less resources and runtime if(bMetaFile)
{
ScopedVclPtrInstance< VirtualDevice > pVDev; const tools::Rectangle aBoundRect(GetSdrObject()->GetCurrentBoundRect());
GDIMetaFile aMtf;
if(MapUnit::Map100thMM != aSourceMapUnit)
{ // tdf#119180 This is UNO API and thus works in 100th_mm, // so if the MapMode from the used SdrModel is *not* equal // to Map100thMM we need to embed the primitives to an adapting // homogen transformation for correct values const basegfx::B2DHomMatrix aMapTransform(
OutputDevice::LogicToLogic(
MapMode(aSourceMapUnit),
MapMode(MapUnit::Map100thMM)));
// Embed primitives to get them in 100th mm
xPrimitives = drawinglayer::primitive2d::Primitive2DContainer { new drawinglayer::primitive2d::TransformPrimitive2D(
aMapTransform,
std::move(xPrimitives))
};
// Update basegfx::B2DRange aRange, too. Here we have the // choice of transforming the existing value or get newly by // again using 'xPrimitives.getB2DRange(aViewInformation2D)'
aRange.transform(aMapTransform);
}
uno::Sequence< uno::Type > const & SvxShape::_getTypes()
{ switch( mpImpl->mnObjId )
{ // shapes without text case SdrObjKind::Page: case SdrObjKind::OLEPluginFrame: case SdrObjKind::OLE2Plugin: case SdrObjKind::OLE2Applet: case SdrObjKind::E3D_Cube: case SdrObjKind::E3D_Sphere: case SdrObjKind::E3D_Lathe: case SdrObjKind::E3D_Extrusion: case SdrObjKind::E3D_Polygon: case SdrObjKind::Media: case SdrObjKind::Table:
{ static uno::Sequence<uno::Type> aTypeSequence{
cppu::UnoType<drawing::XShape>::get(),
cppu::UnoType<lang::XComponent>::get(),
cppu::UnoType<beans::XPropertySet>::get(),
cppu::UnoType<beans::XMultiPropertySet>::get(),
cppu::UnoType<beans::XPropertyState>::get(),
cppu::UnoType<beans::XMultiPropertyStates>::get(),
cppu::UnoType<drawing::XGluePointsSupplier>::get(),
cppu::UnoType<container::XChild>::get(),
cppu::UnoType<lang::XServiceInfo>::get(),
cppu::UnoType<lang::XTypeProvider>::get(),
cppu::UnoType<lang::XUnoTunnel>::get(),
cppu::UnoType<container::XNamed>::get(),
};
return aTypeSequence;
} // shapes with text case SdrObjKind::Rectangle: case SdrObjKind::CircleOrEllipse: case SdrObjKind::Measure: case SdrObjKind::Line: case SdrObjKind::Polygon: case SdrObjKind::PolyLine: case SdrObjKind::PathLine: case SdrObjKind::PathFill: case SdrObjKind::FreehandLine: case SdrObjKind::FreehandFill: case SdrObjKind::PathPoly: case SdrObjKind::PathPolyLine: case SdrObjKind::Graphic: case SdrObjKind::Text: case SdrObjKind::Caption: case SdrObjKind::OLE2: // #i118485# Moved to shapes with text default:
{ static uno::Sequence<uno::Type> aTypeSequence{
cppu::UnoType<drawing::XShape>::get(),
cppu::UnoType<lang::XComponent>::get(),
cppu::UnoType<beans::XPropertySet>::get(),
cppu::UnoType<beans::XMultiPropertySet>::get(),
cppu::UnoType<beans::XPropertyState>::get(),
cppu::UnoType<beans::XMultiPropertyStates>::get(),
cppu::UnoType<drawing::XGluePointsSupplier>::get(),
cppu::UnoType<container::XChild>::get(),
cppu::UnoType<lang::XServiceInfo>::get(),
cppu::UnoType<lang::XTypeProvider>::get(),
cppu::UnoType<lang::XUnoTunnel>::get(),
cppu::UnoType<container::XNamed>::get(), // from SvxUnoTextBase::getTypes()
cppu::UnoType<text::XTextAppend>::get(),
cppu::UnoType<text::XTextCopy>::get(),
cppu::UnoType<container::XEnumerationAccess>::get(),
cppu::UnoType<text::XTextRangeMover>::get(),
};
// do cheap checks first, this method is hot if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint) return; if( !mxSdrObject ) return; const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint); // #i55919# SdrHintKind::ObjectChange is only interesting if it's for this object if (pSdrHint->GetKind() != SdrHintKind::ObjectChange || pSdrHint->GetObject() != mxSdrObject.get()) return;
// prevent object being deleted from under us
rtl::Reference<SdrObject> xSdrSelf(mxSdrObject);
uno::Reference< uno::XInterface > xSelf( mxSdrObject->getWeakUnoShape() ); if( !xSelf.is() )
{
mxSdrObject->RemoveListener(*this);
mxSdrObject.clear(); return;
}
updateShapeKind();
}
// XShape
// The "*LogicRectHack" functions also existed in sch, and those // duplicate symbols cause Bad Things To Happen (TM) #i9462#. // Prefixing with 'svx' and marking static to make sure name collisions // do not occur.
staticbool svx_needLogicRectHack( SdrObject const * pObj )
{ if( pObj->GetObjInventor() == SdrInventor::Default)
{ switch(pObj->GetObjIdentifier())
{ case SdrObjKind::Group: case SdrObjKind::Line: case SdrObjKind::Polygon: case SdrObjKind::PolyLine: case SdrObjKind::PathLine: case SdrObjKind::PathFill: case SdrObjKind::FreehandLine: case SdrObjKind::FreehandFill: case SdrObjKind::Edge: case SdrObjKind::PathPoly: case SdrObjKind::PathPolyLine: case SdrObjKind::Measure: returntrue; default: break;
}
} returnfalse;
}
// Position is relative to anchor, so recalc to absolute position if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
aPt -= GetSdrObject()->GetAnchorPos();
void SAL_CALL SvxShape::setPosition( const awt::Point& Position )
{
::SolarMutexGuard aGuard;
if(HasSdrObject())
{ // do NOT move 3D objects, this would change the homogen // transformation matrix if(dynamic_cast<const E3dCompoundObject* >(GetSdrObject()) == nullptr)
{
tools::Rectangle aRect( svx_getLogicRectHack(GetSdrObject()) );
Point aLocalPos( Position.X, Position.Y );
ForceMetricToItemPoolMetric(aLocalPos);
// Position is absolute, so recalc to position relative to anchor if( GetSdrObject()->getSdrModelFromSdrObject().IsWriter() )
aLocalPos += GetSdrObject()->GetAnchorPos();
bool SvxShape::SetFillAttribute( sal_uInt16 nWID, const OUString& rName, SfxItemSet& rSet, SdrModel const * pModel )
{ // check if an item with the given name and which id is inside the models // pool or the stylesheet pool, if found it's put in the itemset if( !SetFillAttribute( nWID, rName, rSet ) )
{ // we did not find such item in one of the pools, so we check // the property lists that are loaded for the model for items // that support such.
OUString aStrName = SvxUnogetInternalNameForItem(nWID, rName);
if (!HasSdrObject())
{ // Since we have no actual sdr object right now, remember all // properties in a list. These properties will be set when the sdr // object is created.
if (pMap && pMap->nWID)
{ // FIXME: We should throw a UnknownPropertyException here. // But since this class is aggregated from classes that // support additional properties that we don't know here we // silently store *all* properties, even if they may be not // supported after creation.
SvxItemPropertySet::setPropertyValue( pMap, rVal, maUrsAnys );
}
return;
}
if (rPropertyName == "HandlePathObjScale")
{ auto pPathObj = dynamic_cast<SdrPathObj*>(GetSdrObject()); if (pPathObj)
{ bool bHandleScale{}; if (rVal >>= bHandleScale)
{
pPathObj->SetHandleScale(bHandleScale);
}
} return;
}
// A hack to avoid taking incomplete OLE object's size into account when loading // see SdXMLObjectShapeContext::createFastChildContext if (rPropertyName == "IgnoreOLEObjectScale")
{ if (auto pOleObj = DynCastSdrOle2Obj(GetSdrObject())) if (bool bVal; rVal >>= bVal)
pOleObj->SetIgnoreOLEObjectScale(bVal); return;
}
if (!pMap)
{ // The oox layer sets these properties willy-nilly on objects, even if the objects do not support them. // And then it ignores the resulting exceptions, but exception throwing and catching becomes expensive // with complex spreadsheets. So just ignore it here, in absence of a better fix. if (rPropertyName == "FromWordArt" || rPropertyName == "GraphicColorMode" || rPropertyName == "Representation")
{
SAL_WARN("svx", "Ignoring property " << rPropertyName); return;
} throw beans::UnknownPropertyException( rPropertyName, getXWeak());
}
if ((pMap->nFlags & beans::PropertyAttribute::READONLY) != 0) throw beans::PropertyVetoException( "Readonly property can't be set: " + rPropertyName,
uno::Reference<drawing::XShape>(this));
if(bIsNotPersist)
{ // set not-persistent attribute extra
GetSdrObject()->ApplyNotPersistAttr( *pSet );
} else
{ // if we have a XMultiProperty call then the item set // will be set in setPropertyValues later if( !mbIsMultiPropertyCall )
GetSdrObject()->SetMergedItemSetAndBroadcast( *pSet );
}
}
if(!aSet.Count())
{ if(pMap->nWID >= SDRATTR_NOTPERSIST_FIRST && pMap->nWID <= SDRATTR_NOTPERSIST_LAST)
{ // not-persistent attribute, get those extra
GetSdrObject()->TakeNotPersistAttr(aSet);
}
}
if(!aSet.Count())
{ // get default from ItemPool if(SfxItemPool::IsWhich(pMap->nWID))
aSet.Put(GetSdrObject()->getSdrModelFromSdrObject().GetItemPool().GetUserOrPoolDefaultItem(pMap->nWID));
}
// make sure mbIsMultiPropertyCall and mpImpl->mpItemSet are // reset even when an exception is thrown const ::comphelper::ScopeGuard aGuard( [this] () { return this->endSetPropertyValues(); } );
mbIsMultiPropertyCall = true;
if( mpImpl->mpMaster )
{ for( sal_Int32 nIdx = 0; nIdx < nCount; nIdx++, pNames++, pValues++ )
{ try
{
setPropertyValue( *pNames, *pValues );
} catch (beans::UnknownPropertyException&)
{ // ignore, various code likes to opportunistically set properties on objects that don't support those properties
} catch (uno::Exception&)
{
DBG_UNHANDLED_EXCEPTION("svx");
}
}
} else
{
uno::Reference< beans::XPropertySet > xSet;
queryInterface( cppu::UnoType<beans::XPropertySet>::get()) >>= xSet;
// if an item is set, this doesn't mean we want it :) if( beans::PropertyState_DIRECT_VALUE == eState )
{ switch( pMap->nWID )
{ // the following items are disabled by changing the // fill style or the line style. so there is no need // to export items without names which should be empty case XATTR_FILLBITMAP: case XATTR_FILLGRADIENT: case XATTR_FILLHATCH: case XATTR_LINEDASH:
{ const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID); if( ( pItem == nullptr ) || pItem->GetName().isEmpty() )
eState = beans::PropertyState_DEFAULT_VALUE;
} break;
// #i36115# // If e.g. the LineStart is on NONE and thus the string has length 0, it still // may be a hard attribute covering the set LineStart of the parent (Style). // #i37644# // same is for fill float transparency case XATTR_LINEEND: case XATTR_LINESTART: case XATTR_FILLFLOATTRANSPARENCE:
{ const NameOrIndex* pItem = rSet.GetItem<NameOrIndex>(pMap->nWID); if ( pItem == nullptr )
eState = beans::PropertyState_DEFAULT_VALUE;
} break; case XATTR_FILLCOLOR: if (pMap->nMemberId == MID_COLOR_THEME_INDEX)
{ const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID); if (!pColor->getComplexColor().isValidThemeType())
{
eState = beans::PropertyState_DEFAULT_VALUE;
}
} elseif (pMap->nMemberId == MID_COLOR_LUM_MOD)
{ const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
sal_Int16 nLumMod = 10000; for (autoconst& rTransform : pColor->getComplexColor().getTransformations())
{ if (rTransform.meType == model::TransformationType::LumMod)
nLumMod = rTransform.mnValue;
} if (nLumMod == 10000)
{
eState = beans::PropertyState_DEFAULT_VALUE;
}
} elseif (pMap->nMemberId == MID_COLOR_LUM_OFF)
{ const XFillColorItem* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID);
sal_Int16 nLumOff = 0; for (autoconst& rTransform : pColor->getComplexColor().getTransformations())
{ if (rTransform.meType == model::TransformationType::LumOff)
nLumOff = rTransform.mnValue;
} if (nLumOff == 0)
{
eState = beans::PropertyState_DEFAULT_VALUE;
}
} elseif (pMap->nMemberId == MID_COMPLEX_COLOR)
{ autoconst* pColor = rSet.GetItem<XFillColorItem>(pMap->nWID); if (pColor->getComplexColor().getType() == model::ColorType::Unused)
{
eState = beans::PropertyState_DEFAULT_VALUE;
}
} break; case XATTR_LINECOLOR: if (pMap->nMemberId == MID_COMPLEX_COLOR)
{ autoconst* pColor = rSet.GetItem<XLineColorItem>(pMap->nWID); if (pColor->getComplexColor().getType() == model::ColorType::Unused)
{
eState = beans::PropertyState_DEFAULT_VALUE;
}
} break;
}
}
} return eState;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.