CWS-TOOLING: integrate CWS chartpositioning

This commit is contained in:
obo 2010-06-09 08:49:31 +02:00
commit 5147fa872a
34 changed files with 1553 additions and 638 deletions

View file

@ -38,6 +38,7 @@
#include "chartview/ExplicitValueProvider.hxx"
#include "chartview/DrawModelWrapper.hxx"
#include "AxisHelper.hxx"
#include "DiagramHelper.hxx"
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
@ -118,7 +119,7 @@ Reference< chart2::XDiagram > Chart2ModelContact::getChart2Diagram() const
return ChartModelHelper::findDiagram( this->getChartModel() );
}
ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const
uno::Reference< lang::XUnoTunnel > Chart2ModelContact::getChartView() const
{
if(!m_xChartView.is())
{
@ -128,7 +129,12 @@ ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const
if( xFact.is() )
m_xChartView = Reference< lang::XUnoTunnel >( xFact->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY );
}
return m_xChartView;
}
ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const
{
getChartView();
if(!m_xChartView.is())
return 0;
@ -192,30 +198,54 @@ awt::Size Chart2ModelContact::GetPageSize() const
return ChartModelHelper::getPageSize(m_xChartModel);
}
awt::Rectangle Chart2ModelContact::GetDiagramRectangleInclusive() const
awt::Rectangle Chart2ModelContact::SubstractAxisTitleSizes( const awt::Rectangle& rPositionRect )
{
awt::Rectangle aRect;
awt::Rectangle aRect = ExplicitValueProvider::substractAxisTitleSizes(
m_xChartModel, getChartView(), rPositionRect );
return aRect;
}
awt::Rectangle Chart2ModelContact::GetDiagramRectangleIncludingTitle() const
{
awt::Rectangle aRect( GetDiagramRectangleIncludingAxes() );
ExplicitValueProvider* pProvider( getExplicitValueProvider() );
if( pProvider )
{
aRect = pProvider->getRectangleOfObject( lcl_getCIDForDiagram( m_xChartModel ) );
}
//add axis title sizes to the diagram size
aRect = ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle(
m_xChartModel, m_xChartView, aRect );
aRect = ExplicitValueProvider::addAxisTitleSizes(
m_xChartModel, getChartView(), aRect );
return aRect;
}
awt::Size Chart2ModelContact::GetDiagramSizeInclusive() const
awt::Rectangle Chart2ModelContact::GetDiagramRectangleIncludingAxes() const
{
return ToSize( this->GetDiagramRectangleInclusive() );
awt::Rectangle aRect(0,0,0,0);
uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
if( DiagramPositioningMode_INCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ) )
aRect = DiagramHelper::getDiagramRectangleFromModel(m_xChartModel);
else
{
ExplicitValueProvider* pProvider( getExplicitValueProvider() );
if( pProvider )
aRect = pProvider->getRectangleOfObject( C2U("PlotAreaIncludingAxes") );
}
return aRect;
}
awt::Point Chart2ModelContact::GetDiagramPositionInclusive() const
awt::Rectangle Chart2ModelContact::GetDiagramRectangleExcludingAxes() const
{
return ToPoint( this->GetDiagramRectangleInclusive() );
awt::Rectangle aRect(0,0,0,0);
uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
if( DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ) )
aRect = DiagramHelper::getDiagramRectangleFromModel(m_xChartModel);
else
{
ExplicitValueProvider* pProvider( getExplicitValueProvider() );
if( pProvider )
aRect = pProvider->getDiagramRectangleExcludingAxes();
}
return aRect;
}
awt::Size Chart2ModelContact::GetLegendSize() const

View file

@ -93,15 +93,24 @@ public:
*/
::com::sun::star::awt::Size GetPageSize() const;
/** Returns the size of the diagram object in logic coordinates inclusive
the space reserved for axis titles.
/** calculates the current axes title sizes and substract that space them from the given recangle
*/
::com::sun::star::awt::Size GetDiagramSizeInclusive() const;
::com::sun::star::awt::Rectangle SubstractAxisTitleSizes( const ::com::sun::star::awt::Rectangle& rPositionRect );
/** Returns the position of the diagram in logic coordinates inclusive
the space reserved for axis titles.
/** Returns the position and size of the diagram in logic coordinates (100th mm) including
the space used for axes including axes titles.
*/
::com::sun::star::awt::Point GetDiagramPositionInclusive() const;
::com::sun::star::awt::Rectangle GetDiagramRectangleIncludingTitle() const;
/** Returns the position and size of the diagram in logic coordinates (100th mm) including
the space used for axes excluding axes titles.
*/
::com::sun::star::awt::Rectangle GetDiagramRectangleIncludingAxes() const;
/** Returns the position and size of the diagram in logic coordinates (100th mm) excluding
the space used for axes (inner plot area).
*/
::com::sun::star::awt::Rectangle GetDiagramRectangleExcludingAxes() const;
/** Returns the size of the object in logic coordinates.
*/
@ -134,7 +143,8 @@ public:
private: //methods
ExplicitValueProvider* getExplicitValueProvider() const;
::com::sun::star::awt::Rectangle GetDiagramRectangleInclusive() const;
::com::sun::star::uno::Reference<
::com::sun::star::lang::XUnoTunnel > getChartView() const;
public: //member
::com::sun::star::uno::Reference<

View file

@ -59,6 +59,7 @@
#include "DisposeHelper.hxx"
#include <comphelper/InlineContainer.hxx>
#include "WrappedAutomaticPositionProperties.hxx"
#include "CommonConverters.hxx"
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
@ -737,49 +738,23 @@ Reference<
awt::Point SAL_CALL DiagramWrapper::getPosition()
throw (uno::RuntimeException)
{
awt::Point aPosition;
Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() );
if( xProp.is() )
{
bool bSet = false;
chart2::RelativePosition aRelativePosition;
uno::Any aAPosition( xProp->getPropertyValue( C2U( "RelativePosition" ) ) );
if( aAPosition >>= aRelativePosition )
{
awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() );
aPosition.X = static_cast<sal_Int32>(aRelativePosition.Primary*aPageSize.Width);
aPosition.Y = static_cast<sal_Int32>(aRelativePosition.Secondary*aPageSize.Height);
aPosition = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
aPosition, DiagramWrapper::getSize(), aRelativePosition.Anchor );
bSet = true;
}
if(!bSet)
aPosition = m_spChart2ModelContact->GetDiagramPositionInclusive();
}
awt::Point aPosition = ToPoint( m_spChart2ModelContact->GetDiagramRectangleIncludingAxes() );
return aPosition;
}
void SAL_CALL DiagramWrapper::setPosition( const awt::Point& aPosition )
throw (uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() );
if( xProp.is() )
{
if( aPosition.X < 0 || aPosition.Y < 0 )
if( aPosition.X < 0 || aPosition.Y < 0 || aPosition.X > 1 || aPosition.Y > 1 )
{
if( !TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() &&
!TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() )
{
DBG_ERROR("DiagramWrapper::setPosition called with negative position -> automatic values are taken instead" );
uno::Any aEmpty;
xProp->setPropertyValue( C2U( "RelativePosition" ), aEmpty );
return;
}
//else: The saved didagram size does include the axis title sizes thus the position and size could be negative
DBG_ERROR("DiagramWrapper::setPosition called with a position out of range -> automatic values are taken instead" );
uno::Any aEmpty;
xProp->setPropertyValue( C2U( "RelativePosition" ), aEmpty );
return;
}
awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() );
@ -789,31 +764,14 @@ void SAL_CALL DiagramWrapper::setPosition( const awt::Point& aPosition )
aRelativePosition.Primary = double(aPosition.X)/double(aPageSize.Width);
aRelativePosition.Secondary = double(aPosition.Y)/double(aPageSize.Height);
xProp->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aRelativePosition) );
xProp->setPropertyValue( C2U( "PosSizeExcludeAxes" ), uno::makeAny(false) );
}
}
awt::Size SAL_CALL DiagramWrapper::getSize()
throw (uno::RuntimeException)
{
awt::Size aSize;
Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() );
if( xProp.is() )
{
bool bSet = false;
chart2::RelativeSize aRelativeSize;
uno::Any aASize( xProp->getPropertyValue( C2U( "RelativeSize" ) ) );
if(aASize>>=aRelativeSize)
{
awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() );
aSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*aPageSize.Width);
aSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*aPageSize.Height);
bSet = true;
}
if(!bSet)
aSize = m_spChart2ModelContact->GetDiagramSizeInclusive();
}
awt::Size aSize = ToSize( m_spChart2ModelContact->GetDiagramRectangleIncludingAxes() );
return aSize;
}
@ -821,6 +779,7 @@ void SAL_CALL DiagramWrapper::setSize( const awt::Size& aSize )
throw (beans::PropertyVetoException,
uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() );
if( xProp.is() )
{
@ -832,18 +791,14 @@ void SAL_CALL DiagramWrapper::setSize( const awt::Size& aSize )
if( aRelativeSize.Primary > 1 || aRelativeSize.Secondary > 1 )
{
if( !TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() &&
!TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() )
{
DBG_ERROR("DiagramWrapper::setSize called with sizes bigger than page -> automatic values are taken instead" );
uno::Any aEmpty;
xProp->setPropertyValue( C2U( "RelativeSize" ), aEmpty );
return;
}
//else: The saved didagram size does include the axis title sizes thus the position and size could be out of range
DBG_ERROR("DiagramWrapper::setSize called with sizes bigger than page -> automatic values are taken instead" );
uno::Any aEmpty;
xProp->setPropertyValue( C2U( "RelativeSize" ), aEmpty );
return;
}
xProp->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aRelativeSize) );
xProp->setPropertyValue( C2U( "PosSizeExcludeAxes" ), uno::makeAny(false) );
}
}
@ -854,6 +809,81 @@ OUString SAL_CALL DiagramWrapper::getShapeType()
return C2U( "com.sun.star.chart.Diagram" );
}
// ____ XDiagramPositioning ____
void SAL_CALL DiagramWrapper::setAutomaticDiagramPositioning() throw (uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY );
if( xDiaProps.is() )
{
xDiaProps->setPropertyValue( C2U( "RelativeSize" ), Any() );
xDiaProps->setPropertyValue( C2U( "RelativePosition" ), Any() );
}
}
::sal_Bool SAL_CALL DiagramWrapper::isAutomaticDiagramPositioning( ) throw (uno::RuntimeException)
{
uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY );
if( xDiaProps.is() )
{
Any aRelativeSize( xDiaProps->getPropertyValue( C2U( "RelativeSize" ) ) );
Any aRelativePosition( xDiaProps->getPropertyValue( C2U( "RelativePosition" ) ) );
if( aRelativeSize.hasValue() && aRelativePosition.hasValue() )
return false;
}
return true;
}
void SAL_CALL DiagramWrapper::setDiagramPositionExcludingAxes( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
DiagramHelper::setDiagramPositioning( m_spChart2ModelContact->getChartModel(), rPositionRect );
uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY );
if( xDiaProps.is() )
xDiaProps->setPropertyValue(C2U("PosSizeExcludeAxes"), uno::makeAny(true) );
}
::sal_Bool SAL_CALL DiagramWrapper::isExcludingDiagramPositioning() throw (uno::RuntimeException)
{
uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY );
if( xDiaProps.is() )
{
Any aRelativeSize( xDiaProps->getPropertyValue( C2U( "RelativeSize" ) ) );
Any aRelativePosition( xDiaProps->getPropertyValue( C2U( "RelativePosition" ) ) );
if( aRelativeSize.hasValue() && aRelativePosition.hasValue() )
{
sal_Bool bPosSizeExcludeAxes = false;
xDiaProps->getPropertyValue( C2U( "PosSizeExcludeAxes" ) ) >>= bPosSizeExcludeAxes;
return bPosSizeExcludeAxes;
}
}
return false;
}
awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionExcludingAxes( ) throw (uno::RuntimeException)
{
return m_spChart2ModelContact->GetDiagramRectangleExcludingAxes();
}
void SAL_CALL DiagramWrapper::setDiagramPositionIncludingAxes( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
DiagramHelper::setDiagramPositioning( m_spChart2ModelContact->getChartModel(), rPositionRect );
uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY );
if( xDiaProps.is() )
xDiaProps->setPropertyValue(C2U("PosSizeExcludeAxes"), uno::makeAny(false) );
}
awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionIncludingAxes( ) throw (uno::RuntimeException)
{
return m_spChart2ModelContact->GetDiagramRectangleIncludingAxes();
}
void SAL_CALL DiagramWrapper::setDiagramPositionIncludingAxesAndAxisTitles( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException)
{
ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() );
awt::Rectangle aRect( m_spChart2ModelContact->SubstractAxisTitleSizes(rPositionRect) );
DiagramWrapper::setDiagramPositionIncludingAxes( aRect );
}
::com::sun::star::awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionIncludingAxesAndAxisTitles( ) throw (::com::sun::star::uno::RuntimeException)
{
return m_spChart2ModelContact->GetDiagramRectangleIncludingTitle();
}
// ____ XAxisZSupplier ____
Reference<
drawing::XShape > SAL_CALL DiagramWrapper::getZAxisTitle()

View file

@ -30,12 +30,13 @@
#include "WrappedPropertySet.hxx"
#include "ServiceMacros.hxx"
#include "DiagramHelper.hxx"
#include <cppuhelper/implbase11.hxx>
#include <cppuhelper/implbase12.hxx>
#include <comphelper/uno3.hxx>
#include <cppuhelper/interfacecontainer.hxx>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/chart/XDiagramPositioning.hpp>
#include <com/sun/star/chart2/XDiagramProvider.hpp>
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
#include <com/sun/star/chart2/XChartTypeManager.hpp>
@ -61,7 +62,7 @@ namespace wrapper
class Chart2ModelContact;
class DiagramWrapper : public ::cppu::ImplInheritanceHelper11<
class DiagramWrapper : public ::cppu::ImplInheritanceHelper12<
WrappedPropertySet
, ::com::sun::star::chart::XDiagram
, ::com::sun::star::chart::XAxisZSupplier
@ -73,6 +74,7 @@ class DiagramWrapper : public ::cppu::ImplInheritanceHelper11<
, ::com::sun::star::lang::XServiceInfo
, ::com::sun::star::lang::XComponent
// , ::com::sun::star::lang::XEventListener
, ::com::sun::star::chart::XDiagramPositioning
, ::com::sun::star::chart2::XDiagramProvider
, ::com::sun::star::chart::XSecondAxisTitleSupplier
>
@ -209,6 +211,18 @@ public:
// virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source )
// throw (::com::sun::star::uno::RuntimeException);
// ____ XDiagramPositioning ____
virtual void SAL_CALL setAutomaticDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isAutomaticDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setDiagramPositionExcludingAxes( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isExcludingDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionExcludingAxes( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setDiagramPositionIncludingAxes( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionIncludingAxes( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setDiagramPositionIncludingAxesAndAxisTitles( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionIncludingAxesAndAxisTitles( ) throw (::com::sun::star::uno::RuntimeException);
// ____ XDiagramProvider ____
virtual ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XDiagram > SAL_CALL getDiagram()

View file

@ -46,7 +46,6 @@
////#define RBT_DOWNUP 3
////#define RBT_AUTOORDER 4
//#define TP_STAT 905
#define FL_TEXTBREAK 3
#define CBX_TEXTBREAK 2
#define CBX_TEXTOVERLAP 4

View file

@ -30,6 +30,7 @@
#include "DrawViewWrapper.hxx"
#include "chartview/DrawModelWrapper.hxx"
#include "ConfigurationAccess.hxx"
#include "macros.hxx"
#include <unotools/lingucfg.hxx>
#include <editeng/langitem.hxx>
@ -241,6 +242,14 @@ SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
if( pRet )
{
//ignore some special shapes
rtl::OUString aShapeName = pRet->GetName();
if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) )
{
pRet->SetMarkProtect( true );
return getHitObject( rPnt );
}
//3d objects need a special treatment
//because the simple PickObj method is not accurate in this case for performance reasons
E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet);

View file

@ -51,8 +51,7 @@ public:
static bool moveObject( const rtl::OUString& rObjectCID
, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel
, const ::com::sun::star::awt::Rectangle& rNewPositionAndSize
, const ::com::sun::star::awt::Rectangle& rPageRectangle
, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xChartView );
, const ::com::sun::star::awt::Rectangle& rPageRectangle );
};
//.............................................................................

View file

@ -87,27 +87,6 @@ const USHORT nGridWhichPairs[] =
0
};
const USHORT nChartWhichPairs[] =
{
SCHATTR_STYLE_START,SCHATTR_STYLE_END, // 59 - 68 sch/schattr.hxx
0
};
const USHORT nDiagramAreaWhichPairs[] =
{
XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx
XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx
0
};
const USHORT nAreaAndChartWhichPairs[] = // pairs for chart AND area
{
XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx
XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx
SCHATTR_STYLE_START,SCHATTR_STYLE_END, // 59 - 68 sch/schattr.hxx
0
};
const USHORT nLegendWhichPairs[] =
{
XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx

View file

@ -725,6 +725,8 @@ private:
void impl_SetMousePointer( const MouseEvent & rEvent );
void impl_ClearSelection();
void impl_switchDiagramPositioningToExcludingPositioning();
};
//.............................................................................

View file

@ -172,8 +172,7 @@ void SAL_CALL ChartController::executeDispatch_PositionAndSize()
bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
, m_aModel->getModel()
, awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight())
, m_xChartView );
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
if( bChanged )
aUndoGuard.commitAction();
}

View file

@ -50,6 +50,7 @@
#include "RegressionCurveHelper.hxx"
#include "ShapeController.hxx"
#include "DiagramHelper.hxx"
#include "ObjectNameProvider.hxx"
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
@ -242,6 +243,7 @@ void ChartController::executeDispatch_NewArrangement()
Reference< beans::XPropertyState > xState( xDiagram, uno::UNO_QUERY_THROW );
xState->setPropertyToDefault( C2U("RelativeSize"));
xState->setPropertyToDefault( C2U("RelativePosition"));
xState->setPropertyToDefault( C2U("PosSizeExcludeAxes"));
// 3d rotation
ThreeDHelper::set3DSettingsToDefault( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ) );
@ -468,6 +470,8 @@ void ChartController::impl_PasteShapes( SdrModel* pModel )
m_aSelection.applySelection( m_pDrawViewWrapper );
m_pDrawViewWrapper->EndUndo();
impl_switchDiagramPositioningToExcludingPositioning();
}
}
}
@ -514,6 +518,8 @@ void ChartController::impl_PasteStringAsTextShape( const OUString& rString, cons
m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) );
m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pObj ) );
m_pDrawViewWrapper->EndUndo();
impl_switchDiagramPositioningToExcludingPositioning();
}
}
catch ( const uno::Exception& ex )
@ -902,4 +908,14 @@ void ChartController::impl_ShapeControllerDispatch( const util::URL& rURL, const
}
}
void ChartController::impl_switchDiagramPositioningToExcludingPositioning()
{
UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription(
ActionDescriptionProvider::POS_SIZE,
ObjectNameProvider::getName( OBJECTTYPE_DIAGRAM)),
m_xUndoManager, m_aModel->getModel() );
if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_aModel->getModel(), true, true ) )
aUndoGuard.commitAction();
}
} // namespace chart

View file

@ -797,6 +797,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() )
{
pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND );
impl_switchDiagramPositioningToExcludingPositioning();
if ( pDrawViewWrapper->AreObjectsMarked() )
{
if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT )
@ -870,8 +871,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID()
, m_aModel->getModel()
, awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight())
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight())
, m_xChartView );
, awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) );
if( bChanged )
{
bDraggingDone = true;

View file

@ -141,8 +141,6 @@ bool PositionAndSizeHelper::moveObject( ObjectType eObjectType
{
//@todo decide wether x is primary or secondary
//xChartView
//set position:
chart2::RelativePosition aRelativePosition;
aRelativePosition.Anchor = drawing::Alignment_CENTER;
@ -169,7 +167,6 @@ bool PositionAndSizeHelper::moveObject( const rtl::OUString& rObjectCID
, const uno::Reference< frame::XModel >& xChartModel
, const awt::Rectangle& rNewPositionAndSize
, const awt::Rectangle& rPageRectangle
, uno::Reference< uno::XInterface > xChartView
)
{
ControllerLockGuard aLockedControllers( xChartModel );
@ -183,10 +180,6 @@ bool PositionAndSizeHelper::moveObject( const rtl::OUString& rObjectCID
xObjectProp = uno::Reference< beans::XPropertySet >( ObjectIdentifier::getDiagramForCID( rObjectCID, xChartModel ), uno::UNO_QUERY );
if(!xObjectProp.is())
return false;
//add axis title sizes to the diagram size
aNewPositionAndSize = ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle(
xChartModel, xChartView, rNewPositionAndSize );
}
return moveObject( eObjectType, xObjectProp, aNewPositionAndSize, rPageRectangle );
}

View file

@ -46,6 +46,13 @@
namespace chart
{
enum DiagramPositioningMode
{
DiagramPositioningMode_AUTO,
DiagramPositioningMode_EXCLUDING,
DiagramPositioningMode_INCLUDING
};
class OOO_DLLPUBLIC_CHARTTOOLS DiagramHelper
{
public:
@ -318,6 +325,19 @@ public:
const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XChartType >& xChartType );
static DiagramPositioningMode getDiagramPositioningMode( const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XDiagram > & xDiagram );
static bool setDiagramPositioning( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel,
const ::com::sun::star::awt::Rectangle& rPosRect /*100th mm*/ );
static ::com::sun::star::awt::Rectangle getDiagramRectangleFromModel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel );
static bool switchDiagramPositioningToExcludingPositioning( const ::com::sun::star::uno::Reference<
::com::sun::star::frame::XModel >& xChartModel
, bool bResetModifiedState //set model back to unchanged if it was unchanged before
, bool bConvertAlsoFromAutoPositioning );
private:
// not implemented
DiagramHelper();

View file

@ -68,6 +68,8 @@ public:
virtual ::com::sun::star::awt::Rectangle
getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect=false )=0;
virtual ::com::sun::star::awt::Rectangle getDiagramRectangleExcludingAxes()=0;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
getShapeForCID( const rtl::OUString& rObjectCID )=0;
@ -77,12 +79,20 @@ public:
static ExplicitValueProvider* getExplicitValueProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xChartView );
static ::com::sun::star::awt::Rectangle
calculateDiagramPositionAndSizeInclusiveTitle(
addAxisTitleSizes(
const ::com::sun::star::uno::Reference<
::com::sun::star::frame::XModel >& xChartModel
, const ::com::sun::star::uno::Reference<
::com::sun::star::uno::XInterface >& xChartView
, const ::com::sun::star::awt::Rectangle& rExclusivePositionAndSize );
, const ::com::sun::star::awt::Rectangle& rExcludingPositionAndSize );
static ::com::sun::star::awt::Rectangle
substractAxisTitleSizes(
const ::com::sun::star::uno::Reference<
::com::sun::star::frame::XModel >& xChartModel
, const ::com::sun::star::uno::Reference<
::com::sun::star::uno::XInterface >& xChartView
, const ::com::sun::star::awt::Rectangle& rPositionAndSizeIncludingTitles );
static sal_Int32 getExplicitNumberFormatKeyForAxis(
const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis

View file

@ -71,6 +71,7 @@ enum
{
PROP_DIAGRAM_REL_POS,
PROP_DIAGRAM_REL_SIZE,
PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS,
PROP_DIAGRAM_SORT_BY_X_VALUES,
PROP_DIAGRAM_CONNECT_BARS,
PROP_DIAGRAM_GROUP_BARS_PER_AXIS,
@ -100,6 +101,13 @@ void lcl_AddPropertiesToVector(
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEVOID ));
rOutProperties.push_back(
Property( C2U( "PosSizeExcludeAxes" ),
PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS,
::getBooleanCppuType(),
beans::PropertyAttribute::BOUND
| beans::PropertyAttribute::MAYBEDEFAULT ));
rOutProperties.push_back(
Property( C2U( "SortByXValues" ),
PROP_DIAGRAM_SORT_BY_X_VALUES,
@ -171,6 +179,7 @@ void lcl_AddPropertiesToVector(
void lcl_AddDefaultsToMap(
::chart::tPropertyValueMap & rOutMap )
{
::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS, true );
::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_SORT_BY_X_VALUES, false );
::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_CONNECT_BARS, false );
::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_GROUP_BARS_PER_AXIS, true );

View file

@ -39,8 +39,13 @@
#include "CommonConverters.hxx"
#include "ExplicitCategoriesProvider.hxx"
#include "servicenames_charttypes.hxx"
#include "ChartModelHelper.hxx"
#include "RelativePositionHelper.hxx"
#include "ControllerLockGuard.hxx"
#include <com/sun/star/chart/MissingValueTreatment.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XDiagramPositioning.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XChartTypeTemplate.hpp>
@ -49,10 +54,14 @@
#include <com/sun/star/chart2/InterpretedData.hpp>
#include <com/sun/star/chart2/AxisType.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/RelativeSize.hpp>
#include <unotools/saveopt.hxx>
#include <rtl/math.hxx>
#include <com/sun/star/util/XModifiable.hpp>
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using namespace ::std;
@ -1407,4 +1416,142 @@ sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment(
return nResult;
}
//static
DiagramPositioningMode DiagramHelper::getDiagramPositioningMode( const uno::Reference<
chart2::XDiagram > & xDiagram )
{
DiagramPositioningMode eMode = DiagramPositioningMode_AUTO;
uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY );
if( xDiaProps.is() )
{
RelativePosition aRelPos;
RelativeSize aRelSize;
if( (xDiaProps->getPropertyValue(C2U("RelativePosition")) >>= aRelPos ) &&
(xDiaProps->getPropertyValue(C2U("RelativeSize")) >>= aRelSize ) )
{
bool bPosSizeExcludeAxes=false;
xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxes;
if( bPosSizeExcludeAxes )
eMode = DiagramPositioningMode_EXCLUDING;
else
eMode = DiagramPositioningMode_INCLUDING;
}
}
return eMode;
}
void lcl_ensureRange0to1( double& rValue )
{
if(rValue<0.0)
rValue=0.0;
if(rValue>1.0)
rValue=1.0;
}
//static
bool DiagramHelper::setDiagramPositioning( const uno::Reference< frame::XModel >& xChartModel,
const awt::Rectangle& rPosRect /*100th mm*/ )
{
ControllerLockGuard aCtrlLockGuard( xChartModel );
bool bChanged = false;
awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
if( !xDiaProps.is() )
return bChanged;
RelativePosition aOldPos;
RelativeSize aOldSize;
xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aOldPos;
xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aOldSize;
RelativePosition aNewPos;
aNewPos.Anchor = drawing::Alignment_TOP_LEFT;
aNewPos.Primary = double(rPosRect.X)/double(aPageSize.Width);
aNewPos.Secondary = double(rPosRect.Y)/double(aPageSize.Height);
chart2::RelativeSize aNewSize;
aNewSize.Primary = double(rPosRect.Width)/double(aPageSize.Width);
aNewSize.Secondary = double(rPosRect.Height)/double(aPageSize.Height);
lcl_ensureRange0to1( aNewPos.Primary );
lcl_ensureRange0to1( aNewPos.Secondary );
lcl_ensureRange0to1( aNewSize.Primary );
lcl_ensureRange0to1( aNewSize.Secondary );
if( (aNewPos.Primary + aNewSize.Primary) > 1.0 )
aNewPos.Primary = 1.0 - aNewSize.Primary;
if( (aNewPos.Secondary + aNewSize.Secondary) > 1.0 )
aNewPos.Secondary = 1.0 - aNewSize.Secondary;
xDiaProps->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aNewPos) );
xDiaProps->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aNewSize) );
bChanged = (aOldPos.Anchor!=aNewPos.Anchor) ||
(aOldPos.Primary!=aNewPos.Primary) ||
(aOldPos.Secondary!=aNewPos.Secondary) ||
(aOldSize.Primary!=aNewSize.Primary) ||
(aOldSize.Secondary!=aNewSize.Secondary);
return bChanged;
}
//static
awt::Rectangle DiagramHelper::getDiagramRectangleFromModel( const uno::Reference< frame::XModel >& xChartModel )
{
awt::Rectangle aRet(-1,-1,-1,-1);
uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY );
if( !xDiaProps.is() )
return aRet;
awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) );
RelativePosition aRelPos;
RelativeSize aRelSize;
xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aRelPos;
xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aRelSize;
awt::Size aAbsSize(
aRelSize.Primary * aPageSize.Width,
aRelSize.Secondary * aPageSize.Height );
awt::Point aAbsPos(
static_cast< sal_Int32 >( aRelPos.Primary * aPageSize.Width ),
static_cast< sal_Int32 >( aRelPos.Secondary * aPageSize.Height ));
awt::Point aAbsPosLeftTop = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos, aAbsSize, aRelPos.Anchor );
aRet = awt::Rectangle(aAbsPosLeftTop.X, aAbsPosLeftTop.Y, aAbsSize.Width, aAbsSize.Height );
return aRet;
}
//static
bool DiagramHelper::switchDiagramPositioningToExcludingPositioning(
const uno::Reference< frame::XModel >& xChartModel
, bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning )
{
//return true if something was changed
const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
if( nCurrentODFVersion == SvtSaveOptions::ODFVER_LATEST )//#i100778# todo: change this dependent on fileformat evolution
{
uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartModel, uno::UNO_QUERY ) ;
if( xOldDoc.is() )
{
uno::Reference< ::com::sun::star::chart::XDiagramPositioning > xDiagramPositioning( xOldDoc->getDiagram(), uno::UNO_QUERY );
if( xDiagramPositioning.is() && ( bConvertAlsoFromAutoPositioning || !xDiagramPositioning->isAutomaticDiagramPositioning() )
&& !xDiagramPositioning->isExcludingDiagramPositioning() )
{
ControllerLockGuard aCtrlLockGuard( xChartModel );
uno::Reference< util::XModifiable > xModifiable( xChartModel, uno::UNO_QUERY );
bool bModelWasModified = xModifiable.is() && xModifiable->isModified();
xDiagramPositioning->setDiagramPositionExcludingAxes( xDiagramPositioning->calculateDiagramPositionExcludingAxes() );
if(bResetModifiedState && !bModelWasModified && xModifiable.is() )
xModifiable->setModified(sal_False);
return true;
}
}
}
return false;
}
} // namespace chart

View file

@ -121,10 +121,12 @@ bool PiePositionHelper::getInnerAndOuterRadius( double fCategoryX
//-----------------------------------------------------------------------------
PieChart::PieChart( const uno::Reference<XChartType>& xChartTypeModel
, sal_Int32 nDimensionCount )
, sal_Int32 nDimensionCount
, bool bExcludingPositioning )
: VSeriesPlotter( xChartTypeModel, nDimensionCount )
, m_pPosHelper( new PiePositionHelper( NormalAxis_Z, (m_nDimension==3)?0.0:90.0 ) )
, m_bUseRings(false)
, m_bSizeExcludesLabelsAndExplodedSegments(bExcludingPositioning)
{
::rtl::math::setNan(&m_fMaxOffset);
@ -181,6 +183,11 @@ bool PieChart::keepAspectRatio() const
return true;
}
bool PieChart::shouldSnapRectToUsedArea()
{
return true;
}
//-----------------------------------------------------------------
// lang::XServiceInfo
//-----------------------------------------------------------------
@ -273,18 +280,21 @@ double PieChart::getMaxOffset()
if(fExplodePercentage>m_fMaxOffset)
m_fMaxOffset=fExplodePercentage;
uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
if( xSeriesProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
if(!m_bSizeExcludesLabelsAndExplodedSegments)
{
for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
uno::Sequence< sal_Int32 > aAttributedDataPointIndexList;
if( xSeriesProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList )
{
uno::Reference< beans::XPropertySet > xPointProp( pSeries->getPropertiesOfPoint(aAttributedDataPointIndexList[nN]) );
if(xPointProp.is())
for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;)
{
fExplodePercentage=0.0;
xPointProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage;
if(fExplodePercentage>m_fMaxOffset)
m_fMaxOffset=fExplodePercentage;
uno::Reference< beans::XPropertySet > xPointProp( pSeries->getPropertiesOfPoint(aAttributedDataPointIndexList[nN]) );
if(xPointProp.is())
{
fExplodePercentage=0.0;
xPointProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage;
if(fExplodePercentage>m_fMaxOffset)
m_fMaxOffset=fExplodePercentage;
}
}
}
}
@ -396,7 +406,8 @@ void PieChart::createShapes()
for( nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++ )
{
double fLogicInnerRadius, fLogicOuterRadius;
bool bIsVisible = m_pPosHelper->getInnerAndOuterRadius( fSlotX+1.0, fLogicInnerRadius, fLogicOuterRadius, m_bUseRings, getMaxOffset() );
double fOffset = getMaxOffset();
bool bIsVisible = m_pPosHelper->getInnerAndOuterRadius( fSlotX+1.0, fLogicInnerRadius, fLogicOuterRadius, m_bUseRings, fOffset );
if( !bIsVisible )
continue;

View file

@ -46,7 +46,7 @@ class PieChart : public VSeriesPlotter
public:
PieChart( const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XChartType >& xChartTypeModel
, sal_Int32 nDimensionCount );
, sal_Int32 nDimensionCount, bool bExcludingPositioning );
virtual ~PieChart();
//-------------------------------------------------------------------------
@ -72,6 +72,7 @@ public:
//-------------------
virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const;
virtual bool keepAspectRatio() const;
virtual bool shouldSnapRectToUsedArea();
//MinimumAndMaximumSupplier
virtual double getMinimumX();
@ -113,6 +114,7 @@ struct PieLabelInfo;
private: //member
PiePositionHelper* m_pPosHelper;
bool m_bUseRings;
bool m_bSizeExcludesLabelsAndExplodedSegments;
struct PieLabelInfo
{

View file

@ -1744,6 +1744,13 @@ bool VSeriesPlotter::WantToPlotInFrontOfAxisLine()
return ChartTypeHelper::isSeriesInFrontOfAxisLine( m_xChartTypeModel );
}
bool VSeriesPlotter::shouldSnapRectToUsedArea()
{
if( m_nDimension == 3 )
return false;
return true;
}
Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries(
LegendExpansion eLegendExpansion
, const Reference< beans::XPropertySet >& xTextProperties
@ -2066,7 +2073,8 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForCh
//static
VSeriesPlotter* VSeriesPlotter::createSeriesPlotter(
const uno::Reference<XChartType>& xChartTypeModel
, sal_Int32 nDimensionCount )
, sal_Int32 nDimensionCount
, bool bExcludingPositioning )
{
rtl::OUString aChartType = xChartTypeModel->getChartType();
@ -2085,7 +2093,7 @@ VSeriesPlotter* VSeriesPlotter::createSeriesPlotter(
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) )
pRet = new BubbleChart(xChartTypeModel,nDimensionCount);
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE) )
pRet = new PieChart(xChartTypeModel,nDimensionCount);
pRet = new PieChart(xChartTypeModel,nDimensionCount, bExcludingPositioning );
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_NET) )
pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,true,new PolarPlottingPositionHelper(),true,false,1,drawing::Direction3D(1,1,1) );
else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) )

View file

@ -49,6 +49,8 @@
#include <com/sun/star/lang/XTypeProvider.hpp>
// header for class SvxShape
#include <svx/unoshape.hxx>
// header for GetSdrObjectFromXShape
#include <svx/unoapi.hxx>
// header for class E3dScene
#include <svx/scene3d.hxx>
#include <rtl/math.hxx>
@ -179,6 +181,8 @@ void VDiagram::createShapes_2d()
uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xLogicTarget);
m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY );
uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,C2U("PlotAreaExcludingAxes")) );
//create independent group shape as container for datapoints and such things
{
uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,C2U("testonly;CooContainer=XXX_CID"));
@ -195,8 +199,7 @@ void VDiagram::createShapes_2d()
"com.sun.star.drawing.RectangleShape" ) ), uno::UNO_QUERY );
//m_xWall2D->setPosition(m_aAvailablePosIncludingAxes);
//m_xWall2D->setSize(m_aAvailableSizeIncludingAxes);
uno::Reference< drawing::XShapes > xShapes( m_xCoordinateRegionShape, uno::UNO_QUERY );
xShapes->add(m_xWall2D);
xGroupForWall->add(m_xWall2D);
uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY );
if( xProp.is())
{
@ -518,6 +521,7 @@ void VDiagram::createShapes_3d()
m_xOuterGroupShape = uno::Reference< drawing::XShape >(
m_xShapeFactory->createInstance( C2U(
"com.sun.star.drawing.Shape3DSceneObject" ) ), uno::UNO_QUERY );
ShapeFactory::setShapeName( m_xOuterGroupShape, C2U("PlotAreaExcludingAxes") );
m_xLogicTarget->add(m_xOuterGroupShape);
uno::Reference< drawing::XShapes > xOuterGroup_Shapes =

View file

@ -264,7 +264,8 @@ public:
static VSeriesPlotter* createSeriesPlotter( const ::com::sun::star::uno::Reference<
::com::sun::star::chart2::XChartType >& xChartTypeModel
, sal_Int32 nDimensionCount );
, sal_Int32 nDimensionCount
, bool bExcludingPositioning = false /*for pie and donut charts labels and exploded segments are excluded from the given size*/);
sal_Int32 getPointCount() const;
@ -293,6 +294,7 @@ public:
virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize );
bool WantToPlotInFrontOfAxisLine();
virtual bool shouldSnapRectToUsedArea();
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------

View file

@ -37,6 +37,7 @@
#include <editeng/brshitem.hxx>
#include <editeng/sizeitem.hxx>
#include <svl/stritem.hxx>
#include <svl/rectitem.hxx>
#include <svl/ilstitem.hxx>
#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>

View file

@ -169,6 +169,7 @@ ChartView::ChartView(
, m_nScaleYNumerator(1)
, m_nScaleYDenominator(1)
, m_bSdrViewIsInEditMode(sal_False)
, m_aResultingDiagramRectangleExcludingAxes(0,0,0,0)
{
}
@ -313,7 +314,7 @@ uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aF
if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) )
return aRet;
impl_updateView();
update();
SvMemoryStream aStream( 1024, 1024 );
utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream );
@ -681,7 +682,8 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter(
if(nT==0)
m_bChartTypeUsesShiftedXAxisTicksPerDefault = ChartTypeHelper::shiftTicksAtXAxisPerDefault( xChartType );
VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount );
bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram );
VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning );
if( !pPlotter )
continue;
m_aSeriesPlotterList.push_back( pPlotter );
@ -1166,7 +1168,7 @@ drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio()
namespace
{
bool lcl_resizeAfterCompleteCreation( const uno::Reference< XDiagram >& xDiagram )
bool lcl_IsPieOrDonut( const uno::Reference< XDiagram >& xDiagram )
{
//special treatment for pie charts
//the size is checked after complete creation to get the datalabels into the given space
@ -1324,16 +1326,23 @@ sal_Int16 lcl_getDefaultWritingModeFromPool( ::boost::shared_ptr< DrawModelWrapp
} //end anonymous namespace
//------------ create complete diagram shape (inclusive axis and series)
void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer
awt::Rectangle ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer
, const uno::Reference< drawing::XShapes>& xDiagramPlusAxes_Shapes
, const awt::Point& rAvailablePos
, const awt::Size& rAvailableSize
, const awt::Size& rPageSize )
, const awt::Size& rPageSize
, bool bUseFixedInnerSize
, const uno::Reference< drawing::XShape>& xDiagram_MarkHandles /*needs to be resized to fit the result*/
)
{
//return the used rectangle
awt::Rectangle aUsedOuterRect( rAvailablePos.X, rAvailablePos.Y, 0, 0 );
// sal_Int32 nDiagramIndex = 0;//todo if more than one diagam is supported
uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
if( !xDiagram.is())
return;
return aUsedOuterRect;
sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram );
if(!nDimensionCount)
@ -1389,7 +1398,8 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
aVDiagram.init(xDiagramPlusAxes_Shapes,xDiagramPlusAxes_Shapes,m_xShapeFactory);
aVDiagram.createShapes(rAvailablePos,rAvailableSize);
xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion();
aVDiagram.reduceToMimimumSize();
if( !bUseFixedInnerSize )
aVDiagram.reduceToMimimumSize();
}
uno::Reference< drawing::XShapes > xTextTargetShapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxes_Shapes) );
@ -1410,19 +1420,21 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
//calculate resulting size respecting axis label layout and fontscaling
uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY );
::basegfx::B2IRectangle aConsumedOuterRect;
//use first coosys only so far; todo: calculate for more than one coosys if we have more in future
//todo: this is just a workaround at the moment for pie and donut labels
if( !lcl_resizeAfterCompleteCreation(xDiagram) && rVCooSysList.size() > 0 )
bool bIsPieOrDonut = lcl_IsPieOrDonut(xDiagram);
if( !bIsPieOrDonut && rVCooSysList.size() > 0 )
{
uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY );
::basegfx::B2IRectangle aFirstConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) );
VCoordinateSystem* pVCooSys = rVCooSysList[0];
pVCooSys->createMaximumAxesLabels();
::basegfx::B2IRectangle aConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) );
::basegfx::B2IRectangle aNewInnerRect( aVDiagram.adjustInnerSize( aConsumedOuterRect ) );
aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) );
::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
if( !bUseFixedInnerSize )
aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
createTransformationSceneToScreen( aNewInnerRect ) ));
@ -1445,13 +1457,13 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
bLessSpaceConsumedThanExpected = true;
}
if( bLessSpaceConsumedThanExpected )
if( bLessSpaceConsumedThanExpected && !bUseFixedInnerSize )
{
aVDiagram.adjustInnerSize( aConsumedOuterRect );
pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix(
createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) ));
pVCooSys->updatePositions();
}
pVCooSys->updatePositions();//todo: logically this belongs to the condition above, but it seems also to be neccessary to give the axes group shapes the right bounding rects for hit test - probably caused by bug i106183 -> check again if fixed
}
//create axes and grids for the final size
@ -1481,7 +1493,7 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
else
{
xSeriesTarget = xSeriesTargetBehindAxis;
DBG_ASSERT( !lcl_resizeAfterCompleteCreation(xDiagram), "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
DBG_ASSERT( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" );
}
pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,m_xShapeFactory,aCID );
pSeriesPlotter->setPageReferenceSize( rPageSize );
@ -1500,15 +1512,15 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped();
}
//recreate with corrected sizes if requested
if( lcl_resizeAfterCompleteCreation(xDiagram) )
//recreate all with corrected sizes if requested
if( bIsPieOrDonut )
{
m_bPointsWereSkipped = false;
uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY );
::basegfx::B2IRectangle aConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) );
::basegfx::B2IRectangle aNewInnerRect( aVDiagram.adjustInnerSize( aConsumedOuterRect ) );
aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) );
::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() );
if( !bUseFixedInnerSize )
aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect );
for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; aPlotterIter++ )
{
@ -1565,6 +1577,63 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo
pSeriesPlotter->rearrangeLabelToAvoidOverlapIfRequested( rPageSize );
}
}
if( bUseFixedInnerSize )
{
//if( !bIsPieOrDonut )
// aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) );
aUsedOuterRect = awt::Rectangle( aConsumedOuterRect.getMinX(), aConsumedOuterRect.getMinY(), aConsumedOuterRect.getWidth(), aConsumedOuterRect.getHeight() );
}
else
aUsedOuterRect = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height );
bool bSnapRectToUsedArea = false;
for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; aPlotterIter++ )
{
VSeriesPlotter* pSeriesPlotter = *aPlotterIter;
bSnapRectToUsedArea = pSeriesPlotter->shouldSnapRectToUsedArea();
if(bSnapRectToUsedArea)
break;
}
if(bSnapRectToUsedArea)
{
if( bUseFixedInnerSize )
m_aResultingDiagramRectangleExcludingAxes = getRectangleOfObject( C2U("PlotAreaExcludingAxes") );
else
{
::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
}
}
else
{
if( bUseFixedInnerSize )
m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height );
else
{
::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle();
m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() );
}
}
if( xDiagram_MarkHandles.is() )
{
awt::Point aPos(rAvailablePos);
awt::Size aSize(rAvailableSize);
bool bPosSizeExcludeAxesProperty = true;
uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY_THROW );
if( xDiaProps.is() )
xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxesProperty;
if( bUseFixedInnerSize || bPosSizeExcludeAxesProperty )
{
aPos = awt::Point( m_aResultingDiagramRectangleExcludingAxes.X, m_aResultingDiagramRectangleExcludingAxes.Y );
aSize = awt::Size( m_aResultingDiagramRectangleExcludingAxes.Width, m_aResultingDiagramRectangleExcludingAxes.Height );
}
xDiagram_MarkHandles->setPosition( aPos );
xDiagram_MarkHandles->setSize( aSize );
}
return aUsedOuterRect;
}
//-------------------------------------------------------------
@ -1622,6 +1691,12 @@ uno::Reference< drawing::XShape > ChartView::getShapeForCID( const rtl::OUString
return 0;
}
awt::Rectangle ChartView::getDiagramRectangleExcludingAxes()
{
impl_updateView();
return m_aResultingDiagramRectangleExcludingAxes;
}
awt::Rectangle ChartView::getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect )
{
impl_updateView();
@ -1645,7 +1720,10 @@ awt::Rectangle ChartView::getRectangleOfObject( const rtl::OUString& rObjectCID,
SdrObjList* pRootList = pRootSdrObject->GetSubList();
if( pRootList )
{
SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( C2U("MarkHandles"), pRootList );
OUString aShapeName = C2U("MarkHandles");
if( eObjectType == OBJECTTYPE_DIAGRAM )
aShapeName = C2U("PlotAreaIncludingAxes");
SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList );
if( pShape )
xShape = uno::Reference< drawing::XShape >( pShape->getUnoShape(), uno::UNO_QUERY);
}
@ -1933,12 +2011,12 @@ sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabe
}
//static
awt::Rectangle ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle(
awt::Rectangle ExplicitValueProvider::addAxisTitleSizes(
const Reference< frame::XModel >& xChartModel
, const Reference< uno::XInterface >& xChartView
, const awt::Rectangle& rExclusivePositionAndSize )
, const awt::Rectangle& rExcludingPositionAndSize )
{
awt::Rectangle aRet(rExclusivePositionAndSize);
awt::Rectangle aRet(rExcludingPositionAndSize);
//add axis title sizes to the diagram size
uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) );
@ -2000,6 +2078,74 @@ awt::Rectangle ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTi
return aRet;
}
//static
awt::Rectangle ExplicitValueProvider::substractAxisTitleSizes(
const Reference< frame::XModel >& xChartModel
, const Reference< uno::XInterface >& xChartView
, const awt::Rectangle& rPositionAndSizeIncludingTitles )
{
awt::Rectangle aRet(rPositionAndSizeIncludingTitles);
//add axis title sizes to the diagram size
uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) );
uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xChartModel ) );
uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xChartModel ) );
uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xChartModel ) );
if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() )
{
ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView);
if( pExplicitValueProvider )
{
//detect wether x axis points into x direction or not
if( lcl_getPropertySwapXAndYAxis( ChartModelHelper::findDiagram( xChartModel ) ) )
{
std::swap( xTitle_Height, xTitle_Width );
std::swap( xSecondTitle_Height, xSecondTitle_Width );
}
sal_Int32 nTitleSpaceWidth = 0;
sal_Int32 nTitleSpaceHeight = 0;
sal_Int32 nSecondTitleSpaceWidth = 0;
sal_Int32 nSecondTitleSpaceHeight = 0;
if( xTitle_Height.is() )
{
rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, xChartModel ) );
nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
if( nTitleSpaceHeight )
nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
}
if( xTitle_Width.is() )
{
rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, xChartModel ) );
nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
if(nTitleSpaceWidth)
nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
}
if( xSecondTitle_Height.is() )
{
rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, xChartModel ) );
nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height;
if( nSecondTitleSpaceHeight )
nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
}
if( xSecondTitle_Width.is() )
{
rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, xChartModel ) );
nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width;
if( nSecondTitleSpaceWidth )
nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
}
aRet.X += nTitleSpaceWidth;
aRet.Y += nSecondTitleSpaceHeight;
aRet.Width -= (nTitleSpaceWidth + nSecondTitleSpaceWidth);
aRet.Height -= (nTitleSpaceHeight + nSecondTitleSpaceHeight);
}
}
return aRet;
}
double lcl_getPageLayoutDistancePercentage()
{
return 0.02;
@ -2010,9 +2156,10 @@ bool getAvailablePosAndSizeForDiagram(
, const awt::Rectangle& rSpaceLeft
, const awt::Size & rPageSize
, const uno::Reference< XDiagram > & xDiagram
, VTitle* pXTitle, VTitle* pYTitle
, VTitle* pSecondXTitle, VTitle* pSecondYTitle )
, bool& bUseFixedInnerSize )
{
bUseFixedInnerSize = false;
//@todo: we need a size dependent on the axis labels
awt::Rectangle aRemainingSpace(rSpaceLeft);
{
@ -2028,7 +2175,9 @@ bool getAvailablePosAndSizeForDiagram(
uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY);
bool bMakeRoomForTitle = false;
bool bPosSizeExcludeAxes = false;
if( xProp.is() )
xProp->getPropertyValue( C2U( "PosSizeExcludeAxes" ) ) >>= bPosSizeExcludeAxes;
//size:
::com::sun::star::chart2::RelativeSize aRelativeSize;
@ -2036,7 +2185,7 @@ bool getAvailablePosAndSizeForDiagram(
{
rOutAvailableDiagramSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height);
rOutAvailableDiagramSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width);
bMakeRoomForTitle = true;
bUseFixedInnerSize = bPosSizeExcludeAxes;
}
else
rOutAvailableDiagramSize = awt::Size(aRemainingSpace.Width,aRemainingSpace.Height);
@ -2054,7 +2203,7 @@ bool getAvailablePosAndSizeForDiagram(
rOutPos = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject(
awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY))
, rOutAvailableDiagramSize, aRelativePosition.Anchor );
bMakeRoomForTitle = true;
bUseFixedInnerSize = bPosSizeExcludeAxes;
}
else
rOutPos = awt::Point(aRemainingSpace.X,aRemainingSpace.Y);
@ -2067,52 +2216,6 @@ bool getAvailablePosAndSizeForDiagram(
rOutAvailableDiagramSize.Width = rPageSize.Width - rOutPos.X;
}
if( bMakeRoomForTitle )
{
sal_Int32 nTitleSpaceWidth = 0;
sal_Int32 nTitleSpaceHeight = 0;
sal_Int32 nSecondTitleSpaceWidth = 0;
sal_Int32 nSecondTitleSpaceHeight = 0;
{
//todo detect wether x axis points into x direction or not
//detect wether x axis points into x direction or not
if( lcl_getPropertySwapXAndYAxis( xDiagram ) )
{
std::swap( pXTitle, pYTitle );
std::swap( pSecondXTitle, pSecondYTitle );
}
if( pXTitle )
{
nTitleSpaceHeight = pXTitle->getFinalSize().Height;
if(nTitleSpaceHeight)
nTitleSpaceHeight+=lcl_getDiagramTitleSpace();
}
if( pYTitle )
{
nTitleSpaceWidth = pYTitle->getFinalSize().Width;
if(nTitleSpaceWidth)
nTitleSpaceWidth+=lcl_getDiagramTitleSpace();
}
if( pSecondXTitle)
{
nSecondTitleSpaceHeight += pSecondXTitle->getFinalSize().Height;
if(nSecondTitleSpaceHeight)
nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace();
}
if( pSecondYTitle)
{
nSecondTitleSpaceWidth += pSecondYTitle->getFinalSize().Width;
if(nSecondTitleSpaceWidth)
nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace();
}
}
rOutAvailableDiagramSize.Height -= nTitleSpaceHeight + nSecondTitleSpaceHeight;
rOutAvailableDiagramSize.Width -= nTitleSpaceWidth + nSecondTitleSpaceWidth;
rOutPos.X += nTitleSpaceWidth;
rOutPos.Y += nSecondTitleSpaceHeight;
}
return true;
}
@ -2154,6 +2257,19 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment
break;
}
sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2;
sal_Int32 nMaxX = rPageSize.Width - aTitleSize.Width/2;
sal_Int32 nMinX = aTitleSize.Width/2;
sal_Int32 nMinY = aTitleSize.Height/2;
if( aNewPosition.Y > nMaxY )
aNewPosition.Y = nMaxY;
if( aNewPosition.X > nMaxX )
aNewPosition.X = nMaxX;
if( aNewPosition.Y < nMinY )
aNewPosition.Y = nMinY;
if( aNewPosition.X < nMinX )
aNewPosition.X = nMinX;
pVTitle->changePosition( aNewPosition );
}
@ -2478,6 +2594,7 @@ void ChartView::createShapes()
if( impl_AddInDrawsAllByItself() )
return;
m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle(0,0,0,0);
impl_deleteCoordinateSystems();
if( m_pDrawModelWrapper )
{
@ -2519,9 +2636,15 @@ void ChartView::createShapes()
uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) );
rtl::OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) ) );//todo: other index if more than one diagram is possible
uno::Reference< drawing::XShapes > xDiagramPlusAxesPlusMarkHandlesGroup_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xPageShapes,aDiagramCID) );
uno::Reference< drawing::XShape > xDiagramPlusAxes_MarkHandles( ShapeFactory(m_xShapeFactory).createInvisibleRectangle(
uno::Reference< drawing::XShape > xDiagram_MarkHandles( ShapeFactory(m_xShapeFactory).createInvisibleRectangle(
xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) );
ShapeFactory::setShapeName( xDiagramPlusAxes_MarkHandles, C2U("MarkHandles") );
ShapeFactory::setShapeName( xDiagram_MarkHandles, C2U("MarkHandles") );
uno::Reference< drawing::XShape > xDiagram_OuterRect( ShapeFactory(m_xShapeFactory).createInvisibleRectangle(
xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) );
ShapeFactory::setShapeName( xDiagram_OuterRect, C2U("PlotAreaIncludingAxes") );
uno::Reference< drawing::XShapes > xDiagramPlusAxes_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes ) );
//------------ create some titles
@ -2606,21 +2729,22 @@ void ChartView::createShapes()
//------------ create complete diagram shape (inclusive axis and series)
awt::Point aAvailablePosDia;
awt::Size aAvailableSizeForDiagram;
if( getAvailablePosAndSizeForDiagram( aAvailablePosDia, aAvailableSizeForDiagram, aRemainingSpace, aPageSize, ChartModelHelper::findDiagram( m_xChartModel )
, apVTitle_X.get(), apVTitle_Y.get(), apVTitle_SecondX.get(), apVTitle_SecondY.get() ) )
bool bUseFixedInnerSize = false;
if( getAvailablePosAndSizeForDiagram( aAvailablePosDia, aAvailableSizeForDiagram, aRemainingSpace, aPageSize
, ChartModelHelper::findDiagram( m_xChartModel ), bUseFixedInnerSize ) )
{
impl_createDiagramAndContent( aSeriesPlotterContainer
awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent( aSeriesPlotterContainer
, xDiagramPlusAxes_Shapes
, aAvailablePosDia ,aAvailableSizeForDiagram, aPageSize );
, aAvailablePosDia ,aAvailableSizeForDiagram, aPageSize, bUseFixedInnerSize, xDiagram_MarkHandles );
if(xDiagramPlusAxes_MarkHandles.is())
if( xDiagram_OuterRect.is() )
{
xDiagramPlusAxes_MarkHandles->setPosition( aAvailablePosDia );
xDiagramPlusAxes_MarkHandles->setSize( aAvailableSizeForDiagram );
xDiagram_OuterRect->setPosition( awt::Point( aUsedOuterRect.X, aUsedOuterRect.Y ) );
xDiagram_OuterRect->setSize( awt::Size( aUsedOuterRect.Width, aUsedOuterRect.Height ) );
}
//correct axis title position
awt::Rectangle aDiagramPlusAxesRect(aAvailablePosDia.X,aAvailablePosDia.Y,aAvailableSizeForDiagram.Width,aAvailableSizeForDiagram.Height);
awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect );
if(bAutoPosition_XTitle)
changePositionOfAxisTitle( apVTitle_X.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, aPageSize );
if(bAutoPosition_YTitle)
@ -2691,17 +2815,6 @@ void ChartView::impl_updateView()
//create chart view
{
/*
::vos::OGuard aGuard( Application::GetSolarMutex());
while( m_bViewDirty )
{
createShapes();
m_bViewDirty = m_bViewUpdatePending;
m_bViewUpdatePending = false;
m_bInViewUpdate = false;
}
*/
m_bViewDirty = false;
m_bViewUpdatePending = false;
createShapes();
@ -2871,6 +2984,14 @@ void SAL_CALL ChartView::removeModeChangeApproveListener( const uno::Reference<
void SAL_CALL ChartView::update() throw (uno::RuntimeException)
{
impl_updateView();
//#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this):
//Although in general it is a bad idea to change the model from within the view this is exceptionally the best place to do this special conversion.
//When a view update is requested (what happens for creating the metafile or displaying
//the chart in edit mode or printing) it is most likely that all necessary informations are available - like the underlying spreadsheet data for example.
//Those data is important for the correct axis lable sizes which are needed during conversion.
if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_xChartModel, true, false ) )
impl_updateView();
}
// ____ XPropertySet ____

View file

@ -110,6 +110,8 @@ public:
virtual ::com::sun::star::awt::Rectangle getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect=false );
virtual ::com::sun::star::awt::Rectangle getDiagramRectangleExcludingAxes();
::boost::shared_ptr< DrawModelWrapper > getDrawModelWrapper();
// ___XTransferable___
@ -196,11 +198,13 @@ private: //methods
void impl_updateView();
void impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer
::com::sun::star::awt::Rectangle impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer
, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes>& xDiagramPlusAxes_Shapes
, const ::com::sun::star::awt::Point& rAvailablePos
, const ::com::sun::star::awt::Size& rAvailableSize
, const ::com::sun::star::awt::Size& rPageSize );
, const ::com::sun::star::awt::Size& rPageSize
, bool bUseFixedInnerSize
, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& xDiagram_MarkHandles );
private: //member
@ -246,6 +250,8 @@ private: //member
sal_Int32 m_nScaleYDenominator;
sal_Bool m_bSdrViewIsInEditMode;
::com::sun::star::awt::Rectangle m_aResultingDiagramRectangleExcludingAxes;
};
//.............................................................................

View file

@ -39,6 +39,8 @@
#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart/MissingValueTreatment.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XDiagramPositioning.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
@ -52,6 +54,9 @@
#include <com/sun/star/chart2/CurveStyle.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/LegendExpansion.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/StackingDirection.hpp>
#include <com/sun/star/chart2/TickmarkStyle.hpp>
@ -75,38 +80,47 @@ using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
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::beans::XPropertySet;
using ::com::sun::star::i18n::XBreakIterator;
using ::com::sun::star::frame::XModel;
using ::com::sun::star::drawing::XShape;
using ::com::sun::star::drawing::XShapes;
using ::com::sun::star::chart2::XChartDocument;
using ::com::sun::star::chart2::XDiagram;
using ::com::sun::star::chart2::XCoordinateSystemContainer;
using ::com::sun::star::chart2::XCoordinateSystem;
using ::com::sun::star::chart2::XChartTypeContainer;
using ::com::sun::star::chart2::XChartType;
using ::com::sun::star::chart2::XDataSeriesContainer;
using ::com::sun::star::chart2::XDataSeries;
using ::com::sun::star::chart2::XRegressionCurveContainer;
using ::com::sun::star::chart2::XRegressionCurve;
using ::com::sun::star::chart2::XAxis;
using ::com::sun::star::chart2::XScaling;
using ::com::sun::star::chart2::ScaleData;
using ::com::sun::star::chart2::IncrementData;
using ::com::sun::star::chart2::RelativePosition;
using ::com::sun::star::chart2::ScaleData;
using ::com::sun::star::chart2::SubIncrement;
using ::com::sun::star::chart2::XLegend;
using ::com::sun::star::chart2::XTitled;
using ::com::sun::star::chart2::XTitle;
using ::com::sun::star::chart2::XFormattedString;
using ::com::sun::star::chart2::XAxis;
using ::com::sun::star::chart2::XChartDocument;
using ::com::sun::star::chart2::XChartTypeContainer;
using ::com::sun::star::chart2::XColorScheme;
using ::com::sun::star::chart2::XCoordinateSystem;
using ::com::sun::star::chart2::XCoordinateSystemContainer;
using ::com::sun::star::chart2::XChartType;
using ::com::sun::star::chart2::XDataSeries;
using ::com::sun::star::chart2::XDataSeriesContainer;
using ::com::sun::star::chart2::XDiagram;
using ::com::sun::star::chart2::XFormattedString;
using ::com::sun::star::chart2::XLegend;
using ::com::sun::star::chart2::XRegressionCurve;
using ::com::sun::star::chart2::XRegressionCurveContainer;
using ::com::sun::star::chart2::XScaling;
using ::com::sun::star::chart2::XTitle;
using ::com::sun::star::chart2::XTitled;
using ::com::sun::star::chart2::data::XDataSequence;
using ::com::sun::star::chart2::data::XDataSource;
using ::com::sun::star::chart2::data::XLabeledDataSequence;
using ::com::sun::star::chart2::data::XDataSequence;
using ::formula::FormulaGrammar;
using ::formula::FormulaToken;
namespace cssc = ::com::sun::star::chart;
namespace cssc2 = ::com::sun::star::chart2;
// Helpers ====================================================================
namespace {
@ -160,13 +174,15 @@ bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogSc
// Common =====================================================================
/** Stores global data needed in various classes of the Chart export filter. */
class XclExpChRootData : public XclChRootData
struct XclExpChRootData : public XclChRootData
{
public:
explicit XclExpChRootData( XclExpChChart* pChartData );
typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
/** Returns a reference to the parent chart data object. */
inline XclExpChChart& GetChartData() const { return *mpChartData; }
XclExpChChart& mrChartData; /// The chart data object.
XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out.
XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out.
inline explicit XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {}
/** Registers a new future record level. */
void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock );
@ -174,22 +190,10 @@ public:
void InitializeFutureRecBlock( XclExpStream& rStrm );
/** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */
void FinalizeFutureRecBlock( XclExpStream& rStrm );
private:
typedef ::std::vector< XclChFrBlock > XclChFrBlockVector;
XclExpChChart* mpChartData; /// Pointer to the chart data object.
XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out.
XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out.
};
// ----------------------------------------------------------------------------
XclExpChRootData::XclExpChRootData( XclExpChChart* pChartData ) :
mpChartData( pChartData )
{
}
void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock )
{
maUnwrittenFrBlocks.push_back( rFrBlock );
@ -238,9 +242,9 @@ void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm )
// ----------------------------------------------------------------------------
XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart* pChartData ) :
XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) :
XclExpRoot( rRoot ),
mxChData( new XclExpChRootData( pChartData ) )
mxChData( new XclExpChRootData( rChartData ) )
{
}
@ -248,29 +252,34 @@ XclExpChRoot::~XclExpChRoot()
{
}
Reference< XChartDocument > XclExpChRoot::GetChartDocument() const
{
return mxChData->mxChartDoc;
}
XclExpChChart& XclExpChRoot::GetChartData() const
{
return mxChData->GetChartData();
return mxChData->mrChartData;
}
const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
{
return mxChData->GetTypeInfoProvider().GetTypeInfo( eType );
return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
}
const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const
{
return mxChData->GetTypeInfoProvider().GetTypeInfoFromService( rServiceName );
return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName );
}
const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
{
return mxChData->GetFormatInfoProvider().GetFormatInfo( eObjType );
return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
}
void XclExpChRoot::InitConversion( XChartDocRef xChartDoc ) const
void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const
{
mxChData->InitConversion( xChartDoc );
mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
}
void XclExpChRoot::FinishConversion() const
@ -291,11 +300,41 @@ void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uIn
rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx );
}
sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const
{
return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS );
}
sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const
{
return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS );
}
XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const
{
XclChRectangle aRect;
aRect.mnX = CalcChartXFromHmm( rRect.X );
aRect.mnY = CalcChartYFromHmm( rRect.Y );
aRect.mnWidth = CalcChartXFromHmm( rRect.Width );
aRect.mnHeight = CalcChartYFromHmm( rRect.Height );
return aRect;
}
sal_Int32 XclExpChRoot::CalcChartXFromRelative( double fPosX ) const
{
return CalcChartXFromHmm( static_cast< sal_Int32 >( fPosX * mxChData->maChartRect.GetWidth() + 0.5 ) );
}
sal_Int32 XclExpChRoot::CalcChartYFromRelative( double fPosY ) const
{
return CalcChartYFromHmm( static_cast< sal_Int32 >( fPosY * mxChData->maChartRect.GetHeight() + 0.5 ) );
}
void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt,
const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
{
GetChartPropSetHelper().ReadLineProperties(
rLineFmt, mxChData->GetLineDashTable(), rPropSet, ePropMode );
rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode );
}
bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt,
@ -309,7 +348,7 @@ void XclExpChRoot::ConvertEscherFormat(
const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const
{
GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt,
mxChData->GetGradientTable(), mxChData->GetHatchTable(), mxChData->GetBitmapTable(), rPropSet, ePropMode );
*mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode );
}
sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const
@ -404,6 +443,20 @@ void XclExpChFutureRecordBase::Save( XclExpStream& rStrm )
// Frame formatting ===========================================================
XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) :
XclExpRecord( EXC_ID_CHFRAMEPOS, 20 )
{
maData.mnTLMode = nTLMode;
maData.mnBRMode = nBRMode;
}
void XclExpChFramePos::WriteBody( XclExpStream& rStrm )
{
rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect;
}
// ----------------------------------------------------------------------------
XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) :
XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ),
mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) )
@ -1118,6 +1171,36 @@ void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget
// rotation
ConvertRotationBase( GetChRoot(), aTitleProp, true );
// manual text position - only for main title
mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
if( nTarget == EXC_CHOBJLINK_TITLE )
{
Any aRelPos;
if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try
{
// calculate absolute position for CHTEXT record
Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW );
::com::sun::star::awt::Point aPos = xTitleShape->getPosition();
::com::sun::star::awt::Size aSize = xTitleShape->getSize();
::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height );
maData.maRect = CalcChartRectFromHmm( aRect );
::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 );
// manual title position implies manual plot area
GetChartData().SetManualPlotArea();
// calculate the default title position in chart units
sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 );
sal_Int32 nDefPosY = 85;
// set the position relative to the standard position
XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect;
rFrameRect.mnX = maData.maRect.mnX - nDefPosX;
rFrameRect.mnY = maData.maRect.mnY - nDefPosY;
}
catch( Exception& )
{
}
}
}
else
{
@ -1137,8 +1220,7 @@ bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
{
SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx );
namespace cssc = ::com::sun::star::chart2;
cssc::DataPointLabel aPointLabel;
cssc2::DataPointLabel aPointLabel;
if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) )
return false;
@ -1184,31 +1266,33 @@ bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet,
ConvertRotationBase( GetChRoot(), rPropSet, false );
// label placement
sal_Int32 nPlacement = 0;
sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO;
if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) )
{
using namespace ::com::sun::star::chart::DataLabelPlacement;
if( nPlacement == rTypeInfo.mnDefaultLabelPos )
{
maData.mnPlacement = EXC_CHTEXT_POS_DEFAULT;
nLabelPos = EXC_CHTEXT_POS_DEFAULT;
}
else switch( nPlacement )
{
case AVOID_OVERLAP: maData.mnPlacement = EXC_CHTEXT_POS_AUTO; break;
case CENTER: maData.mnPlacement = EXC_CHTEXT_POS_CENTER; break;
case TOP: maData.mnPlacement = EXC_CHTEXT_POS_ABOVE; break;
case TOP_LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break;
case LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break;
case BOTTOM_LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break;
case BOTTOM: maData.mnPlacement = EXC_CHTEXT_POS_BELOW; break;
case BOTTOM_RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break;
case RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break;
case TOP_RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break;
case INSIDE: maData.mnPlacement = EXC_CHTEXT_POS_INSIDE; break;
case OUTSIDE: maData.mnPlacement = EXC_CHTEXT_POS_OUTSIDE; break;
case NEAR_ORIGIN: maData.mnPlacement = EXC_CHTEXT_POS_AXIS; break;
case AVOID_OVERLAP: nLabelPos = EXC_CHTEXT_POS_AUTO; break;
case CENTER: nLabelPos = EXC_CHTEXT_POS_CENTER; break;
case TOP: nLabelPos = EXC_CHTEXT_POS_ABOVE; break;
case TOP_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
case LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
case BOTTOM_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break;
case BOTTOM: nLabelPos = EXC_CHTEXT_POS_BELOW; break;
case BOTTOM_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
case RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
case TOP_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break;
case INSIDE: nLabelPos = EXC_CHTEXT_POS_INSIDE; break;
case OUTSIDE: nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break;
case NEAR_ORIGIN: nLabelPos = EXC_CHTEXT_POS_AXIS; break;
default: DBG_ERRORFILE( "XclExpChText::ConvertDataLabel - unknown label placement type" );
}
}
::insert_value( maData.mnFlags2, nLabelPos, 0, 4 );
// source link (contains number format)
mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) );
if( bShowValue || bShowPercent )
@ -1255,6 +1339,8 @@ sal_uInt16 XclExpChText::GetAttLabelFlags() const
void XclExpChText::WriteSubRecords( XclExpStream& rStrm )
{
// CHFRAMEPOS record
lclSaveRecord( rStrm, mxFramePos );
// CHFONT record
lclSaveRecord( rStrm, mxFont );
// CHSOURCELINK group
@ -1279,7 +1365,7 @@ void XclExpChText::WriteBody( XclExpStream& rStrm )
if( GetBiff() == EXC_BIFF8 )
{
rStrm << GetPalette().GetColorIndex( mnTextColorId )
<< maData.mnPlacement
<< maData.mnFlags2
<< maData.mnRotation;
}
}
@ -1604,7 +1690,6 @@ bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& r
bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE );
if( bOk )
{
namespace cssc = ::com::sun::star::chart;
switch( nBarStyle )
{
case cssc::ErrorBarStyle::ABSOLUTE:
@ -2148,12 +2233,66 @@ void XclExpChLegend::Convert( const ScfPropertySet& rPropSet )
// text properties
mxText.reset( new XclExpChText( GetChRoot() ) );
mxText->ConvertLegend( rPropSet );
// special legend properties
GetChartPropSetHelper().ReadLegendProperties( maData, rPropSet );
// legend position
Any aRelPosAny;
rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION );
if( aRelPosAny.has< RelativePosition >() )
{
try
{
/* The 'RelativePosition' property is used as indicator of manually
changed legend position, but due to the different anchor modes
used by this property (in the RelativePosition.Anchor member)
it cannot be used to calculate the position easily. For this,
the Chart1 API will be used instead. */
Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW );
// coordinates in CHLEGEND record written but not used by Excel
mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) );
XclChFramePos& rFramePos = mxFramePos->GetFramePosData();
rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( xChart1Legend->getPosition().X );
rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( xChart1Legend->getPosition().Y );
// manual legend position implies manual plot area
GetChartData().SetManualPlotArea();
maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
}
catch( Exception& )
{
OSL_ENSURE( false, "XclExpChLegend::Convert - cannot get legend shape" );
maData.mnDockMode = EXC_CHLEGEND_RIGHT;
}
}
else
{
cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION );
switch( eApiPos )
{
case cssc2::LegendPosition_LINE_START: maData.mnDockMode = EXC_CHLEGEND_LEFT; break;
case cssc2::LegendPosition_LINE_END: maData.mnDockMode = EXC_CHLEGEND_RIGHT; break;
case cssc2::LegendPosition_PAGE_START: maData.mnDockMode = EXC_CHLEGEND_TOP; break;
case cssc2::LegendPosition_PAGE_END: maData.mnDockMode = EXC_CHLEGEND_BOTTOM; break;
default:
OSL_ENSURE( false, "XclExpChLegend::Convert - unrecognized legend position" );
maData.mnDockMode = EXC_CHLEGEND_RIGHT;
}
}
// legend expansion
cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED;
rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION );
::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc2::LegendExpansion_WIDE );
// other flags
::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES );
const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY;
::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
}
void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm )
{
lclSaveRecord( rStrm, mxFramePos );
lclSaveRecord( rStrm, mxText );
lclSaveRecord( rStrm, mxFrame );
}
@ -2252,13 +2391,12 @@ void XclExpChTypeGroup::ConvertSeries(
{
// stacking direction (stacked/percent/deep 3d) from first series
ScfPropertySet aSeriesProp( aSeriesVec.front() );
namespace cssc = ::com::sun::star::chart2;
cssc::StackingDirection eStacking;
cssc2::StackingDirection eStacking;
if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) )
eStacking = cssc::StackingDirection_NO_STACKING;
eStacking = cssc2::StackingDirection_NO_STACKING;
// stacked or percent chart
if( maTypeInfo.mbSupportsStacking && (eStacking == cssc::StackingDirection_Y_STACKING) )
if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) )
{
// percent overrides simple stacking
maType.SetStacked( bPercent );
@ -2275,7 +2413,7 @@ void XclExpChTypeGroup::ConvertSeries(
}
// deep 3d chart or clustered 3d chart (stacked is not clustered)
if( (eStacking == cssc::StackingDirection_NO_STACKING) && Is3dWallChart() )
if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() )
mxChart3d->SetClustered();
// varied point colors
@ -2396,7 +2534,8 @@ bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries,
void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm )
{
rStrm << maData.maRect << maData.mnFlags << maData.mnGroupIdx;
rStrm.WriteZeroBytes( 16 );
rStrm << maData.mnFlags << maData.mnGroupIdx;
}
// Axes =======================================================================
@ -2421,7 +2560,6 @@ void XclExpChLabelRange::Convert( const ScaleData& rScaleData, bool bMirrorOrien
void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
{
namespace cssc = ::com::sun::star::chart;
cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION );
double fCrossingPos = 1.0;
@ -2479,13 +2617,11 @@ void XclExpChValueRange::Convert( const ScaleData& rScaleData )
::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor );
// reverse order
namespace cssc = ::com::sun::star::chart2;
::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc::AxisOrientation_REVERSE );
::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE );
}
void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet )
{
namespace cssc = ::com::sun::star::chart;
cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE;
double fCrossingPos = 0.0;
if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) )
@ -2569,7 +2705,6 @@ void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeIn
}
else
{
namespace cssc = ::com::sun::star::chart;
cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS;
rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION );
switch( eApiLabelPos )
@ -2602,9 +2737,9 @@ void XclExpChTick::WriteBody( XclExpStream& rStrm )
rStrm << maData.mnMajor
<< maData.mnMinor
<< maData.mnLabelPos
<< maData.mnBackMode
<< maData.maRect
<< maData.maTextColor
<< maData.mnBackMode;
rStrm.WriteZeroBytes( 16 );
rStrm << maData.maTextColor
<< maData.mnFlags;
if( GetBiff() == EXC_BIFF8 )
rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation;
@ -2758,7 +2893,8 @@ void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm )
void XclExpChAxis::WriteBody( XclExpStream& rStrm )
{
rStrm << maData.mnType << maData.maRect;
rStrm << maData.mnType;
rStrm.WriteZeroBytes( 16 );
}
// ----------------------------------------------------------------------------
@ -2903,6 +3039,28 @@ sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16
}
}
// inner and outer plot area position and size
try
{
Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW );
Reference< ::com::sun::star::chart::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW );
// set manual flag in chart data
if( !xPositioning->isAutomaticDiagramPositioning() )
GetChartData().SetManualPlotArea();
// the CHAXESSET record contains the inner plot area
maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() );
// the embedded CHFRAMEPOS record contains the outer plot area
mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) );
// for pie charts, always use inner plot area size to exclude the data labels as Excel does
const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get();
bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE);
mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect :
CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() );
}
catch( Exception& )
{
}
// return first unused chart type group index for next axes set
return nGroupIdx;
}
@ -2915,14 +3073,7 @@ bool XclExpChAxesSet::Is3dChart() const
void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm )
{
/* Need to set a reasonable size for the plot area, otherwise Excel will
move away embedded shapes while auto-sizing the plot area. This is just
a wild guess, but will be fixed with implementing manual positioning of
chart elements. */
rStrm.StartRecord( EXC_ID_CHFRAMEPOS, 20 );
rStrm << sal_uInt16(2) << sal_uInt16(2) << sal_uInt32(66) << sal_uInt32(626) << sal_uInt32(3384) << sal_uInt32(3231);
rStrm.EndRecord();
lclSaveRecord( rStrm, mxFramePos );
lclSaveRecord( rStrm, mxXAxis );
lclSaveRecord( rStrm, mxYAxis );
lclSaveRecord( rStrm, mxZAxis );
@ -2974,10 +3125,10 @@ void XclExpChAxesSet::WriteBody( XclExpStream& rStrm )
// The chart object ===========================================================
XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
Reference< XChartDocument > xChartDoc, const Size& rSize ) :
XclExpChGroupBase( XclExpChRoot( rRoot, this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) :
XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 )
{
Size aPtSize = OutputDevice::LogicToLogic( rSize, MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) );
// rectangle is stored in 16.16 fixed-point format
maRect.mnX = maRect.mnY = 0;
maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 );
@ -3001,8 +3152,8 @@ XclExpChChart::XclExpChChart( const XclExpRoot& rRoot,
bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS );
::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden );
// initialize API conversion (remembers xChartDoc internally)
InitConversion( xChartDoc );
// initialize API conversion (remembers xChartDoc and rChartRect internally)
InitConversion( xChartDoc, rChartRect );
// chart frame
ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
@ -3060,6 +3211,13 @@ void XclExpChChart::SetDataLabel( XclExpChTextRef xText )
maLabels.AppendRecord( xText );
}
void XclExpChChart::SetManualPlotArea()
{
// this flag does not exist in BIFF5
if( GetBiff() == EXC_BIFF8 )
::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
}
void XclExpChChart::WriteSubRecords( XclExpStream& rStrm )
{
// background format
@ -3105,7 +3263,7 @@ XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot,
/* Create a new independent object manager with own DFF stream for the
DGCONTAINER, pass global manager as parent for shared usage of
global DFF data (picture container etc.). */
mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_UNIT, EXC_CHART_UNIT ) );
mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) );
// initialize the drawing object list
mxObjMgr->StartSheet();
// process the draw page (convert all shapes)
@ -3128,17 +3286,17 @@ void XclExpChartDrawing::Save( XclExpStream& rStrm )
// ----------------------------------------------------------------------------
XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Size& rSize ) :
XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) :
XclExpSubStream( EXC_BOF_CHART ),
XclExpRoot( rRoot )
{
AppendNewRecord( new XclExpChartPageSettings( rRoot ) );
AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) );
AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rSize ) );
AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) );
AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) );
Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY );
AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rSize ) );
AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) );
}
// ============================================================================

View file

@ -956,8 +956,8 @@ XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape
aShapeProp.GetProperty( xModel, CREATE_OUSTRING( "Model" ) );
::com::sun::star::awt::Rectangle aBoundRect;
aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) );
Size aSize( aBoundRect.Width, aBoundRect.Height );
mxChart.reset( new XclExpChart( GetRoot(), xModel, aSize ) );
Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) );
mxChart.reset( new XclExpChart( GetRoot(), xModel, aChartRect ) );
}
XclExpChartObj::~XclExpChartObj()

433
sc/source/filter/excel/xichart.cxx Normal file → Executable file
View file

@ -37,12 +37,14 @@
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/ProjectionMode.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
#include <com/sun/star/chart/ChartAxisLabelPosition.hpp>
#include <com/sun/star/chart/ChartAxisMarkPosition.hpp>
#include <com/sun/star/chart/ChartAxisPosition.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XDiagramPositioning.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/XDiagram.hpp>
#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
@ -57,8 +59,11 @@
#include <com/sun/star/chart2/CurveStyle.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
#include <com/sun/star/chart2/LegendExpansion.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/StackingDirection.hpp>
#include <com/sun/star/chart2/TickmarkStyle.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart/MissingValueTreatment.hpp>
@ -98,36 +103,41 @@ using ::com::sun::star::frame::XModel;
using ::com::sun::star::util::XNumberFormatsSupplier;
using ::com::sun::star::drawing::XDrawPage;
using ::com::sun::star::drawing::XDrawPageSupplier;
using ::com::sun::star::drawing::XShape;
using ::com::sun::star::chart2::IncrementData;
using ::com::sun::star::chart2::RelativePosition;
using ::com::sun::star::chart2::ScaleData;
using ::com::sun::star::chart2::SubIncrement;
using ::com::sun::star::chart2::XAxis;
using ::com::sun::star::chart2::XChartDocument;
using ::com::sun::star::chart2::XDiagram;
using ::com::sun::star::chart2::XCoordinateSystemContainer;
using ::com::sun::star::chart2::XCoordinateSystem;
using ::com::sun::star::chart2::XChartTypeContainer;
using ::com::sun::star::chart2::XChartType;
using ::com::sun::star::chart2::XDataSeriesContainer;
using ::com::sun::star::chart2::XChartTypeContainer;
using ::com::sun::star::chart2::XCoordinateSystem;
using ::com::sun::star::chart2::XCoordinateSystemContainer;
using ::com::sun::star::chart2::XDataSeries;
using ::com::sun::star::chart2::XDataSeriesContainer;
using ::com::sun::star::chart2::XDiagram;
using ::com::sun::star::chart2::XFormattedString;
using ::com::sun::star::chart2::XLegend;
using ::com::sun::star::chart2::XRegressionCurve;
using ::com::sun::star::chart2::XRegressionCurveContainer;
using ::com::sun::star::chart2::XAxis;
using ::com::sun::star::chart2::XScaling;
using ::com::sun::star::chart2::ScaleData;
using ::com::sun::star::chart2::IncrementData;
using ::com::sun::star::chart2::SubIncrement;
using ::com::sun::star::chart2::XLegend;
using ::com::sun::star::chart2::XTitled;
using ::com::sun::star::chart2::XTitle;
using ::com::sun::star::chart2::XFormattedString;
using ::com::sun::star::chart2::XTitled;
using ::com::sun::star::chart2::data::XDataProvider;
using ::com::sun::star::chart2::data::XDataReceiver;
using ::com::sun::star::chart2::data::XDataSequence;
using ::com::sun::star::chart2::data::XDataSink;
using ::com::sun::star::chart2::data::XLabeledDataSequence;
using ::com::sun::star::chart2::data::XDataSequence;
using ::formula::FormulaToken;
using ::formula::StackVar;
namespace cssc = ::com::sun::star::chart;
namespace cssc2 = ::com::sun::star::chart2;
// Helpers ====================================================================
namespace {
@ -158,28 +168,18 @@ void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bC
// Common =====================================================================
/** Stores global data needed in various classes of the Chart import filter. */
class XclImpChRootData : public XclChRootData
struct XclImpChRootData : public XclChRootData
{
public:
explicit XclImpChRootData( XclImpChChart* pChartData );
XclImpChChart& mrChartData; /// The chart data object.
/** Returns a reference to the parent chart data object. */
inline XclImpChChart& GetChartData() const { return *mpChartData; }
private:
XclImpChChart* mpChartData; /// Pointer to the chart data object.
inline explicit XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {}
};
XclImpChRootData::XclImpChRootData( XclImpChChart* pChartData ) :
mpChartData( pChartData )
{
}
// ----------------------------------------------------------------------------
XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart* pChartData ) :
XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) :
XclImpRoot( rRoot ),
mxChData( new XclImpChRootData( pChartData ) )
mxChData( new XclImpChRootData( rChartData ) )
{
}
@ -189,22 +189,22 @@ XclImpChRoot::~XclImpChRoot()
XclImpChChart& XclImpChRoot::GetChartData() const
{
return mxChData->GetChartData();
return mxChData->mrChartData;
}
const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const
{
return mxChData->GetTypeInfoProvider().GetTypeInfo( eType );
return mxChData->mxTypeInfoProv->GetTypeInfo( eType );
}
const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const
{
return mxChData->GetTypeInfoProvider().GetTypeInfoFromRecId( nRecId );
return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId );
}
const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const
{
return mxChData->GetFormatInfoProvider().GetFormatInfo( eObjType );
return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType );
}
Color XclImpChRoot::GetFontAutoColor() const
@ -225,10 +225,10 @@ Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const
return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans );
}
void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc ) const
void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) const
{
// create formatting object tables
mxChData->InitConversion( xChartDoc );
mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect );
// lock the model to suppress any internal updates
Reference< XModel > xModel( xChartDoc, UNO_QUERY );
@ -255,7 +255,7 @@ void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
{
rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
// unlock the model
Reference< XModel > xModel( mxChData->GetChartDoc(), UNO_QUERY );
Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY );
if( xModel.is() )
xModel->unlockControllers();
rDffConv.Progress( EXC_CHART_PROGRESS_SIZE );
@ -265,14 +265,48 @@ void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const
Reference< XDataProvider > XclImpChRoot::GetDataProvider() const
{
return mxChData->GetChartDoc()->getDataProvider();
return mxChData->mxChartDoc->getDataProvider();
}
Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const
{
return mxChData->GetTitleShape( rTitleKey );
}
sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const
{
return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 );
}
sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const
{
return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 );
}
::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const
{
return ::com::sun::star::awt::Rectangle(
CalcHmmFromChartX( rRect.mnX ),
CalcHmmFromChartY( rRect.mnY ),
CalcHmmFromChartX( rRect.mnWidth ),
CalcHmmFromChartY( rRect.mnHeight ) );
}
double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const
{
return static_cast< double >( CalcHmmFromChartX( nPosX ) ) / mxChData->maChartRect.GetWidth();
}
double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const
{
return static_cast< double >( CalcHmmFromChartY( nPosY ) ) / mxChData->maChartRect.GetHeight();
}
void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet,
const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const
{
GetChartPropSetHelper().WriteLineProperties(
rPropSet, mxChData->GetLineDashTable(), rLineFmt, ePropMode );
rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode );
}
void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet,
@ -286,7 +320,7 @@ void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet,
XclChPropertyMode ePropMode ) const
{
GetChartPropSetHelper().WriteEscherProperties( rPropSet,
mxChData->GetGradientTable(), mxChData->GetHatchTable(), mxChData->GetBitmapTable(),
*mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable,
rEscherFmt, rPicFmt, ePropMode );
}
@ -357,7 +391,13 @@ void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm )
void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm )
{
rStrm >> maData.mnObjType >> maData.mnSizeMode >> maData.maRect;
rStrm >> maData.mnTLMode >> maData.mnBRMode;
/* According to the spec, the upper 16 bits of all members in the
rectangle are unused and may contain garbage. */
maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 );
maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 );
maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 );
maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 );
}
// ----------------------------------------------------------------------------
@ -862,9 +902,7 @@ void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm )
// #116397# BIFF8: index into palette used instead of RGB data
maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() );
// placement and rotation
rStrm >> maData.mnPlacement >> maData.mnRotation;
// lower 4 bits used for placement, other bits contain garbage
maData.mnPlacement &= 0x000F;
rStrm >> maData.mnFlags2 >> maData.mnRotation;
}
else
{
@ -878,6 +916,10 @@ void XclImpChText::ReadSubRecord( XclImpStream& rStrm )
{
switch( rStrm.GetRecId() )
{
case EXC_ID_CHFRAMEPOS:
mxFramePos.reset( new XclImpChFramePos );
mxFramePos->ReadChFramePos( rStrm );
break;
case EXC_ID_CHFONT:
mxFont.reset( new XclImpChFont );
mxFont->ReadChFont( rStrm );
@ -1002,8 +1044,7 @@ void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeIn
bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL );
// create API struct for label values, set API label separator
namespace cssc = ::com::sun::star::chart2;
cssc::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol );
rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel );
String aSep = mxLabelProps.is() ? mxLabelProps->maSeparator : String( sal_Unicode( '\n' ) );
if( aSep.Len() == 0 )
@ -1016,9 +1057,9 @@ void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeIn
ConvertFont( rPropSet );
ConvertRotation( rPropSet, false );
// label placement
using namespace ::com::sun::star::chart::DataLabelPlacement;
using namespace cssc::DataLabelPlacement;
sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos;
switch( maData.mnPlacement )
switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) )
{
case EXC_CHTEXT_POS_DEFAULT: nPlacement = rTypeInfo.mnDefaultLabelPos; break;
case EXC_CHTEXT_POS_OUTSIDE: nPlacement = OUTSIDE; break;
@ -1064,6 +1105,62 @@ Reference< XTitle > XclImpChText::CreateTitle() const
return xTitle;
}
void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const
{
if( !mxFramePos ) return;
const XclChFramePos& rPosData = mxFramePos->GetFramePosData();
OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT),
"XclImpChText::ConvertTitlePosition - unexpected frame position mode" );
/* Check if title is moved manually. To get the actual position of the
title, we do some kind of hack and use the values from the CHTEXT
record, effectively ignoring the contents of the CHFRAMEPOS record
which contains the position relative to the default title position
(according to the spec, the CHFRAMEPOS supersedes the CHTEXT record).
Especially when it comes to axis titles, things would become very
complicated here, because the relative title position is stored in a
measurement unit that is dependent on the size of the inner plot area,
the interpretation of the X and Y coordinate is dependent on the
direction of the axis, and in 3D charts, and the title default
positions are dependent on the 3D view settings (rotation, elevation,
and perspective). Thus, it is easier to assume that the creator has
written out the correct absolute position and size of the title in the
CHTEXT record. This is assured by checking that the shape size stored
in the CHTEXT record is non-zero. */
if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) &&
((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) &&
(maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try
{
Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW );
// the call to XShape.getSize() may recalc the chart view
::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize();
// rotated titles need special handling...
sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 );
double fRad = nScRot * F_PI18000;
double fSin = fabs( sin( fRad ) );
double fCos = fabs( cos( fRad ) );
::com::sun::star::awt::Size aBoundSize(
static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ),
static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) );
// calculate the title position from the values in the CHTEXT record
::com::sun::star::awt::Point aTitlePos(
CalcHmmFromChartX( maData.maRect.mnX ),
CalcHmmFromChartY( maData.maRect.mnY ) );
// add part of height to X direction, if title is rotated down (clockwise)
if( nScRot > 18000 )
aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 );
// add part of width to Y direction, if title is rotated up (counterclockwise)
else if( nScRot > 0 )
aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 );
// set the resulting position at the title shape
xTitleShape->setPosition( aTitlePos );
}
catch( Exception& )
{
}
}
void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm )
{
if( GetBiff() == EXC_BIFF8 )
@ -1087,12 +1184,14 @@ void lclUpdateText( XclImpChTextRef& rxText, XclImpChTextRef xDefText )
rxText = xDefText;
}
void lclFinalizeTitle( XclImpChTextRef& rxTitle, XclImpChTextRef xDefText )
void lclFinalizeTitle( XclImpChTextRef& rxTitle, XclImpChTextRef xDefText, const String& rAutoTitle )
{
/* Do not update a title, if it is not visible (if rxTitle is null).
Existing reference indicates enabled title. */
if( rxTitle.is() )
{
if( !rxTitle->HasString() )
rxTitle->SetString( rAutoTitle );
if( rxTitle->HasString() )
rxTitle->UpdateText( xDefText.get() );
else
@ -1544,7 +1643,6 @@ Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSer
aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 );
// type of displayed error
namespace cssc = ::com::sun::star::chart;
switch( pPrimaryBar->maData.mnSourceType )
{
case EXC_CHSERERR_PERCENT:
@ -2281,6 +2379,10 @@ void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm )
{
switch( rStrm.GetRecId() )
{
case EXC_ID_CHFRAMEPOS:
mxFramePos.reset( new XclImpChFramePos );
mxFramePos->ReadChFramePos( rStrm );
break;
case EXC_ID_CHTEXT:
mxText.reset( new XclImpChText( GetChRoot() ) );
mxText->ReadRecordGroup( rStrm );
@ -2307,6 +2409,7 @@ Reference< XLegend > XclImpChLegend::CreateLegend() const
if( xLegend.is() )
{
ScfPropertySet aLegendProp( xLegend );
aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true );
// frame properties
if( mxFrame.is() )
@ -2314,8 +2417,69 @@ Reference< XLegend > XclImpChLegend::CreateLegend() const
// text properties
if( mxText.is() )
mxText->ConvertFont( aLegendProp );
// special legend properties
GetChartPropSetHelper().WriteLegendProperties( aLegendProp, maData );
/* Legend position and size. Default positions are used only if the
plot area is positioned automatically (Excel sets the plot area to
manual mode, if the legend is moved or resized). With manual plot
areas, Excel ignores the value in maData.mnDockMode completely. */
cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM;
cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED;
if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode )
{
case EXC_CHLEGEND_LEFT: eApiPos = cssc2::LegendPosition_LINE_START; eApiExpand = cssc2::LegendExpansion_HIGH; break;
case EXC_CHLEGEND_RIGHT: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break;
case EXC_CHLEGEND_TOP: eApiPos = cssc2::LegendPosition_PAGE_START; eApiExpand = cssc2::LegendExpansion_WIDE; break;
case EXC_CHLEGEND_BOTTOM: eApiPos = cssc2::LegendPosition_PAGE_END; eApiExpand = cssc2::LegendExpansion_WIDE; break;
// top-right not supported
case EXC_CHLEGEND_CORNER: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break;
}
// no automatic position: try to find the correct position and size
if( eApiPos == cssc2::LegendPosition_CUSTOM )
{
const XclChFramePos* pFramePos = mxFramePos.is() ? &mxFramePos->GetFramePosData() : 0;
/* Legend position. Only the settings from the CHFRAMEPOS record
are used by Excel, the position in the CHLEGEND record will be
ignored. */
if( pFramePos )
{
RelativePosition aRelPos;
aRelPos.Primary = CalcRelativeFromChartX( pFramePos->maRect.mnX );
aRelPos.Secondary = CalcRelativeFromChartY( pFramePos->maRect.mnY );
aRelPos.Anchor = ::com::sun::star::drawing::Alignment_TOP_LEFT;
aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos );
}
else
{
// no manual position found, just go for the default
eApiPos = cssc2::LegendPosition_LINE_END;
}
/* Legend size. #i71697# It is not possible to set the legend size
directly in the Chart, do some magic here. */
if( !pFramePos || (pFramePos->mnBRMode != EXC_CHFRAMEPOS_ABSSIZE_POINTS) ||
(pFramePos->maRect.mnWidth == 0) || (pFramePos->maRect.mnHeight == 0) )
{
// automatic size: determine entry direction from flags
eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED,
cssc2::LegendExpansion_HIGH, cssc2::LegendExpansion_WIDE );
}
else
{
// legend size is given in points, not in chart units
double fRatio = static_cast< double >( pFramePos->maRect.mnWidth ) / pFramePos->maRect.mnHeight;
if( fRatio > 1.5 )
eApiExpand = cssc2::LegendExpansion_WIDE;
else if( fRatio < 0.75 )
eApiExpand = cssc2::LegendExpansion_HIGH;
else
eApiExpand = cssc2::LegendExpansion_BALANCED;
}
}
aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos );
aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand );
}
return xLegend;
}
@ -2358,7 +2522,8 @@ XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) :
void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm )
{
rStrm >> maData.maRect >> maData.mnFlags >> maData.mnGroupIdx;
rStrm.Ignore( 16 );
rStrm >> maData.mnFlags >> maData.mnGroupIdx;
}
void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm )
@ -2548,13 +2713,12 @@ void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType,
if( xSeriesCont.is() && xSeries.is() )
{
// series stacking mode
namespace cssc = ::com::sun::star::chart2;
cssc::StackingDirection eStacking = cssc::StackingDirection_NO_STACKING;
cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING;
// stacked overrides deep-3d
if( maType.IsStacked() || maType.IsPercent() )
eStacking = cssc::StackingDirection_Y_STACKING;
eStacking = cssc2::StackingDirection_Y_STACKING;
else if( Is3dDeepChart() )
eStacking = cssc::StackingDirection_Z_STACKING;
eStacking = cssc2::StackingDirection_Z_STACKING;
// additional series properties
ScfPropertySet aSeriesProp( xSeries );
@ -2674,11 +2838,9 @@ void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleDat
// do not break text into several lines unless all labels are visible
rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maData.mnLabelFreq == 1 );
// do not stagger labels in two lines
namespace cssc = ::com::sun::star::chart;
rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE );
// reverse order
namespace cssc2 = ::com::sun::star::chart2;
bool bReverse = ::get_flag( maData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient;
rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
@ -2692,7 +2854,6 @@ void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3d
But: the Y axis has to be moved to "end", if the X axis is mirrored,
to keep it at the left end of the chart. */
bool bMaxCross = ::get_flag( maData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS );
namespace cssc = ::com::sun::star::chart;
cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
@ -2756,7 +2917,6 @@ void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) co
}
// reverse order
namespace cssc2 = ::com::sun::star::chart2;
bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient;
rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL;
}
@ -2768,7 +2928,6 @@ void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const
bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE );
// crossing mode (max-cross flag overrides other crossing settings)
namespace cssc = ::com::sun::star::chart;
cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE;
rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos );
@ -2791,7 +2950,7 @@ sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos )
return nApiTickmarks;
}
::com::sun::star::chart::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos )
{
using namespace ::com::sun::star::chart;
switch( nXclLabelPos )
@ -2815,9 +2974,9 @@ void XclImpChTick::ReadChTick( XclImpStream& rStrm )
rStrm >> maData.mnMajor
>> maData.mnMinor
>> maData.mnLabelPos
>> maData.mnBackMode
>> maData.maRect
>> maData.maTextColor
>> maData.mnBackMode;
rStrm.Ignore( 16 );
rStrm >> maData.maTextColor
>> maData.mnFlags;
if( GetBiff() == EXC_BIFF8 )
@ -2850,7 +3009,7 @@ void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const
rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) );
rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) );
rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) );
rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS );
rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS );
}
// ----------------------------------------------------------------------------
@ -2864,7 +3023,7 @@ XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) :
void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm )
{
rStrm >> maData.mnType >> maData.maRect;
rStrm >> maData.mnType;
}
void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm )
@ -2941,8 +3100,6 @@ sal_uInt16 XclImpChAxis::GetRotation() const
Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const
{
namespace cssc2 = ::com::sun::star::chart2;
// create the axis object (always)
Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY );
if( xAxis.is() )
@ -3136,8 +3293,8 @@ void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm )
switch( rStrm.GetRecId() )
{
case EXC_ID_CHFRAMEPOS:
mxPos.reset( new XclImpChFramePos );
mxPos->ReadChFramePos( rStrm );
mxFramePos.reset( new XclImpChFramePos );
mxFramePos->ReadChFramePos( rStrm );
break;
case EXC_ID_CHAXIS:
ReadChAxis( rStrm );
@ -3188,9 +3345,10 @@ void XclImpChAxesSet::Finalize()
// finalize axis titles
XclImpChTextRef xDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE );
lclFinalizeTitle( mxXAxisTitle, xDefText );
lclFinalizeTitle( mxYAxisTitle, xDefText );
lclFinalizeTitle( mxZAxisTitle, xDefText );
String aAutoTitle = CREATE_STRING( "Axis Title" );
lclFinalizeTitle( mxXAxisTitle, xDefText, aAutoTitle );
lclFinalizeTitle( mxYAxisTitle, xDefText, aAutoTitle );
lclFinalizeTitle( mxZAxisTitle, xDefText, aAutoTitle );
// #i47745# missing plot frame -> invisible border and area
if( !mxPlotFrame )
@ -3252,6 +3410,16 @@ void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const
}
}
void XclImpChAxesSet::ConvertTitlePositions() const
{
if( mxXAxisTitle.is() )
mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) );
if( mxYAxisTitle.is() )
mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) );
if( mxZAxisTitle.is() )
mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) );
}
void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm )
{
XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) );
@ -3358,11 +3526,15 @@ void XclImpChAxesSet::ConvertAxis(
if( xAxis.is() )
{
// create and attach the axis title
if( xChAxisTitle.is() )
if( xChAxisTitle.is() ) try
{
Reference< XTitled > xTitled( xAxis, UNO_QUERY );
if( xTitled.is() )
xTitled->setTitleObject( xChAxisTitle->CreateTitle() );
Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW );
Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW );
xTitled->setTitleObject( xTitle );
}
catch( Exception& )
{
DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis title" );
}
// insert axis into coordinate system
@ -3416,7 +3588,7 @@ void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const
// The chart object ===========================================================
XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) :
XclImpChRoot( rRoot, this )
XclImpChRoot( rRoot, *this )
{
mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) );
mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) );
@ -3516,23 +3688,34 @@ XclImpChTextRef XclImpChChart::GetDefaultText( XclChTextType eTextType ) const
return maDefTexts.get( nDefTextId );
}
void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffConverter& rDffConv, const OUString& rObjName ) const
bool XclImpChChart::IsManualPlotArea() const
{
// there is no real automatic mode in BIFF5 charts
return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA );
}
void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc,
XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const
{
// initialize conversion (locks the model to suppress any internal updates)
InitConversion( xChartDoc );
InitConversion( xChartDoc, rChartRect );
// chart frame and title
// chart frame formatting
if( mxFrame.is() )
{
ScfPropertySet aFrameProp( xChartDoc->getPageBackground() );
mxFrame->Convert( aFrameProp );
}
if( mxTitle.is() )
// chart title
if( mxTitle.is() ) try
{
Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW );
Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW );
xTitled->setTitleObject( xTitle );
}
catch( Exception& )
{
Reference< XTitled > xTitled( xChartDoc, UNO_QUERY );
Reference< XTitle > xTitle = mxTitle->CreateTitle();
if( xTitled.is() && xTitle.is() )
xTitled->setTitleObject( xTitle );
}
/* Create the diagram object and attach it to the chart document. Currently,
@ -3548,13 +3731,48 @@ void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffCon
if( xDiagram.is() && mxLegend.is() )
xDiagram->setLegend( mxLegend->CreateLegend() );
// set the IncludeHiddenCells property via the old API as only this ensures that the data provider and al created sequences get this flag correctly
Reference< com::sun::star::chart::XChartDocument > xStandardApiChartDoc( xChartDoc, UNO_QUERY );
if( xStandardApiChartDoc.is() )
/* Following all conversions needing the old Chart1 API that involves full
initialization of the chart view. */
Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY );
if( xChart1Doc.is() )
{
ScfPropertySet aDiagramProp( xStandardApiChartDoc->getDiagram() );
bool bShowVisCells = (maProps.mnFlags & EXC_CHPROPS_SHOWVISIBLEONLY);
aDiagramProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram();
/* Set the 'IncludeHiddenCells' property via the old API as only this
ensures that the data provider and all created sequences get this
flag correctly. */
ScfPropertySet aDiaProp( xDiagram1 );
bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY );
aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells );
// plot area position and size (there is no real automatic mode in BIFF5 charts)
XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos();
if( IsManualPlotArea() && xPlotAreaPos.is() ) try
{
const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData();
if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) )
{
Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW );
::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect );
// for pie charts, always set inner plot area size to exclude the data labels as Excel does
const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get();
if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) )
xPositioning->setDiagramPositionExcludingAxes( aDiagramRect );
else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() )
xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect );
else
xPositioning->setDiagramPositionIncludingAxes( aDiagramRect );
}
}
catch( Exception& )
{
}
// positions of all title objects
if( mxTitle.is() )
mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) );
mxPrimAxesSet->ConvertTitlePositions();
mxSecnAxesSet->ConvertTitlePositions();
}
// unlock the model
@ -3689,21 +3907,24 @@ void XclImpChChart::FinalizeDataFormats()
void XclImpChChart::FinalizeTitle()
{
if( (!mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString())) && !mxSecnAxesSet->IsValidAxesSet() )
// special handling for auto-generated title
String aAutoTitle;
if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) )
{
/* Chart title is auto-generated from series title, if there is only
one series with title in the chart. */
const String& rSerTitle = mxPrimAxesSet->GetSingleSeriesTitle();
if( rSerTitle.Len() > 0 )
// automatic title from first series name (if there are no series on secondary axes set)
if( !mxSecnAxesSet->IsValidAxesSet() )
aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle();
if( mxTitle.is() || (aAutoTitle.Len() > 0) )
{
if( !mxTitle )
mxTitle.reset( new XclImpChText( GetChRoot() ) );
mxTitle->SetString( rSerTitle );
if( aAutoTitle.Len() == 0 )
aAutoTitle = CREATE_STRING( "Chart Title" );
}
}
// will reset mxTitle, if it does not contain a string
lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ) );
// will reset mxTitle, if it does not contain a string and no auto title exists
lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle );
}
Reference< XDiagram > XclImpChChart::CreateDiagram() const
@ -3715,7 +3936,7 @@ Reference< XDiagram > XclImpChChart::CreateDiagram() const
ScfPropertySet aDiaProp( xDiagram );
// treatment of missing values
using namespace ::com::sun::star::chart::MissingValueTreatment;
using namespace cssc::MissingValueTreatment;
sal_Int32 nMissingValues = LEAVE_GAP;
switch( maProps.mnEmptyMode )
{
@ -3775,10 +3996,10 @@ Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool
in the cell address components of the client anchor. In old BIFF3-BIFF5
objects, the position is stored in the offset components of the anchor. */
Rectangle aRect(
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ) );
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ),
static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) );
aRect.Justify();
// move shapes into chart area for sheet charts
if( mbOwnTab )
@ -3892,7 +4113,7 @@ void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffC
if( xChartDoc.is() )
{
if( mxChartData.is() )
mxChartData->Convert( xChartDoc, rDffConv, rObjName );
mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect );
if( mxChartDrawing.is() )
mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect );
}

202
sc/source/filter/excel/xlchart.cxx Normal file → Executable file
View file

@ -38,11 +38,13 @@
#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <com/sun/star/chart2/RelativePosition.hpp>
#include <com/sun/star/chart2/LegendPosition.hpp>
#include <com/sun/star/chart2/LegendExpansion.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart/XAxisXSupplier.hpp>
#include <com/sun/star/chart/XAxisYSupplier.hpp>
#include <com/sun/star/chart/XAxisZSupplier.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
#include <rtl/math.hxx>
#include <svl/itemset.hxx>
@ -55,9 +57,8 @@
#include <filter/msfilter/escherex.hxx>
#include <editeng/memberids.hrc>
#include "global.hxx"
#include "xlconst.hxx"
#include "xlroot.hxx"
#include "xlstyle.hxx"
#include "xltools.hxx"
using ::rtl::OUString;
using ::com::sun::star::uno::Any;
@ -66,6 +67,9 @@ using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::chart2::XChartDocument;
using ::com::sun::star::drawing::XShape;
namespace cssc = ::com::sun::star::chart;
// Common =====================================================================
@ -104,8 +108,8 @@ XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) :
// Frame formatting ===========================================================
XclChFramePos::XclChFramePos() :
mnObjType( EXC_CHFRAMEPOS_ANY ),
mnSizeMode( EXC_CHFRAMEPOS_AUTOSIZE )
mnTLMode( EXC_CHFRAMEPOS_PARENT ),
mnBRMode( EXC_CHFRAMEPOS_PARENT )
{
}
@ -189,7 +193,7 @@ XclChText::XclChText() :
mnVAlign( EXC_CHTEXT_ALIGN_CENTER ),
mnBackMode( EXC_CHTEXT_TRANSPARENT ),
mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ),
mnPlacement( EXC_CHTEXT_POS_DEFAULT ),
mnFlags2( EXC_CHTEXT_POS_DEFAULT ),
mnRotation( EXC_ROT_NONE )
{
}
@ -512,7 +516,7 @@ const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartTyp
const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType";
const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo
namespace csscd = ::com::sun::star::chart::DataLabelPlacement;
namespace csscd = cssc::DataLabelPlacement;
static const XclChTypeInfo spTypeInfos[] =
{
@ -680,10 +684,6 @@ const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Colo
/** Property names for bitmap area style. */
const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 };
/** Property names for legend properties. */
const sal_Char* const sppcLegendNames[] =
{ "Show", "AnchorPosition", "Expansion", "RelativePosition", 0 };
} // namespace
// ----------------------------------------------------------------------------
@ -698,8 +698,7 @@ XclChPropSetHelper::XclChPropSetHelper() :
maGradHlpFilled( sppcGradNamesFilled ),
maHatchHlpCommon( sppcHatchNamesCommon ),
maHatchHlpFilled( sppcHatchNamesFilled ),
maBitmapHlp( sppcBitmapNames ),
maLegendHlp( sppcLegendNames )
maBitmapHlp( sppcBitmapNames )
{
}
@ -957,46 +956,6 @@ sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPr
XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) );
}
void XclChPropSetHelper::ReadLegendProperties( XclChLegend& rLegend, const ScfPropertySet& rPropSet )
{
namespace cssc = ::com::sun::star::chart2;
namespace cssd = ::com::sun::star::drawing;
// read the properties
bool bShow;
cssc::LegendPosition eApiPos;
cssc::LegendExpansion eApiExpand;
Any aRelPosAny;
maLegendHlp.ReadFromPropertySet( rPropSet );
maLegendHlp >> bShow >> eApiPos >> eApiExpand >> aRelPosAny;
DBG_ASSERT( bShow, "XclChPropSetHelper::ReadLegendProperties - legend must be visible" );
// legend position
switch( eApiPos )
{
case cssc::LegendPosition_LINE_START: rLegend.mnDockMode = EXC_CHLEGEND_LEFT; break;
case cssc::LegendPosition_LINE_END: rLegend.mnDockMode = EXC_CHLEGEND_RIGHT; break;
case cssc::LegendPosition_PAGE_START: rLegend.mnDockMode = EXC_CHLEGEND_TOP; break;
case cssc::LegendPosition_PAGE_END: rLegend.mnDockMode = EXC_CHLEGEND_BOTTOM; break;
default: rLegend.mnDockMode = EXC_CHLEGEND_NOTDOCKED;
}
// legend expansion
::set_flag( rLegend.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc::LegendExpansion_WIDE );
// legend position
if( rLegend.mnDockMode == EXC_CHLEGEND_NOTDOCKED )
{
cssc::RelativePosition aRelPos;
if( aRelPosAny >>= aRelPos )
{
rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT );
rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT );
}
else
rLegend.mnDockMode = EXC_CHLEGEND_LEFT;
}
::set_flag( rLegend.mnFlags, EXC_CHLEGEND_DOCKED, rLegend.mnDockMode != EXC_CHLEGEND_NOTDOCKED );
}
// write properties -----------------------------------------------------------
void XclChPropSetHelper::WriteLineProperties(
@ -1207,51 +1166,6 @@ void XclChPropSetHelper::WriteRotationProperties(
}
}
void XclChPropSetHelper::WriteLegendProperties(
ScfPropertySet& rPropSet, const XclChLegend& rLegend )
{
namespace cssc = ::com::sun::star::chart2;
namespace cssd = ::com::sun::star::drawing;
// legend position
cssc::LegendPosition eApiPos = cssc::LegendPosition_CUSTOM;
switch( rLegend.mnDockMode )
{
case EXC_CHLEGEND_LEFT: eApiPos = cssc::LegendPosition_LINE_START; break;
case EXC_CHLEGEND_RIGHT: eApiPos = cssc::LegendPosition_LINE_END; break;
case EXC_CHLEGEND_TOP: eApiPos = cssc::LegendPosition_PAGE_START; break;
case EXC_CHLEGEND_BOTTOM: eApiPos = cssc::LegendPosition_PAGE_END; break;
}
// legend expansion
cssc::LegendExpansion eApiExpand = ::get_flagvalue(
rLegend.mnFlags, EXC_CHLEGEND_STACKED, cssc::LegendExpansion_HIGH, cssc::LegendExpansion_WIDE );
// legend position
Any aRelPosAny;
if( eApiPos == cssc::LegendPosition_CUSTOM )
{
// #i71697# it is not possible to set the size directly, do some magic here
double fRatio = ((rLegend.maRect.mnWidth > 0) && (rLegend.maRect.mnHeight > 0)) ?
(static_cast< double >( rLegend.maRect.mnWidth ) / rLegend.maRect.mnHeight) : 1.0;
if( fRatio > 1.5 )
eApiExpand = cssc::LegendExpansion_WIDE;
else if( fRatio < 0.75 )
eApiExpand = cssc::LegendExpansion_HIGH;
else
eApiExpand = cssc::LegendExpansion_BALANCED;
// set position
cssc::RelativePosition aRelPos;
aRelPos.Primary = static_cast< double >( rLegend.maRect.mnX ) / EXC_CHART_UNIT;
aRelPos.Secondary = static_cast< double >( rLegend.maRect.mnY ) / EXC_CHART_UNIT;
aRelPos.Anchor = cssd::Alignment_TOP_LEFT;
aRelPosAny <<= aRelPos;
}
// write the properties
maLegendHlp.InitializeWrite();
maLegendHlp << true << eApiPos << eApiExpand << aRelPosAny;
maLegendHlp.WriteToPropertySet( rPropSet );
}
// private --------------------------------------------------------------------
ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode )
@ -1301,27 +1215,81 @@ ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMod
// ============================================================================
namespace {
/* The following local functions implement getting the XShape interface of all
supported title objects (chart and axes). This needs some effort due to the
design of the old Chart1 API used to access these objects. */
/** A code fragment that returns a shape object from the passed shape supplier
using the specified interface function. Checks a boolean property first. */
#define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \
ScfPropertySet aPropSet( shape_supplier ); \
if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #property_name ) ) ) \
return shape_supplier->supplier_func(); \
return Reference< XShape >(); \
/** Implements a function returning the drawing shape of an axis title, if
existing, using the specified API interface and its function. */
#define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \
Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \
{ \
Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \
EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \
}
/** Returns the drawing shape of the main title, if existing. */
Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc )
{
EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle )
}
EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle )
EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle )
EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle )
EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle )
EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle )
#undef EXC_DEFINEFUNC_GETAXISTITLESHAPE
#undef EXC_IMPLEMENT_GETTITLESHAPE
} // namespace
// ----------------------------------------------------------------------------
XclChRootData::XclChRootData() :
mxTypeInfoProv( new XclChTypeInfoProvider ),
mxFmtInfoProv( new XclChFormatInfoProvider )
mxFmtInfoProv( new XclChFormatInfoProvider ),
mnBorderGapX( 0 ),
mnBorderGapY( 0 )
{
// remember some title shape getter functions
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape;
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape;
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape;
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape;
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape;
maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape;
}
XclChRootData::~XclChRootData()
{
}
Reference< XChartDocument > XclChRootData::GetChartDoc() const
void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect )
{
DBG_ASSERT( mxChartDoc.is(), "XclChRootData::GetChartDoc - missing chart document" );
return mxChartDoc;
}
// remember chart document reference and chart shape position/size
DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
mxChartDoc = rxChartDoc;
maChartRect = rChartRect;
void XclChRootData::InitConversion( XChartDocRef xChartDoc )
{
// remember chart document reference
DBG_ASSERT( xChartDoc.is(), "XclChRootData::InitConversion - missing chart document" );
mxChartDoc = xChartDoc;
// Excel excludes a border of 5 pixels in each direction from chart area
mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 );
mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 );
// size of a chart unit in 1/100 mm
mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS;
mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS;
// create object tables
Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY );
@ -1346,5 +1314,15 @@ void XclChRootData::FinishConversion()
mxChartDoc.clear();
}
// ============================================================================
Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const
{
XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey );
OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" );
Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY );
Reference< XShape > xTitleShape;
if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) )
xTitleShape = (aIt->second)( xChart1Doc );
return xTitleShape;
}
// ============================================================================

View file

@ -28,7 +28,11 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "xlroot.hxx"
#include <com/sun/star/awt/XDevice.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <comphelper/processfactory.hxx>
#include <vcl/svapp.hxx>
#include <svl/stritem.hxx>
#include <svl/languageoptions.hxx>
@ -57,6 +61,15 @@
namespace ApiScriptType = ::com::sun::star::i18n::ScriptType;
using ::rtl::OUString;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::awt::XDevice;
using ::com::sun::star::awt::DeviceInfo;
using ::com::sun::star::frame::XFrame;
using ::com::sun::star::frame::XFramesSupplier;
using ::com::sun::star::lang::XMultiServiceFactory;
// Global data ================================================================
@ -88,6 +101,8 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
mxFontPropSetHlp( new XclFontPropSetHelper ),
mxChPropSetHlp( new XclChPropSetHelper ),
mxRD( new RootData ),//!
mfScreenPixelX( 50.0 ),
mfScreenPixelY( 50.0 ),
mnCharWidth( 110 ),
mnScTab( 0 ),
mbExport( bExport )
@ -129,6 +144,22 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium,
mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) );
else
mxExtDocOpt.reset( new ScExtDocOptions );
// screen pixel size
try
{
Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW );
Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW );
Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW );
Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
DeviceInfo aDeviceInfo = xDevice->getInfo();
mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0;
mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0;
}
catch( Exception& )
{
OSL_ENSURE( false, "XclRootData::XclRootData - cannot get output device info" );
}
}
XclRootData::~XclRootData()
@ -199,6 +230,16 @@ void XclRoot::SetCharWidth( const XclFontData& rFontData )
}
}
sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const
{
return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 );
}
sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const
{
return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 );
}
String XclRoot::RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const
{
::std::vector< OUString > aDefaultPasswords;

View file

@ -39,6 +39,10 @@
class Size;
namespace com { namespace sun { namespace star {
namespace awt
{
struct Rectangle;
}
namespace frame
{
class XModel;
@ -65,7 +69,7 @@ namespace com { namespace sun { namespace star {
// Common =====================================================================
class XclExpChRootData;
struct XclExpChRootData;
class XclExpChChart;
/** Base class for complex chart classes, provides access to other components
@ -80,11 +84,13 @@ public:
typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
public:
explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart* pChartData );
explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData );
virtual ~XclExpChRoot();
/** Returns this root instance - for code readability in derived classes. */
inline const XclExpChRoot& GetChRoot() const { return *this; }
/** Returns the API Chart document model. */
XChartDocRef GetChartDocument() const;
/** Returns a reference to the parent chart data object. */
XclExpChChart& GetChartData() const;
/** Returns chart type info for a unique chart type identifier. */
@ -96,7 +102,7 @@ public:
const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const;
/** Starts the API chart document conversion. Must be called once before all API conversion. */
void InitConversion( XChartDocRef xChartDoc ) const;
void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
/** Finishes the API chart document conversion. Must be called once after all API conversion. */
void FinishConversion() const;
@ -105,6 +111,18 @@ public:
/** Sets a system color and the respective color identifier. */
void SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const;
/** Converts the passed horizontal coordinate from 1/100 mm to Excel chart units. */
sal_Int32 CalcChartXFromHmm( sal_Int32 nPosX ) const;
/** Converts the passed vertical coordinate from 1/100 mm to Excel chart units. */
sal_Int32 CalcChartYFromHmm( sal_Int32 nPosY ) const;
/** Converts the passed rectangle from 1/100 mm to Excel chart units. */
XclChRectangle CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const;
/** Converts the passed horizontal coordinate from a relative position to Excel chart units. */
sal_Int32 CalcChartXFromRelative( double fPosX ) const;
/** Converts the passed vertical coordinate from a relative position to Excel chart units. */
sal_Int32 CalcChartYFromRelative( double fPosY ) const;
/** Reads all line properties from the passed property set. */
void ConvertLineFormat(
XclChLineFormat& rLineFmt,
@ -191,6 +209,25 @@ public:
// Frame formatting ===========================================================
class XclExpChFramePos : public XclExpRecord
{
public:
explicit XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode );
/** Returns read/write access to the frame position data. */
inline XclChFramePos& GetFramePosData() { return maData; }
private:
virtual void WriteBody( XclExpStream& rStrm );
private:
XclChFramePos maData; /// Position of the frame.
};
typedef ScfRef< XclExpChFramePos > XclExpChFramePosRef;
// ----------------------------------------------------------------------------
class XclExpChLineFormat : public XclExpRecord
{
public:
@ -514,6 +551,7 @@ private:
private:
XclChText maData; /// Contents of the CHTEXT record.
XclExpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
XclExpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
XclExpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record).
@ -830,8 +868,8 @@ typedef ScfRef< XclExpChChart3d > XclExpChChart3dRef;
/** Represents the CHLEGEND record group describing the chart legend.
The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAME group,
CHTEXT group, CHEND.
The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
group, CHTEXT group, CHEND.
*/
class XclExpChLegend : public XclExpChGroupBase
{
@ -849,6 +887,7 @@ private:
private:
XclChLegend maData; /// Contents of the CHLEGEND record.
XclExpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
XclExpChTextRef mxText; /// Legend text format (CHTEXT group).
XclExpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
};
@ -1137,6 +1176,7 @@ private:
typedef XclExpRecordList< XclExpChTypeGroup > XclExpChTypeGroupList;
XclChAxesSet maData; /// Contents of the CHAXESSET record.
XclExpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
XclExpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
XclExpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
XclExpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
@ -1164,7 +1204,7 @@ public:
public:
explicit XclExpChChart( const XclExpRoot& rRoot,
XChartDocRef xChartDoc, const Size& rSize );
XChartDocRef xChartDoc, const Rectangle& rChartRect );
/** Creates, registers and returns a new data series object. */
XclExpChSeriesRef CreateSeries();
@ -1172,6 +1212,8 @@ public:
void RemoveLastSeries();
/** Stores a CHTEXT group that describes a data point label. */
void SetDataLabel( XclExpChTextRef xText );
/** Sets the plot area position and size to manual mode. */
void SetManualPlotArea();
/** Writes all embedded records. */
virtual void WriteSubRecords( XclExpStream& rStrm );
@ -1224,7 +1266,7 @@ public:
public:
explicit XclExpChart( const XclExpRoot& rRoot,
XModelRef xModel, const Size& rSize );
XModelRef xModel, const Rectangle& rChartRect );
};
// ============================================================================

View file

@ -43,10 +43,18 @@
#include "xistring.hxx"
namespace com { namespace sun { namespace star {
namespace awt
{
struct Rectangle;
}
namespace frame
{
class XModel;
}
namespace drawing
{
class XShape;
}
namespace chart2
{
struct ScaleData;
@ -75,7 +83,7 @@ struct XclObjFillData;
// Common =====================================================================
class ScfProgressBar;
class XclImpChRootData;
struct XclImpChRootData;
class XclImpChChart;
class ScTokenArray;
@ -83,11 +91,10 @@ class ScTokenArray;
class XclImpChRoot : public XclImpRoot
{
public:
typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider > XDataProviderRef;
typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
public:
explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart* pChartData );
explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData );
virtual ~XclImpChRoot();
/** Returns this root instance - for code readability in derived classes. */
@ -109,12 +116,28 @@ public:
Color GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const;
/** Starts the API chart document conversion. Must be called once before all API conversion. */
void InitConversion( XChartDocRef xChartDoc ) const;
void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const;
/** Finishes the API chart document conversion. Must be called once after all API conversion. */
void FinishConversion( XclImpDffConverter& rDffConv ) const;
/** Returns the data provider for the chart document. */
XDataProviderRef GetDataProvider() const;
::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider >
GetDataProvider() const;
/** Returns the drawing shape interface of the specified title object. */
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
GetTitleShape( const XclChTextKey& rTitleKey ) const;
/** Converts the passed horizontal coordinate from Excel chart units into 1/100 mm. */
sal_Int32 CalcHmmFromChartX( sal_Int32 nPosX ) const;
/** Converts the passed vertical coordinate from Excel chart units into 1/100 mm. */
sal_Int32 CalcHmmFromChartY( sal_Int32 nPosY ) const;
/** Converts the passed rectangle from Excel chart units into 1/100 mm. */
::com::sun::star::awt::Rectangle CalcHmmFromChartRect( const XclChRectangle& rRect ) const;
/** Converts the passed horizontal coordinate from Excel chart units into a relative position. */
double CalcRelativeFromChartX( sal_Int32 nPosX ) const;
/** Converts the passed vertical coordinate from Excel chart units into a relative position. */
double CalcRelativeFromChartY( sal_Int32 nPosY ) const;
/** Writes all line properties to the passed property set. */
void ConvertLineFormat(
@ -184,6 +207,9 @@ public:
/** Reads the CHFRAMEPOS record (frame position and size). */
void ReadChFramePos( XclImpStream& rStrm );
/** Returns read-only access to the imported frame position data. */
inline const XclChFramePos& GetFramePosData() const { return maData; }
private:
XclChFramePos maData; /// Position of the frame.
};
@ -506,6 +532,8 @@ public:
void ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const;
/** Creates a title text object. */
XTitleRef CreateTitle() const;
/** Converts the manual position of the specified title */
void ConvertTitlePosition( const XclChTextKey& rTitleKey ) const;
private:
using XclImpChRoot::ConvertFont;
@ -519,6 +547,7 @@ private:
XclChText maData; /// Contents of the CHTEXT record.
XclChObjectLink maObjLink; /// Link target for this text object.
XclFormatRunVec maFormats; /// Formatting runs (CHFORMATRUNS record).
XclImpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record).
XclImpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record).
XclImpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group).
XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record).
@ -922,8 +951,8 @@ typedef ScfRef< XclImpChChart3d > XclImpChChart3dRef;
/** Represents the CHLEGEND record group describing the chart legend.
The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAME group,
CHTEXT group, CHEND.
The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME
group, CHTEXT group, CHEND.
*/
class XclImpChLegend : public XclImpChGroupBase, protected XclImpChRoot
{
@ -945,6 +974,7 @@ public:
private:
XclChLegend maData; /// Contents of the CHLEGEND record.
XclImpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record).
XclImpChTextRef mxText; /// Legend text format (CHTEXT group).
XclImpChFrameRef mxFrame; /// Legend frame format (CHFRAME group).
};
@ -1265,6 +1295,8 @@ public:
/** Returns the axes set index used by the chart API. */
inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); }
/** Returns the outer plot area position, if existing. */
inline XclImpChFramePosRef GetPlotAreaFramePos() const { return mxFramePos; }
/** Returns the specified chart type group. */
inline XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const { return maTypeGroups.get( nGroupIdx ); }
/** Returns the first chart type group. */
@ -1276,6 +1308,8 @@ public:
/** Creates a coordinate system and converts all series and axis settings. */
void Convert( XDiagramRef xDiagram ) const;
/** Converts the manual positions of all axis titles. */
void ConvertTitlePositions() const;
private:
/** Reads a CHAXIS record group containing a single axis. */
@ -1304,7 +1338,7 @@ private:
typedef ScfRefMap< sal_uInt16, XclImpChTypeGroup > XclImpChTypeGroupMap;
XclChAxesSet maData; /// Contents of the CHAXESSET record.
XclImpChFramePosRef mxPos; /// Position of the axes set (CHFRAMEPOS record).
XclImpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record).
XclImpChAxisRef mxXAxis; /// The X axis (CHAXIS group).
XclImpChAxisRef mxYAxis; /// The Y axis (CHAXIS group).
XclImpChAxisRef mxZAxis; /// The Z axis (CHAXIS group).
@ -1351,13 +1385,16 @@ public:
XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const;
/** Returns the specified default text. */
XclImpChTextRef GetDefaultText( XclChTextType eTextType ) const;
/** Returns true, if the plot area has benn moved and/or resized manually. */
bool IsManualPlotArea() const;
/** Returns the number of units on the progress bar needed for the chart. */
inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; }
/** Converts and writes all properties to the passed chart. */
void Convert( XChartDocRef xChartDoc,
XclImpDffConverter& rDffConv,
const ::rtl::OUString& rObjName ) const;
const ::rtl::OUString& rObjName,
const Rectangle& rChartRect ) const;
private:
/** Reads a CHSERIES group (data series source and formatting). */

138
sc/source/filter/inc/xlchart.hxx Normal file → Executable file
View file

@ -34,14 +34,19 @@
#define EXC_CHART2_3DBAR_HAIRLINES_ONLY 1
#include <map>
#include <tools/gen.hxx>
#include "fapihelper.hxx"
namespace com { namespace sun { namespace star {
namespace container { class XNameContainer; }
namespace lang { class XMultiServiceFactory; }
namespace chart { class XChartDocument; }
namespace chart2 { class XChartDocument; }
namespace drawing { class XShape; }
} } }
class XclRoot;
// Property names =============================================================
// service names
@ -72,6 +77,7 @@ namespace com { namespace sun { namespace star {
// property names
#define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" )
#define EXC_CHPROP_ANCHORPOSITION CREATE_OUSTRING( "AnchorPosition" )
#define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" )
#define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" )
#define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" )
@ -94,10 +100,12 @@ namespace com { namespace sun { namespace star {
#define EXC_CHPROP_ERRORBARSTYLE CREATE_OUSTRING( "ErrorBarStyle" )
#define EXC_CHPROP_ERRORBARX CREATE_OUSTRING( "ErrorBarX" )
#define EXC_CHPROP_ERRORBARY CREATE_OUSTRING( "ErrorBarY" )
#define EXC_CHPROP_EXPANSION CREATE_OUSTRING( "Expansion" )
#define EXC_CHPROP_FILLBITMAPMODE CREATE_OUSTRING( "FillBitmapMode" )
#define EXC_CHPROP_FILLSTYLE CREATE_OUSTRING( "FillStyle" )
#define EXC_CHPROP_GAPWIDTHSEQ CREATE_OUSTRING( "GapwidthSequence" )
#define EXC_CHPROP_GEOMETRY3D CREATE_OUSTRING( "Geometry3D" )
#define EXC_CHPROP_HASMAINTITLE CREATE_OUSTRING( "HasMainTitle" )
#define EXC_CHPROP_INCLUDEHIDDENCELLS CREATE_OUSTRING( "IncludeHiddenCells" )
#define EXC_CHPROP_JAPANESE CREATE_OUSTRING( "Japanese" )
#define EXC_CHPROP_LABEL CREATE_OUSTRING( "Label" )
@ -116,6 +124,7 @@ namespace com { namespace sun { namespace star {
#define EXC_CHPROP_PERCENTDIAGONAL CREATE_OUSTRING( "PercentDiagonal" )
#define EXC_CHPROP_PERSPECTIVE CREATE_OUSTRING( "Perspective" )
#define EXC_CHPROP_POSITIVEERROR CREATE_OUSTRING( "PositiveError" )
#define EXC_CHPROP_RELATIVEPOSITION CREATE_OUSTRING( "RelativePosition" )
#define EXC_CHPROP_RIGHTANGLEDAXES CREATE_OUSTRING( "RightAngledAxes" )
#define EXC_CHPROP_ROLE CREATE_OUSTRING( "Role" )
#define EXC_CHPROP_ROTATIONHORIZONTAL CREATE_OUSTRING( "RotationHorizontal" )
@ -169,7 +178,8 @@ const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use
const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index.
const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index.
const sal_Int32 EXC_CHART_UNIT = 4000; /// Chart objects are positioned in 1/4000 of chart area.
const sal_Int32 EXC_CHART_TOTALUNITS = 4000; /// Most chart objects are positioned in 1/4000 of chart area.
const sal_Int32 EXC_CHART_PLOTAREAUNITS = 1000; /// For objects that are positioned in 1/1000 of plot area.
// (0x0850) CHFRINFO ----------------------------------------------------------
@ -604,7 +614,8 @@ const sal_uInt16 EXC_ID_CHPROPERTIES = 0x1044;
const sal_uInt16 EXC_CHPROPS_MANSERIES = 0x0001; /// Manual series allocation.
const sal_uInt16 EXC_CHPROPS_SHOWVISIBLEONLY = 0x0002; /// Show visible cells only.
const sal_uInt16 EXC_CHPROPS_NORESIZE = 0x0004; /// Do not resize chart with window.
const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Plot area with CHFRAMEPOS records.
const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Manual plot area mode.
const sal_uInt16 EXC_CHPROPS_USEMANPLOTAREA = 0x0010; /// Manual plot area layout in CHFRAMEPOS record.
const sal_uInt8 EXC_CHPROPS_EMPTY_SKIP = 0; /// Skip empty values.
const sal_uInt8 EXC_CHPROPS_EMPTY_ZERO = 1; /// Plot empty values as zero.
@ -643,11 +654,11 @@ const sal_uInt16 EXC_ID_CHFORMAT = 0x104E;
const sal_uInt16 EXC_ID_CHFRAMEPOS = 0x104F;
const sal_uInt16 EXC_CHFRAMEPOS_ANY = 2;
const sal_uInt16 EXC_CHFRAMEPOS_LEGEND = 5;
const sal_uInt16 EXC_CHFRAMEPOS_MANUALSIZE = 1;
const sal_uInt16 EXC_CHFRAMEPOS_AUTOSIZE = 2;
const sal_uInt16 EXC_CHFRAMEPOS_POINTS = 0;
const sal_uInt16 EXC_CHFRAMEPOS_ABSSIZE_POINTS = 1;
const sal_uInt16 EXC_CHFRAMEPOS_PARENT = 2;
const sal_uInt16 EXC_CHFRAMEPOS_DEFOFFSET_PLOT = 3;
const sal_uInt16 EXC_CHFRAMEPOS_CHARTSIZE = 5;
// (0x1050) CHFORMATRUNS ------------------------------------------------------
@ -774,8 +785,8 @@ struct XclChFrBlock
struct XclChFramePos
{
XclChRectangle maRect; /// Object dependent position data.
sal_uInt16 mnObjType; /// Object type.
sal_uInt16 mnSizeMode; /// Size mode (manual, automatic).
sal_uInt16 mnTLMode; /// Top-left position mode.
sal_uInt16 mnBRMode; /// Bottom-right position mode.
explicit XclChFramePos();
};
@ -885,7 +896,7 @@ struct XclChText
sal_uInt8 mnVAlign; /// Vertical alignment.
sal_uInt16 mnBackMode; /// Background mode: transparent, opaque.
sal_uInt16 mnFlags; /// Additional flags.
sal_uInt16 mnPlacement; /// Text object placement (BIFF8+).
sal_uInt16 mnFlags2; /// Text object placement and text direction (BIFF8+).
sal_uInt16 mnRotation; /// Text object rotation (BIFF8+).
explicit XclChText();
@ -1013,7 +1024,6 @@ struct XclChLegend
struct XclChTypeGroup
{
XclChRectangle maRect; /// Position (not used).
sal_uInt16 mnFlags; /// Additional flags.
sal_uInt16 mnGroupIdx; /// Chart type group index.
@ -1060,7 +1070,6 @@ struct XclChValueRange
struct XclChTick
{
XclChRectangle maRect; /// Position (not used).
Color maTextColor; /// Tick labels color.
sal_uInt8 mnMajor; /// Type of tick marks of major grid.
sal_uInt8 mnMinor; /// Type of tick marks of minor grid.
@ -1076,7 +1085,6 @@ struct XclChTick
struct XclChAxis
{
XclChRectangle maRect; /// Position (not used).
sal_uInt16 mnType; /// Axis type.
explicit XclChAxis();
@ -1089,7 +1097,7 @@ struct XclChAxis
struct XclChAxesSet
{
XclChRectangle maRect; /// Position of the axes set.
XclChRectangle maRect; /// Position of the axes set (inner plot area).
sal_uInt16 mnAxesSetId; /// Primary/secondary axes set.
explicit XclChAxesSet();
@ -1158,16 +1166,6 @@ enum XclChFrameType
EXC_CHFRAMETYPE_INVISIBLE /// Missing frame represents invisible formatting.
};
/** Enumerates different text box types for default text formatting. */
enum XclChTextType
{
EXC_CHTEXTTYPE_TITLE, /// Chart title.
EXC_CHTEXTTYPE_LEGEND, /// Chart legend.
EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles.
EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels.
EXC_CHTEXTTYPE_DATALABEL /// Data point labels.
};
/** Contains information about auto formatting of a specific chart object type. */
struct XclChFormatInfo
{
@ -1298,6 +1296,30 @@ private:
XclChTypeInfoMap maInfoMap; /// Maps chart types to type info data.
};
// Chart text and title object helpers ========================================
/** Enumerates different text box types for default text formatting and title
positioning. */
enum XclChTextType
{
EXC_CHTEXTTYPE_TITLE, /// Chart title.
EXC_CHTEXTTYPE_LEGEND, /// Chart legend.
EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles.
EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels.
EXC_CHTEXTTYPE_DATALABEL /// Data point labels.
};
/** A map key for text and title objects. */
struct XclChTextKey : public ::std::pair< XclChTextType, ::std::pair< sal_uInt16, sal_uInt16 > >
{
inline explicit XclChTextKey( XclChTextType eTextType, sal_uInt16 nMainIdx = 0, sal_uInt16 nSubIdx = 0 )
{ first = eTextType; second.first = nMainIdx; second.second = nSubIdx; }
};
/** Function prototype receiving a chart document and returning a title shape. */
typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
(*XclChGetShapeFunc)( const ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument >& );
// Property helpers ===========================================================
class XclChObjectTable
@ -1363,10 +1385,6 @@ public:
sal_uInt16 ReadRotationProperties(
const ScfPropertySet& rPropSet,
bool bSupportsStacked );
/** Reads all legend properties from the passed property set. */
void ReadLegendProperties(
XclChLegend& rLegend,
const ScfPropertySet& rPropSet );
/** Writes all line properties to the passed property set. */
void WriteLineProperties(
@ -1397,10 +1415,6 @@ public:
ScfPropertySet& rPropSet,
sal_uInt16 nRotation,
bool bSupportsStacked );
/** Writes all legend properties to the passed property set. */
void WriteLegendProperties(
ScfPropertySet& rPropSet,
const XclChLegend& rLegend );
private:
/** Returns a line property set helper according to the passed property mode. */
@ -1423,51 +1437,47 @@ private:
ScfPropSetHelper maHatchHlpCommon; /// Properties for hatches in common objects.
ScfPropSetHelper maHatchHlpFilled; /// Properties for hatches in filled series.
ScfPropSetHelper maBitmapHlp; /// Properties for bitmaps.
ScfPropSetHelper maLegendHlp; /// Properties for legend.
};
// ============================================================================
/** Base struct for internal root data structs for import and export. */
class XclChRootData
struct XclChRootData
{
public:
typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef;
typedef ScfRef< XclChTypeInfoProvider > XclChTypeProvRef;
typedef ScfRef< XclChFormatInfoProvider > XclChFmtInfoProvRef;
typedef ScfRef< XclChObjectTable > XclChObjectTableRef;
typedef ::std::map< XclChTextKey, XclChGetShapeFunc > XclChGetShapeFuncMap;
public:
explicit XclChRootData();
virtual ~XclChRootData();
/** Returns the API reference of the chart document. */
XChartDocRef GetChartDoc() const;
/** Returns the chart type info provider, that contains data about all chart types. */
inline XclChTypeInfoProvider& GetTypeInfoProvider() const { return *mxTypeInfoProv; }
/** Returns the chart type info provider, that contains data about all chart types. */
inline XclChFormatInfoProvider& GetFormatInfoProvider() const { return *mxFmtInfoProv; }
inline XclChObjectTable& GetLineDashTable() const { return *mxLineDashTable; }
inline XclChObjectTable& GetGradientTable() const { return *mxGradientTable; }
inline XclChObjectTable& GetHatchTable() const { return *mxHatchTable; }
inline XclChObjectTable& GetBitmapTable() const { return *mxBitmapTable; }
/** Starts the API chart document conversion. Must be called once before any API access. */
void InitConversion( XChartDocRef xChartDoc );
/** Finishes the API chart document conversion. Must be called once before any API access. */
void FinishConversion();
private:
typedef ScfRef< XclChTypeInfoProvider > XclChTypeProvRef;
typedef ScfRef< XclChFormatInfoProvider > XclChFmtInfoProvRef;
typedef ScfRef< XclChObjectTable > XclChObjectTableRef;
XChartDocRef mxChartDoc; /// The chart document.
::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >
mxChartDoc; /// The chart document.
Rectangle maChartRect; /// Position and size of the chart shape.
XclChTypeProvRef mxTypeInfoProv; /// Provides info about chart types.
XclChFmtInfoProvRef mxFmtInfoProv; /// Provides info about auto formatting.
XclChObjectTableRef mxLineDashTable; /// Container for line dash styles.
XclChObjectTableRef mxGradientTable; /// Container for gradient fill styles.
XclChObjectTableRef mxHatchTable; /// Container for hatch fill styles.
XclChObjectTableRef mxBitmapTable; /// Container for bitmap fill styles.
XclChGetShapeFuncMap maGetShapeFuncs; /// Maps title shape getter functions.
sal_Int32 mnBorderGapX; /// Border gap to chart space in 1/100mm.
sal_Int32 mnBorderGapY; /// Border gap to chart space in 1/100mm.
double mfUnitSizeX; /// Size of a chart X unit (1/4000 of chart width) in 1/100 mm.
double mfUnitSizeY; /// Size of a chart Y unit (1/4000 of chart height) in 1/100 mm.
explicit XclChRootData();
virtual ~XclChRootData();
/** Starts the API chart document conversion. Must be called once before any API access. */
void InitConversion(
const XclRoot& rRoot,
const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc,
const Rectangle& rChartRect );
/** Finishes the API chart document conversion. Must be called once before any API access. */
void FinishConversion();
/** Returns the drawing shape interface of the specified title object. */
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
GetTitleShape( const XclChTextKey& rTitleKey ) const;
};
// ============================================================================

View file

@ -113,6 +113,8 @@ struct XclRootData
XclTracerRef mxTracer; /// Filter tracer.
RootDataRef mxRD; /// Old RootData struct. Will be removed.
double mfScreenPixelX; /// Width of a screen pixel (1/100 mm).
double mfScreenPixelY; /// Height of a screen pixel (1/100 mm).
long mnCharWidth; /// Width of '0' in default font (twips).
SCTAB mnScTab; /// Current Calc sheet index.
const bool mbExport; /// false = Import, true = Export.
@ -177,6 +179,11 @@ public:
/** Returns the current Calc sheet index. */
inline SCTAB GetCurrScTab() const { return mrData.mnScTab; }
/** Calculates the width of the passed number of pixels in 1/100 mm. */
sal_Int32 GetHmmFromPixelX( double fPixelX ) const;
/** Calculates the height of the passed number of pixels in 1/100 mm. */
sal_Int32 GetHmmFromPixelY( double fPixelY ) const;
/** Returns the medium to import from. */
inline SfxMedium& GetMedium() const { return mrData.mrMedium; }
/** Returns the document URL of the imported/exported file. */