diff options
Diffstat (limited to 'reportdesign/source')
188 files changed, 50367 insertions, 0 deletions
diff --git a/reportdesign/source/core/api/FixedLine.cxx b/reportdesign/source/core/api/FixedLine.cxx new file mode 100644 index 000000000..8a70f07a5 --- /dev/null +++ b/reportdesign/source/core/api/FixedLine.cxx @@ -0,0 +1,565 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <FixedLine.hxx> +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> +#include <Tools.hxx> +#include <FormatCondition.hxx> +#include <ReportHelperImpl.hxx> + +#define MIN_WIDTH 80 +#define MIN_HEIGHT 20 + +namespace reportdesign +{ + + using namespace com::sun::star; +static uno::Sequence< OUString > lcl_getLineOptionals() +{ + OUString pProps[] = { + OUString(PROPERTY_DATAFIELD) + ,OUString(PROPERTY_DEFAULTCONTROL) + ,OUString(PROPERTY_CONTROLBORDER) + ,OUString(PROPERTY_CONTROLBORDERCOLOR) + ,OUString(PROPERTY_CHARCOLOR) + ,OUString(PROPERTY_CHAREMPHASIS) + ,OUString(PROPERTY_CHARFONTCHARSET) + ,OUString(PROPERTY_CHARFONTFAMILY) + ,OUString(PROPERTY_CHARFONTNAME) + ,OUString(PROPERTY_CHARFONTPITCH) + ,OUString(PROPERTY_CHARFONTSTYLENAME) + ,OUString(PROPERTY_CHARHEIGHT) + ,OUString(PROPERTY_CHARPOSTURE) + ,OUString(PROPERTY_CHARRELIEF) + ,OUString(PROPERTY_FONTDESCRIPTOR) + ,OUString(PROPERTY_FONTDESCRIPTORASIAN) + ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX) + ,OUString(PROPERTY_CONTROLTEXTEMPHASISMARK) + ,OUString(PROPERTY_CHARROTATION) + ,OUString(PROPERTY_CHARSCALEWIDTH) + ,OUString(PROPERTY_CHARSTRIKEOUT) + ,OUString(PROPERTY_CHARUNDERLINECOLOR) + ,OUString(PROPERTY_CHARUNDERLINE) + ,OUString(PROPERTY_CHARWEIGHT) + ,OUString(PROPERTY_CHARWORDMODE) + ,OUString(PROPERTY_CONTROLBACKGROUND) + ,OUString(PROPERTY_CONTROLBACKGROUNDTRANSPARENT) + ,OUString(PROPERTY_CHARFLASH) + ,OUString(PROPERTY_CHARAUTOKERNING) + ,OUString(PROPERTY_CHARESCAPEMENTHEIGHT) + ,OUString(PROPERTY_CHARLOCALE) + ,OUString(PROPERTY_CHARESCAPEMENT) + ,OUString(PROPERTY_CHARCASEMAP) + ,OUString(PROPERTY_CHARCOMBINEISON) + ,OUString(PROPERTY_CHARCOMBINEPREFIX) + ,OUString(PROPERTY_CHARCOMBINESUFFIX) + ,OUString(PROPERTY_CHARHIDDEN) + ,OUString(PROPERTY_CHARSHADOWED) + ,OUString(PROPERTY_CHARCONTOURED) + ,OUString(PROPERTY_HYPERLINKURL) + ,OUString(PROPERTY_HYPERLINKTARGET) + ,OUString(PROPERTY_HYPERLINKNAME) + ,OUString(PROPERTY_VISITEDCHARSTYLENAME) + ,OUString(PROPERTY_UNVISITEDCHARSTYLENAME) + ,OUString(PROPERTY_CHARKERNING) + ,OUString(PROPERTY_PRINTREPEATEDVALUES) + ,OUString(PROPERTY_CONDITIONALPRINTEXPRESSION) + ,OUString(PROPERTY_PRINTWHENGROUPCHANGE) + ,OUString(PROPERTY_MASTERFIELDS) + ,OUString(PROPERTY_DETAILFIELDS) + ,OUString(PROPERTY_PARAADJUST) + + , OUString(PROPERTY_CHAREMPHASISASIAN) + , OUString(PROPERTY_CHARFONTNAMEASIAN) + , OUString(PROPERTY_CHARFONTSTYLENAMEASIAN) + , OUString(PROPERTY_CHARFONTFAMILYASIAN) + , OUString(PROPERTY_CHARFONTCHARSETASIAN) + , OUString(PROPERTY_CHARFONTPITCHASIAN) + , OUString(PROPERTY_CHARHEIGHTASIAN) + , OUString(PROPERTY_CHARUNDERLINEASIAN) + , OUString(PROPERTY_CHARWEIGHTASIAN) + , OUString(PROPERTY_CHARPOSTUREASIAN) + , OUString(PROPERTY_CHARWORDMODEASIAN) + , OUString(PROPERTY_CHARROTATIONASIAN) + , OUString(PROPERTY_CHARSCALEWIDTHASIAN) + , OUString(PROPERTY_CHARLOCALEASIAN) + , OUString(PROPERTY_CHAREMPHASISCOMPLEX) + , OUString(PROPERTY_CHARFONTNAMECOMPLEX) + , OUString(PROPERTY_CHARFONTSTYLENAMECOMPLEX) + , OUString(PROPERTY_CHARFONTFAMILYCOMPLEX) + , OUString(PROPERTY_CHARFONTCHARSETCOMPLEX) + , OUString(PROPERTY_CHARFONTPITCHCOMPLEX) + , OUString(PROPERTY_CHARHEIGHTCOMPLEX) + , OUString(PROPERTY_CHARUNDERLINECOMPLEX) + , OUString(PROPERTY_CHARWEIGHTCOMPLEX) + , OUString(PROPERTY_CHARPOSTURECOMPLEX) + , OUString(PROPERTY_CHARWORDMODECOMPLEX) + , OUString(PROPERTY_CHARROTATIONCOMPLEX) + , OUString(PROPERTY_CHARSCALEWIDTHCOMPLEX) + , OUString(PROPERTY_CHARLOCALECOMPLEX) + + + }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + +OFixedLine::OFixedLine(uno::Reference< uno::XComponentContext > const & _xContext) +:FixedLineBase(m_aMutex) +,FixedLinePropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getLineOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_LineStyle( drawing::LineStyle_NONE ) +,m_nOrientation(1) +,m_LineColor(0) +,m_LineTransparence(0) +,m_LineWidth(0) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FIXEDLINE); + m_aProps.aComponent.m_nWidth = MIN_WIDTH; +} + +OFixedLine::OFixedLine(uno::Reference< uno::XComponentContext > const & _xContext + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,uno::Reference< drawing::XShape >& _xShape + ,sal_Int32 _nOrientation) +:FixedLineBase(m_aMutex) +,FixedLinePropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getLineOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_LineStyle( drawing::LineStyle_NONE ) +,m_nOrientation(_nOrientation) +,m_LineColor(0) +,m_LineTransparence(0) +,m_LineWidth(0) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FIXEDLINE); + m_aProps.aComponent.m_xFactory = _xFactory; + osl_atomic_increment( &m_refCount ); + try + { + awt::Size aSize = _xShape->getSize(); + if ( m_nOrientation == 1 ) + { + if ( aSize.Width < MIN_WIDTH ) + { + aSize.Width = MIN_WIDTH; + _xShape->setSize(aSize); + } + } + else if ( MIN_HEIGHT > aSize.Height ) + { + aSize.Height = MIN_HEIGHT; + _xShape->setSize(aSize); + } + m_aProps.aComponent.setShape(_xShape,this,m_refCount); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OFixedLine::OFixedLine"); + } + osl_atomic_decrement( &m_refCount ); +} + +OFixedLine::~OFixedLine() +{ +} + +IMPLEMENT_FORWARD_REFCOUNT( OFixedLine, FixedLineBase ) + +uno::Any SAL_CALL OFixedLine::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = FixedLineBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = FixedLinePropertySet::queryInterface(_rType); + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn.hasValue() ? aReturn : (m_aProps.aComponent.m_xProxy.is() ? m_aProps.aComponent.m_xProxy->queryAggregation(_rType) : aReturn); +} + +void SAL_CALL OFixedLine::dispose() +{ + FixedLinePropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +OUString OFixedLine::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OFixedLine"; +} + + +OUString SAL_CALL OFixedLine::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OFixedLine::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_FIXEDLINE }; + + return aServices; +} + +uno::Reference< uno::XInterface > OFixedLine::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OFixedLine(xContext)); +} + + +uno::Sequence< OUString > SAL_CALL OFixedLine::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OFixedLine::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportComponent +REPORTCOMPONENT_IMPL3(OFixedLine,m_aProps.aComponent) +REPORTCOMPONENT_NOMASTERDETAIL(OFixedLine) + +::sal_Int16 SAL_CALL OFixedLine::getControlBorder( ) +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setControlBorder( ::sal_Int16 /*_border*/ ) +{ + throw beans::UnknownPropertyException(); +} + +::sal_Int32 SAL_CALL OFixedLine::getControlBorderColor() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setControlBorderColor( ::sal_Int32 /*_bordercolor*/ ) +{ + throw beans::UnknownPropertyException(); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OFixedLine::getPropertySetInfo( ) +{ + return FixedLinePropertySet::getPropertySetInfo(); +} + +void SAL_CALL OFixedLine::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + FixedLinePropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OFixedLine::getPropertyValue( const OUString& PropertyName ) +{ + return FixedLinePropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OFixedLine::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + FixedLinePropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OFixedLine::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + FixedLinePropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OFixedLine::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FixedLinePropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OFixedLine::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FixedLinePropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XReportControlModel +OUString SAL_CALL OFixedLine::getDataField() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setDataField( const OUString& /*_datafield*/ ) +{ + throw beans::UnknownPropertyException(); +} + +::sal_Int32 SAL_CALL OFixedLine::getControlBackground() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setControlBackground( ::sal_Int32 /*_backgroundcolor*/ ) +{ + throw beans::UnknownPropertyException(); +} + +sal_Bool SAL_CALL OFixedLine::getControlBackgroundTransparent() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setControlBackgroundTransparent( sal_Bool /*_controlbackgroundtransparent*/ ) +{ + throw beans::UnknownPropertyException(); +} + +sal_Bool SAL_CALL OFixedLine::getPrintWhenGroupChange() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setPrintWhenGroupChange( sal_Bool /*_printwhengroupchange*/ ) +{ + throw beans::UnknownPropertyException(); +} + +OUString SAL_CALL OFixedLine::getConditionalPrintExpression() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedLine::setConditionalPrintExpression( const OUString& /*_conditionalprintexpression*/ ) +{ + throw beans::UnknownPropertyException(); +} + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OFixedLine::createClone( ) +{ + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XFixedLine> xSet(cloneObject(xSource,m_aProps.aComponent.m_xFactory,SERVICE_FIXEDLINE),uno::UNO_QUERY_THROW); + return xSet; +} + + +// XFixedLine + +::sal_Int32 SAL_CALL OFixedLine::getOrientation() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_nOrientation; +} + +void SAL_CALL OFixedLine::setOrientation( ::sal_Int32 _orientation ) +{ + set(PROPERTY_ORIENTATION,_orientation,m_nOrientation); +} + +drawing::LineStyle SAL_CALL OFixedLine::getLineStyle() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_LineStyle; +} + +void SAL_CALL OFixedLine::setLineStyle( drawing::LineStyle _linestyle ) +{ + set(PROPERTY_LINESTYLE,_linestyle,m_LineStyle); +} + +drawing::LineDash SAL_CALL OFixedLine::getLineDash() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_LineDash; +} + +void SAL_CALL OFixedLine::setLineDash( const drawing::LineDash& _linedash ) +{ + set(PROPERTY_LINEDASH,_linedash,m_LineDash); +} + +::sal_Int32 SAL_CALL OFixedLine::getLineColor() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_LineColor; +} + +void SAL_CALL OFixedLine::setLineColor( ::sal_Int32 _linecolor ) +{ + set(PROPERTY_LINECOLOR,_linecolor,m_LineColor); +} + +::sal_Int16 SAL_CALL OFixedLine::getLineTransparence() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_LineTransparence; +} + +void SAL_CALL OFixedLine::setLineTransparence( ::sal_Int16 _linetransparence ) +{ + set(PROPERTY_LINETRANSPARENCE,_linetransparence,m_LineTransparence); +} + +::sal_Int32 SAL_CALL OFixedLine::getLineWidth() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_LineWidth; +} + +void SAL_CALL OFixedLine::setLineWidth( ::sal_Int32 _linewidth ) +{ + set(PROPERTY_LINEWIDTH,_linewidth,m_LineWidth); +} + + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OFixedLine::getParent( ) +{ + return OShapeHelper::getParent(this); +} + +void SAL_CALL OFixedLine::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + OShapeHelper::setParent(Parent,this); +} + +uno::Reference< report::XFormatCondition > SAL_CALL OFixedLine::createFormatCondition( ) +{ + return new OFormatCondition(m_aProps.aComponent.m_xContext); +} + +// XContainer +void SAL_CALL OFixedLine::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.addContainerListener(xListener); +} + +void SAL_CALL OFixedLine::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.removeContainerListener(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OFixedLine::getElementType( ) +{ + return cppu::UnoType<report::XFormatCondition>::get(); +} + +sal_Bool SAL_CALL OFixedLine::hasElements( ) +{ + return m_aProps.hasElements(); +} + +// XIndexContainer +void SAL_CALL OFixedLine::insertByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.insertByIndex(Index,Element); +} + +void SAL_CALL OFixedLine::removeByIndex( ::sal_Int32 Index ) +{ + m_aProps.removeByIndex(Index); +} + +// XIndexReplace +void SAL_CALL OFixedLine::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.replaceByIndex(Index,Element); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OFixedLine::getCount( ) +{ + return m_aProps.getCount(); +} + +uno::Any SAL_CALL OFixedLine::getByIndex( ::sal_Int32 Index ) +{ + return m_aProps.getByIndex( Index ); +} + +// XShape +awt::Point SAL_CALL OFixedLine::getPosition( ) +{ + return OShapeHelper::getPosition(this); +} + +void SAL_CALL OFixedLine::setPosition( const awt::Point& aPosition ) +{ + OShapeHelper::setPosition(aPosition,this); +} + +awt::Size SAL_CALL OFixedLine::getSize( ) +{ + return OShapeHelper::getSize(this); +} + +void SAL_CALL OFixedLine::setSize( const awt::Size& aSize ) +{ + if ( aSize.Width < MIN_WIDTH && m_nOrientation == 1 ) + throw beans::PropertyVetoException("Too small width for FixedLine; minimum is " + OUString::number(MIN_WIDTH) + "0 micrometer", static_cast<cppu::OWeakObject*>(this)); + else if ( aSize.Height < MIN_HEIGHT && m_nOrientation == 0 ) + throw beans::PropertyVetoException("Too small height for FixedLine; minimum is " + OUString::number(MIN_HEIGHT) + "0 micrometer", static_cast<cppu::OWeakObject*>(this)); + OShapeHelper::setSize(aSize,this); +} + +// XShapeDescriptor +OUString SAL_CALL OFixedLine::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aProps.aComponent.m_xShape.is() ) + return m_aProps.aComponent.m_xShape->getShapeType(); + return "com.sun.star.drawing.ControlShape"; +} + +OUString SAL_CALL OFixedLine::getHyperLinkURL() +{ + throw beans::UnknownPropertyException(); +} +void SAL_CALL OFixedLine::setHyperLinkURL(const OUString & /*the_value*/) +{ + throw beans::UnknownPropertyException(); +} +OUString SAL_CALL OFixedLine::getHyperLinkTarget() +{ + throw beans::UnknownPropertyException(); +} +void SAL_CALL OFixedLine::setHyperLinkTarget(const OUString & /*the_value*/) +{ + throw beans::UnknownPropertyException(); +} +OUString SAL_CALL OFixedLine::getHyperLinkName() +{ + throw beans::UnknownPropertyException(); +} +void SAL_CALL OFixedLine::setHyperLinkName(const OUString & /*the_value*/) +{ + throw beans::UnknownPropertyException(); +} + +NO_REPORTCONTROLFORMAT_IMPL(OFixedLine) + +sal_Bool SAL_CALL OFixedLine::getPrintRepeatedValues() +{ + throw beans::UnknownPropertyException(); +} +void SAL_CALL OFixedLine::setPrintRepeatedValues( sal_Bool /*_printrepeatedvalues*/ ) +{ + throw beans::UnknownPropertyException(); +} + + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/FixedText.cxx b/reportdesign/source/core/api/FixedText.cxx new file mode 100644 index 000000000..f8c7bef51 --- /dev/null +++ b/reportdesign/source/core/api/FixedText.cxx @@ -0,0 +1,323 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <FixedText.hxx> +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <Tools.hxx> +#include <tools/color.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <FormatCondition.hxx> +#include <ReportHelperImpl.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + +static uno::Sequence< OUString > lcl_getFixedTextOptionals() +{ + OUString pProps[] = { OUString(PROPERTY_DATAFIELD),OUString(PROPERTY_MASTERFIELDS),OUString(PROPERTY_DETAILFIELDS) }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + +OFixedText::OFixedText(uno::Reference< uno::XComponentContext > const & _xContext) +:FixedTextBase(m_aMutex) +,FixedTextPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getFixedTextOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FIXEDTEXT); + m_aProps.aComponent.m_nBorder = 0; // no border +} + +OFixedText::OFixedText(uno::Reference< uno::XComponentContext > const & _xContext + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,uno::Reference< drawing::XShape >& _xShape) +:FixedTextBase(m_aMutex) +,FixedTextPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getFixedTextOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FIXEDTEXT); + m_aProps.aComponent.m_nBorder = 0; // no border + m_aProps.aComponent.m_xFactory = _xFactory; + osl_atomic_increment( &m_refCount ); + { + m_aProps.aComponent.setShape(_xShape,this,m_refCount); + } + osl_atomic_decrement( &m_refCount ); +} + +OFixedText::~OFixedText() +{ +} + +IMPLEMENT_FORWARD_REFCOUNT( OFixedText, FixedTextBase ) + +uno::Any SAL_CALL OFixedText::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = FixedTextBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = FixedTextPropertySet::queryInterface(_rType); + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn.hasValue() ? aReturn : (m_aProps.aComponent.m_xProxy.is() ? m_aProps.aComponent.m_xProxy->queryAggregation(_rType) : aReturn); +} + + +void SAL_CALL OFixedText::dispose() +{ + FixedTextPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); + uno::Reference< report::XFixedText> xHoldAlive = this; +} + +OUString OFixedText::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OFixedText"; +} + + +OUString SAL_CALL OFixedText::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OFixedText::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_FIXEDTEXT }; + + return aServices; +} + +uno::Reference< uno::XInterface > OFixedText::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OFixedText(xContext)); +} + + +uno::Sequence< OUString > SAL_CALL OFixedText::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OFixedText::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportComponent +REPORTCOMPONENT_IMPL(OFixedText,m_aProps.aComponent) +REPORTCOMPONENT_IMPL2(OFixedText,m_aProps.aComponent) +REPORTCOMPONENT_NOMASTERDETAIL(OFixedText) +REPORTCONTROLFORMAT_IMPL(OFixedText,m_aProps.aFormatProperties) + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OFixedText::getPropertySetInfo( ) +{ + return FixedTextPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OFixedText::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + FixedTextPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OFixedText::getPropertyValue( const OUString& PropertyName ) +{ + return FixedTextPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OFixedText::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + FixedTextPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OFixedText::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + FixedTextPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OFixedText::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FixedTextPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OFixedText::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FixedTextPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XReportControlModel +OUString SAL_CALL OFixedText::getDataField() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OFixedText::setDataField( const OUString& /*_datafield*/ ) +{ + throw beans::UnknownPropertyException(); +} + + +sal_Bool SAL_CALL OFixedText::getPrintWhenGroupChange() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.bPrintWhenGroupChange; +} + +void SAL_CALL OFixedText::setPrintWhenGroupChange( sal_Bool _printwhengroupchange ) +{ + set(PROPERTY_PRINTWHENGROUPCHANGE,_printwhengroupchange,m_aProps.bPrintWhenGroupChange); +} + +OUString SAL_CALL OFixedText::getConditionalPrintExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aConditionalPrintExpression; +} + +void SAL_CALL OFixedText::setConditionalPrintExpression( const OUString& _conditionalprintexpression ) +{ + set(PROPERTY_CONDITIONALPRINTEXPRESSION,_conditionalprintexpression,m_aProps.aConditionalPrintExpression); +} + + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OFixedText::createClone( ) +{ + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XFixedText> xSet(cloneObject(xSource,m_aProps.aComponent.m_xFactory,SERVICE_FIXEDTEXT),uno::UNO_QUERY_THROW); + return xSet; +} + + +// XFixedText +OUString SAL_CALL OFixedText::getLabel() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_sLabel; +} + +void SAL_CALL OFixedText::setLabel( const OUString& _label ) +{ + set(PROPERTY_LABEL,_label,m_sLabel); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OFixedText::getParent( ) +{ + return OShapeHelper::getParent(this); +} + +void SAL_CALL OFixedText::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + OShapeHelper::setParent(Parent,this); +} + +uno::Reference< report::XFormatCondition > SAL_CALL OFixedText::createFormatCondition( ) +{ + return new OFormatCondition(m_aProps.aComponent.m_xContext); +} + +// XContainer +void SAL_CALL OFixedText::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.addContainerListener(xListener); +} + +void SAL_CALL OFixedText::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.removeContainerListener(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OFixedText::getElementType( ) +{ + return cppu::UnoType<report::XFormatCondition>::get(); +} + +sal_Bool SAL_CALL OFixedText::hasElements( ) +{ + return m_aProps.hasElements(); +} + +// XIndexContainer +void SAL_CALL OFixedText::insertByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.insertByIndex(Index,Element); +} + +void SAL_CALL OFixedText::removeByIndex( ::sal_Int32 Index ) +{ + m_aProps.removeByIndex(Index); +} + +// XIndexReplace +void SAL_CALL OFixedText::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.replaceByIndex(Index,Element); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OFixedText::getCount( ) +{ + return m_aProps.getCount(); +} + +uno::Any SAL_CALL OFixedText::getByIndex( ::sal_Int32 Index ) +{ + return m_aProps.getByIndex( Index ); +} + +// XShape +awt::Point SAL_CALL OFixedText::getPosition( ) +{ + return OShapeHelper::getPosition(this); +} + +void SAL_CALL OFixedText::setPosition( const awt::Point& aPosition ) +{ + OShapeHelper::setPosition(aPosition,this); +} + +awt::Size SAL_CALL OFixedText::getSize( ) +{ + return OShapeHelper::getSize(this); +} + +void SAL_CALL OFixedText::setSize( const awt::Size& aSize ) +{ + OShapeHelper::setSize(aSize,this); +} + + +// XShapeDescriptor +OUString SAL_CALL OFixedText::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aProps.aComponent.m_xShape.is() ) + return m_aProps.aComponent.m_xShape->getShapeType(); + return "com.sun.star.drawing.ControlShape"; +} + + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/FormatCondition.cxx b/reportdesign/source/core/api/FormatCondition.cxx new file mode 100644 index 000000000..04558f710 --- /dev/null +++ b/reportdesign/source/core/api/FormatCondition.cxx @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <FormatCondition.hxx> +#include <strings.hxx> +#include <tools/color.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <ReportHelperImpl.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + +uno::Reference< uno::XInterface > OFormatCondition::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OFormatCondition(xContext)); +} + + +OFormatCondition::OFormatCondition(uno::Reference< uno::XComponentContext > const & _xContext) +:FormatConditionBase(m_aMutex) +,FormatConditionPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()) +,m_bEnabled(true) +{ +} + +OFormatCondition::~OFormatCondition() +{ +} + +IMPLEMENT_FORWARD_XINTERFACE2(OFormatCondition,FormatConditionBase,FormatConditionPropertySet) + +void SAL_CALL OFormatCondition::dispose() +{ + FormatConditionPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +OUString OFormatCondition::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OFormatCondition"; +} + + +OUString SAL_CALL OFormatCondition::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OFormatCondition::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_FORMATCONDITION }; + + return aServices; +} + +uno::Sequence< OUString > SAL_CALL OFormatCondition::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OFormatCondition::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OFormatCondition::getPropertySetInfo( ) +{ + return FormatConditionPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OFormatCondition::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + FormatConditionPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OFormatCondition::getPropertyValue( const OUString& PropertyName ) +{ + return FormatConditionPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OFormatCondition::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + FormatConditionPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OFormatCondition::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + FormatConditionPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OFormatCondition::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FormatConditionPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OFormatCondition::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FormatConditionPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XFormatCondition +sal_Bool SAL_CALL OFormatCondition::getEnabled() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bEnabled; +} + +void SAL_CALL OFormatCondition::setEnabled( sal_Bool _enabled ) +{ + set(PROPERTY_ENABLED,_enabled,m_bEnabled); +} + +OUString SAL_CALL OFormatCondition::getFormula() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_sFormula; +} + +void SAL_CALL OFormatCondition::setFormula( const OUString& _formula ) +{ + set(PROPERTY_FORMULA,_formula,m_sFormula); +} + +// XReportControlFormat +REPORTCONTROLFORMAT_IMPL(OFormatCondition,m_aFormatProperties) + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/FormattedField.cxx b/reportdesign/source/core/api/FormattedField.cxx new file mode 100644 index 000000000..c8bcad859 --- /dev/null +++ b/reportdesign/source/core/api/FormattedField.cxx @@ -0,0 +1,361 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <FormattedField.hxx> +#include <com/sun/star/sdbc/XDataSource.hpp> +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <tools/color.hxx> +#include <connectivity/dbtools.hxx> +#include <comphelper/property.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <Tools.hxx> +#include <FormatCondition.hxx> +#include <ReportHelperImpl.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + using namespace comphelper; + +uno::Reference< uno::XInterface > OFormattedField::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OFormattedField(xContext)); +} + +static uno::Sequence< OUString > lcl_getFormattedFieldOptionals() +{ + OUString pProps[] = { OUString(PROPERTY_MASTERFIELDS),OUString(PROPERTY_DETAILFIELDS) }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + +OFormattedField::OFormattedField(uno::Reference< uno::XComponentContext > const & _xContext) +:FormattedFieldBase(m_aMutex) +,FormattedFieldPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getFormattedFieldOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nFormatKey(0) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FORMATTEDFIELD); +} + +OFormattedField::OFormattedField(uno::Reference< uno::XComponentContext > const & _xContext + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,uno::Reference< drawing::XShape >& _xShape) +:FormattedFieldBase(m_aMutex) +,FormattedFieldPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getFormattedFieldOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nFormatKey(0) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_FORMATTEDFIELD); + m_aProps.aComponent.m_xFactory = _xFactory; + osl_atomic_increment( &m_refCount ); + { + m_aProps.aComponent.setShape(_xShape,this,m_refCount); + } + osl_atomic_decrement( &m_refCount ); +} + +OFormattedField::~OFormattedField() +{ +} + +IMPLEMENT_FORWARD_REFCOUNT( OFormattedField, FormattedFieldBase ) + +uno::Any SAL_CALL OFormattedField::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = FormattedFieldBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = FormattedFieldPropertySet::queryInterface(_rType); + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn.hasValue() ? aReturn : (m_aProps.aComponent.m_xProxy.is() ? m_aProps.aComponent.m_xProxy->queryAggregation(_rType) : aReturn); +} + + +void SAL_CALL OFormattedField::dispose() +{ + FormattedFieldPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); + m_xFormatsSupplier.clear(); +} + +OUString OFormattedField::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OFormattedField"; +} + + +OUString SAL_CALL OFormattedField::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OFormattedField::getSupportedServiceNames_Static( ) +{ + return { SERVICE_FORMATTEDFIELD, "com.sun.star.awt.UnoControlFormattedFieldModel" }; +} + +uno::Sequence< OUString > SAL_CALL OFormattedField::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OFormattedField::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportComponent +REPORTCOMPONENT_IMPL(OFormattedField,m_aProps.aComponent) +REPORTCOMPONENT_IMPL2(OFormattedField,m_aProps.aComponent) +REPORTCOMPONENT_NOMASTERDETAIL(OFormattedField) +REPORTCONTROLFORMAT_IMPL(OFormattedField,m_aProps.aFormatProperties) + + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OFormattedField::getPropertySetInfo( ) +{ + return FormattedFieldPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OFormattedField::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + // special case here /// TODO check + if ( !aValue.hasValue() && aPropertyName == PROPERTY_FORMATKEY ) + m_nFormatKey = 0; + else + FormattedFieldPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OFormattedField::getPropertyValue( const OUString& PropertyName ) +{ + return FormattedFieldPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OFormattedField::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + FormattedFieldPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OFormattedField::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + FormattedFieldPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OFormattedField::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FormattedFieldPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OFormattedField::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FormattedFieldPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XReportControlModel +OUString SAL_CALL OFormattedField::getDataField() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aDataField; +} + +void SAL_CALL OFormattedField::setDataField( const OUString& _datafield ) +{ + set(PROPERTY_DATAFIELD,_datafield,m_aProps.aDataField); +} + +sal_Bool SAL_CALL OFormattedField::getPrintWhenGroupChange() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.bPrintWhenGroupChange; +} + +void SAL_CALL OFormattedField::setPrintWhenGroupChange( sal_Bool _printwhengroupchange ) +{ + set(PROPERTY_PRINTWHENGROUPCHANGE,_printwhengroupchange,m_aProps.bPrintWhenGroupChange); +} + +OUString SAL_CALL OFormattedField::getConditionalPrintExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aConditionalPrintExpression; +} + +void SAL_CALL OFormattedField::setConditionalPrintExpression( const OUString& _conditionalprintexpression ) +{ + set(PROPERTY_CONDITIONALPRINTEXPRESSION,_conditionalprintexpression,m_aProps.aConditionalPrintExpression); +} + + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OFormattedField::createClone( ) +{ + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XFormattedField> xSet(cloneObject(xSource,m_aProps.aComponent.m_xFactory,SERVICE_FORMATTEDFIELD),uno::UNO_QUERY_THROW); + + sal_Int32 i = 0; + for (const auto& rxFormatCondition : m_aProps.m_aFormatConditions) + { + uno::Reference< report::XFormatCondition > xCond = xSet->createFormatCondition(); + ::comphelper::copyProperties(rxFormatCondition, xCond); + xSet->insertByIndex(i,uno::Any(xCond)); + ++i; + } + return xSet; +} + +// XFormattedField + +::sal_Int32 SAL_CALL OFormattedField::getFormatKey() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_nFormatKey; +} + +void SAL_CALL OFormattedField::setFormatKey(::sal_Int32 _formatkey) +{ + set(PROPERTY_FORMATKEY,_formatkey,m_nFormatKey); +} + +uno::Reference< util::XNumberFormatsSupplier > SAL_CALL OFormattedField::getFormatsSupplier() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( !m_xFormatsSupplier.is() ) + { + uno::Reference< report::XSection> xSection = getSection(); + if ( xSection.is() ) + m_xFormatsSupplier.set(xSection->getReportDefinition(),uno::UNO_QUERY); + if ( !m_xFormatsSupplier.is() ) + { + uno::Reference< beans::XPropertySet> xProp(::dbtools::findDataSource(getParent()),uno::UNO_QUERY); + if ( xProp.is() ) + m_xFormatsSupplier.set(xProp->getPropertyValue("NumberFormatsSupplier"),uno::UNO_QUERY); + } + } + return m_xFormatsSupplier; +} + +void SAL_CALL OFormattedField::setFormatsSupplier( const uno::Reference< util::XNumberFormatsSupplier >& _formatssupplier ) +{ + set(PROPERTY_FORMATSSUPPLIER,_formatssupplier,m_xFormatsSupplier); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OFormattedField::getParent( ) +{ + return OShapeHelper::getParent(this); +} + +void SAL_CALL OFormattedField::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + OShapeHelper::setParent(Parent,this); +} + +uno::Reference< report::XFormatCondition > SAL_CALL OFormattedField::createFormatCondition( ) +{ + return new OFormatCondition(m_aProps.aComponent.m_xContext); +} + +// XContainer +void SAL_CALL OFormattedField::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.addContainerListener(xListener); +} + +void SAL_CALL OFormattedField::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.removeContainerListener(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OFormattedField::getElementType( ) +{ + return cppu::UnoType<report::XFormatCondition>::get(); +} + +sal_Bool SAL_CALL OFormattedField::hasElements( ) +{ + return m_aProps.hasElements(); +} + +// XIndexContainer +void SAL_CALL OFormattedField::insertByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.insertByIndex(Index,Element); +} + +void SAL_CALL OFormattedField::removeByIndex( ::sal_Int32 Index ) +{ + m_aProps.removeByIndex(Index); +} + +// XIndexReplace +void SAL_CALL OFormattedField::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.replaceByIndex(Index,Element); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OFormattedField::getCount( ) +{ + return m_aProps.getCount(); +} + +uno::Any SAL_CALL OFormattedField::getByIndex( ::sal_Int32 Index ) +{ + return m_aProps.getByIndex( Index ); +} + +// XShape +awt::Point SAL_CALL OFormattedField::getPosition( ) +{ + return OShapeHelper::getPosition(this); +} + +void SAL_CALL OFormattedField::setPosition( const awt::Point& aPosition ) +{ + OShapeHelper::setPosition(aPosition,this); +} + +awt::Size SAL_CALL OFormattedField::getSize( ) +{ + return OShapeHelper::getSize(this); +} + +void SAL_CALL OFormattedField::setSize( const awt::Size& aSize ) +{ + OShapeHelper::setSize(aSize,this); +} + + +// XShapeDescriptor +OUString SAL_CALL OFormattedField::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aProps.aComponent.m_xShape.is() ) + return m_aProps.aComponent.m_xShape->getShapeType(); + return "com.sun.star.drawing.ControlShape"; +} + + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Function.cxx b/reportdesign/source/core/api/Function.cxx new file mode 100644 index 000000000..55150a992 --- /dev/null +++ b/reportdesign/source/core/api/Function.cxx @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Function.hxx> +#include <strings.hxx> +#include <cppuhelper/supportsservice.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + +uno::Reference< uno::XInterface > OFunction::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OFunction(xContext)); +} + + +OFunction::OFunction(uno::Reference< uno::XComponentContext > const & _xContext) +:FunctionBase(m_aMutex) +,FunctionPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()) +,m_bPreEvaluated(false) +,m_bDeepTraversing(false) +{ + m_sInitialFormula.IsPresent = false; +} + +OFunction::~OFunction() +{ +} + +IMPLEMENT_FORWARD_XINTERFACE2(OFunction,FunctionBase,FunctionPropertySet) + +void SAL_CALL OFunction::dispose() +{ + FunctionPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +OUString OFunction::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OFunction"; +} + + +OUString SAL_CALL OFunction::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OFunction::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_FUNCTION }; + + return aServices; +} + +uno::Sequence< OUString > SAL_CALL OFunction::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OFunction::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OFunction::getPropertySetInfo( ) +{ + return FunctionPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OFunction::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + FunctionPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OFunction::getPropertyValue( const OUString& PropertyName ) +{ + return FunctionPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OFunction::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + FunctionPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OFunction::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + FunctionPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OFunction::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FunctionPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OFunction::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + FunctionPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// report::XFunction: +sal_Bool SAL_CALL OFunction::getPreEvaluated() +{ + osl::MutexGuard g(m_aMutex); + return m_bPreEvaluated; +} + + +void SAL_CALL OFunction::setPreEvaluated(sal_Bool the_value) +{ + set(PROPERTY_PREEVALUATED,the_value,m_bPreEvaluated); +} + +sal_Bool SAL_CALL OFunction::getDeepTraversing() +{ + osl::MutexGuard g(m_aMutex); + return m_bDeepTraversing; +} + + +void SAL_CALL OFunction::setDeepTraversing(sal_Bool the_value) +{ + set(PROPERTY_DEEPTRAVERSING,the_value,m_bDeepTraversing); +} + + +OUString SAL_CALL OFunction::getName() +{ + osl::MutexGuard g(m_aMutex); + return m_sName; +} + + +void SAL_CALL OFunction::setName(const OUString & the_value) +{ + set(PROPERTY_NAME,the_value,m_sName); +} + +OUString SAL_CALL OFunction::getFormula() +{ + osl::MutexGuard g(m_aMutex); + return m_sFormula; +} + +void SAL_CALL OFunction::setFormula(const OUString & the_value) +{ + set(PROPERTY_FORMULA,the_value,m_sFormula); +} + +beans::Optional< OUString> SAL_CALL OFunction::getInitialFormula() +{ + osl::MutexGuard g(m_aMutex); + return m_sInitialFormula; +} + +void SAL_CALL OFunction::setInitialFormula(const beans::Optional< OUString> & the_value) +{ + set(PROPERTY_INITIALFORMULA,the_value,m_sInitialFormula); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OFunction::getParent( ) +{ + osl::MutexGuard g(m_aMutex); + return m_xParent; +} + +void SAL_CALL OFunction::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + osl::MutexGuard g(m_aMutex); + if ( Parent.is() ) + { + uno::Reference< report::XFunctions> xFunctions(Parent,uno::UNO_QUERY_THROW); + m_xParent = xFunctions; + } + else + m_xParent.clear(); +} + + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Functions.cxx b/reportdesign/source/core/api/Functions.cxx new file mode 100644 index 000000000..820d3c0ea --- /dev/null +++ b/reportdesign/source/core/api/Functions.cxx @@ -0,0 +1,193 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Functions.hxx> +#include <Function.hxx> +#include <core_resource.hxx> +#include <strings.hrc> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/NoSupportException.hpp> +#include <o3tl/safeint.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + +OFunctions::OFunctions(const uno::Reference< report::XFunctionsSupplier >& _xParent,const uno::Reference< uno::XComponentContext >& context) +:FunctionsBase(m_aMutex) +,m_aContainerListeners(m_aMutex) +,m_xContext(context) +,m_xParent(_xParent) +{ +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +OFunctions::~OFunctions() +{ +} + +void SAL_CALL OFunctions::dispose() +{ + cppu::WeakComponentImplHelperBase::dispose(); +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +void SAL_CALL OFunctions::disposing() +{ + for (auto& rFunction : m_aFunctions) + rFunction->dispose(); + m_aFunctions.clear(); + lang::EventObject aDisposeEvent( static_cast< ::cppu::OWeakObject* >( this ) ); + m_aContainerListeners.disposeAndClear( aDisposeEvent ); + m_xContext.clear(); +} + +// XFunctionsSupplier + +uno::Reference< report::XFunction > SAL_CALL OFunctions::createFunction( ) +{ + return new OFunction(m_xContext); +} + +// XIndexContainer +void SAL_CALL OFunctions::insertByIndex( ::sal_Int32 Index, const uno::Any& aElement ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + bool bAdd = (Index == static_cast<sal_Int32>(m_aFunctions.size())); + if ( !bAdd ) + checkIndex(Index); + uno::Reference< report::XFunction > xFunction(aElement,uno::UNO_QUERY); + if ( !xFunction.is() ) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2); + + if ( bAdd ) + m_aFunctions.push_back(xFunction); + else + { + TFunctions::iterator aPos = m_aFunctions.begin(); + ::std::advance(aPos,Index); + m_aFunctions.insert(aPos, xFunction); + } + xFunction->setParent(*this); + } + // notify our container listeners + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), aElement, uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementInserted,aEvent); +} + + +void SAL_CALL OFunctions::removeByIndex( ::sal_Int32 Index ) +{ + uno::Reference< report::XFunction > xFunction; + { + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + TFunctions::iterator aPos = m_aFunctions.begin(); + ::std::advance(aPos,Index); + xFunction = *aPos; + m_aFunctions.erase(aPos); + xFunction->setParent(nullptr); + } + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), uno::Any(xFunction), uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementRemoved,aEvent); +} + +// XIndexReplace +void SAL_CALL OFunctions::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + uno::Any aOldElement; + { + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + uno::Reference< report::XFunction > xFunction(Element,uno::UNO_QUERY); + if ( !xFunction.is() ) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2); + TFunctions::iterator aPos = m_aFunctions.begin(); + ::std::advance(aPos,Index); + aOldElement <<= *aPos; + *aPos = xFunction; + } + + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), Element, aOldElement); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementReplaced,aEvent); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OFunctions::getCount( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aFunctions.size(); +} + +uno::Any SAL_CALL OFunctions::getByIndex( ::sal_Int32 Index ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + TFunctions::const_iterator aPos = m_aFunctions.begin(); + ::std::advance(aPos,Index); + return uno::Any(*aPos); +} + +// XElementAccess +uno::Type SAL_CALL OFunctions::getElementType( ) +{ + return cppu::UnoType<report::XFunction>::get(); +} + +sal_Bool SAL_CALL OFunctions::hasElements( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return !m_aFunctions.empty(); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OFunctions::getParent( ) +{ + return m_xParent; +} + +void SAL_CALL OFunctions::setParent( const uno::Reference< uno::XInterface >& /*Parent*/ ) +{ + throw lang::NoSupportException(); +} + +// XContainer +void SAL_CALL OFunctions::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.addInterface(xListener); +} + +void SAL_CALL OFunctions::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.removeInterface(xListener); +} + +void OFunctions::checkIndex(sal_Int32 _nIndex) +{ + if ( _nIndex < 0 || m_aFunctions.size() <= o3tl::make_unsigned(_nIndex) ) + throw lang::IndexOutOfBoundsException(); +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Group.cxx b/reportdesign/source/core/api/Group.cxx new file mode 100644 index 000000000..b78e433cb --- /dev/null +++ b/reportdesign/source/core/api/Group.cxx @@ -0,0 +1,321 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Group.hxx> +#include <Section.hxx> +#include <com/sun/star/lang/NoSupportException.hpp> +#include <com/sun/star/report/GroupOn.hpp> +#include <com/sun/star/report/KeepTogether.hpp> +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <Tools.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/types.hxx> +#include <Functions.hxx> + + +namespace reportdesign +{ + + using namespace com::sun::star; + +OGroup::OGroup(const uno::Reference< report::XGroups >& _xParent + ,const uno::Reference< uno::XComponentContext >& _xContext) +:GroupBase(m_aMutex) +,GroupPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()) +,m_xContext(_xContext) +,m_xParent(_xParent) +{ + osl_atomic_increment(&m_refCount); + { + m_xFunctions = new OFunctions(this,m_xContext); + } + osl_atomic_decrement( &m_refCount ); +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +OGroup::~OGroup() +{ +} + +IMPLEMENT_FORWARD_XINTERFACE2(OGroup,GroupBase,GroupPropertySet) + +OUString SAL_CALL OGroup::getImplementationName( ) +{ + return "com.sun.star.comp.report.Group"; +} + +uno::Sequence< OUString> OGroup::getSupportedServiceNames_Static() +{ + uno::Sequence<OUString> aSupported { SERVICE_GROUP }; + return aSupported; +} + +uno::Sequence< OUString> SAL_CALL OGroup::getSupportedServiceNames() +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OGroup::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +void SAL_CALL OGroup::dispose() +{ + GroupPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +void SAL_CALL OGroup::disposing() +{ + m_xHeader.clear(); + m_xFooter.clear(); + ::comphelper::disposeComponent(m_xFunctions); + m_xContext.clear(); +} + +// XGroup +sal_Bool SAL_CALL OGroup::getSortAscending() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_eSortAscending; +} + +void SAL_CALL OGroup::setSortAscending( sal_Bool _sortascending ) +{ + set(PROPERTY_SORTASCENDING,_sortascending,m_aProps.m_eSortAscending); +} + +sal_Bool SAL_CALL OGroup::getHeaderOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xHeader.is(); +} + +void SAL_CALL OGroup::setHeaderOn( sal_Bool _headeron ) +{ + if ( bool(_headeron) != m_xHeader.is() ) + { + OUString sName(RptResId(RID_STR_GROUP_HEADER)); + setSection(PROPERTY_HEADERON,_headeron,sName,m_xHeader); + } +} + +sal_Bool SAL_CALL OGroup::getFooterOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xFooter.is(); +} + +void SAL_CALL OGroup::setFooterOn( sal_Bool _footeron ) +{ + if ( bool(_footeron) != m_xFooter.is() ) + { + OUString sName(RptResId(RID_STR_GROUP_FOOTER)); + setSection(PROPERTY_FOOTERON,_footeron,sName,m_xFooter); + } +} + +uno::Reference< report::XSection > SAL_CALL OGroup::getHeader() +{ + uno::Reference< report::XSection > xRet; + { + ::osl::MutexGuard aGuard(m_aMutex); + xRet = m_xHeader; + } + + if ( !xRet.is() ) + throw container::NoSuchElementException(); + return xRet; +} + +uno::Reference< report::XSection > SAL_CALL OGroup::getFooter() +{ + uno::Reference< report::XSection > xRet; + { + ::osl::MutexGuard aGuard(m_aMutex); + xRet = m_xFooter; + } + + if ( !xRet.is() ) + throw container::NoSuchElementException(); + return xRet; +} + +::sal_Int16 SAL_CALL OGroup::getGroupOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_nGroupOn; +} + +void SAL_CALL OGroup::setGroupOn( ::sal_Int16 _groupon ) +{ + if ( _groupon < report::GroupOn::DEFAULT || _groupon > report::GroupOn::INTERVAL ) + throwIllegallArgumentException(u"css::report::GroupOn" + ,*this + ,1); + set(PROPERTY_GROUPON,_groupon,m_aProps.m_nGroupOn); +} + +::sal_Int32 SAL_CALL OGroup::getGroupInterval() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_nGroupInterval; +} + +void SAL_CALL OGroup::setGroupInterval( ::sal_Int32 _groupinterval ) +{ + set(PROPERTY_GROUPINTERVAL,_groupinterval,m_aProps.m_nGroupInterval); +} + +::sal_Int16 SAL_CALL OGroup::getKeepTogether() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_nKeepTogether; +} + +void SAL_CALL OGroup::setKeepTogether( ::sal_Int16 _keeptogether ) +{ + if ( _keeptogether < report::KeepTogether::NO || _keeptogether > report::KeepTogether::WITH_FIRST_DETAIL ) + throwIllegallArgumentException(u"css::report::KeepTogether" + ,*this + ,1); + set(PROPERTY_KEEPTOGETHER,_keeptogether,m_aProps.m_nKeepTogether); +} + +uno::Reference< report::XGroups > SAL_CALL OGroup::getGroups() +{ + return m_xParent; +} + +OUString SAL_CALL OGroup::getExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_sExpression; +} + +void SAL_CALL OGroup::setExpression( const OUString& _expression ) +{ + set(PROPERTY_EXPRESSION,_expression,m_aProps.m_sExpression); +} + +sal_Bool SAL_CALL OGroup::getStartNewColumn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_bStartNewColumn; +} + +void SAL_CALL OGroup::setStartNewColumn( sal_Bool _startnewcolumn ) +{ + set(PROPERTY_STARTNEWCOLUMN,_startnewcolumn,m_aProps.m_bStartNewColumn); +} + + +sal_Bool SAL_CALL OGroup::getResetPageNumber() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.m_bResetPageNumber; +} + +void SAL_CALL OGroup::setResetPageNumber( sal_Bool _resetpagenumber ) +{ + set(PROPERTY_RESETPAGENUMBER,_resetpagenumber,m_aProps.m_bResetPageNumber); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OGroup::getParent( ) +{ + return m_xParent; +} + +void SAL_CALL OGroup::setParent( const uno::Reference< uno::XInterface >& /*Parent*/ ) +{ + throw lang::NoSupportException(); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OGroup::getPropertySetInfo( ) +{ + return GroupPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OGroup::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + GroupPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OGroup::getPropertyValue( const OUString& PropertyName ) +{ + return GroupPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OGroup::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + GroupPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OGroup::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + GroupPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OGroup::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + GroupPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OGroup::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + GroupPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +void OGroup::setSection( const OUString& _sProperty + ,bool _bOn + ,const OUString& _sName + ,uno::Reference< report::XSection>& _member) +{ + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, uno::Any(_member), uno::Any(_bOn), &l); + + // create section if needed + if ( _bOn && !_member.is() ) + _member = OSection::createOSection(this, m_xContext); + else if ( !_bOn ) + ::comphelper::disposeComponent(_member); + + if ( _member.is() ) + _member->setName(_sName); + } + l.notify(); +} + +uno::Reference< report::XFunctions > SAL_CALL OGroup::getFunctions() +{ + return m_xFunctions; +} + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Groups.cxx b/reportdesign/source/core/api/Groups.cxx new file mode 100644 index 000000000..780c6093b --- /dev/null +++ b/reportdesign/source/core/api/Groups.cxx @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Groups.hxx> +#include <Group.hxx> +#include <com/sun/star/lang/NoSupportException.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <o3tl/safeint.hxx> +#include <core_resource.hxx> +#include <strings.hrc> + +namespace reportdesign +{ + + using namespace com::sun::star; + +OGroups::OGroups(const uno::Reference< report::XReportDefinition >& _xParent,const uno::Reference< uno::XComponentContext >& context) +:GroupsBase(m_aMutex) +,m_aContainerListeners(m_aMutex) +,m_xContext(context) +,m_xParent(_xParent) +{ +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +OGroups::~OGroups() +{ +} + +void SAL_CALL OGroups::dispose() +{ + cppu::WeakComponentImplHelperBase::dispose(); +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +void SAL_CALL OGroups::disposing() +{ + for(auto& rGroup : m_aGroups) + rGroup->dispose(); + m_aGroups.clear(); + lang::EventObject aDisposeEvent( static_cast< ::cppu::OWeakObject* >( this ) ); + m_aContainerListeners.disposeAndClear( aDisposeEvent ); + m_xContext.clear(); +} + +// XGroups +uno::Reference< report::XReportDefinition > SAL_CALL OGroups::getReportDefinition() +{ + return m_xParent; +} + +uno::Reference< report::XGroup > SAL_CALL OGroups::createGroup( ) +{ + return new OGroup(this,m_xContext); +} + +// XIndexContainer +void SAL_CALL OGroups::insertByIndex( ::sal_Int32 Index, const uno::Any& aElement ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + bool bAdd = (Index == static_cast<sal_Int32>(m_aGroups.size())); + if ( !bAdd ) + checkIndex(Index); + uno::Reference< report::XGroup > xGroup(aElement,uno::UNO_QUERY); + if ( !xGroup.is() ) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2); + + if ( bAdd ) + m_aGroups.push_back(xGroup); + else + { + TGroups::iterator aPos = m_aGroups.begin(); + ::std::advance(aPos,Index); + m_aGroups.insert(aPos, xGroup); + } + } + // notify our container listeners + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), aElement, uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementInserted,aEvent); +} + + +void SAL_CALL OGroups::removeByIndex( ::sal_Int32 Index ) +{ + uno::Reference< report::XGroup > xGroup; + { + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + TGroups::iterator aPos = m_aGroups.begin(); + ::std::advance(aPos,Index); + xGroup = *aPos; + m_aGroups.erase(aPos); + } + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), uno::Any(xGroup), uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementRemoved,aEvent); +} + +// XIndexReplace +void SAL_CALL OGroups::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + uno::Any aOldElement; + { + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + uno::Reference< report::XGroup > xGroup(Element,uno::UNO_QUERY); + if ( !xGroup.is() ) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2); + TGroups::iterator aPos = m_aGroups.begin(); + ::std::advance(aPos,Index); + aOldElement <<= *aPos; + *aPos = xGroup; + } + + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(Index), Element, aOldElement); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementReplaced,aEvent); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OGroups::getCount( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aGroups.size(); +} + +uno::Any SAL_CALL OGroups::getByIndex( ::sal_Int32 Index ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkIndex(Index); + TGroups::const_iterator aPos = m_aGroups.begin(); + ::std::advance(aPos,Index); + return uno::Any(*aPos); +} + +// XElementAccess +uno::Type SAL_CALL OGroups::getElementType( ) +{ + return cppu::UnoType<report::XGroup>::get(); +} + +sal_Bool SAL_CALL OGroups::hasElements( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return !m_aGroups.empty(); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OGroups::getParent( ) +{ + return m_xParent; +} + +void SAL_CALL OGroups::setParent( const uno::Reference< uno::XInterface >& /*Parent*/ ) +{ + throw lang::NoSupportException(); +} + +// XContainer +void SAL_CALL OGroups::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.addInterface(xListener); +} + +void SAL_CALL OGroups::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.removeInterface(xListener); +} + +void OGroups::checkIndex(sal_Int32 _nIndex) +{ + if ( _nIndex < 0 || m_aGroups.size() <= o3tl::make_unsigned(_nIndex) ) + throw lang::IndexOutOfBoundsException(); +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ImageControl.cxx b/reportdesign/source/core/api/ImageControl.cxx new file mode 100644 index 000000000..371f8831e --- /dev/null +++ b/reportdesign/source/core/api/ImageControl.cxx @@ -0,0 +1,482 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ImageControl.hxx> +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <Tools.hxx> +#include <tools/color.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <FormatCondition.hxx> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <ReportHelperImpl.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; +static uno::Sequence< OUString > lcl_getImageOptionals() +{ + OUString pProps[] = { + OUString(PROPERTY_CHARCOLOR) + ,OUString(PROPERTY_CHAREMPHASIS) + ,OUString(PROPERTY_CHARFONTCHARSET) + ,OUString(PROPERTY_CHARFONTFAMILY) + ,OUString(PROPERTY_CHARFONTNAME) + ,OUString(PROPERTY_CHARFONTPITCH) + ,OUString(PROPERTY_CHARFONTSTYLENAME) + ,OUString(PROPERTY_CHARHEIGHT) + ,OUString(PROPERTY_CHARPOSTURE) + ,OUString(PROPERTY_CHARRELIEF) + ,OUString(PROPERTY_FONTDESCRIPTOR) + ,OUString(PROPERTY_FONTDESCRIPTORASIAN) + ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX) + ,OUString(PROPERTY_CONTROLTEXTEMPHASISMARK) + ,OUString(PROPERTY_CHARROTATION) + ,OUString(PROPERTY_CHARSCALEWIDTH) + ,OUString(PROPERTY_CHARSTRIKEOUT) + ,OUString(PROPERTY_CHARUNDERLINECOLOR) + ,OUString(PROPERTY_CHARUNDERLINE) + ,OUString(PROPERTY_CHARWEIGHT) + ,OUString(PROPERTY_CHARWORDMODE) + ,OUString(PROPERTY_CHARFLASH) + ,OUString(PROPERTY_CHARAUTOKERNING) + ,OUString(PROPERTY_CHARESCAPEMENTHEIGHT) + ,OUString(PROPERTY_CHARLOCALE) + ,OUString(PROPERTY_CHARESCAPEMENT) + ,OUString(PROPERTY_CHARCASEMAP) + ,OUString(PROPERTY_CHARCOMBINEISON) + ,OUString(PROPERTY_CHARCOMBINEPREFIX) + ,OUString(PROPERTY_CHARCOMBINESUFFIX) + ,OUString(PROPERTY_CHARHIDDEN) + ,OUString(PROPERTY_CHARSHADOWED) + ,OUString(PROPERTY_CHARCONTOURED) + ,OUString(PROPERTY_VISITEDCHARSTYLENAME) + ,OUString(PROPERTY_UNVISITEDCHARSTYLENAME) + ,OUString(PROPERTY_CHARKERNING) + ,OUString(PROPERTY_MASTERFIELDS) + ,OUString(PROPERTY_DETAILFIELDS) + ,OUString(PROPERTY_PARAADJUST) + , OUString(PROPERTY_CHAREMPHASISASIAN) + , OUString(PROPERTY_CHARFONTNAMEASIAN) + , OUString(PROPERTY_CHARFONTSTYLENAMEASIAN) + , OUString(PROPERTY_CHARFONTFAMILYASIAN) + , OUString(PROPERTY_CHARFONTCHARSETASIAN) + , OUString(PROPERTY_CHARFONTPITCHASIAN) + , OUString(PROPERTY_CHARHEIGHTASIAN) + , OUString(PROPERTY_CHARUNDERLINEASIAN) + , OUString(PROPERTY_CHARWEIGHTASIAN) + , OUString(PROPERTY_CHARPOSTUREASIAN) + , OUString(PROPERTY_CHARWORDMODEASIAN) + , OUString(PROPERTY_CHARROTATIONASIAN) + , OUString(PROPERTY_CHARSCALEWIDTHASIAN) + , OUString(PROPERTY_CHARLOCALEASIAN) + , OUString(PROPERTY_CHAREMPHASISCOMPLEX) + , OUString(PROPERTY_CHARFONTNAMECOMPLEX) + , OUString(PROPERTY_CHARFONTSTYLENAMECOMPLEX) + , OUString(PROPERTY_CHARFONTFAMILYCOMPLEX) + , OUString(PROPERTY_CHARFONTCHARSETCOMPLEX) + , OUString(PROPERTY_CHARFONTPITCHCOMPLEX) + , OUString(PROPERTY_CHARHEIGHTCOMPLEX) + , OUString(PROPERTY_CHARUNDERLINECOMPLEX) + , OUString(PROPERTY_CHARWEIGHTCOMPLEX) + , OUString(PROPERTY_CHARPOSTURECOMPLEX) + , OUString(PROPERTY_CHARWORDMODECOMPLEX) + , OUString(PROPERTY_CHARROTATIONCOMPLEX) + , OUString(PROPERTY_CHARSCALEWIDTHCOMPLEX) + , OUString(PROPERTY_CHARLOCALECOMPLEX) + + }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + + +OImageControl::OImageControl(uno::Reference< uno::XComponentContext > const & _xContext) +:ImageControlBase(m_aMutex) +,ImageControlPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getImageOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nScaleMode(awt::ImageScaleMode::NONE) +,m_bPreserveIRI(true) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_IMAGECONTROL); +} + +OImageControl::OImageControl(uno::Reference< uno::XComponentContext > const & _xContext + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,uno::Reference< drawing::XShape >& _xShape) +:ImageControlBase(m_aMutex) +,ImageControlPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getImageOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nScaleMode(awt::ImageScaleMode::NONE) +,m_bPreserveIRI(true) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_IMAGECONTROL); + m_aProps.aComponent.m_xFactory = _xFactory; + osl_atomic_increment( &m_refCount ); + { + m_aProps.aComponent.setShape(_xShape,this,m_refCount); + } + osl_atomic_decrement( &m_refCount ); +} + +OImageControl::~OImageControl() +{ +} + +//IMPLEMENT_FORWARD_XINTERFACE2(OImageControl,ImageControlBase,ImageControlPropertySet) +IMPLEMENT_FORWARD_REFCOUNT( OImageControl, ImageControlBase ) + +uno::Any SAL_CALL OImageControl::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = ImageControlBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = ImageControlPropertySet::queryInterface(_rType); + + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn.hasValue() ? aReturn : (m_aProps.aComponent.m_xProxy.is() ? m_aProps.aComponent.m_xProxy->queryAggregation(_rType) : aReturn); +} + + +void SAL_CALL OImageControl::dispose() +{ + ImageControlPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +OUString OImageControl::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OImageControl"; +} + + +OUString SAL_CALL OImageControl::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OImageControl::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_IMAGECONTROL }; + + return aServices; +} + +uno::Reference< uno::XInterface > OImageControl::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OImageControl(xContext)); +} + + +uno::Sequence< OUString > SAL_CALL OImageControl::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OImageControl::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportComponent +REPORTCOMPONENT_IMPL(OImageControl,m_aProps.aComponent) +REPORTCOMPONENT_IMPL2(OImageControl,m_aProps.aComponent) +REPORTCOMPONENT_NOMASTERDETAIL(OImageControl) +NO_REPORTCONTROLFORMAT_IMPL(OImageControl) +OUString SAL_CALL OImageControl::getHyperLinkURL() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aFormatProperties.sHyperLinkURL; +} +void SAL_CALL OImageControl::setHyperLinkURL(const OUString & the_value) +{ + set(PROPERTY_HYPERLINKURL,the_value,m_aProps.aFormatProperties.sHyperLinkURL); +} +OUString SAL_CALL OImageControl::getHyperLinkTarget() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aFormatProperties.sHyperLinkTarget; +} +void SAL_CALL OImageControl::setHyperLinkTarget(const OUString & the_value) +{ + set(PROPERTY_HYPERLINKTARGET,the_value,m_aProps.aFormatProperties.sHyperLinkTarget); +} +OUString SAL_CALL OImageControl::getHyperLinkName() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aFormatProperties.sHyperLinkName; +} +void SAL_CALL OImageControl::setHyperLinkName(const OUString & the_value) +{ + set(PROPERTY_HYPERLINKNAME,the_value,m_aProps.aFormatProperties.sHyperLinkName); +} + + +::sal_Int32 SAL_CALL OImageControl::getControlBackground() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aFormatProperties.m_bBackgroundTransparent ? static_cast<sal_Int32>(COL_TRANSPARENT) : m_aProps.aFormatProperties.nBackgroundColor; +} + +void SAL_CALL OImageControl::setControlBackground( ::sal_Int32 _backgroundcolor ) +{ + bool bTransparent = _backgroundcolor == static_cast<sal_Int32>(COL_TRANSPARENT); + setControlBackgroundTransparent(bTransparent); + if ( !bTransparent ) + set(PROPERTY_CONTROLBACKGROUND,_backgroundcolor,m_aProps.aFormatProperties.nBackgroundColor); +} + +sal_Bool SAL_CALL OImageControl::getControlBackgroundTransparent() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aFormatProperties.m_bBackgroundTransparent; +} + +void SAL_CALL OImageControl::setControlBackgroundTransparent( sal_Bool _controlbackgroundtransparent ) +{ + set(PROPERTY_CONTROLBACKGROUNDTRANSPARENT,_controlbackgroundtransparent,m_aProps.aFormatProperties.m_bBackgroundTransparent); + if ( _controlbackgroundtransparent ) + set(PROPERTY_CONTROLBACKGROUND,static_cast<sal_Int32>(COL_TRANSPARENT),m_aProps.aFormatProperties.nBackgroundColor); +} + + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OImageControl::getPropertySetInfo( ) +{ + return ImageControlPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OImageControl::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + ImageControlPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OImageControl::getPropertyValue( const OUString& PropertyName ) +{ + return ImageControlPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OImageControl::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + ImageControlPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OImageControl::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + ImageControlPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OImageControl::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ImageControlPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OImageControl::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ImageControlPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XReportControlModel +OUString SAL_CALL OImageControl::getDataField() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aDataField; +} + +void SAL_CALL OImageControl::setDataField( const OUString& _datafield ) +{ + set(PROPERTY_DATAFIELD,_datafield,m_aProps.aDataField); +} + + +sal_Bool SAL_CALL OImageControl::getPrintWhenGroupChange() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.bPrintWhenGroupChange; +} + +void SAL_CALL OImageControl::setPrintWhenGroupChange( sal_Bool _printwhengroupchange ) +{ + set(PROPERTY_PRINTWHENGROUPCHANGE,_printwhengroupchange,m_aProps.bPrintWhenGroupChange); +} + +OUString SAL_CALL OImageControl::getConditionalPrintExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aConditionalPrintExpression; +} + +void SAL_CALL OImageControl::setConditionalPrintExpression( const OUString& _conditionalprintexpression ) +{ + set(PROPERTY_CONDITIONALPRINTEXPRESSION,_conditionalprintexpression,m_aProps.aConditionalPrintExpression); +} + + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OImageControl::createClone( ) +{ + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XImageControl> xSet(cloneObject(xSource,m_aProps.aComponent.m_xFactory,SERVICE_IMAGECONTROL),uno::UNO_QUERY_THROW); + return xSet; +} + + +// XImageControl + +OUString SAL_CALL OImageControl::getImageURL() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aImageURL; +} + +void SAL_CALL OImageControl::setImageURL( const OUString& _imageurl ) +{ + set(PROPERTY_IMAGEURL,_imageurl,m_aImageURL); +} + +uno::Reference< awt::XImageProducer > SAL_CALL OImageControl::getImageProducer( ) +{ + return uno::Reference< awt::XImageProducer >(); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OImageControl::getParent( ) +{ + return OShapeHelper::getParent(this); +} + +void SAL_CALL OImageControl::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + OShapeHelper::setParent(Parent,this); +} +uno::Reference< report::XFormatCondition > SAL_CALL OImageControl::createFormatCondition( ) +{ + return new OFormatCondition(m_aProps.aComponent.m_xContext); +} + +// XContainer +void SAL_CALL OImageControl::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.addContainerListener(xListener); +} + +void SAL_CALL OImageControl::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.removeContainerListener(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OImageControl::getElementType( ) +{ + return cppu::UnoType<report::XFormatCondition>::get(); +} + +sal_Bool SAL_CALL OImageControl::hasElements( ) +{ + return m_aProps.hasElements(); +} + +// XIndexContainer +void SAL_CALL OImageControl::insertByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.insertByIndex(Index,Element); +} + +void SAL_CALL OImageControl::removeByIndex( ::sal_Int32 Index ) +{ + m_aProps.removeByIndex(Index); +} + +// XIndexReplace +void SAL_CALL OImageControl::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.replaceByIndex(Index,Element); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OImageControl::getCount( ) +{ + return m_aProps.getCount(); +} + +uno::Any SAL_CALL OImageControl::getByIndex( ::sal_Int32 Index ) +{ + return m_aProps.getByIndex( Index ); +} + + +// XShape +awt::Point SAL_CALL OImageControl::getPosition( ) +{ + return OShapeHelper::getPosition(this); +} + +void SAL_CALL OImageControl::setPosition( const awt::Point& aPosition ) +{ + OShapeHelper::setPosition(aPosition,this); +} + +awt::Size SAL_CALL OImageControl::getSize( ) +{ + return OShapeHelper::getSize(this); +} + +void SAL_CALL OImageControl::setSize( const awt::Size& aSize ) +{ + OShapeHelper::setSize(aSize,this); +} + + +// XShapeDescriptor +OUString SAL_CALL OImageControl::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aProps.aComponent.m_xShape.is() ) + return m_aProps.aComponent.m_xShape->getShapeType(); + return "com.sun.star.drawing.ControlShape"; +} + +::sal_Int16 SAL_CALL OImageControl::getScaleMode() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_nScaleMode; +} + +void SAL_CALL OImageControl::setScaleMode( ::sal_Int16 _scalemode ) +{ + if ( _scalemode < awt::ImageScaleMode::NONE ||_scalemode > awt::ImageScaleMode::ANISOTROPIC ) + throw lang::IllegalArgumentException(); + set(PROPERTY_SCALEMODE,_scalemode,m_nScaleMode); +} + +sal_Bool SAL_CALL OImageControl::getPreserveIRI() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bPreserveIRI; +} + +void SAL_CALL OImageControl::setPreserveIRI( sal_Bool _preserveiri ) +{ + set(PROPERTY_PRESERVEIRI,_preserveiri,m_bPreserveIRI); +} + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ReportComponent.cxx b/reportdesign/source/core/api/ReportComponent.cxx new file mode 100644 index 000000000..5c036b5d6 --- /dev/null +++ b/reportdesign/source/core/api/ReportComponent.cxx @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportComponent.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/outdev.hxx> +#include <vcl/settings.hxx> + +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontWidth.hpp> +#include <ReportControlModel.hxx> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <comphelper/uno3.hxx> +#include <unotools/lingucfg.hxx> +#include <i18nlangtag/mslangid.hxx> +#include <i18nlangtag/languagetag.hxx> + + +namespace reportdesign +{ + + using namespace com::sun::star; + using namespace comphelper; + +static void lcl_getDefaultFonts( vcl::Font& rLatinFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont, LanguageType _eLatin, LanguageType _eCJK, LanguageType _eCTL ) +{ + LanguageType eLatin = _eLatin; + + // If the UI language is Korean, the default Latin font has to + // be queried for Korean, too (the Latin language from the document can't be Korean). + // This is the same logic as in SwDocShell::InitNew. + LanguageType eUiLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType(); + if (MsLangId::isKorean(eUiLanguage)) + eLatin = eUiLanguage; + + rLatinFont = OutputDevice::GetDefaultFont( DefaultFontType::LATIN_PRESENTATION, eLatin, GetDefaultFontFlags::OnlyOne ); + rCJKFont = OutputDevice::GetDefaultFont( DefaultFontType::CJK_PRESENTATION, _eCJK, GetDefaultFontFlags::OnlyOne ); + rCTLFont = OutputDevice::GetDefaultFont( DefaultFontType::CTL_PRESENTATION, _eCTL, GetDefaultFontFlags::OnlyOne ) ; +} +OFormatProperties::OFormatProperties() + :nAlign(style::ParagraphAdjust_LEFT) + ,nFontEmphasisMark(0) + ,nFontRelief(0) + ,nTextColor(0) + ,nTextLineColor(0) + ,nBackgroundColor(COL_TRANSPARENT) + ,aVerticalAlignment( style::VerticalAlignment_TOP ) + ,nCharEscapement(0) + ,nCharCaseMap(0) + ,nCharKerning(0) + ,nCharEscapementHeight(100) + ,m_bBackgroundTransparent(true) + ,bCharFlash(false) + ,bCharAutoKerning(false) + ,bCharCombineIsOn(false) + ,bCharHidden(false) + ,bCharShadowed(false) + ,bCharContoured(false) +{ + try + { + SvtLinguConfig aLinguConfig; + using namespace ::com::sun::star::i18n::ScriptType; + + aLinguConfig.GetProperty(u"DefaultLocale") >>= aCharLocale; + LanguageType eCurLang = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aCharLocale, false), LATIN); + aLinguConfig.GetProperty(u"DefaultLocale_CJK") >>= aCharLocaleAsian; + LanguageType eCurLangCJK = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aCharLocaleAsian, false), ASIAN); + aLinguConfig.GetProperty(u"DefaultLocale_CTL") >>= aCharLocaleComplex; + LanguageType eCurLangCTL = MsLangId::resolveSystemLanguageByScriptType(LanguageTag::convertToLanguageType( aCharLocaleComplex, false), COMPLEX); + + vcl::Font aLatin,aCJK,aCTL; + lcl_getDefaultFonts(aLatin,aCJK,aCTL,eCurLang,eCurLangCJK,eCurLangCTL); + aFontDescriptor = VCLUnoHelper::CreateFontDescriptor(aLatin); + aAsianFontDescriptor = VCLUnoHelper::CreateFontDescriptor(aCJK); + aComplexFontDescriptor = VCLUnoHelper::CreateFontDescriptor(aCTL); + } + catch(const uno::Exception&) + { + } + aFontDescriptor.Weight = awt::FontWeight::NORMAL; + aFontDescriptor.CharacterWidth = awt::FontWidth::NORMAL; +} + +void OReportComponentProperties::setShape(uno::Reference< drawing::XShape >& _xShape,const uno::Reference< report::XReportComponent>& _xTunnel,oslInterlockedCount& _rRefCount) +{ + osl_atomic_increment( &_rRefCount ); + { + m_xProxy.set(_xShape,uno::UNO_QUERY); + ::comphelper::query_aggregation(m_xProxy,m_xShape); + ::comphelper::query_aggregation(m_xProxy,m_xProperty); + _xShape.clear(); + m_xTypeProvider.set(m_xShape,uno::UNO_QUERY); + m_xUnoTunnel.set(m_xShape,uno::UNO_QUERY); + m_xServiceInfo.set(m_xShape,uno::UNO_QUERY); + + // set ourself as delegator + if ( m_xProxy.is() ) + m_xProxy->setDelegator( _xTunnel ); + } + osl_atomic_decrement( &_rRefCount ); +} + +OReportComponentProperties::~OReportComponentProperties() +{ + if ( m_xProxy.is() ) + { + m_xProxy->setDelegator( nullptr ); + m_xProxy.clear(); + } +} + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ReportControlModel.cxx b/reportdesign/source/core/api/ReportControlModel.cxx new file mode 100644 index 000000000..16dee9bd1 --- /dev/null +++ b/reportdesign/source/core/api/ReportControlModel.cxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportControlModel.hxx> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <o3tl/safeint.hxx> +namespace reportdesign +{ +using namespace com::sun::star; +using namespace comphelper; + +// XContainer +void OReportControlModel::addContainerListener( + const uno::Reference<container::XContainerListener>& xListener) +{ + aContainerListeners.addInterface(xListener); +} + +void OReportControlModel::removeContainerListener( + const uno::Reference<container::XContainerListener>& xListener) +{ + aContainerListeners.removeInterface(xListener); +} + +bool OReportControlModel::hasElements() +{ + ::osl::MutexGuard aGuard(m_rMutex); + return !m_aFormatConditions.empty(); +} + +// XIndexContainer +void OReportControlModel::insertByIndex(::sal_Int32 Index, const uno::Any& Element) +{ + uno::Reference<report::XFormatCondition> xElement(Element, uno::UNO_QUERY); + if (!xElement.is()) + throw lang::IllegalArgumentException(); + + uno::Reference<container::XContainer> xBroadcaster; + { + ::osl::MutexGuard aGuard(m_rMutex); + xBroadcaster = m_pOwner; + if (Index > static_cast<sal_Int32>(m_aFormatConditions.size())) + throw lang::IndexOutOfBoundsException(); + + m_aFormatConditions.insert(m_aFormatConditions.begin() + Index, xElement); + } + + // notify our container listeners + container::ContainerEvent aEvent(xBroadcaster, uno::Any(Index), Element, uno::Any()); + aContainerListeners.notifyEach(&container::XContainerListener::elementInserted, aEvent); +} + +void OReportControlModel::removeByIndex(::sal_Int32 Index) +{ + uno::Any Element; + uno::Reference<container::XContainer> xBroadcaster; + { + ::osl::MutexGuard aGuard(m_rMutex); + xBroadcaster = m_pOwner; + checkIndex(Index); + Element <<= m_aFormatConditions[Index]; + m_aFormatConditions.erase(m_aFormatConditions.begin() + Index); + } + container::ContainerEvent aEvent(xBroadcaster, uno::Any(Index), Element, uno::Any()); + aContainerListeners.notifyEach(&container::XContainerListener::elementRemoved, aEvent); +} + +// XIndexReplace +void OReportControlModel::replaceByIndex(::sal_Int32 Index, const uno::Any& Element) +{ + uno::Reference<report::XFormatCondition> xElement(Element, uno::UNO_QUERY); + if (!xElement.is()) + throw lang::IllegalArgumentException(); + uno::Reference<container::XContainer> xBroadcaster; + { + ::osl::MutexGuard aGuard(m_rMutex); + xBroadcaster = m_pOwner; + checkIndex(Index); + m_aFormatConditions[Index] = xElement; + } + container::ContainerEvent aEvent(xBroadcaster, uno::Any(Index), Element, uno::Any()); + aContainerListeners.notifyEach(&container::XContainerListener::elementReplaced, aEvent); +} + +// XIndexAccess +::sal_Int32 OReportControlModel::getCount() +{ + ::osl::MutexGuard aGuard(m_rMutex); + return m_aFormatConditions.size(); +} + +uno::Any OReportControlModel::getByIndex(::sal_Int32 Index) +{ + uno::Any aElement; + { + ::osl::MutexGuard aGuard(m_rMutex); + checkIndex(Index); + aElement <<= m_aFormatConditions[Index]; + } + return aElement; +} + +void OReportControlModel::checkIndex(sal_Int32 _nIndex) +{ + if (_nIndex < 0 || m_aFormatConditions.size() <= o3tl::make_unsigned(_nIndex)) + throw lang::IndexOutOfBoundsException(); +} + +bool OReportControlModel::isInterfaceForbidden(const uno::Type& _rType) +{ + return (_rType == cppu::UnoType<beans::XPropertyState>::get() + || _rType == cppu::UnoType<beans::XMultiPropertySet>::get()); +} + +} // reportdesign + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ReportDefinition.cxx b/reportdesign/source/core/api/ReportDefinition.cxx new file mode 100644 index 000000000..282b66b06 --- /dev/null +++ b/reportdesign/source/core/api/ReportDefinition.cxx @@ -0,0 +1,2666 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <vector> +#include <string_view> + +#include <officecfg/Office/Common.hxx> +#include <ReportDefinition.hxx> + +#include <Functions.hxx> +#include <Groups.hxx> +#include <ReportComponent.hxx> +#include <ReportHelperImpl.hxx> +#include <RptDef.hxx> +#include <RptModel.hxx> +#include <Section.hxx> +#include <Tools.hxx> +#include <UndoEnv.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <strings.hxx> + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/XMultiPropertyStates.hpp> +#include <com/sun/star/chart2/data/DatabaseDataProvider.hpp> +#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp> +#include <com/sun/star/document/DocumentProperties.hpp> +#include <com/sun/star/document/IndexedPropertyValues.hpp> +#include <com/sun/star/document/EventObject.hpp> +#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/embed/EmbedMapUnits.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/embed/StorageFactory.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/io/IOException.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/report/GroupKeepTogether.hpp> +#include <com/sun/star/report/ReportPrintOption.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/style/GraphicLocation.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/style/PageStyleLayout.hpp> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/table/ShadowFormat.hpp> +#include <com/sun/star/task/InteractionHandler.hpp> +#include <com/sun/star/task/XStatusIndicator.hpp> +#include <com/sun/star/ui/UIConfigurationManager.hpp> +#include <com/sun/star/util/CloseVetoException.hpp> +#include <com/sun/star/util/NumberFormatsSupplier.hpp> +#include <com/sun/star/xml/AttributeData.hpp> +#include <com/sun/star/xml/sax/Writer.hpp> + +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/documentconstants.hxx> +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/indexedpropertyvalues.hxx> +#include <unotools/mediadescriptor.hxx> +#include <comphelper/namecontainer.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/numberedcollection.hxx> +#include <comphelper/proparrhlp.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <comphelper/propertystatecontainer.hxx> +#include <comphelper/seqstream.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/uno3.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <connectivity/CommonTools.hxx> +#include <connectivity/dbtools.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/types.hxx> +#include <dbaccess/dbaundomanager.hxx> +#include <editeng/paperinf.hxx> +#include <framework/titlehelper.hxx> +#include <o3tl/safeint.hxx> +#include <svl/itempool.hxx> +#include <svl/undo.hxx> +#include <svx/svdlayer.hxx> +#include <svx/unofill.hxx> +#include <svx/xmleohlp.hxx> +#include <svx/xmlgrhlp.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> + +// page styles +constexpr OUStringLiteral SC_UNO_PAGE_LEFTBORDER = u"LeftBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_RIGHTBORDER = u"RightBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_BOTTBORDER = u"BottomBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_TOPBORDER = u"TopBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_LEFTBRDDIST = u"LeftBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_RIGHTBRDDIST = u"RightBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_BOTTBRDDIST = u"BottomBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_TOPBRDDIST = u"TopBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_BORDERDIST = u"BorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_SHADOWFORM = u"ShadowFormat"; +constexpr OUStringLiteral SC_UNO_PAGE_PAPERTRAY = u"PrinterPaperTray"; +constexpr OUStringLiteral SC_UNO_PAGE_SCALEVAL = u"PageScale"; +constexpr OUStringLiteral SC_UNO_PAGE_SCALETOPAG = u"ScaleToPages"; +constexpr OUStringLiteral SC_UNO_PAGE_SCALETOX = u"ScaleToPagesX"; +constexpr OUStringLiteral SC_UNO_PAGE_SCALETOY = u"ScaleToPagesY"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBACKCOL = u"HeaderBackColor"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBACKTRAN = u"HeaderBackTransparent"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRGRFFILT = u"HeaderBackGraphicFilter"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRGRFLOC = u"HeaderBackGraphicLocation"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRGRF = u"HeaderBackGraphic"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRLEFTBOR = u"HeaderLeftBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRRIGHTBOR = u"HeaderRightBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBOTTBOR = u"HeaderBottomBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRTOPBOR = u"HeaderTopBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRLEFTBDIS = u"HeaderLeftBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRRIGHTBDIS = u"HeaderRightBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBOTTBDIS = u"HeaderBottomBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRTOPBDIS = u"HeaderTopBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBRDDIST = u"HeaderBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRSHADOW = u"HeaderShadowFormat"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRLEFTMAR = u"HeaderLeftMargin"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRRIGHTMAR = u"HeaderRightMargin"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRBODYDIST = u"HeaderBodyDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRHEIGHT = u"HeaderHeight"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRON = u"HeaderIsOn"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRDYNAMIC = u"HeaderIsDynamicHeight"; +constexpr OUStringLiteral SC_UNO_PAGE_HDRSHARED = u"HeaderIsShared"; +constexpr OUStringLiteral SC_UNO_PAGE_FIRSTHDRSHARED = u"FirstPageHeaderIsShared"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBACKCOL = u"FooterBackColor"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBACKTRAN = u"FooterBackTransparent"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRGRFFILT = u"FooterBackGraphicFilter"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRGRFLOC = u"FooterBackGraphicLocation"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRGRF = u"FooterBackGraphic"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRLEFTBOR = u"FooterLeftBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRRIGHTBOR = u"FooterRightBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBOTTBOR = u"FooterBottomBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRTOPBOR = u"FooterTopBorder"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRLEFTBDIS = u"FooterLeftBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRRIGHTBDIS = u"FooterRightBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBOTTBDIS = u"FooterBottomBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRTOPBDIS = u"FooterTopBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBRDDIST = u"FooterBorderDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRSHADOW = u"FooterShadowFormat"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRLEFTMAR = u"FooterLeftMargin"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRRIGHTMAR = u"FooterRightMargin"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRBODYDIST = u"FooterBodyDistance"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRHEIGHT = u"FooterHeight"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRON = u"FooterIsOn"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRDYNAMIC = u"FooterIsDynamicHeight"; +constexpr OUStringLiteral SC_UNO_PAGE_FTRSHARED = u"FooterIsShared"; +constexpr OUStringLiteral SC_UNO_PAGE_FIRSTFTRSHARED = u"FirstPageFooterIsShared"; + +namespace reportdesign +{ + using namespace com::sun::star; + using namespace rptui; + +static void lcl_setModelReadOnly(const uno::Reference< embed::XStorage >& _xStorage,std::shared_ptr<rptui::OReportModel> const & _rModel) +{ + uno::Reference<beans::XPropertySet> xProp(_xStorage,uno::UNO_QUERY); + sal_Int32 nOpenMode = embed::ElementModes::READ; + if ( xProp.is() ) + xProp->getPropertyValue("OpenMode") >>= nOpenMode; + + _rModel->SetReadOnly((nOpenMode & embed::ElementModes::WRITE) != embed::ElementModes::WRITE); +} +static void lcl_stripLoadArguments( utl::MediaDescriptor& _rDescriptor, uno::Sequence< beans::PropertyValue >& _rArgs ) +{ + _rDescriptor.erase( "StatusIndicator" ); + _rDescriptor.erase( "InteractionHandler" ); + _rDescriptor.erase( "Model" ); + _rDescriptor >> _rArgs; +} + +static void lcl_extractAndStartStatusIndicator( const utl::MediaDescriptor& _rDescriptor, uno::Reference< task::XStatusIndicator >& _rxStatusIndicator, + uno::Sequence< uno::Any >& _rCallArgs ) +{ + try + { + _rxStatusIndicator = _rDescriptor.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_STATUSINDICATOR, _rxStatusIndicator ); + if ( _rxStatusIndicator.is() ) + { + _rxStatusIndicator->start( OUString(), sal_Int32(1000000) ); + + sal_Int32 nLength = _rCallArgs.getLength(); + _rCallArgs.realloc( nLength + 1 ); + _rCallArgs.getArray()[ nLength ] <<= _rxStatusIndicator; + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_extractAndStartStatusIndicator" ); + } +} + +typedef ::comphelper::OPropertyStateContainer OStyle_PBASE; + +namespace { + +class OStyle; + +} + +typedef ::comphelper::OPropertyArrayUsageHelper < OStyle + > OStyle_PABASE; +typedef ::cppu::WeakImplHelper< style::XStyle, beans::XMultiPropertyStates> TStyleBASE; + +namespace { + +class OStyle : public ::comphelper::OMutexAndBroadcastHelper + ,public TStyleBASE + ,public OStyle_PBASE + ,public OStyle_PABASE +{ + awt::Size m_aSize; + +protected: + void getPropertyDefaultByHandle( sal_Int32 _nHandle, uno::Any& _rDefault ) const override; + virtual ~OStyle() override {} +public: + OStyle(); + + + DECLARE_XINTERFACE( ) + + // XPropertySet + css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() override; + ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override; + + // XStyle + sal_Bool SAL_CALL isUserDefined( ) override; + sal_Bool SAL_CALL isInUse( ) override; + OUString SAL_CALL getParentStyle( ) override; + void SAL_CALL setParentStyle( const OUString& aParentStyle ) override; + + // XNamed + OUString SAL_CALL getName( ) override; + void SAL_CALL setName( const OUString& aName ) override; + + // XMultiPropertyState + uno::Sequence< beans::PropertyState > SAL_CALL getPropertyStates( const uno::Sequence< OUString >& aPropertyNames ) override + { + return OStyle_PBASE::getPropertyStates(aPropertyNames); + } + void SAL_CALL setAllPropertiesToDefault( ) override; + void SAL_CALL setPropertiesToDefault( const uno::Sequence< OUString >& aPropertyNames ) override; + uno::Sequence< uno::Any > SAL_CALL getPropertyDefaults( const uno::Sequence< OUString >& aPropertyNames ) override; +}; + +} + +OStyle::OStyle() +:OStyle_PBASE(m_aBHelper) +,m_aSize(21000,29700) +{ + const ::Size aDefaultSize = SvxPaperInfo::GetDefaultPaperSize( MapUnit::Map100thMM ); + m_aSize.Height = aDefaultSize.Height(); + m_aSize.Width = aDefaultSize.Width(); + + const sal_Int32 nMargin = 2000; + const sal_Int32 nBound = beans::PropertyAttribute::BOUND; + const sal_Int32 nMayBeVoid = beans::PropertyAttribute::MAYBEVOID; + + sal_Int32 i = 0; + registerPropertyNoMember( PROPERTY_NAME, ++i, nBound, cppu::UnoType<OUString>::get(), css::uno::Any(OUString("Default")) ); + + registerPropertyNoMember(PROPERTY_BACKCOLOR, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(COL_TRANSPARENT)); + + registerPropertyNoMember(PROPERTY_BACKGRAPHICLOCATION, ++i,nBound, cppu::UnoType<style::GraphicLocation>::get(), css::uno::Any(style::GraphicLocation_NONE)); + registerPropertyNoMember(PROPERTY_BACKTRANSPARENT, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(true)); + registerPropertyNoMember(SC_UNO_PAGE_BORDERDIST, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_BOTTBORDER, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_BOTTBRDDIST, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(PROPERTY_BOTTOMMARGIN, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(nMargin)); + registerPropertyNoMember("DisplayName", ++i,nBound, cppu::UnoType<OUString>::get(), css::uno::Any(OUString())); + registerPropertyNoMember(SC_UNO_PAGE_FTRBACKCOL, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(COL_TRANSPARENT)); + registerPropertyNoMember(SC_UNO_PAGE_FTRGRFFILT, ++i,nBound, cppu::UnoType<OUString>::get(), css::uno::Any(OUString())); + registerPropertyNoMember(SC_UNO_PAGE_FTRGRFLOC, ++i,nBound, cppu::UnoType<style::GraphicLocation>::get(), css::uno::Any(style::GraphicLocation_NONE)); + registerPropertyNoMember(SC_UNO_PAGE_FTRGRF, ++i,nBound|nMayBeVoid, cppu::UnoType<graphic::XGraphic>::get(), css::uno::Any(uno::Reference<graphic::XGraphic>())); + registerPropertyNoMember(SC_UNO_PAGE_FTRBACKTRAN, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(true)); + registerPropertyNoMember(SC_UNO_PAGE_FTRBODYDIST, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRBRDDIST, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRBOTTBOR, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_FTRBOTTBDIS, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRHEIGHT, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRDYNAMIC, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_FTRON, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_FTRSHARED, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_FIRSTFTRSHARED, ++i,nBound,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTBOR, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTBDIS, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRLEFTMAR, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRRIGHTBOR, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_FTRRIGHTBDIS,++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRRIGHTMAR, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_FTRSHADOW, ++i,nBound, cppu::UnoType<table::ShadowFormat>::get(), css::uno::Any(table::ShadowFormat())); + registerPropertyNoMember(SC_UNO_PAGE_FTRTOPBOR, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_FTRTOPBDIS, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + + registerPropertyNoMember(SC_UNO_PAGE_HDRBACKCOL, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(COL_TRANSPARENT)); + registerPropertyNoMember(SC_UNO_PAGE_HDRGRFFILT, ++i,nBound|nMayBeVoid, cppu::UnoType<OUString>::get(), css::uno::Any(OUString())); + registerPropertyNoMember(SC_UNO_PAGE_HDRGRFLOC, ++i,nBound|nMayBeVoid, cppu::UnoType<style::GraphicLocation>::get(), css::uno::Any(style::GraphicLocation_NONE)); + registerPropertyNoMember(SC_UNO_PAGE_HDRGRF, ++i,nBound|nMayBeVoid, cppu::UnoType<graphic::XGraphic>::get(), css::uno::Any(uno::Reference<graphic::XGraphic>())); + registerPropertyNoMember(SC_UNO_PAGE_HDRBACKTRAN, ++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(true)); + registerPropertyNoMember(SC_UNO_PAGE_HDRBODYDIST, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRBRDDIST, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRBOTTBOR, ++i,nBound|nMayBeVoid, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_HDRBOTTBDIS, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRHEIGHT, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRDYNAMIC, ++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_HDRON, ++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_HDRSHARED, ++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_FIRSTHDRSHARED, ++i,nBound|nMayBeVoid,cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTBOR, ++i,nBound|nMayBeVoid, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTBDIS, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRLEFTMAR, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRRIGHTBOR, ++i,nBound|nMayBeVoid, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_HDRRIGHTBDIS,++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRRIGHTMAR, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(SC_UNO_PAGE_HDRSHADOW, ++i,nBound|nMayBeVoid, cppu::UnoType<table::ShadowFormat>::get(), css::uno::Any(table::ShadowFormat())); + registerPropertyNoMember(SC_UNO_PAGE_HDRTOPBOR, ++i,nBound|nMayBeVoid, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_HDRTOPBDIS, ++i,nBound|nMayBeVoid, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + + registerProperty(PROPERTY_HEIGHT, ++i,nBound,&m_aSize.Height, ::cppu::UnoType<sal_Int32>::get() ); + registerPropertyNoMember(PROPERTY_ISLANDSCAPE, ++i,nBound, cppu::UnoType<bool>::get(), css::uno::Any(false)); + registerPropertyNoMember(SC_UNO_PAGE_LEFTBORDER, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_LEFTBRDDIST, ++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(PROPERTY_LEFTMARGIN, ++i,beans::PropertyAttribute::BOUND, ::cppu::UnoType<sal_Int32>::get(), css::uno::Any(nMargin)); + registerPropertyNoMember(PROPERTY_NUMBERINGTYPE, ++i,nBound, cppu::UnoType<sal_Int16>::get(), css::uno::Any(style::NumberingType::ARABIC)); + registerPropertyNoMember(SC_UNO_PAGE_SCALEVAL, ++i,nBound, cppu::UnoType<sal_Int16>::get(), css::uno::Any(sal_Int16(0))); + registerPropertyNoMember(PROPERTY_PAGESTYLELAYOUT, ++i,nBound, cppu::UnoType<style::PageStyleLayout>::get(), css::uno::Any(style::PageStyleLayout_ALL)); + registerPropertyNoMember(SC_UNO_PAGE_PAPERTRAY, ++i,nBound, cppu::UnoType<OUString>::get(), css::uno::Any(OUString("[From printer settings]"))); + registerPropertyNoMember(SC_UNO_PAGE_RIGHTBORDER, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_RIGHTBRDDIST,++i,nBound, cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(PROPERTY_RIGHTMARGIN, ++i,beans::PropertyAttribute::BOUND,::cppu::UnoType<sal_Int32>::get(), css::uno::Any(nMargin)); + registerPropertyNoMember(SC_UNO_PAGE_SCALETOPAG, ++i,nBound, cppu::UnoType<sal_Int16>::get(), css::uno::Any(sal_Int16(0))); + registerPropertyNoMember(SC_UNO_PAGE_SCALETOX, ++i,nBound, cppu::UnoType<sal_Int16>::get(), css::uno::Any(sal_Int16(0))); + registerPropertyNoMember(SC_UNO_PAGE_SCALETOY, ++i,nBound, cppu::UnoType<sal_Int16>::get(), css::uno::Any(sal_Int16(0))); + registerPropertyNoMember(SC_UNO_PAGE_SHADOWFORM, ++i,nBound, cppu::UnoType<table::ShadowFormat>::get(), css::uno::Any(table::ShadowFormat())); + registerProperty(PROPERTY_PAPERSIZE, ++i,beans::PropertyAttribute::BOUND,&m_aSize, cppu::UnoType<awt::Size>::get() ); + registerPropertyNoMember(SC_UNO_PAGE_TOPBORDER, ++i,nBound, cppu::UnoType<table::BorderLine2>::get(), css::uno::Any(table::BorderLine2())); + registerPropertyNoMember(SC_UNO_PAGE_TOPBRDDIST, ++i,nBound,::cppu::UnoType<sal_Int32>::get(), css::uno::Any(sal_Int32(0))); + registerPropertyNoMember(PROPERTY_TOPMARGIN, ++i,nBound,::cppu::UnoType<sal_Int32>::get(), css::uno::Any(nMargin)); + registerPropertyNoMember("UserDefinedAttributes", ++i,nBound, cppu::UnoType<container::XNameContainer>::get(), css::uno::Any(comphelper::NameContainer_createInstance(cppu::UnoType<xml::AttributeData>::get()))); + registerProperty(PROPERTY_WIDTH, ++i,nBound,&m_aSize.Width, cppu::UnoType<sal_Int32>::get() ); + registerPropertyNoMember("PrinterName", ++i,nBound, cppu::UnoType<OUString>::get(), css::uno::Any(OUString())); + registerPropertyNoMember("PrinterSetup", ++i,nBound,cppu::UnoType<uno::Sequence<sal_Int8>>::get(), css::uno::Any(uno::Sequence<sal_Int8>())); + + +} + +IMPLEMENT_FORWARD_XINTERFACE2(OStyle,TStyleBASE,OStyle_PBASE) + +uno::Reference< beans::XPropertySetInfo> SAL_CALL OStyle::getPropertySetInfo() +{ + return createPropertySetInfo( getInfoHelper() ); +} + +void OStyle::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, uno::Any& /*_rDefault*/ ) const +{ +} + +::cppu::IPropertyArrayHelper& OStyle::getInfoHelper() +{ + return *getArrayHelper(); +} + +::cppu::IPropertyArrayHelper* OStyle::createArrayHelper( ) const +{ + uno::Sequence< beans::Property > aProps; + describeProperties(aProps); + return new ::cppu::OPropertyArrayHelper(aProps); +} + +// XStyle +sal_Bool SAL_CALL OStyle::isUserDefined( ) +{ + return false; +} + +sal_Bool SAL_CALL OStyle::isInUse( ) +{ + return true; +} + +OUString SAL_CALL OStyle::getParentStyle( ) +{ + return OUString(); +} + +void SAL_CALL OStyle::setParentStyle( const OUString& /*aParentStyle*/ ) +{ +} + +// XNamed +OUString SAL_CALL OStyle::getName( ) +{ + OUString sName; + getPropertyValue(PROPERTY_NAME) >>= sName; + return sName; +} + +void SAL_CALL OStyle::setName( const OUString& aName ) +{ + setPropertyValue(PROPERTY_NAME,uno::Any(aName)); +} + +void SAL_CALL OStyle::setAllPropertiesToDefault( ) +{ +} + +void SAL_CALL OStyle::setPropertiesToDefault( const uno::Sequence< OUString >& aPropertyNames ) +{ + for(const OUString& rName : aPropertyNames) + setPropertyToDefault(rName); +} + +uno::Sequence< uno::Any > SAL_CALL OStyle::getPropertyDefaults( const uno::Sequence< OUString >& aPropertyNames ) +{ + uno::Sequence< uno::Any > aRet(aPropertyNames.getLength()); + std::transform(aPropertyNames.begin(), aPropertyNames.end(), aRet.getArray(), + [this](const OUString& rName) -> uno::Any { return getPropertyDefault(rName); }); + return aRet; +} + +struct OReportDefinitionImpl +{ + uno::WeakReference< uno::XInterface > m_xParent; + ::comphelper::OInterfaceContainerHelper3<document::XStorageChangeListener> m_aStorageChangeListeners; + ::comphelper::OInterfaceContainerHelper3<util::XCloseListener> m_aCloseListener; + ::comphelper::OInterfaceContainerHelper3<util::XModifyListener> m_aModifyListeners; + ::comphelper::OInterfaceContainerHelper3<document::XEventListener> m_aLegacyEventListeners; + ::comphelper::OInterfaceContainerHelper3<document::XDocumentEventListener> m_aDocEventListeners; + ::std::vector< uno::Reference< frame::XController> > m_aControllers; + uno::Sequence< beans::PropertyValue > m_aArgs; + + uno::Reference< report::XGroups > m_xGroups; + uno::Reference< report::XSection> m_xReportHeader; + uno::Reference< report::XSection> m_xReportFooter; + uno::Reference< report::XSection> m_xPageHeader; + uno::Reference< report::XSection> m_xPageFooter; + uno::Reference< report::XSection> m_xDetail; + uno::Reference< embed::XStorage > m_xStorage; + uno::Reference< frame::XController > m_xCurrentController; + uno::Reference< container::XIndexAccess > m_xViewData; + uno::Reference< container::XNameAccess > m_xStyles; + uno::Reference< container::XNameAccess> m_xXMLNamespaceMap; + uno::Reference< container::XNameAccess> m_xGradientTable; + uno::Reference< container::XNameAccess> m_xHatchTable; + uno::Reference< container::XNameAccess> m_xBitmapTable; + uno::Reference< container::XNameAccess> m_xTransparencyGradientTable; + uno::Reference< container::XNameAccess> m_xDashTable; + uno::Reference< container::XNameAccess> m_xMarkerTable; + uno::Reference< report::XFunctions > m_xFunctions; + uno::Reference< ui::XUIConfigurationManager2> m_xUIConfigurationManager; + uno::Reference< util::XNumberFormatsSupplier> m_xNumberFormatsSupplier; + uno::Reference< sdbc::XConnection> m_xActiveConnection; + uno::Reference< frame::XTitle > m_xTitleHelper; + uno::Reference< frame::XUntitledNumbers > m_xNumberedControllers; + uno::Reference< document::XDocumentProperties > m_xDocumentProperties; + + std::shared_ptr< ::comphelper::EmbeddedObjectContainer> + m_pObjectContainer; + std::shared_ptr<rptui::OReportModel> m_pReportModel; + ::rtl::Reference< ::dbaui::UndoManager > m_pUndoManager; + OUString m_sCaption; + OUString m_sCommand; + OUString m_sFilter; + OUString m_sMimeType; + OUString m_sIdentifier; + OUString m_sDataSourceName; + awt::Size m_aVisualAreaSize; + ::sal_Int64 m_nAspect; + ::sal_Int16 m_nGroupKeepTogether; + ::sal_Int16 m_nPageHeaderOption; + ::sal_Int16 m_nPageFooterOption; + ::sal_Int32 m_nCommandType; + bool m_bControllersLocked; + bool m_bModified; + bool m_bEscapeProcessing; + bool m_bSetModifiedEnabled; + + explicit OReportDefinitionImpl(::osl::Mutex& _aMutex) + :m_aStorageChangeListeners(_aMutex) + ,m_aCloseListener(_aMutex) + ,m_aModifyListeners(_aMutex) + ,m_aLegacyEventListeners(_aMutex) + ,m_aDocEventListeners(_aMutex) + ,m_sMimeType(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII) + ,m_sIdentifier(SERVICE_REPORTDEFINITION) + // default visual area is 8 x 7 cm + ,m_aVisualAreaSize( 8000, 7000 ) + ,m_nAspect(embed::Aspects::MSOLE_CONTENT) + ,m_nGroupKeepTogether(0) + ,m_nPageHeaderOption(0) + ,m_nPageFooterOption(0) + ,m_nCommandType(sdb::CommandType::TABLE) + ,m_bControllersLocked(false) + ,m_bModified(false) + ,m_bEscapeProcessing(true) + ,m_bSetModifiedEnabled( true ) + {} +}; + +OReportDefinition::OReportDefinition(uno::Reference< uno::XComponentContext > const & _xContext) +: ::cppu::BaseMutex(), + ReportDefinitionBase(m_aMutex), + ReportDefinitionPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()), + ::comphelper::IEmbeddedHelper(), + m_aProps(std::make_shared<OReportComponentProperties>(_xContext)), + m_pImpl(std::make_shared<OReportDefinitionImpl>(m_aMutex)) +{ + m_aProps->m_sName = RptResId(RID_STR_REPORT); + osl_atomic_increment(&m_refCount); + { + init(); + m_pImpl->m_xGroups = new OGroups(this,m_aProps->m_xContext); + m_pImpl->m_xDetail = OSection::createOSection(this,m_aProps->m_xContext); + m_pImpl->m_xDetail->setName(RptResId(RID_STR_DETAIL)); + } + osl_atomic_decrement( &m_refCount ); +} + +OReportDefinition::OReportDefinition( + uno::Reference< uno::XComponentContext > const & _xContext, + const uno::Reference< lang::XMultiServiceFactory>& _xFactory, + uno::Reference< drawing::XShape >& _xShape) +: ::cppu::BaseMutex(), + ReportDefinitionBase(m_aMutex), + ReportDefinitionPropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()), + ::comphelper::IEmbeddedHelper(), + m_aProps(std::make_shared<OReportComponentProperties>(_xContext)), + m_pImpl(std::make_shared<OReportDefinitionImpl>(m_aMutex)) +{ + m_aProps->m_sName = RptResId(RID_STR_REPORT); + m_aProps->m_xFactory = _xFactory; + osl_atomic_increment(&m_refCount); + { + m_aProps->setShape(_xShape,this,m_refCount); + init(); + m_pImpl->m_xGroups = new OGroups(this,m_aProps->m_xContext); + m_pImpl->m_xDetail = OSection::createOSection(this,m_aProps->m_xContext); + m_pImpl->m_xDetail->setName(RptResId(RID_STR_DETAIL)); + } + osl_atomic_decrement( &m_refCount ); +} + +OReportDefinition::~OReportDefinition() +{ + if ( !ReportDefinitionBase::rBHelper.bInDispose && !ReportDefinitionBase::rBHelper.bDisposed ) + { + acquire(); + dispose(); + } +} + +IMPLEMENT_FORWARD_REFCOUNT( OReportDefinition, ReportDefinitionBase ) +void OReportDefinition::init() +{ + try + { + m_pImpl->m_pReportModel = std::make_shared<OReportModel>(this); + m_pImpl->m_pReportModel->GetItemPool().FreezeIdRanges(); + m_pImpl->m_pReportModel->SetScaleUnit( MapUnit::Map100thMM ); + SdrLayerAdmin& rAdmin = m_pImpl->m_pReportModel->GetLayerAdmin(); + rAdmin.NewLayer("front", RPT_LAYER_FRONT.get()); + rAdmin.NewLayer("back", RPT_LAYER_BACK.get()); + rAdmin.NewLayer("HiddenLayer", RPT_LAYER_HIDDEN.get()); + + m_pImpl->m_pUndoManager = new ::dbaui::UndoManager( *this, m_aMutex ); + m_pImpl->m_pReportModel->SetSdrUndoManager( &m_pImpl->m_pUndoManager->GetSfxUndoManager() ); + + m_pImpl->m_xFunctions = new OFunctions(this,m_aProps->m_xContext); + if ( !m_pImpl->m_xStorage.is() ) + m_pImpl->m_xStorage = ::comphelper::OStorageHelper::GetTemporaryStorage(); + + uno::Reference<beans::XPropertySet> xStorProps(m_pImpl->m_xStorage,uno::UNO_QUERY); + if ( xStorProps.is()) + { + OUString sMediaType; + xStorProps->getPropertyValue("MediaType") >>= sMediaType; + if ( sMediaType.isEmpty() ) + xStorProps->setPropertyValue("MediaType",uno::Any(OUString(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII))); + } + m_pImpl->m_pObjectContainer = std::make_shared<comphelper::EmbeddedObjectContainer>(m_pImpl->m_xStorage , static_cast<cppu::OWeakObject*>(this) ); + } + catch (const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void SAL_CALL OReportDefinition::dispose() +{ + ReportDefinitionPropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +void SAL_CALL OReportDefinition::disposing() +{ + notifyEvent("OnUnload"); + + uno::Reference< frame::XModel > xHoldAlive( this ); + + lang::EventObject aDisposeEvent( static_cast< ::cppu::OWeakObject* >( this ) ); + m_pImpl->m_aModifyListeners.disposeAndClear( aDisposeEvent ); + m_pImpl->m_aCloseListener.disposeAndClear( aDisposeEvent ); + m_pImpl->m_aLegacyEventListeners.disposeAndClear( aDisposeEvent ); + m_pImpl->m_aDocEventListeners.disposeAndClear( aDisposeEvent ); + m_pImpl->m_aStorageChangeListeners.disposeAndClear( aDisposeEvent ); + + // SYNCHRONIZED ---> + { + SolarMutexGuard aSolarGuard; + osl::MutexGuard aGuard(m_aMutex); + + m_pImpl->m_aControllers.clear(); + + ::comphelper::disposeComponent(m_pImpl->m_xGroups); + m_pImpl->m_xReportHeader.clear(); + m_pImpl->m_xReportFooter.clear(); + m_pImpl->m_xPageHeader.clear(); + m_pImpl->m_xPageFooter.clear(); + m_pImpl->m_xDetail.clear(); + ::comphelper::disposeComponent(m_pImpl->m_xFunctions); + + //::comphelper::disposeComponent(m_pImpl->m_xStorage); + // don't dispose, this currently is the task of either the ref count going to + // 0, or of the embedded object (if we're embedded, which is the only possible + // case so far) + // #i78366# + m_pImpl->m_xStorage.clear(); + m_pImpl->m_xViewData.clear(); + m_pImpl->m_xCurrentController.clear(); + m_pImpl->m_xNumberFormatsSupplier.clear(); + m_pImpl->m_xStyles.clear(); + m_pImpl->m_xXMLNamespaceMap.clear(); + m_pImpl->m_xGradientTable.clear(); + m_pImpl->m_xHatchTable.clear(); + m_pImpl->m_xBitmapTable.clear(); + m_pImpl->m_xTransparencyGradientTable.clear(); + m_pImpl->m_xDashTable.clear(); + m_pImpl->m_xMarkerTable.clear(); + m_pImpl->m_xUIConfigurationManager.clear(); + m_pImpl->m_pReportModel.reset(); + m_pImpl->m_pObjectContainer.reset(); + m_pImpl->m_aArgs.realloc(0); + m_pImpl->m_xTitleHelper.clear(); + m_pImpl->m_xNumberedControllers.clear(); + } + // <--- SYNCHRONIZED +} + + +OUString OReportDefinition::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OReportDefinition"; +} + +OUString SAL_CALL OReportDefinition::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OReportDefinition::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { SERVICE_REPORTDEFINITION }; + + return aServices; +} + +uno::Sequence< OUString > SAL_CALL OReportDefinition::getSupportedServiceNames( ) +{ + // first collect the services which are supported by our aggregate + uno::Sequence< OUString > aSupported; + if ( m_aProps->m_xServiceInfo.is() ) + aSupported = m_aProps->m_xServiceInfo->getSupportedServiceNames(); + + // append our own service, if necessary + if ( ::comphelper::findValue( aSupported, SERVICE_REPORTDEFINITION ) == -1 ) + { + sal_Int32 nLen = aSupported.getLength(); + aSupported.realloc( nLen + 1 ); + aSupported.getArray()[ nLen ] = SERVICE_REPORTDEFINITION; + } + + // outta here + return aSupported; +} + +sal_Bool SAL_CALL OReportDefinition::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +uno::Any SAL_CALL OReportDefinition::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = ReportDefinitionBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = ReportDefinitionPropertySet::queryInterface(_rType); + + return aReturn.hasValue() ? aReturn : (m_aProps->m_xProxy.is() ? m_aProps->m_xProxy->queryAggregation(_rType) : aReturn); +} +uno::Sequence< uno::Type > SAL_CALL OReportDefinition::getTypes( ) +{ + if ( m_aProps->m_xTypeProvider.is() ) + return ::comphelper::concatSequences( + ReportDefinitionBase::getTypes(), + m_aProps->m_xTypeProvider->getTypes() + ); + return ReportDefinitionBase::getTypes(); +} + +uno::Reference< uno::XInterface > OReportDefinition::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OReportDefinition(xContext)); +} + +// XReportDefinition +OUString SAL_CALL OReportDefinition::getCaption() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_sCaption; +} + +void SAL_CALL OReportDefinition::setCaption( const OUString& _caption ) +{ + set(PROPERTY_CAPTION,_caption,m_pImpl->m_sCaption); +} + +::sal_Int16 SAL_CALL OReportDefinition::getGroupKeepTogether() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_nGroupKeepTogether; +} + +void SAL_CALL OReportDefinition::setGroupKeepTogether( ::sal_Int16 _groupkeeptogether ) +{ + if ( _groupkeeptogether < report::GroupKeepTogether::PER_PAGE || _groupkeeptogether > report::GroupKeepTogether::PER_COLUMN ) + throwIllegallArgumentException(u"css::report::GroupKeepTogether" + ,*this + ,1); + set(PROPERTY_GROUPKEEPTOGETHER,_groupkeeptogether,m_pImpl->m_nGroupKeepTogether); +} + +::sal_Int16 SAL_CALL OReportDefinition::getPageHeaderOption() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_nPageHeaderOption; +} + +void SAL_CALL OReportDefinition::setPageHeaderOption( ::sal_Int16 _pageheaderoption ) +{ + if ( _pageheaderoption < report::ReportPrintOption::ALL_PAGES || _pageheaderoption > report::ReportPrintOption::NOT_WITH_REPORT_HEADER_FOOTER ) + throwIllegallArgumentException(u"css::report::ReportPrintOption" + ,*this + ,1); + set(PROPERTY_PAGEHEADEROPTION,_pageheaderoption,m_pImpl->m_nPageHeaderOption); +} + +::sal_Int16 SAL_CALL OReportDefinition::getPageFooterOption() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_nPageFooterOption; +} + +void SAL_CALL OReportDefinition::setPageFooterOption( ::sal_Int16 _pagefooteroption ) +{ + if ( _pagefooteroption < report::ReportPrintOption::ALL_PAGES || _pagefooteroption > report::ReportPrintOption::NOT_WITH_REPORT_HEADER_FOOTER ) + throwIllegallArgumentException(u"css::report::ReportPrintOption" + ,*this + ,1); + set(PROPERTY_PAGEFOOTEROPTION,_pagefooteroption,m_pImpl->m_nPageFooterOption); +} + +OUString SAL_CALL OReportDefinition::getCommand() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_sCommand; +} + +void SAL_CALL OReportDefinition::setCommand( const OUString& _command ) +{ + set(PROPERTY_COMMAND,_command,m_pImpl->m_sCommand); +} + +::sal_Int32 SAL_CALL OReportDefinition::getCommandType() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_nCommandType; +} + +void SAL_CALL OReportDefinition::setCommandType( ::sal_Int32 _commandtype ) +{ + if ( _commandtype < sdb::CommandType::TABLE || _commandtype > sdb::CommandType::COMMAND ) + throwIllegallArgumentException(u"css::sdb::CommandType" + ,*this + ,1); + set(PROPERTY_COMMANDTYPE,_commandtype,m_pImpl->m_nCommandType); +} + +OUString SAL_CALL OReportDefinition::getFilter() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_sFilter; +} + +void SAL_CALL OReportDefinition::setFilter( const OUString& _filter ) +{ + set(PROPERTY_FILTER,_filter,m_pImpl->m_sFilter); +} + +sal_Bool SAL_CALL OReportDefinition::getEscapeProcessing() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_bEscapeProcessing; +} + +void SAL_CALL OReportDefinition::setEscapeProcessing( sal_Bool _escapeprocessing ) +{ + set(PROPERTY_ESCAPEPROCESSING,_escapeprocessing,m_pImpl->m_bEscapeProcessing); +} + +sal_Bool SAL_CALL OReportDefinition::getReportHeaderOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xReportHeader.is(); +} + +void SAL_CALL OReportDefinition::setReportHeaderOn( sal_Bool _reportheaderon ) +{ + if ( bool(_reportheaderon) != m_pImpl->m_xReportHeader.is() ) + { + setSection(PROPERTY_REPORTHEADERON,_reportheaderon,RptResId(RID_STR_REPORT_HEADER),m_pImpl->m_xReportHeader); + } +} + +sal_Bool SAL_CALL OReportDefinition::getReportFooterOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xReportFooter.is(); +} + +void SAL_CALL OReportDefinition::setReportFooterOn( sal_Bool _reportfooteron ) +{ + if ( bool(_reportfooteron) != m_pImpl->m_xReportFooter.is() ) + { + setSection(PROPERTY_REPORTFOOTERON,_reportfooteron,RptResId(RID_STR_REPORT_FOOTER),m_pImpl->m_xReportFooter); + } +} + +sal_Bool SAL_CALL OReportDefinition::getPageHeaderOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xPageHeader.is(); +} + +void SAL_CALL OReportDefinition::setPageHeaderOn( sal_Bool _pageheaderon ) +{ + if ( bool(_pageheaderon) != m_pImpl->m_xPageHeader.is() ) + { + setSection(PROPERTY_PAGEHEADERON,_pageheaderon,RptResId(RID_STR_PAGE_HEADER),m_pImpl->m_xPageHeader); + } +} + +sal_Bool SAL_CALL OReportDefinition::getPageFooterOn() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xPageFooter.is(); +} + +void SAL_CALL OReportDefinition::setPageFooterOn( sal_Bool _pagefooteron ) +{ + if ( bool(_pagefooteron) != m_pImpl->m_xPageFooter.is() ) + { + setSection(PROPERTY_PAGEFOOTERON,_pagefooteron,RptResId(RID_STR_PAGE_FOOTER),m_pImpl->m_xPageFooter); + } +} + +uno::Reference< report::XGroups > SAL_CALL OReportDefinition::getGroups() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xGroups; +} + +uno::Reference< report::XSection > SAL_CALL OReportDefinition::getReportHeader() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( !m_pImpl->m_xReportHeader.is() ) + throw container::NoSuchElementException(); + return m_pImpl->m_xReportHeader; +} + +uno::Reference< report::XSection > SAL_CALL OReportDefinition::getPageHeader() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( !m_pImpl->m_xPageHeader.is() ) + throw container::NoSuchElementException(); + return m_pImpl->m_xPageHeader; +} + +uno::Reference< report::XSection > SAL_CALL OReportDefinition::getDetail() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xDetail; +} + +uno::Reference< report::XSection > SAL_CALL OReportDefinition::getPageFooter() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( !m_pImpl->m_xPageFooter.is() ) + throw container::NoSuchElementException(); + return m_pImpl->m_xPageFooter; +} + +uno::Reference< report::XSection > SAL_CALL OReportDefinition::getReportFooter() +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( !m_pImpl->m_xReportFooter.is() ) + throw container::NoSuchElementException(); + return m_pImpl->m_xReportFooter; +} + +uno::Reference< document::XEventBroadcaster > SAL_CALL OReportDefinition::getEventBroadcaster( ) +{ + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return this; +} + +// XReportComponent +REPORTCOMPONENT_MASTERDETAIL(OReportDefinition,*m_aProps) +REPORTCOMPONENT_IMPL(OReportDefinition,*m_aProps) +REPORTCOMPONENT_IMPL2(OReportDefinition,*m_aProps) + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OReportDefinition::getPropertySetInfo( ) +{ + return ReportDefinitionPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OReportDefinition::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + ReportDefinitionPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OReportDefinition::getPropertyValue( const OUString& PropertyName ) +{ + return ReportDefinitionPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OReportDefinition::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + ReportDefinitionPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OReportDefinition::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + ReportDefinitionPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OReportDefinition::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ReportDefinitionPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OReportDefinition::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ReportDefinitionPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OReportDefinition::getParent( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< container::XChild > xChild; + comphelper::query_aggregation(m_aProps->m_xProxy,xChild); + if ( xChild.is() ) + return xChild->getParent(); + return m_pImpl->m_xParent; +} + +void SAL_CALL OReportDefinition::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps->m_xParent = uno::Reference< container::XChild >(Parent,uno::UNO_QUERY); + m_pImpl->m_xParent = Parent; + uno::Reference< container::XChild > xChild; + comphelper::query_aggregation(m_aProps->m_xProxy,xChild); + if ( xChild.is() ) + xChild->setParent(Parent); +} + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OReportDefinition::createClone( ) +{ + OSL_FAIL("Not yet implemented correctly"); + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XReportDefinition> xSet(cloneObject(xSource,m_aProps->m_xFactory,SERVICE_REPORTDEFINITION),uno::UNO_QUERY_THROW); + return xSet; +} + +void OReportDefinition::setSection( const OUString& _sProperty + ,bool _bOn + ,const OUString& _sName + ,uno::Reference< report::XSection>& _member) +{ + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, uno::Any(_member), uno::Any(_bOn), &l); + + // create section if needed + if ( _bOn && !_member.is() ) + _member = OSection::createOSection(this, getContext(), _sProperty == PROPERTY_PAGEHEADERON || _sProperty == PROPERTY_PAGEFOOTERON); + else if ( !_bOn ) + ::comphelper::disposeComponent(_member); + + if ( _member.is() ) + _member->setName(_sName); + } + l.notify(); +} + +// XCloseBroadcaster +void SAL_CALL OReportDefinition::addCloseListener( const uno::Reference< util::XCloseListener >& _xListener ) +{ + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( _xListener.is() ) + m_pImpl->m_aCloseListener.addInterface(_xListener); +} + +void SAL_CALL OReportDefinition::removeCloseListener( const uno::Reference< util::XCloseListener >& _xListener ) +{ + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aCloseListener.removeInterface(_xListener); +} + +// XCloseable +void SAL_CALL OReportDefinition::close(sal_Bool bDeliverOwnership) +{ + SolarMutexGuard aSolarGuard; + + ::osl::ResettableMutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + // notify our container listeners + lang::EventObject aEvt( static_cast< ::cppu::OWeakObject* >( this ) ); + aGuard.clear(); + m_pImpl->m_aCloseListener.forEach( + [&aEvt, &bDeliverOwnership] (uno::Reference<util::XCloseListener> const& xListener) { + return xListener->queryClosing(aEvt, bDeliverOwnership); + }); + aGuard.reset(); + + + ::std::vector< uno::Reference< frame::XController> > aCopy = m_pImpl->m_aControllers; + for (auto& rxController : aCopy) + { + if ( rxController.is() ) + { + try + { + uno::Reference< util::XCloseable> xFrame( rxController->getFrame(), uno::UNO_QUERY ); + if ( xFrame.is() ) + xFrame->close( bDeliverOwnership ); + } + catch (const util::CloseVetoException&) { throw; } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "ODatabaseDocument::impl_closeControllerFrames" ); + } + } + } + + aGuard.clear(); + m_pImpl->m_aCloseListener.notifyEach(&util::XCloseListener::notifyClosing,aEvt); + aGuard.reset(); + + dispose(); +} + +// XModel +sal_Bool SAL_CALL OReportDefinition::attachResource( const OUString& /*_rURL*/, const uno::Sequence< beans::PropertyValue >& _aArguments ) +{ + // LLA: we had a deadlock problem in our context, so we get the SolarMutex earlier. + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed( ReportDefinitionBase::rBHelper.bDisposed ); + utl::MediaDescriptor aDescriptor( _aArguments ); + + m_pImpl->m_pUndoManager->GetSfxUndoManager().EnableUndo( false ); + try + { + fillArgs(aDescriptor); + m_pImpl->m_pReportModel->SetModified(false); + } + catch (...) + { + m_pImpl->m_pUndoManager->GetSfxUndoManager().EnableUndo( true ); + throw; + } + m_pImpl->m_pUndoManager->GetSfxUndoManager().EnableUndo( true ); + return true; +} + +void OReportDefinition::fillArgs(utl::MediaDescriptor& _aDescriptor) +{ + uno::Sequence<beans::PropertyValue> aComponentData; + aComponentData = _aDescriptor.getUnpackedValueOrDefault("ComponentData",aComponentData); + if ( aComponentData.hasElements() && (!m_pImpl->m_xActiveConnection.is() || !m_pImpl->m_xNumberFormatsSupplier.is()) ) + { + ::comphelper::SequenceAsHashMap aComponentDataMap( aComponentData ); + m_pImpl->m_xActiveConnection = aComponentDataMap.getUnpackedValueOrDefault("ActiveConnection",m_pImpl->m_xActiveConnection); + m_pImpl->m_xNumberFormatsSupplier = dbtools::getNumberFormats(m_pImpl->m_xActiveConnection); + } + if ( !m_pImpl->m_xNumberFormatsSupplier.is() ) + { + m_pImpl->m_xNumberFormatsSupplier.set( util::NumberFormatsSupplier::createWithDefaultLocale( m_aProps->m_xContext ) ); + } + lcl_stripLoadArguments( _aDescriptor, m_pImpl->m_aArgs ); + OUString sCaption; + sCaption = _aDescriptor.getUnpackedValueOrDefault("DocumentTitle",sCaption); + setCaption(sCaption); +} + +OUString SAL_CALL OReportDefinition::getURL( ) +{ + return OUString(); +} + +uno::Sequence< beans::PropertyValue > SAL_CALL OReportDefinition::getArgs( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_aArgs; +} + +void SAL_CALL OReportDefinition::connectController( const uno::Reference< frame::XController >& _xController ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aControllers.push_back(_xController); + if ( _xController.is() && m_pImpl->m_xViewData.is() ) + { + sal_Int32 nCount = m_pImpl->m_xViewData->getCount(); + if (nCount) + _xController->restoreViewData(m_pImpl->m_xViewData->getByIndex(nCount - 1)); + } +} + +void SAL_CALL OReportDefinition::disconnectController( const uno::Reference< frame::XController >& _xController ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + ::std::vector< uno::Reference< frame::XController> >::iterator aFind = ::std::find(m_pImpl->m_aControllers.begin(),m_pImpl->m_aControllers.end(),_xController); + if ( aFind != m_pImpl->m_aControllers.end() ) + m_pImpl->m_aControllers.erase(aFind); + if ( m_pImpl->m_xCurrentController == _xController ) + m_pImpl->m_xCurrentController.clear(); +} + +void SAL_CALL OReportDefinition::lockControllers( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_bControllersLocked = true; +} + +void SAL_CALL OReportDefinition::unlockControllers( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_bControllersLocked = false; +} + +sal_Bool SAL_CALL OReportDefinition::hasControllersLocked( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_bControllersLocked; +} + +uno::Reference< frame::XController > SAL_CALL OReportDefinition::getCurrentController( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_xCurrentController; +} + +void SAL_CALL OReportDefinition::setCurrentController( const uno::Reference< frame::XController >& _xController ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( ::std::find(m_pImpl->m_aControllers.begin(),m_pImpl->m_aControllers.end(),_xController) == m_pImpl->m_aControllers.end() ) + throw container::NoSuchElementException(); + m_pImpl->m_xCurrentController = _xController; +} + +uno::Reference< uno::XInterface > SAL_CALL OReportDefinition::getCurrentSelection( ) +{ + return uno::Reference< uno::XInterface >(); +} + +void OReportDefinition::impl_loadFromStorage_nolck_throw( const uno::Reference< embed::XStorage >& _xStorageToLoadFrom, + const uno::Sequence< beans::PropertyValue >& _aMediaDescriptor ) +{ + m_pImpl->m_xStorage = _xStorageToLoadFrom; + + utl::MediaDescriptor aDescriptor( _aMediaDescriptor ); + fillArgs(aDescriptor); + aDescriptor.createItemIfMissing("Storage",uno::Any(_xStorageToLoadFrom)); + + uno::Sequence< uno::Any > aDelegatorArguments(_aMediaDescriptor.getLength()); + uno::Any* pIter = aDelegatorArguments.getArray(); + uno::Any* pEnd = pIter + aDelegatorArguments.getLength(); + for(sal_Int32 i = 0;pIter != pEnd;++pIter,++i) + { + *pIter <<= _aMediaDescriptor[i]; + } + sal_Int32 nPos = aDelegatorArguments.getLength(); + aDelegatorArguments.realloc(nPos+1); + beans::PropertyValue aPropVal; + aPropVal.Name = "Storage"; + aPropVal.Value <<= _xStorageToLoadFrom; + aDelegatorArguments.getArray()[nPos] <<= aPropVal; + + rptui::OXUndoEnvironment& rEnv = m_pImpl->m_pReportModel->GetUndoEnv(); + rptui::OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + { + uno::Reference< document::XFilter > xFilter( + m_aProps->m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.report.OReportFilter",aDelegatorArguments,m_aProps->m_xContext), + uno::UNO_QUERY_THROW ); + + uno::Reference< document::XImporter> xImporter(xFilter,uno::UNO_QUERY_THROW); + uno::Reference<XComponent> xComponent(static_cast<OWeakObject*>(this),uno::UNO_QUERY); + xImporter->setTargetDocument(xComponent); + + utl::MediaDescriptor aTemp; + aTemp << aDelegatorArguments; + xFilter->filter(aTemp.getAsConstPropertyValueList()); + + lcl_setModelReadOnly(m_pImpl->m_xStorage,m_pImpl->m_pReportModel); + m_pImpl->m_pObjectContainer->SwitchPersistence(m_pImpl->m_xStorage); + } +} + +// XStorageBasedDocument +void SAL_CALL OReportDefinition::loadFromStorage( const uno::Reference< embed::XStorage >& _xStorageToLoadFrom + , const uno::Sequence< beans::PropertyValue >& _aMediaDescriptor ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + impl_loadFromStorage_nolck_throw( _xStorageToLoadFrom, _aMediaDescriptor ); +} + +void SAL_CALL OReportDefinition::storeToStorage( const uno::Reference< embed::XStorage >& _xStorageToSaveTo, const uno::Sequence< beans::PropertyValue >& _aMediaDescriptor ) +{ + if ( !_xStorageToSaveTo.is() ) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,1); + + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + // create XStatusIndicator + uno::Reference<task::XStatusIndicator> xStatusIndicator; + uno::Sequence< uno::Any > aDelegatorArguments; + utl::MediaDescriptor aDescriptor( _aMediaDescriptor ); + lcl_extractAndStartStatusIndicator( aDescriptor, xStatusIndicator, aDelegatorArguments ); + bool AutoSaveEvent = false; + aDescriptor[utl::MediaDescriptor::PROP_AUTOSAVEEVENT] >>= AutoSaveEvent; + + // properties + uno::Sequence < beans::PropertyValue > aProps; + + // export sub streams for package, else full stream into a file + uno::Reference< beans::XPropertySet> xProp(_xStorageToSaveTo,uno::UNO_QUERY); + if ( xProp.is() ) + { + static constexpr OUStringLiteral sPropName = u"MediaType"; + OUString sOldMediaType; + xProp->getPropertyValue(sPropName) >>= sOldMediaType; + if ( !xProp->getPropertyValue(sPropName).hasValue() || sOldMediaType.isEmpty() || MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII != sOldMediaType ) + xProp->setPropertyValue( sPropName, uno::Any(OUString(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII)) ); + } + + /** property map for export info set */ + static comphelper::PropertyMapEntry const aExportInfoMap[] = + { + { OUString("UsePrettyPrinting") , 0, cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("StreamName") , 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("StreamRelPath") , 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("BaseURI") , 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + }; + uno::Reference< beans::XPropertySet > xInfoSet( comphelper::GenericPropertySet_CreateInstance( new comphelper::PropertySetInfo( aExportInfoMap ) ) ); + + xInfoSet->setPropertyValue("UsePrettyPrinting", uno::Any(officecfg::Office::Common::Save::Document::PrettyPrinting::get())); + if ( officecfg::Office::Common::Save::URL::FileSystem::get() ) + { + const OUString sVal( aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTBASEURL, OUString()) ); + xInfoSet->setPropertyValue("BaseURI", uno::Any(sVal)); + } + const OUString sHierarchicalDocumentName( aDescriptor.getUnpackedValueOrDefault("HierarchicalDocumentName",OUString()) ); + xInfoSet->setPropertyValue("StreamRelPath", uno::Any(sHierarchicalDocumentName)); + + + sal_Int32 nArgsLen = aDelegatorArguments.getLength(); + aDelegatorArguments.realloc(nArgsLen+3); + auto pDelegatorArguments = aDelegatorArguments.getArray(); + pDelegatorArguments[nArgsLen++] <<= xInfoSet; + + uno::Reference< document::XEmbeddedObjectResolver > xObjectResolver; + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler; + rtl::Reference<SvXMLGraphicHelper> xGraphicHelper = SvXMLGraphicHelper::Create(_xStorageToSaveTo,SvXMLGraphicHelperMode::Write); + xGraphicStorageHandler = xGraphicHelper.get(); + xGraphicHelper.clear(); + xObjectResolver = SvXMLEmbeddedObjectHelper::Create( _xStorageToSaveTo,*this, SvXMLEmbeddedObjectHelperMode::Write ).get(); + + pDelegatorArguments[nArgsLen++] <<= xGraphicStorageHandler; + pDelegatorArguments[nArgsLen++] <<= xObjectResolver; + + uno::Reference<XComponent> xCom(static_cast<OWeakObject*>(this),uno::UNO_QUERY); + // Try to write to settings.xml, meta.xml, and styles.xml; only really care about success of + // write to content.xml (keeping logic of commit 94ccba3eebc83b58e74e18f0e028c6a995ce6aa6) + xInfoSet->setPropertyValue("StreamName", uno::Any(OUString("settings.xml"))); + WriteThroughComponent(xCom, "settings.xml", "com.sun.star.comp.report.XMLSettingsExporter", + aDelegatorArguments, aProps, _xStorageToSaveTo); + + xInfoSet->setPropertyValue("StreamName", uno::Any(OUString("meta.xml"))); + WriteThroughComponent(xCom, "meta.xml", "com.sun.star.comp.report.XMLMetaExporter", + aDelegatorArguments, aProps, _xStorageToSaveTo); + + xInfoSet->setPropertyValue("StreamName", uno::Any(OUString("styles.xml"))); + WriteThroughComponent(xCom, "styles.xml", "com.sun.star.comp.report.XMLStylesExporter", + aDelegatorArguments, aProps, _xStorageToSaveTo); + + xInfoSet->setPropertyValue("StreamName", uno::Any(OUString("content.xml"))); + bool bOk = WriteThroughComponent(xCom, "content.xml", "com.sun.star.comp.report.ExportFilter", + aDelegatorArguments, aProps, _xStorageToSaveTo); + + uno::Any aImage; + uno::Reference< embed::XVisualObject > xCurrentController(getCurrentController(),uno::UNO_QUERY); + if ( xCurrentController.is() ) + { + xCurrentController->setVisualAreaSize(m_pImpl->m_nAspect,m_pImpl->m_aVisualAreaSize); + aImage = xCurrentController->getPreferredVisualRepresentation( m_pImpl->m_nAspect ).Data; + } + if ( aImage.hasValue() ) + { + uno::Sequence<sal_Int8> aSeq; + aImage >>= aSeq; + uno::Reference<io::XInputStream> xStream = new ::comphelper::SequenceInputStream( aSeq ); + m_pImpl->m_pObjectContainer->InsertGraphicStreamDirectly(xStream, "report", "image/png"); + } + + if (bOk) + { + bool bPersist = false; + if ( _xStorageToSaveTo == m_pImpl->m_xStorage ) + bPersist = m_pImpl->m_pObjectContainer->StoreChildren(true,false); + else + bPersist = m_pImpl->m_pObjectContainer->StoreAsChildren(true,true,AutoSaveEvent,_xStorageToSaveTo); + + if( bPersist ) + m_pImpl->m_pObjectContainer->SetPersistentEntries(m_pImpl->m_xStorage); + try + { + uno::Reference<embed::XTransactedObject> xTransact(_xStorageToSaveTo,uno::UNO_QUERY); + if ( xTransact.is() ) + xTransact->commit(); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Could not commit report storage!"); + throw io::IOException(); + } + + if ( _xStorageToSaveTo == m_pImpl->m_xStorage ) + setModified(false); + } + if ( xStatusIndicator.is() ) + xStatusIndicator->end(); +} + +void SAL_CALL OReportDefinition::switchToStorage( + const uno::Reference< embed::XStorage >& xStorage) +{ + if (!xStorage.is()) + throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,1); + { + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_xStorage = xStorage; + lcl_setModelReadOnly(m_pImpl->m_xStorage,m_pImpl->m_pReportModel); + m_pImpl->m_pObjectContainer->SwitchPersistence(m_pImpl->m_xStorage); + } + // notify our container listeners + m_pImpl->m_aStorageChangeListeners.forEach( + [this, &xStorage] (uno::Reference<document::XStorageChangeListener> const& xListener) { + return xListener->notifyStorageChange(static_cast<OWeakObject*>(this), xStorage); + }); +} + +uno::Reference< embed::XStorage > SAL_CALL OReportDefinition::getDocumentStorage( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_xStorage; +} + +void SAL_CALL OReportDefinition::addStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( xListener.is() ) + m_pImpl->m_aStorageChangeListeners.addInterface(xListener); +} + +void SAL_CALL OReportDefinition::removeStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aStorageChangeListeners.removeInterface(xListener); +} + +bool OReportDefinition::WriteThroughComponent( + const uno::Reference<lang::XComponent> & xComponent, + const char* pStreamName, + const char* pServiceName, + const uno::Sequence<uno::Any> & rArguments, + const uno::Sequence<beans::PropertyValue> & rMediaDesc, + const uno::Reference<embed::XStorage>& _xStorageToSaveTo) +{ + OSL_ENSURE( nullptr != pStreamName, "Need stream name!" ); + OSL_ENSURE( nullptr != pServiceName, "Need service name!" ); + + // open stream + OUString sStreamName = OUString::createFromAscii( pStreamName ); + uno::Reference<io::XStream> xStream = _xStorageToSaveTo->openStreamElement( sStreamName,embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE ); + if ( !xStream.is() ) + return false; + uno::Reference<io::XOutputStream> xOutputStream = xStream->getOutputStream(); + OSL_ENSURE(xOutputStream.is(), "Can't create output stream in package!"); + if ( ! xOutputStream.is() ) + return false; + + uno::Reference<beans::XPropertySet> xStreamProp(xOutputStream,uno::UNO_QUERY); + OSL_ENSURE(xStreamProp.is(),"No valid property set for the output stream!"); + + uno::Reference<io::XSeekable> xSeek(xStreamProp,uno::UNO_QUERY); + if ( xSeek.is() ) + { + xSeek->seek(0); + } + + xStreamProp->setPropertyValue( "MediaType", uno::Any(OUString("text/xml")) ); + + // encrypt all streams + xStreamProp->setPropertyValue( "UseCommonStoragePasswordEncryption", + uno::Any( true ) ); + + // set buffer and create outputstream + + // write the stuff + bool bRet = WriteThroughComponent( + xOutputStream, xComponent, + pServiceName, rArguments, rMediaDesc ); + // finally, commit stream. + return bRet; +} + +bool OReportDefinition::WriteThroughComponent( + const uno::Reference<io::XOutputStream> & xOutputStream, + const uno::Reference<lang::XComponent> & xComponent, + const char* pServiceName, + const uno::Sequence<uno::Any> & rArguments, + const uno::Sequence<beans::PropertyValue> & rMediaDesc) +{ + OSL_ENSURE( xOutputStream.is(), "I really need an output stream!" ); + OSL_ENSURE( xComponent.is(), "Need component!" ); + OSL_ENSURE( nullptr != pServiceName, "Need component name!" ); + + // get component + uno::Reference< xml::sax::XWriter > xSaxWriter( + xml::sax::Writer::create(m_aProps->m_xContext) ); + + // connect XML writer to output stream + xSaxWriter->setOutputStream( xOutputStream ); + + // prepare arguments (prepend doc handler to given arguments) + uno::Sequence<uno::Any> aArgs( 1 + rArguments.getLength() ); + auto pArgs = aArgs.getArray(); + *pArgs <<= xSaxWriter; + std::copy(rArguments.begin(), rArguments.end(), std::next(pArgs)); + + // get filter component + uno::Reference< document::XExporter > xExporter( + m_aProps->m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + OUString::createFromAscii(pServiceName), aArgs,m_aProps->m_xContext), uno::UNO_QUERY); + OSL_ENSURE( xExporter.is(), + "can't instantiate export filter component" ); + if( !xExporter.is() ) + return false; + + // connect model and filter + xExporter->setSourceDocument( xComponent ); + + // filter! + uno::Reference<document::XFilter> xFilter( xExporter, uno::UNO_QUERY ); + return xFilter->filter( rMediaDesc ); +} + +// XLoadable +void SAL_CALL OReportDefinition::initNew( ) +{ + setPageHeaderOn( true ); + setPageFooterOn( true ); +} + +void SAL_CALL OReportDefinition::load( const uno::Sequence< beans::PropertyValue >& _rArguments ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + // TODO: this code is pretty similar to what happens in ODatabaseModelImpl::getOrCreateRootStorage, + // perhaps we can share code here. + + ::comphelper::NamedValueCollection aArguments( _rArguments ); + + // the source for the to-be-created storage: either a URL, or a stream + uno::Reference< io::XInputStream > xStream; + OUString sURL; + + if ( aArguments.has( "Stream" ) ) + { + aArguments.get_ensureType( "Stream", xStream ); + aArguments.remove( "Stream" ); + } + else if ( aArguments.has( "InputStream" ) ) + { + aArguments.get_ensureType( "InputStream", xStream ); + aArguments.remove( "InputStream" ); + } + + if ( aArguments.has( "FileName" ) ) + { + aArguments.get_ensureType( "FileName", sURL ); + aArguments.remove( "FileName" ); + } + else if ( aArguments.has( "URL" ) ) + { + aArguments.get_ensureType( "URL", sURL ); + aArguments.remove( "URL" ); + } + + uno::Any aStorageSource; + if ( xStream.is() ) + aStorageSource <<= xStream; + else if ( !sURL.isEmpty() ) + aStorageSource <<= sURL; + else + throw lang::IllegalArgumentException( + "No input source (URL or InputStream) found.", + // TODO: resource + *this, + 1 + ); + + uno::Reference< lang::XSingleServiceFactory > xStorageFactory( embed::StorageFactory::create( m_aProps->m_xContext ) ); + + // open read-write per default, unless told otherwise in the MediaDescriptor + uno::Reference< embed::XStorage > xDocumentStorage; + const sal_Int32 nOpenModes[2] = { + embed::ElementModes::READWRITE, + embed::ElementModes::READ + }; + size_t nFirstOpenMode = 0; + if ( aArguments.has( "ReadOnly" ) ) + { + bool bReadOnly = false; + aArguments.get_ensureType( "ReadOnly", bReadOnly ); + nFirstOpenMode = bReadOnly ? 1 : 0; + } + const size_t nLastOpenMode = SAL_N_ELEMENTS( nOpenModes ) - 1; + for ( size_t i=nFirstOpenMode; i <= nLastOpenMode; ++i ) + { + uno::Sequence< uno::Any > aStorageCreationArgs{ aStorageSource, uno::Any(nOpenModes[i]) }; + + try + { + xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), uno::UNO_QUERY_THROW ); + } + catch (const uno::Exception&) + { + if ( i == nLastOpenMode ) + { + css::uno::Any anyEx = cppu::getCaughtException(); + throw lang::WrappedTargetException( + "An error occurred while creating the document storage.", + // TODO: resource + *this, + anyEx + ); + } + } + } + + if ( !xDocumentStorage.is() ) + { + throw uno::RuntimeException(); + } + + if (!aArguments.has("DocumentBaseURL") && !sURL.isEmpty()) + { + aArguments.put("DocumentBaseURL", sURL); + } + + impl_loadFromStorage_nolck_throw( xDocumentStorage, aArguments.getPropertyValues() ); + // TODO: do we need to take ownership of the storage? In opposite to loadFromStorage, we created the storage + // ourself here, and perhaps this means we're also responsible for it ...? +} + +// XVisualObject +void SAL_CALL OReportDefinition::setVisualAreaSize( ::sal_Int64 _nAspect, const awt::Size& _aSize ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + bool bChanged = + (m_pImpl->m_aVisualAreaSize.Width != _aSize.Width || + m_pImpl->m_aVisualAreaSize.Height != _aSize.Height); + m_pImpl->m_aVisualAreaSize = _aSize; + if( bChanged ) + setModified( true ); + m_pImpl->m_nAspect = _nAspect; +} + +awt::Size SAL_CALL OReportDefinition::getVisualAreaSize( ::sal_Int64 /*_nAspect*/ ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_aVisualAreaSize; +} + +embed::VisualRepresentation SAL_CALL OReportDefinition::getPreferredVisualRepresentation( ::sal_Int64 /*_nAspect*/ ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + embed::VisualRepresentation aResult; + OUString sMimeType; + uno::Reference<io::XInputStream> xStream = m_pImpl->m_pObjectContainer->GetGraphicStream("report", &sMimeType); + if ( xStream.is() ) + { + uno::Sequence<sal_Int8> aSeq; + xStream->readBytes(aSeq,xStream->available()); + xStream->closeInput(); + aResult.Data <<= aSeq; + aResult.Flavor.MimeType = sMimeType; + aResult.Flavor.DataType = cppu::UnoType<decltype(aSeq)>::get(); + } + + return aResult; +} + +::sal_Int32 SAL_CALL OReportDefinition::getMapUnit( ::sal_Int64 /*nAspect*/ ) +{ + return embed::EmbedMapUnits::ONE_100TH_MM; +} + +// XModifiable +sal_Bool SAL_CALL OReportDefinition::disableSetModified( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + ::connectivity::checkDisposed( ReportDefinitionBase::rBHelper.bDisposed ); + + const bool bWasEnabled = m_pImpl->m_bSetModifiedEnabled; + m_pImpl->m_bSetModifiedEnabled = false; + return bWasEnabled; +} + +sal_Bool SAL_CALL OReportDefinition::enableSetModified( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + ::connectivity::checkDisposed( ReportDefinitionBase::rBHelper.bDisposed ); + + const bool bWasEnabled = m_pImpl->m_bSetModifiedEnabled; + m_pImpl->m_bSetModifiedEnabled = true; + return bWasEnabled; +} + +sal_Bool SAL_CALL OReportDefinition::isSetModifiedEnabled( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + ::connectivity::checkDisposed( ReportDefinitionBase::rBHelper.bDisposed ); + + return m_pImpl->m_bSetModifiedEnabled; +} + +// XModifiable +sal_Bool SAL_CALL OReportDefinition::isModified( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_bModified; +} + +void SAL_CALL OReportDefinition::setModified( sal_Bool _bModified ) +{ + osl::ClearableMutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + if ( !m_pImpl->m_bSetModifiedEnabled ) + return; + + if ( m_pImpl->m_pReportModel->IsReadOnly() && _bModified ) + throw beans::PropertyVetoException(); + if ( m_pImpl->m_bModified != bool(_bModified) ) + { + m_pImpl->m_bModified = _bModified; + if ( m_pImpl->m_pReportModel->IsChanged() != bool(_bModified) ) + m_pImpl->m_pReportModel->SetChanged(_bModified); + + lang::EventObject aEvent(*this); + aGuard.clear(); + m_pImpl->m_aModifyListeners.notifyEach(&util::XModifyListener::modified,aEvent); + notifyEvent("OnModifyChanged"); + } +} + +// XModifyBroadcaster +void SAL_CALL OReportDefinition::addModifyListener( const uno::Reference< util::XModifyListener >& _xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( _xListener.is() ) + m_pImpl->m_aModifyListeners.addInterface(_xListener); +} + +void SAL_CALL OReportDefinition::removeModifyListener( const uno::Reference< util::XModifyListener >& _xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aModifyListeners.removeInterface(_xListener); +} + +void OReportDefinition::notifyEvent(const OUString& _sEventName) +{ + try + { + osl::ClearableMutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + document::EventObject aEvt(*this, _sEventName); + aGuard.clear(); + m_pImpl->m_aLegacyEventListeners.notifyEach(&document::XEventListener::notifyEvent,aEvt); + } + catch (const uno::Exception&) + { + } + + notifyDocumentEvent(_sEventName, nullptr, css::uno::Any()); +} + +// document::XDocumentEventBroadcaster +void SAL_CALL OReportDefinition::notifyDocumentEvent( const OUString& rEventName, const uno::Reference< frame::XController2 >& rViewController, const uno::Any& rSupplement ) +{ + try + { + osl::ClearableMutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + document::DocumentEvent aEvt(*this, rEventName, rViewController, rSupplement); + aGuard.clear(); + m_pImpl->m_aDocEventListeners.notifyEach(&document::XDocumentEventListener::documentEventOccured,aEvt); + } + catch (const uno::Exception&) + { + } +} + +void SAL_CALL OReportDefinition::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& rListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( rListener.is() ) + m_pImpl->m_aDocEventListeners.addInterface(rListener); +} + +void SAL_CALL OReportDefinition::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& rListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aDocEventListeners.removeInterface(rListener); +} + +// document::XEventBroadcaster +void SAL_CALL OReportDefinition::addEventListener(const uno::Reference< document::XEventListener >& _xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( _xListener.is() ) + m_pImpl->m_aLegacyEventListeners.addInterface(_xListener); +} + +void SAL_CALL OReportDefinition::removeEventListener( const uno::Reference< document::XEventListener >& _xListener ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_aLegacyEventListeners.removeInterface(_xListener); +} + +// document::XViewDataSupplier +uno::Reference< container::XIndexAccess > SAL_CALL OReportDefinition::getViewData( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( !m_pImpl->m_xViewData.is() ) + { + rtl::Reference<comphelper::IndexedPropertyValuesContainer> xNewViewData = new comphelper::IndexedPropertyValuesContainer(); + m_pImpl->m_xViewData = xNewViewData; + for (const auto& rxController : m_pImpl->m_aControllers) + { + if ( rxController.is() ) + { + try + { + xNewViewData->insertByIndex(xNewViewData->getCount(), rxController->getViewData()); + } + catch (const uno::Exception&) + { + } + } + } + + } + return m_pImpl->m_xViewData; +} + +void SAL_CALL OReportDefinition::setViewData( const uno::Reference< container::XIndexAccess >& Data ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_xViewData = Data; +} + +uno::Reference< report::XFunctions > SAL_CALL OReportDefinition::getFunctions() +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_xFunctions; +} + +uno::Reference< ui::XUIConfigurationManager > SAL_CALL OReportDefinition::getUIConfigurationManager( ) +{ + return uno::Reference< ui::XUIConfigurationManager >( getUIConfigurationManager2(), uno::UNO_QUERY_THROW ); +} + +uno::Reference< ui::XUIConfigurationManager2 > OReportDefinition::getUIConfigurationManager2( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + if ( !m_pImpl->m_xUIConfigurationManager.is() ) + { + m_pImpl->m_xUIConfigurationManager = ui::UIConfigurationManager::create(m_aProps->m_xContext); + + uno::Reference< embed::XStorage > xConfigStorage; + // initialize ui configuration manager with document substorage + m_pImpl->m_xUIConfigurationManager->setStorage( xConfigStorage ); + } + + return m_pImpl->m_xUIConfigurationManager; +} + +uno::Reference< embed::XStorage > SAL_CALL OReportDefinition::getDocumentSubStorage( const OUString& aStorageName, sal_Int32 nMode ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_xStorage->openStorageElement(aStorageName, nMode); +} + +uno::Sequence< OUString > SAL_CALL OReportDefinition::getDocumentSubStoragesNames( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + uno::Reference<container::XNameAccess> xNameAccess = m_pImpl->m_xStorage; + return xNameAccess.is() ? xNameAccess->getElementNames() : uno::Sequence< OUString >(); +} + +OUString SAL_CALL OReportDefinition::getMimeType() +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_sMimeType; +} + +void SAL_CALL OReportDefinition::setMimeType( const OUString& _mimetype ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + const uno::Sequence< OUString > aList = getAvailableMimeTypes(); + if ( ::std::find(aList.begin(), aList.end(), _mimetype) == aList.end() ) + throwIllegallArgumentException(u"getAvailableMimeTypes()" + ,*this + ,1); + set(PROPERTY_MIMETYPE,_mimetype,m_pImpl->m_sMimeType); +} + +uno::Sequence< OUString > SAL_CALL OReportDefinition::getAvailableMimeTypes( ) +{ + return { MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII, MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII }; +} + +// css::XUnoTunnel +sal_Int64 SAL_CALL OReportDefinition::getSomething( const uno::Sequence< sal_Int8 >& rId ) +{ + sal_Int64 nRet = 0; + if (comphelper::isUnoTunnelId<OReportDefinition>(rId) ) + nRet = comphelper::getSomething_cast(this); + else + { + uno::Reference< lang::XUnoTunnel> xUnoTunnel(m_pImpl->m_xNumberFormatsSupplier,uno::UNO_QUERY); + if ( xUnoTunnel.is() ) + nRet = xUnoTunnel->getSomething(rId); + } + if ( !nRet ) + { + uno::Reference< lang::XUnoTunnel> xTunnel; + ::comphelper::query_aggregation(m_aProps->m_xProxy,xTunnel); + if ( xTunnel.is() ) + nRet = xTunnel->getSomething(rId); + } + + return nRet; +} + +uno::Sequence< sal_Int8 > SAL_CALL OReportDefinition::getImplementationId( ) +{ + return css::uno::Sequence<sal_Int8>(); +} + +const uno::Sequence< sal_Int8 > & OReportDefinition::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +uno::Reference< uno::XComponentContext > OReportDefinition::getContext() +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_aProps->m_xContext; +} + +std::shared_ptr<rptui::OReportModel> OReportDefinition::getSdrModel(const uno::Reference< report::XReportDefinition >& _xReportDefinition) +{ + std::shared_ptr<rptui::OReportModel> pReportModel; + auto pReportDefinition = comphelper::getFromUnoTunnel<OReportDefinition>(_xReportDefinition); + if (pReportDefinition) + pReportModel = pReportDefinition->m_pImpl->m_pReportModel; + return pReportModel; +} + +SdrModel& OReportDefinition::getSdrModelFromUnoModel() const +{ + OSL_ENSURE(m_pImpl->m_pReportModel, "No SdrModel in ReportDesign, should not happen"); + return *m_pImpl->m_pReportModel; +} + +uno::Reference< uno::XInterface > SAL_CALL OReportDefinition::createInstanceWithArguments( const OUString& aServiceSpecifier, const uno::Sequence< uno::Any >& _aArgs) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + uno::Reference< uno::XInterface > xRet; + if ( aServiceSpecifier.startsWith( "com.sun.star.document.ImportEmbeddedObjectResolver") ) + { + uno::Reference< embed::XStorage > xStorage; + for(const uno::Any& rArg : _aArgs) + { + beans::NamedValue aValue; + rArg >>= aValue; + if ( aValue.Name == "Storage" ) + aValue.Value >>= xStorage; + } + m_pImpl->m_pObjectContainer->SwitchPersistence(xStorage); + xRet = static_cast< ::cppu::OWeakObject* >(SvXMLEmbeddedObjectHelper::Create( xStorage,*this, SvXMLEmbeddedObjectHelperMode::Read ).get()); + } + return xRet; +} + +uno::Reference< uno::XInterface > SAL_CALL OReportDefinition::createInstance( const OUString& aServiceSpecifier ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + uno::Reference< drawing::XShape > xShape; + if ( aServiceSpecifier.startsWith( "com.sun.star.report." ) ) + { + if ( aServiceSpecifier == SERVICE_SHAPE ) + xShape.set(SvxUnoDrawMSFactory::createInstance("com.sun.star.drawing.CustomShape"),uno::UNO_QUERY_THROW); + else if ( aServiceSpecifier == SERVICE_FORMATTEDFIELD + || aServiceSpecifier == SERVICE_FIXEDTEXT + || aServiceSpecifier == SERVICE_FIXEDLINE + || aServiceSpecifier == SERVICE_IMAGECONTROL ) + xShape.set(SvxUnoDrawMSFactory::createInstance("com.sun.star.drawing.ControlShape"),uno::UNO_QUERY_THROW); + else + xShape.set(SvxUnoDrawMSFactory::createInstance("com.sun.star.drawing.OLE2Shape"),uno::UNO_QUERY_THROW); + } + else if ( aServiceSpecifier.startsWith( "com.sun.star.form.component." ) ) + { + xShape.set(m_aProps->m_xContext->getServiceManager()->createInstanceWithContext(aServiceSpecifier,m_aProps->m_xContext),uno::UNO_QUERY); + } + else if ( aServiceSpecifier == "com.sun.star.style.PageStyle" || + aServiceSpecifier == "com.sun.star.style.FrameStyle" || + aServiceSpecifier == "com.sun.star.style.GraphicStyle" + ) + { + uno::Reference< style::XStyle> xStyle = new OStyle(); + xStyle->setName("Default"); + return xStyle; + } + else if ( aServiceSpecifier == "com.sun.star.document.Settings" ) + { + uno::Reference<beans::XPropertySet> xProp = new OStyle(); + + return xProp; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.Defaults" ) + { + uno::Reference<beans::XPropertySet> xProp = new OStyle(); + return xProp; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.GradientTable" ) + { + if ( !m_pImpl->m_xGradientTable.is() ) + m_pImpl->m_xGradientTable.set(SvxUnoGradientTable_createInstance(m_pImpl->m_pReportModel.get()),uno::UNO_QUERY); + return m_pImpl->m_xGradientTable; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.HatchTable" ) + { + if ( !m_pImpl->m_xHatchTable.is() ) + m_pImpl->m_xHatchTable.set(SvxUnoHatchTable_createInstance(m_pImpl->m_pReportModel.get()),uno::UNO_QUERY); + return m_pImpl->m_xHatchTable; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" ) + { + if ( !m_pImpl->m_xBitmapTable.is() ) + m_pImpl->m_xBitmapTable.set(SvxUnoBitmapTable_createInstance(m_pImpl->m_pReportModel.get()),uno::UNO_QUERY); + return m_pImpl->m_xBitmapTable; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" ) + { + if ( !m_pImpl->m_xTransparencyGradientTable.is() ) + m_pImpl->m_xTransparencyGradientTable.set(SvxUnoTransGradientTable_createInstance(m_pImpl->m_pReportModel.get()),uno::UNO_QUERY); + return m_pImpl->m_xTransparencyGradientTable; + } + else if ( aServiceSpecifier == "com.sun.star.drawing.DashTable" ) + { + if ( !m_pImpl->m_xDashTable.is() ) + m_pImpl->m_xDashTable.set(SvxUnoDashTable_createInstance(m_pImpl->m_pReportModel.get()),uno::UNO_QUERY); + return m_pImpl->m_xDashTable; + } + else if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" ) + { + if( !m_pImpl->m_xMarkerTable.is() ) + m_pImpl->m_xMarkerTable.set(SvxUnoMarkerTable_createInstance( m_pImpl->m_pReportModel.get() ),uno::UNO_QUERY); + return m_pImpl->m_xMarkerTable; + } + else if ( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" ) + return static_cast< ::cppu::OWeakObject* >(SvXMLEmbeddedObjectHelper::Create( m_pImpl->m_xStorage,*this, SvXMLEmbeddedObjectHelperMode::Read ).get()); + else if ( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" ) + return static_cast< ::cppu::OWeakObject* >(SvXMLEmbeddedObjectHelper::Create( m_pImpl->m_xStorage,*this, SvXMLEmbeddedObjectHelperMode::Write ).get()); + else if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler") + { + rtl::Reference<SvXMLGraphicHelper> xGraphicHelper = SvXMLGraphicHelper::Create(m_pImpl->m_xStorage,SvXMLGraphicHelperMode::Write); + uno::Reference< uno::XInterface> xRet(static_cast< ::cppu::OWeakObject* >(xGraphicHelper.get())); + return xRet; + } + else if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler") + { + rtl::Reference<SvXMLGraphicHelper> xGraphicHelper = SvXMLGraphicHelper::Create(m_pImpl->m_xStorage,SvXMLGraphicHelperMode::Write); + uno::Reference< uno::XInterface> xRet(static_cast< ::cppu::OWeakObject* >(xGraphicHelper.get())); + return xRet; + } + else if ( aServiceSpecifier == "com.sun.star.chart2.data.DataProvider" ) + { + uno::Reference<chart2::data::XDatabaseDataProvider> xDataProvider(chart2::data::DatabaseDataProvider::createWithConnection( m_aProps->m_xContext, m_pImpl->m_xActiveConnection )); + xDataProvider->setRowLimit(10); + uno::Reference< container::XChild > xChild(xDataProvider,uno::UNO_QUERY); + if ( xChild.is() ) + xChild->setParent(*this); + return uno::Reference< uno::XInterface >(xDataProvider,uno::UNO_QUERY); + } + else if ( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" ) + { + if ( !m_pImpl->m_xXMLNamespaceMap.is() ) + m_pImpl->m_xXMLNamespaceMap = comphelper::NameContainer_createInstance( cppu::UnoType<OUString>::get() ).get(); + return m_pImpl->m_xXMLNamespaceMap; + } + else + xShape.set(SvxUnoDrawMSFactory::createInstance( aServiceSpecifier ),uno::UNO_QUERY_THROW); + + return m_pImpl->m_pReportModel->createShape(aServiceSpecifier,xShape); +} + +uno::Sequence< OUString > SAL_CALL OReportDefinition::getAvailableServiceNames() +{ + static const std::u16string_view aSvxComponentServiceNameList[] = + { + u"com.sun.star.form.component.FixedText", + u"com.sun.star.form.component.DatabaseImageControl", + u"com.sun.star.style.PageStyle", + u"com.sun.star.style.GraphicStyle", + u"com.sun.star.style.FrameStyle", + u"com.sun.star.drawing.Defaults", + u"com.sun.star.document.ImportEmbeddedObjectResolver", + u"com.sun.star.document.ExportEmbeddedObjectResolver", + u"com.sun.star.document.ImportGraphicStorageHandler", + u"com.sun.star.document.ExportGraphicStorageHandler", + u"com.sun.star.chart2.data.DataProvider", + u"com.sun.star.xml.NamespaceMap", + u"com.sun.star.document.Settings", + u"com.sun.star.drawing.GradientTable", + u"com.sun.star.drawing.HatchTable", + u"com.sun.star.drawing.BitmapTable", + u"com.sun.star.drawing.TransparencyGradientTable", + u"com.sun.star.drawing.DashTable", + u"com.sun.star.drawing.MarkerTable" + }; + + static const sal_uInt16 nSvxComponentServiceNameListCount = SAL_N_ELEMENTS(aSvxComponentServiceNameList); + + uno::Sequence< OUString > aSeq( nSvxComponentServiceNameListCount ); + OUString* pStrings = aSeq.getArray(); + for( sal_uInt16 nIdx = 0; nIdx < nSvxComponentServiceNameListCount; nIdx++ ) + pStrings[nIdx] = aSvxComponentServiceNameList[nIdx]; + + uno::Sequence< OUString > aParentSeq( SvxUnoDrawMSFactory::getAvailableServiceNames() ); + return comphelper::concatSequences( aParentSeq, aSeq ); +} + +// XShape +awt::Point SAL_CALL OReportDefinition::getPosition( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( m_aProps->m_xShape.is() ) + return m_aProps->m_xShape->getPosition(); + return awt::Point(m_aProps->m_nPosX,m_aProps->m_nPosY); +} + +void SAL_CALL OReportDefinition::setPosition( const awt::Point& aPosition ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( m_aProps->m_xShape.is() ) + m_aProps->m_xShape->setPosition(aPosition); + set(PROPERTY_POSITIONX,aPosition.X,m_aProps->m_nPosX); + set(PROPERTY_POSITIONY,aPosition.Y,m_aProps->m_nPosY); +} + +awt::Size SAL_CALL OReportDefinition::getSize( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( m_aProps->m_xShape.is() ) + return m_aProps->m_xShape->getSize(); + return awt::Size(m_aProps->m_nWidth,m_aProps->m_nHeight); +} + +void SAL_CALL OReportDefinition::setSize( const awt::Size& aSize ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( m_aProps->m_xShape.is() ) + m_aProps->m_xShape->setSize(aSize); + set(PROPERTY_WIDTH,aSize.Width,m_aProps->m_nWidth); + set(PROPERTY_HEIGHT,aSize.Height,m_aProps->m_nHeight); +} + + +// XShapeDescriptor +OUString SAL_CALL OReportDefinition::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( m_aProps->m_xShape.is() ) + return m_aProps->m_xShape->getShapeType(); + return "com.sun.star.drawing.OLE2Shape"; +} + +typedef ::cppu::WeakImplHelper< container::XNameContainer, + container::XIndexAccess + > TStylesBASE; + +namespace { + +class OStylesHelper: + public cppu::BaseMutex, public TStylesBASE +{ + typedef ::std::map< OUString, uno::Any , ::comphelper::UStringMixLess> TStyleElements; + TStyleElements m_aElements; + ::std::vector<TStyleElements::iterator> m_aElementsPos; + uno::Type m_aType; + +protected: + virtual ~OStylesHelper() override {} +public: + explicit OStylesHelper(const uno::Type& rType = cppu::UnoType<container::XElementAccess>::get()); + OStylesHelper(const OStylesHelper&) = delete; + OStylesHelper& operator=(const OStylesHelper&) = delete; + + // XNameContainer + virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override; + virtual void SAL_CALL removeByName( const OUString& Name ) override; + + // XNameReplace + virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override; + + // container::XElementAccess + virtual uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + // container::XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) override; + virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override; + + // container::XNameAccess + virtual uno::Any SAL_CALL getByName( const OUString& aName ) override; + virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) override; + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; +}; + +} + +OStylesHelper::OStylesHelper(const uno::Type& rType) + : cppu::BaseMutex() + , m_aType(rType) +{ +} +; + +// container::XElementAccess +uno::Type SAL_CALL OStylesHelper::getElementType( ) +{ + return m_aType; +} + +sal_Bool SAL_CALL OStylesHelper::hasElements( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return !m_aElementsPos.empty(); +} + +// container::XIndexAccess +sal_Int32 SAL_CALL OStylesHelper::getCount( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aElementsPos.size(); +} + +uno::Any SAL_CALL OStylesHelper::getByIndex( sal_Int32 Index ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( Index < 0 || o3tl::make_unsigned(Index) >= m_aElementsPos.size() ) + throw lang::IndexOutOfBoundsException(); + return m_aElementsPos[Index]->second; +} + +// container::XNameAccess +uno::Any SAL_CALL OStylesHelper::getByName( const OUString& aName ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + TStyleElements::const_iterator aFind = m_aElements.find(aName); + if ( aFind == m_aElements.end() ) + throw container::NoSuchElementException(); + return aFind->second; +} + +uno::Sequence< OUString > SAL_CALL OStylesHelper::getElementNames( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Sequence< OUString > aNameList(m_aElementsPos.size()); + + OUString* pStringArray = aNameList.getArray(); + for(const auto& rIter : m_aElementsPos) + { + *pStringArray = rIter->first; + ++pStringArray; + } + + return aNameList; +} + +sal_Bool SAL_CALL OStylesHelper::hasByName( const OUString& aName ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aElements.find(aName) != m_aElements.end(); +} + +// XNameContainer +void SAL_CALL OStylesHelper::insertByName( const OUString& aName, const uno::Any& aElement ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aElements.find(aName) != m_aElements.end() ) + throw container::ElementExistException(); + + if ( !aElement.isExtractableTo(m_aType) ) + throw lang::IllegalArgumentException(); + + m_aElementsPos.push_back(m_aElements.emplace(aName,aElement).first); +} + +void SAL_CALL OStylesHelper::removeByName( const OUString& aName ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + TStyleElements::const_iterator aFind = m_aElements.find(aName); + if ( aFind != m_aElements.end() ) + throw container::NoSuchElementException(); + m_aElementsPos.erase(::std::find(m_aElementsPos.begin(),m_aElementsPos.end(),aFind)); + m_aElements.erase(aFind); +} + +// XNameReplace +void SAL_CALL OStylesHelper::replaceByName( const OUString& aName, const uno::Any& aElement ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + TStyleElements::iterator aFind = m_aElements.find(aName); + if ( aFind == m_aElements.end() ) + throw container::NoSuchElementException(); + if ( !aElement.isExtractableTo(m_aType) ) + throw lang::IllegalArgumentException(); + aFind->second = aElement; +} + +uno::Reference< container::XNameAccess > SAL_CALL OReportDefinition::getStyleFamilies( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( !m_pImpl->m_xStyles.is() ) + { + m_pImpl->m_xStyles = new OStylesHelper(); + uno::Reference< container::XNameContainer> xStyles(m_pImpl->m_xStyles,uno::UNO_QUERY); + + uno::Reference< container::XNameContainer> xPageStyles = new OStylesHelper(cppu::UnoType<style::XStyle>::get()); + xStyles->insertByName("PageStyles",uno::Any(xPageStyles)); + uno::Reference< style::XStyle> xPageStyle(createInstance("com.sun.star.style.PageStyle"),uno::UNO_QUERY); + xPageStyles->insertByName(xPageStyle->getName(),uno::Any(xPageStyle)); + + uno::Reference< container::XNameContainer> xFrameStyles = new OStylesHelper(cppu::UnoType<style::XStyle>::get()); + xStyles->insertByName("FrameStyles",uno::Any(xFrameStyles)); + uno::Reference< style::XStyle> xFrameStyle(createInstance("com.sun.star.style.FrameStyle"),uno::UNO_QUERY); + xFrameStyles->insertByName(xFrameStyle->getName(),uno::Any(xFrameStyle)); + + uno::Reference< container::XNameContainer> xGraphicStyles = new OStylesHelper(cppu::UnoType<style::XStyle>::get()); + xStyles->insertByName("graphics",uno::Any(xGraphicStyles)); + uno::Reference< style::XStyle> xGraphicStyle(createInstance("com.sun.star.style.GraphicStyle"),uno::UNO_QUERY); + xGraphicStyles->insertByName(xGraphicStyle->getName(),uno::Any(xGraphicStyle)); + } + return m_pImpl->m_xStyles; +} +OUString SAL_CALL OReportDefinition::getIdentifier( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + return m_pImpl->m_sIdentifier; +} + +void SAL_CALL OReportDefinition::setIdentifier( const OUString& Identifier ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + m_pImpl->m_sIdentifier = Identifier; +} + +// XNumberFormatsSupplier +uno::Reference< beans::XPropertySet > SAL_CALL OReportDefinition::getNumberFormatSettings( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_pImpl->m_xNumberFormatsSupplier.is() ) + return m_pImpl->m_xNumberFormatsSupplier->getNumberFormatSettings(); + return uno::Reference< beans::XPropertySet >(); +} + +uno::Reference< util::XNumberFormats > SAL_CALL OReportDefinition::getNumberFormats( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_pImpl->m_xNumberFormatsSupplier.is() ) + return m_pImpl->m_xNumberFormatsSupplier->getNumberFormats(); + return uno::Reference< util::XNumberFormats >(); +} + +::comphelper::EmbeddedObjectContainer& OReportDefinition::getEmbeddedObjectContainer() const +{ + return *m_pImpl->m_pObjectContainer; +} + +uno::Reference< embed::XStorage > OReportDefinition::getStorage() const +{ + return m_pImpl->m_xStorage; +} + +uno::Reference< task::XInteractionHandler > OReportDefinition::getInteractionHandler() const +{ + uno::Reference< task::XInteractionHandler > xRet( + task::InteractionHandler::createWithParent(m_aProps->m_xContext, nullptr), uno::UNO_QUERY_THROW); + return xRet; +} + +uno::Reference< sdbc::XConnection > SAL_CALL OReportDefinition::getActiveConnection() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->m_xActiveConnection; +} + +void SAL_CALL OReportDefinition::setActiveConnection( const uno::Reference< sdbc::XConnection >& _activeconnection ) +{ + if ( !_activeconnection.is() ) + throw lang::IllegalArgumentException(); + set(PROPERTY_ACTIVECONNECTION,_activeconnection,m_pImpl->m_xActiveConnection); +} + +OUString SAL_CALL OReportDefinition::getDataSourceName() +{ + osl::MutexGuard g(m_aMutex); + return m_pImpl->m_sDataSourceName; +} + +void SAL_CALL OReportDefinition::setDataSourceName(const OUString& the_value) +{ + set(PROPERTY_DATASOURCENAME,the_value,m_pImpl->m_sDataSourceName); +} + +bool OReportDefinition::isEnableSetModified() const +{ + return true; +} + +OUString OReportDefinition::getDocumentBaseURL() const +{ + // TODO: should this be in getURL()? not sure... + uno::Reference<frame::XModel> const xParent( + const_cast<OReportDefinition*>(this)->getParent(), uno::UNO_QUERY); + if (xParent.is()) + { + return xParent->getURL(); + } + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + for (beans::PropertyValue const& it : std::as_const(m_pImpl->m_aArgs)) + { + if (it.Name == "DocumentBaseURL") + return it.Value.get<OUString>(); + } + + return OUString(); +} + +uno::Reference< frame::XTitle > OReportDefinition::impl_getTitleHelper_throw() +{ + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + if ( ! m_pImpl->m_xTitleHelper.is ()) + { + uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(m_aProps->m_xContext); + + m_pImpl->m_xTitleHelper = new ::framework::TitleHelper( m_aProps->m_xContext, uno::Reference< frame::XModel >(this), + uno::Reference<frame::XUntitledNumbers>(xDesktop, uno::UNO_QUERY_THROW) ); + } + + return m_pImpl->m_xTitleHelper; +} + +uno::Reference< frame::XUntitledNumbers > OReportDefinition::impl_getUntitledHelper_throw() +{ + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + if ( ! m_pImpl->m_xNumberedControllers.is ()) + { + rtl::Reference<::comphelper::NumberedCollection> pHelper = new ::comphelper::NumberedCollection(); + m_pImpl->m_xNumberedControllers = pHelper; + + pHelper->setOwner (uno::Reference< frame::XModel >(this)); + pHelper->setUntitledPrefix (" : "); + } + + return m_pImpl->m_xNumberedControllers; +} + +// css.frame.XTitle +OUString SAL_CALL OReportDefinition::getTitle() +{ + // SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + return impl_getTitleHelper_throw()->getTitle (); +} + +// css.frame.XTitle +void SAL_CALL OReportDefinition::setTitle( const OUString& sTitle ) +{ + // SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + impl_getTitleHelper_throw()->setTitle (sTitle); +} + +// css.frame.XTitleChangeBroadcaster +void SAL_CALL OReportDefinition::addTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener ) +{ + // SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), uno::UNO_QUERY); + if (xBroadcaster.is ()) + xBroadcaster->addTitleChangeListener (xListener); +} + +// css.frame.XTitleChangeBroadcaster +void SAL_CALL OReportDefinition::removeTitleChangeListener( const uno::Reference< frame::XTitleChangeListener >& xListener ) +{ + // SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), uno::UNO_QUERY); + if (xBroadcaster.is ()) + xBroadcaster->removeTitleChangeListener (xListener); +} + +// css.frame.XUntitledNumbers +::sal_Int32 SAL_CALL OReportDefinition::leaseNumber( const uno::Reference< uno::XInterface >& xComponent ) +{ + // object already disposed? + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + return impl_getUntitledHelper_throw()->leaseNumber (xComponent); +} + +// css.frame.XUntitledNumbers +void SAL_CALL OReportDefinition::releaseNumber( ::sal_Int32 nNumber ) +{ + // object already disposed? + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + impl_getUntitledHelper_throw()->releaseNumber (nNumber); +} + +// css.frame.XUntitledNumbers +void SAL_CALL OReportDefinition::releaseNumberForComponent( const uno::Reference< uno::XInterface >& xComponent ) +{ + // object already disposed? + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + impl_getUntitledHelper_throw()->releaseNumberForComponent (xComponent); +} + +// css.frame.XUntitledNumbers +OUString SAL_CALL OReportDefinition::getUntitledPrefix() +{ + // object already disposed? + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + + return impl_getUntitledHelper_throw()->getUntitledPrefix (); +} + +uno::Reference< document::XDocumentProperties > SAL_CALL OReportDefinition::getDocumentProperties( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportDefinitionBase::rBHelper.bDisposed); + if ( !m_pImpl->m_xDocumentProperties.is() ) + { + m_pImpl->m_xDocumentProperties.set(document::DocumentProperties::create(m_aProps->m_xContext)); + } + return m_pImpl->m_xDocumentProperties; +} + +uno::Any SAL_CALL OReportDefinition::getTransferData( const datatransfer::DataFlavor& aFlavor ) +{ + uno::Any aResult; + if( !isDataFlavorSupported( aFlavor ) ) + { + throw datatransfer::UnsupportedFlavorException(aFlavor.MimeType, static_cast< ::cppu::OWeakObject* >( this )); + } + + try + { + aResult = getPreferredVisualRepresentation(0).Data; + } + catch (const uno::Exception &) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + + return aResult; +} + +uno::Sequence< datatransfer::DataFlavor > SAL_CALL OReportDefinition::getTransferDataFlavors( ) +{ + return { { "image/png", "PNG", cppu::UnoType<uno::Sequence< sal_Int8 >>::get() } }; +} + +sal_Bool SAL_CALL OReportDefinition::isDataFlavorSupported( const datatransfer::DataFlavor& aFlavor ) +{ + return aFlavor.MimeType == "image/png"; +} + + +uno::Reference< document::XUndoManager > SAL_CALL OReportDefinition::getUndoManager( ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + return m_pImpl->m_pUndoManager; +} + +}// namespace reportdesign + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ReportEngineJFree.cxx b/reportdesign/source/core/api/ReportEngineJFree.cxx new file mode 100644 index 000000000..30a51d7b9 --- /dev/null +++ b/reportdesign/source/core/api/ReportEngineJFree.cxx @@ -0,0 +1,370 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <com/sun/star/beans/PropertyValue.hpp> +#include <ReportEngineJFree.hxx> +#include <comphelper/storagehelper.hxx> +#include <connectivity/dbtools.hxx> +#include <comphelper/mimeconfighelper.hxx> +#include <comphelper/string.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/embed/XTransactedObject.hpp> + +#include <com/sun/star/task/XJob.hpp> + +#include <unotools/useroptions.hxx> +#include <unotools/tempfile.hxx> +#include <unotools/sharedunocomponent.hxx> + +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> + +#include <connectivity/CommonTools.hxx> +#include <sfx2/docfilt.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + using namespace comphelper; + + +OReportEngineJFree::OReportEngineJFree( const uno::Reference< uno::XComponentContext >& context) +:ReportEngineBase(m_aMutex) +,ReportEnginePropertySet(context,IMPLEMENTS_PROPERTY_SET,uno::Sequence< OUString >()) +,m_xContext(context) +,m_nMaxRows(0) +{ +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +OReportEngineJFree::~OReportEngineJFree() +{ +} + +IMPLEMENT_FORWARD_XINTERFACE2(OReportEngineJFree,ReportEngineBase,ReportEnginePropertySet) + +void SAL_CALL OReportEngineJFree::dispose() +{ + ReportEnginePropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); + m_xActiveConnection.clear(); +} + +OUString OReportEngineJFree::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.OReportEngineJFree"; +} + + +OUString SAL_CALL OReportEngineJFree::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OReportEngineJFree::getSupportedServiceNames_Static( ) +{ + uno::Sequence< OUString > aServices { "com.sun.star.report.ReportEngine" }; + + return aServices; +} + +uno::Reference< uno::XInterface > OReportEngineJFree::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OReportEngineJFree(xContext)); +} + + +uno::Sequence< OUString > SAL_CALL OReportEngineJFree::getSupportedServiceNames( ) +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OReportEngineJFree::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportEngine + // Attributes +uno::Reference< report::XReportDefinition > SAL_CALL OReportEngineJFree::getReportDefinition() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xReport; +} + +void SAL_CALL OReportEngineJFree::setReportDefinition( const uno::Reference< report::XReportDefinition >& _report ) +{ + if ( !_report.is() ) + throw lang::IllegalArgumentException(); + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_xReport != _report ) + { + prepareSet(PROPERTY_REPORTDEFINITION, uno::Any(m_xReport), uno::Any(_report), &l); + m_xReport = _report; + } + } + l.notify(); +} + +uno::Reference< task::XStatusIndicator > SAL_CALL OReportEngineJFree::getStatusIndicator() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_StatusIndicator; +} + +void SAL_CALL OReportEngineJFree::setStatusIndicator( const uno::Reference< task::XStatusIndicator >& _statusindicator ) +{ + set(PROPERTY_STATUSINDICATOR,_statusindicator,m_StatusIndicator); +} + +OUString OReportEngineJFree::getNewOutputName() +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed); + if ( !m_xReport.is() || !m_xActiveConnection.is() ) + throw lang::IllegalArgumentException(); + + static constexpr OUStringLiteral s_sMediaType = u"MediaType"; + + MimeConfigurationHelper aConfighelper(m_xContext); + const OUString sMimeType = m_xReport->getMimeType(); + std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilter( aConfighelper.GetDocServiceNameFromMediaType(sMimeType) ); + OUString sExt(".rpt"); + if ( pFilter ) + sExt = ::comphelper::string::stripStart(pFilter->GetDefaultExtension(), '*'); + + uno::Reference< embed::XStorage > xTemp = OStorageHelper::GetTemporaryStorage(/*sFileTemp,embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,*/ m_xContext); + utl::DisposableComponent aTemp(xTemp); + uno::Sequence< beans::PropertyValue > aEmpty; + uno::Reference< beans::XPropertySet> xStorageProp(xTemp,uno::UNO_QUERY); + if ( xStorageProp.is() ) + { + xStorageProp->setPropertyValue( s_sMediaType, uno::Any(sMimeType)); + } + m_xReport->storeToStorage(xTemp,aEmpty); // store to temp file because it may contain information which isn't in the database yet. + + OUString sFileURL; + OUString sName = m_xReport->getCaption(); + if ( sName.isEmpty() ) + sName = m_xReport->getName(); + { + ::utl::TempFile aTestFile(sName, false, &sExt); + if ( !aTestFile.IsValid() ) + { + sName = RptResId(RID_STR_REPORT); + ::utl::TempFile aFile(sName, false, &sExt); + sFileURL = aFile.GetURL(); + } + else + sFileURL = aTestFile.GetURL(); + } + + uno::Reference< embed::XStorage > xOut = OStorageHelper::GetStorageFromURL(sFileURL,embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE, m_xContext); + utl::DisposableComponent aOut(xOut); + xStorageProp.set(xOut,uno::UNO_QUERY); + if ( xStorageProp.is() ) + { + xStorageProp->setPropertyValue( s_sMediaType, uno::Any(sMimeType)); + } + + // some meta data + SvtUserOptions aUserOpts; + OUString sAuthor = aUserOpts.GetFirstName() + + " " + + aUserOpts.GetLastName(); + + uno::Sequence< beans::NamedValue > aConvertedProperties{ + {"InputStorage", uno::Any(xTemp) }, + {"OutputStorage", uno::Any(xOut) }, + {PROPERTY_REPORTDEFINITION, uno::Any(m_xReport) }, + {PROPERTY_ACTIVECONNECTION, uno::Any(m_xActiveConnection) }, + {PROPERTY_MAXROWS, uno::Any(m_nMaxRows) }, + {"Author", uno::Any(sAuthor) }, + {"Title", uno::Any(m_xReport->getCaption()) } + }; + + OUString sOutputName; + + // create job factory and initialize + const OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_xContext); + uno::Reference<task::XJob> xJob(m_xContext->getServiceManager()->createInstanceWithContext(sReportEngineServiceName,m_xContext),uno::UNO_QUERY_THROW); + if ( !m_xReport->getCommand().isEmpty() ) + { + xJob->execute(aConvertedProperties); + if ( xStorageProp.is() ) + { + sOutputName = sFileURL; + } + } + + uno::Reference<embed::XTransactedObject> xTransact(xOut,uno::UNO_QUERY); + if ( !sOutputName.isEmpty() && xTransact.is() ) + xTransact->commit(); + + if ( sOutputName.isEmpty() ) + throw lang::IllegalArgumentException(); + + return sOutputName; +} + +// Methods +uno::Reference< frame::XModel > SAL_CALL OReportEngineJFree::createDocumentModel( ) +{ + return createDocumentAlive(nullptr,true); +} + +uno::Reference< frame::XModel > SAL_CALL OReportEngineJFree::createDocumentAlive( const uno::Reference< frame::XFrame >& _frame ) +{ + return createDocumentAlive(_frame,false); +} + +uno::Reference< frame::XModel > OReportEngineJFree::createDocumentAlive( const uno::Reference< frame::XFrame >& _frame,bool _bHidden ) +{ + uno::Reference< frame::XModel > xModel; + OUString sOutputName = getNewOutputName(); // starts implicitly the report generator + if ( !sOutputName.isEmpty() ) + { + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed); + uno::Reference<frame::XComponentLoader> xFrameLoad(_frame,uno::UNO_QUERY); + if ( !xFrameLoad.is() ) + { + // if there is no frame given, find the right + xFrameLoad = frame::Desktop::create(m_xContext); + sal_Int32 const nFrameSearchFlag = frame::FrameSearchFlag::TASKS | frame::FrameSearchFlag::CREATE; + uno::Reference< frame::XFrame> xFrame = uno::Reference< frame::XFrame>(xFrameLoad,uno::UNO_QUERY_THROW)->findFrame("_blank",nFrameSearchFlag); + xFrameLoad.set( xFrame,uno::UNO_QUERY); + } + + if ( xFrameLoad.is() ) + { + uno::Sequence < beans::PropertyValue > aArgs( _bHidden ? 3 : 2 ); + auto pArgs = aArgs.getArray(); + sal_Int32 nLen = 0; + pArgs[nLen].Name = "AsTemplate"; + pArgs[nLen++].Value <<= false; + + pArgs[nLen].Name = "ReadOnly"; + pArgs[nLen++].Value <<= true; + + if ( _bHidden ) + { + pArgs[nLen].Name = "Hidden"; + pArgs[nLen++].Value <<= true; + } + + xModel.set( xFrameLoad->loadComponentFromURL( + sOutputName, + OUString(), // empty frame name + 0, + aArgs + ),uno::UNO_QUERY); + } + } + return xModel; +} + +util::URL SAL_CALL OReportEngineJFree::createDocument( ) +{ + util::URL aRet; + uno::Reference< frame::XModel > xModel = createDocumentModel(); + if ( xModel.is() ) + { + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed); + } + return aRet; +} + +void SAL_CALL OReportEngineJFree::interrupt( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + ::connectivity::checkDisposed(ReportEngineBase::rBHelper.bDisposed); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OReportEngineJFree::getPropertySetInfo( ) +{ + return ReportEnginePropertySet::getPropertySetInfo(); +} + +void SAL_CALL OReportEngineJFree::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + ReportEnginePropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OReportEngineJFree::getPropertyValue( const OUString& PropertyName ) +{ + return ReportEnginePropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OReportEngineJFree::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + ReportEnginePropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OReportEngineJFree::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + ReportEnginePropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OReportEngineJFree::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ReportEnginePropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OReportEngineJFree::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + ReportEnginePropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +uno::Reference< sdbc::XConnection > SAL_CALL OReportEngineJFree::getActiveConnection() +{ + return m_xActiveConnection; +} + +void SAL_CALL OReportEngineJFree::setActiveConnection( const uno::Reference< sdbc::XConnection >& _activeconnection ) +{ + if ( !_activeconnection.is() ) + throw lang::IllegalArgumentException(); + set(PROPERTY_ACTIVECONNECTION,_activeconnection,m_xActiveConnection); +} + +::sal_Int32 SAL_CALL OReportEngineJFree::getMaxRows() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_nMaxRows; +} + +void SAL_CALL OReportEngineJFree::setMaxRows( ::sal_Int32 MaxRows ) +{ + set(PROPERTY_MAXROWS,MaxRows,m_nMaxRows); +} + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/ReportVisitor.cxx b/reportdesign/source/core/api/ReportVisitor.cxx new file mode 100644 index 000000000..3e62fd69e --- /dev/null +++ b/reportdesign/source/core/api/ReportVisitor.cxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ReportVisitor.hxx> + +#include <osl/diagnose.h> + +namespace reportdesign +{ +using namespace com::sun::star; + +OReportVisitor::OReportVisitor(ITraverseReport* _pTraverseReport) + : m_pTraverseReport(_pTraverseReport) +{ + OSL_ENSURE(m_pTraverseReport, "ReportDefinition must be not NULL!"); +} + +void OReportVisitor::start(const uno::Reference<report::XReportDefinition>& _xReportDefinition) +{ + OSL_ENSURE(_xReportDefinition.is(), "ReportDefinition is NULL!"); + if (!_xReportDefinition.is()) + return; + + m_pTraverseReport->traverseReport(_xReportDefinition); + m_pTraverseReport->traverseReportFunctions(_xReportDefinition->getFunctions()); + if (_xReportDefinition->getPageHeaderOn()) + m_pTraverseReport->traversePageHeader(_xReportDefinition->getPageHeader()); + if (_xReportDefinition->getReportHeaderOn()) + m_pTraverseReport->traverseReportHeader(_xReportDefinition->getReportHeader()); + + uno::Reference<report::XGroups> xGroups = _xReportDefinition->getGroups(); + m_pTraverseReport->traverseGroups(xGroups); + const sal_Int32 nCount = xGroups->getCount(); + sal_Int32 i = 0; + for (; i < nCount; ++i) + { + uno::Reference<report::XGroup> xGroup(xGroups->getByIndex(i), uno::UNO_QUERY); + m_pTraverseReport->traverseGroup(xGroup); + m_pTraverseReport->traverseGroupFunctions(xGroup->getFunctions()); + if (xGroup->getHeaderOn()) + m_pTraverseReport->traverseGroupHeader(xGroup->getHeader()); + } + + m_pTraverseReport->traverseDetail(_xReportDefinition->getDetail()); + + for (i = 0; i < nCount; ++i) + { + uno::Reference<report::XGroup> xGroup(xGroups->getByIndex(i), uno::UNO_QUERY); + if (xGroup->getFooterOn()) + m_pTraverseReport->traverseGroupFooter(xGroup->getFooter()); + } + + if (_xReportDefinition->getPageFooterOn()) + m_pTraverseReport->traversePageFooter(_xReportDefinition->getPageFooter()); + if (_xReportDefinition->getReportFooterOn()) + m_pTraverseReport->traverseReportFooter(_xReportDefinition->getReportFooter()); +} + +void OReportVisitor::start(const uno::Reference<report::XGroup>& _xGroup) +{ + OSL_ENSURE(_xGroup.is(), "Group is NULL!"); + if (!_xGroup.is()) + return; + m_pTraverseReport->traverseGroup(_xGroup); + m_pTraverseReport->traverseGroupFunctions(_xGroup->getFunctions()); + if (_xGroup->getHeaderOn()) + m_pTraverseReport->traverseGroupHeader(_xGroup->getHeader()); + if (_xGroup->getFooterOn()) + m_pTraverseReport->traverseGroupFooter(_xGroup->getFooter()); +} + +} // namespace reportdesign + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Section.cxx b/reportdesign/source/core/api/Section.cxx new file mode 100644 index 000000000..e7a8e7561 --- /dev/null +++ b/reportdesign/source/core/api/Section.cxx @@ -0,0 +1,601 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Section.hxx> +#include <comphelper/enumhelper.hxx> +#include <comphelper/servicehelper.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/report/XReportComponent.hpp> +#include <com/sun/star/report/ForceNewPage.hpp> +#include <com/sun/star/lang/NoSupportException.hpp> +#include <strings.hxx> +#include <Tools.hxx> +#include <RptModel.hxx> +#include <RptPage.hxx> +#include <ReportControlModel.hxx> +#include <ReportDefinition.hxx> +#include <vcl/svapp.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + using namespace comphelper; + + +static uno::Sequence< OUString> lcl_getGroupAbsent() +{ + const OUString pProps[] = { + OUString(PROPERTY_CANGROW) + ,OUString(PROPERTY_CANSHRINK) + }; + + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + + +static uno::Sequence< OUString> lcl_getAbsent(bool _bPageSection) +{ + if ( _bPageSection ) + { + const OUString pProps[] = { + OUString(PROPERTY_FORCENEWPAGE) + ,OUString(PROPERTY_NEWROWORCOL) + ,OUString(PROPERTY_KEEPTOGETHER) + ,OUString(PROPERTY_CANGROW) + ,OUString(PROPERTY_CANSHRINK) + ,OUString(PROPERTY_REPEATSECTION) + }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); + } + + const OUString pProps[] = { + OUString(PROPERTY_CANGROW) + ,OUString(PROPERTY_CANSHRINK) + ,OUString(PROPERTY_REPEATSECTION) + }; + + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + +uno::Reference<report::XSection> OSection::createOSection( + const uno::Reference< report::XReportDefinition >& xParentDef, + const uno::Reference< uno::XComponentContext >& context, + bool const bPageSection) +{ + rtl::Reference<OSection> pNew = + new OSection(xParentDef, nullptr, context, lcl_getAbsent(bPageSection)); + pNew->init(); + return pNew; +} + +uno::Reference<report::XSection> OSection::createOSection( + const uno::Reference< report::XGroup >& xParentGroup, + const uno::Reference< uno::XComponentContext >& context) +{ + rtl::Reference<OSection> pNew = + new OSection(nullptr, xParentGroup, context, lcl_getGroupAbsent()); + pNew->init(); + return pNew; +} + + +OSection::OSection(const uno::Reference< report::XReportDefinition >& xParentDef + ,const uno::Reference< report::XGroup >& xParentGroup + ,const uno::Reference< uno::XComponentContext >& context + ,uno::Sequence< OUString> const& rStrings) +:SectionBase(m_aMutex) +,SectionPropertySet(context,SectionPropertySet::IMPLEMENTS_PROPERTY_SET,rStrings) +,m_aContainerListeners(m_aMutex) +,m_xGroup(xParentGroup) +,m_xReportDefinition(xParentDef) +,m_nHeight(3000) +,m_nBackgroundColor(COL_TRANSPARENT) +,m_nForceNewPage(report::ForceNewPage::NONE) +,m_nNewRowOrCol(report::ForceNewPage::NONE) +,m_bKeepTogether(false) +,m_bRepeatSection(false) +,m_bVisible(true) +,m_bBacktransparent(true) +,m_bInRemoveNotify(false) +,m_bInInsertNotify(false) +{ +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +OSection::~OSection() +{ +} + +//IMPLEMENT_FORWARD_XINTERFACE2(OSection,SectionBase,SectionPropertySet) +IMPLEMENT_FORWARD_REFCOUNT( OSection, SectionBase ) + +uno::Any SAL_CALL OSection::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = SectionBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = SectionPropertySet::queryInterface(_rType); + + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn; +} + + +void SAL_CALL OSection::dispose() +{ + OSL_ENSURE(!rBHelper.bDisposed,"Already disposed!"); + SectionPropertySet::dispose(); + uno::Reference<lang::XComponent> const xPageComponent(m_xDrawPage, + uno::UNO_QUERY); + if (xPageComponent.is()) + { + xPageComponent->dispose(); + } + cppu::WeakComponentImplHelperBase::dispose(); + +} + +// TODO: VirtualFunctionFinder: This is virtual function! + +void SAL_CALL OSection::disposing() +{ + lang::EventObject aDisposeEvent( static_cast< ::cppu::OWeakObject* >( this ) ); + m_aContainerListeners.disposeAndClear( aDisposeEvent ); +} + +OUString SAL_CALL OSection::getImplementationName( ) +{ + return "com.sun.star.comp.report.Section"; +} + +uno::Sequence< OUString> OSection::getSupportedServiceNames_Static() +{ + uno::Sequence<OUString> aSupported { SERVICE_SECTION }; + return aSupported; +} + +uno::Sequence< OUString> SAL_CALL OSection::getSupportedServiceNames() +{ + return getSupportedServiceNames_Static(); +} + +sal_Bool SAL_CALL OSection::supportsService( const OUString& _rServiceName ) +{ + return cppu::supportsService(this, _rServiceName); +} + +void OSection::init() +{ + SolarMutexGuard g; // lock while manipulating SdrModel + uno::Reference< report::XReportDefinition> xReport = getReportDefinition(); + std::shared_ptr<rptui::OReportModel> pModel = OReportDefinition::getSdrModel(xReport); + assert(pModel && "No model set at the report definition!"); + if ( !pModel ) + return; + + uno::Reference<report::XSection> const xSection(this); + SdrPage & rSdrPage(*pModel->createNewPage(xSection)); + m_xDrawPage.set(rSdrPage.getUnoPage(), uno::UNO_QUERY_THROW); + m_xDrawPage_ShapeGrouper.set(m_xDrawPage, uno::UNO_QUERY_THROW); + // apparently we may also get OReportDrawPage which doesn't support this + m_xDrawPage_FormSupplier.set(m_xDrawPage, uno::UNO_QUERY); + m_xDrawPage_Tunnel.set(m_xDrawPage, uno::UNO_QUERY_THROW); + // fdo#53872: now also exchange the XDrawPage in the SdrPage so that + // rSdrPage.getUnoPage returns this + rSdrPage.SetUnoPage(this); + // createNewPage _should_ have stored away 2 uno::References to this, + // so our ref count cannot be 1 here, so this isn't destroyed here + assert(m_refCount > 1); +} + +// XSection + +sal_Bool SAL_CALL OSection::getVisible() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bVisible; +} + +void SAL_CALL OSection::setVisible( sal_Bool _visible ) +{ + set(PROPERTY_VISIBLE,_visible,m_bVisible); +} + +OUString SAL_CALL OSection::getName() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_sName; +} + +void SAL_CALL OSection::setName( const OUString& _name ) +{ + set(PROPERTY_NAME,_name,m_sName); +} + +::sal_uInt32 SAL_CALL OSection::getHeight() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_nHeight; +} + +void SAL_CALL OSection::setHeight( ::sal_uInt32 _height ) +{ + set(PROPERTY_HEIGHT,_height,m_nHeight); +} + +::sal_Int32 SAL_CALL OSection::getBackColor() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bBacktransparent ? static_cast<sal_Int32>(COL_TRANSPARENT) : m_nBackgroundColor; +} + +void SAL_CALL OSection::setBackColor( ::sal_Int32 _backgroundcolor ) +{ + bool bTransparent = _backgroundcolor == static_cast<sal_Int32>(COL_TRANSPARENT); + setBackTransparent(bTransparent); + if ( !bTransparent ) + set(PROPERTY_BACKCOLOR,_backgroundcolor,m_nBackgroundColor); +} + +sal_Bool SAL_CALL OSection::getBackTransparent() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bBacktransparent; +} + +void SAL_CALL OSection::setBackTransparent( sal_Bool _backtransparent ) +{ + set(PROPERTY_BACKTRANSPARENT,_backtransparent,m_bBacktransparent); + if ( _backtransparent ) + set(PROPERTY_BACKCOLOR,static_cast<sal_Int32>(COL_TRANSPARENT),m_nBackgroundColor); +} + +OUString SAL_CALL OSection::getConditionalPrintExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_sConditionalPrintExpression; +} + +void SAL_CALL OSection::setConditionalPrintExpression( const OUString& _conditionalprintexpression ) +{ + set(PROPERTY_CONDITIONALPRINTEXPRESSION,_conditionalprintexpression,m_sConditionalPrintExpression); +} + +void OSection::checkNotPageHeaderFooter() +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< report::XReportDefinition > xRet = m_xReportDefinition; + if ( xRet.is() ) + { + if ( xRet->getPageHeaderOn() && xRet->getPageHeader() == *this ) + throw beans::UnknownPropertyException(); + if ( xRet->getPageFooterOn() && xRet->getPageFooter() == *this ) + throw beans::UnknownPropertyException(); + } +} + +::sal_Int16 SAL_CALL OSection::getForceNewPage() +{ + ::osl::MutexGuard aGuard(m_aMutex); + + checkNotPageHeaderFooter(); + return m_nForceNewPage; +} + +void SAL_CALL OSection::setForceNewPage( ::sal_Int16 _forcenewpage ) +{ + if ( _forcenewpage < report::ForceNewPage::NONE || _forcenewpage > report::ForceNewPage::BEFORE_AFTER_SECTION ) + throwIllegallArgumentException(u"css::report::ForceNewPage" + ,*this + ,1); + checkNotPageHeaderFooter(); + set(PROPERTY_FORCENEWPAGE,_forcenewpage,m_nForceNewPage); +} + +::sal_Int16 SAL_CALL OSection::getNewRowOrCol() +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkNotPageHeaderFooter(); + return m_nNewRowOrCol; +} + +void SAL_CALL OSection::setNewRowOrCol( ::sal_Int16 _newroworcol ) +{ + if ( _newroworcol < report::ForceNewPage::NONE || _newroworcol > report::ForceNewPage::BEFORE_AFTER_SECTION ) + throwIllegallArgumentException(u"css::report::ForceNewPage" + ,*this + ,1); + checkNotPageHeaderFooter(); + + set(PROPERTY_NEWROWORCOL,_newroworcol,m_nNewRowOrCol); +} + +sal_Bool SAL_CALL OSection::getKeepTogether() +{ + ::osl::MutexGuard aGuard(m_aMutex); + checkNotPageHeaderFooter(); + return m_bKeepTogether; +} + +void SAL_CALL OSection::setKeepTogether( sal_Bool _keeptogether ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + checkNotPageHeaderFooter(); + } + + set(PROPERTY_KEEPTOGETHER,_keeptogether,m_bKeepTogether); +} + +sal_Bool SAL_CALL OSection::getCanGrow() +{ + throw beans::UnknownPropertyException(); ///TODO: unsupported at the moment +} + +void SAL_CALL OSection::setCanGrow( sal_Bool /*_cangrow*/ ) +{ + throw beans::UnknownPropertyException(); ///TODO: unsupported at the moment +} + +sal_Bool SAL_CALL OSection::getCanShrink() +{ + throw beans::UnknownPropertyException(); ///TODO: unsupported at the moment +} + +void SAL_CALL OSection::setCanShrink( sal_Bool /*_canshrink*/ ) +{ + throw beans::UnknownPropertyException(); ///TODO: unsupported at the moment +} + +sal_Bool SAL_CALL OSection::getRepeatSection() +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< report::XGroup > xGroup = m_xGroup; + if ( !xGroup.is() ) + throw beans::UnknownPropertyException(); + return m_bRepeatSection; +} + +void SAL_CALL OSection::setRepeatSection( sal_Bool _repeatsection ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< report::XGroup > xGroup = m_xGroup; + if ( !xGroup.is() ) + throw beans::UnknownPropertyException(); + } + set(PROPERTY_REPEATSECTION,_repeatsection,m_bRepeatSection); +} + +uno::Reference< report::XGroup > SAL_CALL OSection::getGroup() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xGroup; +} + +uno::Reference< report::XReportDefinition > SAL_CALL OSection::getReportDefinition() +{ + ::osl::MutexGuard aGuard(m_aMutex); + uno::Reference< report::XReportDefinition > xRet = m_xReportDefinition; + uno::Reference< report::XGroup > xGroup = m_xGroup; + if ( !xRet.is() && xGroup.is() ) + { + uno::Reference< report::XGroups> xGroups(xGroup->getGroups()); + if ( xGroups.is() ) + xRet = xGroups->getReportDefinition(); + } + + return xRet; +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OSection::getParent( ) +{ + uno::Reference< uno::XInterface > xRet; + { + ::osl::MutexGuard aGuard(m_aMutex); + xRet = m_xReportDefinition; + if ( !xRet.is() ) + xRet = m_xGroup; + } + return xRet; +} + +void SAL_CALL OSection::setParent( const uno::Reference< uno::XInterface >& /*Parent*/ ) +{ + throw lang::NoSupportException(); +} + +// XContainer +void SAL_CALL OSection::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.addInterface(xListener); +} + +void SAL_CALL OSection::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aContainerListeners.removeInterface(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OSection::getElementType( ) +{ + return cppu::UnoType<report::XReportComponent>::get(); +} + +sal_Bool SAL_CALL OSection::hasElements( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xDrawPage.is() && m_xDrawPage->hasElements(); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OSection::getCount( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xDrawPage.is() ? m_xDrawPage->getCount() : 0; +} + +uno::Any SAL_CALL OSection::getByIndex( ::sal_Int32 Index ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_xDrawPage.is() ? m_xDrawPage->getByIndex(Index) : uno::Any(); +} + +// XEnumerationAccess +uno::Reference< container::XEnumeration > SAL_CALL OSection::createEnumeration( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + return new ::comphelper::OEnumerationByIndex(static_cast<XSection*>(this)); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OSection::getPropertySetInfo( ) +{ + return SectionPropertySet::getPropertySetInfo(); +} + +void SAL_CALL OSection::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + SectionPropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OSection::getPropertyValue( const OUString& PropertyName ) +{ + return SectionPropertySet::getPropertyValue( PropertyName); +} + +void SAL_CALL OSection::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + SectionPropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OSection::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + SectionPropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OSection::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + SectionPropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OSection::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + SectionPropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OSection::add( const uno::Reference< drawing::XShape >& xShape ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + m_bInInsertNotify = true; + OSL_ENSURE(m_xDrawPage.is(),"No DrawPage!"); + m_xDrawPage->add(xShape); + m_bInInsertNotify = false; + } + notifyElementAdded(xShape); +} + +void SAL_CALL OSection::remove( const uno::Reference< drawing::XShape >& xShape ) +{ + { + ::osl::MutexGuard aGuard(m_aMutex); + m_bInRemoveNotify = true; + OSL_ENSURE(m_xDrawPage.is(),"No DrawPage!"); + m_xDrawPage->remove(xShape); + m_bInRemoveNotify = false; + } + notifyElementRemoved(xShape); +} + +// XShapeGrouper +uno::Reference< drawing::XShapeGroup > SAL_CALL +OSection::group(uno::Reference< drawing::XShapes > const& xShapes) +{ + // no lock because m_xDrawPage_ShapeGrouper is const + return (m_xDrawPage_ShapeGrouper.is()) + ? m_xDrawPage_ShapeGrouper->group(xShapes) + : nullptr; +} +void SAL_CALL +OSection::ungroup(uno::Reference<drawing::XShapeGroup> const& xGroup) +{ + // no lock because m_xDrawPage_ShapeGrouper is const + if (m_xDrawPage_ShapeGrouper.is()) { + m_xDrawPage_ShapeGrouper->ungroup(xGroup); + } +} + +// XFormsSupplier +uno::Reference<container::XNameContainer> SAL_CALL OSection::getForms() +{ + // no lock because m_xDrawPage_FormSupplier is const + return (m_xDrawPage_FormSupplier.is()) + ? m_xDrawPage_FormSupplier->getForms() + : nullptr; +} +// XFormsSupplier2 +sal_Bool SAL_CALL OSection::hasForms() +{ + // no lock because m_xDrawPage_FormSupplier is const + return (m_xDrawPage_FormSupplier.is()) + && m_xDrawPage_FormSupplier->hasForms(); +} + + +// css::lang::XUnoTunnel + +sal_Int64 OSection::getSomething( const uno::Sequence< sal_Int8 > & rId ) +{ + if (comphelper::isUnoTunnelId<OSection>(rId) ) + return comphelper::getSomething_cast(this); + return (m_xDrawPage_Tunnel.is()) ? m_xDrawPage_Tunnel->getSomething(rId) : 0; +} + +const uno::Sequence< sal_Int8 > & OSection::getUnoTunnelId() +{ + static const comphelper::UnoIdInit implId; + return implId.getSeq(); +} + +void OSection::notifyElementAdded(const uno::Reference< drawing::XShape >& xShape ) +{ + if ( !m_bInInsertNotify ) + { + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(), uno::Any(xShape), uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementInserted,aEvent); + } +} + +void OSection::notifyElementRemoved(const uno::Reference< drawing::XShape >& xShape) +{ + if ( !m_bInRemoveNotify ) + { + // notify our container listeners + container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::Any(), uno::Any(xShape), uno::Any()); + m_aContainerListeners.notifyEach(&container::XContainerListener::elementRemoved,aEvent); + } +} + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Shape.cxx b/reportdesign/source/core/api/Shape.cxx new file mode 100644 index 000000000..413f02e1b --- /dev/null +++ b/reportdesign/source/core/api/Shape.cxx @@ -0,0 +1,494 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Shape.hxx> + +#include <cppuhelper/supportsservice.hxx> +#include <svx/svdobj.hxx> +#include <tools/diagnose_ex.h> + +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <Tools.hxx> +#include <FormatCondition.hxx> +#include <ReportHelperImpl.hxx> + +namespace reportdesign +{ + + using namespace com::sun::star; + using namespace comphelper; +static uno::Sequence< OUString > lcl_getShapeOptionals() +{ + const OUString pProps[] = { + OUString(PROPERTY_DATAFIELD) + ,OUString(PROPERTY_CONTROLBACKGROUND) + ,OUString(PROPERTY_CONTROLBACKGROUNDTRANSPARENT) + }; + return uno::Sequence< OUString >(pProps,SAL_N_ELEMENTS(pProps)); +} + + +OShape::OShape(uno::Reference< uno::XComponentContext > const & _xContext) +:ShapeBase(m_aMutex) +,ShapePropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getShapeOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nZOrder(0) +,m_bOpaque(false) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_SHAPE); +} + +OShape::OShape(uno::Reference< uno::XComponentContext > const & _xContext + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,uno::Reference< drawing::XShape >& _xShape + ,const OUString& _sServiceName) +:ShapeBase(m_aMutex) +,ShapePropertySet(_xContext,IMPLEMENTS_PROPERTY_SET,lcl_getShapeOptionals()) +,m_aProps(m_aMutex,static_cast< container::XContainer*>( this ),_xContext) +,m_nZOrder(0) +,m_bOpaque(false) +,m_sServiceName(_sServiceName) +{ + m_aProps.aComponent.m_sName = RptResId(RID_STR_SHAPE); + m_aProps.aComponent.m_xFactory = _xFactory; + osl_atomic_increment( &m_refCount ); + { + uno::Reference<beans::XPropertySet> xProp(_xShape,uno::UNO_QUERY); + if ( xProp.is() ) + { + xProp->getPropertyValue(PROPERTY_ZORDER) >>= m_nZOrder; + xProp.clear(); + } + m_aProps.aComponent.setShape(_xShape,this,m_refCount); + } + osl_atomic_decrement( &m_refCount ); +} + +OShape::~OShape() +{ +} + +//IMPLEMENT_FORWARD_XINTERFACE2(OShape,ShapeBase,ShapePropertySet) +IMPLEMENT_FORWARD_REFCOUNT( OShape, ShapeBase ) + +uno::Any SAL_CALL OShape::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = ShapeBase::queryInterface(_rType); + if ( !aReturn.hasValue() ) + aReturn = ShapePropertySet::queryInterface(_rType); + + if ( !aReturn.hasValue() && OReportControlModel::isInterfaceForbidden(_rType) ) + return aReturn; + + return aReturn.hasValue() ? aReturn : (m_aProps.aComponent.m_xProxy.is() ? m_aProps.aComponent.m_xProxy->queryAggregation(_rType) : aReturn); +} + + +void SAL_CALL OShape::dispose() +{ + ShapePropertySet::dispose(); + cppu::WeakComponentImplHelperBase::dispose(); +} + +uno::Reference< uno::XInterface > OShape::create(uno::Reference< uno::XComponentContext > const & xContext) +{ + return *(new OShape(xContext)); +} + + +OUString OShape::getImplementationName_Static( ) +{ + return "com.sun.star.comp.report.Shape"; +} + + +OUString SAL_CALL OShape::getImplementationName( ) +{ + return getImplementationName_Static(); +} + +uno::Sequence< OUString > OShape::getSupportedServiceNames_Static( ) +{ + return { SERVICE_SHAPE }; +} + +uno::Sequence< OUString > SAL_CALL OShape::getSupportedServiceNames( ) +{ + if(m_sServiceName.isEmpty()) + { + return getSupportedServiceNames_Static(); + } + else + { + return { SERVICE_SHAPE, m_sServiceName }; + } +} + +sal_Bool SAL_CALL OShape::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XReportComponent +REPORTCOMPONENT_IMPL(OShape,m_aProps.aComponent) +REPORTCOMPONENT_IMPL2(OShape,m_aProps.aComponent) +REPORTCOMPONENT_MASTERDETAIL(OShape,m_aProps.aComponent) +REPORTCONTROLFORMAT_IMPL2(OShape,m_aProps.aFormatProperties) + +::sal_Int32 SAL_CALL OShape::getControlBackground() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OShape::setControlBackground( ::sal_Int32 /*_backgroundcolor*/ ) +{ + throw beans::UnknownPropertyException(); +} + +sal_Bool SAL_CALL OShape::getControlBackgroundTransparent() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OShape::setControlBackgroundTransparent( sal_Bool /*_controlbackgroundtransparent*/ ) +{ + throw beans::UnknownPropertyException(); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL OShape::getPropertySetInfo( ) +{ + + //return ShapePropertySet::getPropertySetInfo(); + return cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() ); +} + +cppu::IPropertyArrayHelper& OShape::getInfoHelper() +{ + if (!m_pAggHelper) + { + uno::Sequence<beans::Property> aAggSeq; + if ( m_aProps.aComponent.m_xProperty.is() ) + aAggSeq = m_aProps.aComponent.m_xProperty->getPropertySetInfo()->getProperties(); + m_pAggHelper.reset(new OPropertyArrayAggregationHelper(ShapePropertySet::getPropertySetInfo()->getProperties(),aAggSeq)); + } + return *m_pAggHelper; +} + + +void SAL_CALL OShape::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate ) + m_aProps.aComponent.m_xProperty->setPropertyValue( aPropertyName,aValue); + // can be in both + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator ) + ShapePropertySet::setPropertyValue( aPropertyName, aValue ); +} + +uno::Any SAL_CALL OShape::getPropertyValue( const OUString& PropertyName ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate ) + return m_aProps.aComponent.m_xProperty->getPropertyValue( PropertyName); + // can be in both + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator ) + return ShapePropertySet::getPropertyValue( PropertyName); + return uno::Any(); +} + +void SAL_CALL OShape::addPropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate || aPropertyName.isEmpty() ) + m_aProps.aComponent.m_xProperty->addPropertyChangeListener( aPropertyName, xListener); + // can be in both + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator || aPropertyName.isEmpty() ) + ShapePropertySet::addPropertyChangeListener( aPropertyName, xListener ); +} + +void SAL_CALL OShape::removePropertyChangeListener( const OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate || aPropertyName.isEmpty() ) + m_aProps.aComponent.m_xProperty->removePropertyChangeListener( aPropertyName, aListener ); + // can be in both + if( m_pAggHelper->classifyProperty(aPropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator || aPropertyName.isEmpty() ) + ShapePropertySet::removePropertyChangeListener( aPropertyName, aListener ); +} + +void SAL_CALL OShape::addVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate || PropertyName.isEmpty() ) + m_aProps.aComponent.m_xProperty->addVetoableChangeListener( PropertyName, aListener ); + // can be in both + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator || PropertyName.isEmpty() ) + ShapePropertySet::addVetoableChangeListener( PropertyName, aListener ); +} + +void SAL_CALL OShape::removeVetoableChangeListener( const OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) +{ + getInfoHelper(); + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate || PropertyName.isEmpty() ) + m_aProps.aComponent.m_xProperty->removeVetoableChangeListener( PropertyName, aListener ); + // can be in both + if( m_pAggHelper->classifyProperty(PropertyName) == OPropertyArrayAggregationHelper::PropertyOrigin::Delegator || PropertyName.isEmpty() ) + ShapePropertySet::removeVetoableChangeListener( PropertyName, aListener ); +} + +// XReportControlModel +OUString SAL_CALL OShape::getDataField() +{ + throw beans::UnknownPropertyException(); +} + +void SAL_CALL OShape::setDataField( const OUString& /*_datafield*/ ) +{ + throw beans::UnknownPropertyException(); +} + +sal_Bool SAL_CALL OShape::getPrintWhenGroupChange() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.bPrintWhenGroupChange; +} + +void SAL_CALL OShape::setPrintWhenGroupChange( sal_Bool _printwhengroupchange ) +{ + set(PROPERTY_PRINTWHENGROUPCHANGE,_printwhengroupchange,m_aProps.bPrintWhenGroupChange); +} + +OUString SAL_CALL OShape::getConditionalPrintExpression() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_aProps.aConditionalPrintExpression; +} + +void SAL_CALL OShape::setConditionalPrintExpression( const OUString& _conditionalprintexpression ) +{ + set(PROPERTY_CONDITIONALPRINTEXPRESSION,_conditionalprintexpression,m_aProps.aConditionalPrintExpression); +} + + +// XCloneable +uno::Reference< util::XCloneable > SAL_CALL OShape::createClone( ) +{ + uno::Reference< report::XReportComponent> xSource = this; + uno::Reference< report::XReportComponent> xSet; + try + { + SdrObject* pObject = SdrObject::getSdrObjectFromXShape( xSource ); + if ( pObject ) + { + SdrObject* pClone(pObject->CloneSdrObject(pObject->getSdrModelFromSdrObject())); + if ( pClone ) + { + xSet.set(pClone->getUnoShape(),uno::UNO_QUERY_THROW ); + } + } + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + return xSet; +} + +// XChild +uno::Reference< uno::XInterface > SAL_CALL OShape::getParent( ) +{ + return OShapeHelper::getParent(this); +} + +void SAL_CALL OShape::setParent( const uno::Reference< uno::XInterface >& Parent ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xParent = uno::Reference< container::XChild >(Parent,uno::UNO_QUERY); +} +uno::Reference< report::XFormatCondition > SAL_CALL OShape::createFormatCondition( ) +{ + return new OFormatCondition(m_aProps.aComponent.m_xContext); +} + +// XContainer +void SAL_CALL OShape::addContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.addContainerListener(xListener); +} + +void SAL_CALL OShape::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener ) +{ + m_aProps.removeContainerListener(xListener); +} + +// XElementAccess +uno::Type SAL_CALL OShape::getElementType( ) +{ + return cppu::UnoType<report::XFormatCondition>::get(); +} + +sal_Bool SAL_CALL OShape::hasElements( ) +{ + return m_aProps.hasElements(); +} + +// XIndexContainer +void SAL_CALL OShape::insertByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.insertByIndex(Index,Element); +} + +void SAL_CALL OShape::removeByIndex( ::sal_Int32 Index ) +{ + m_aProps.removeByIndex(Index); +} + +// XIndexReplace +void SAL_CALL OShape::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element ) +{ + m_aProps.replaceByIndex(Index,Element); +} + +// XIndexAccess +::sal_Int32 SAL_CALL OShape::getCount( ) +{ + return m_aProps.getCount(); +} + +uno::Any SAL_CALL OShape::getByIndex( ::sal_Int32 Index ) +{ + return m_aProps.getByIndex( Index ); +} + +// XShape +awt::Point SAL_CALL OShape::getPosition( ) +{ + return OShapeHelper::getPosition(this); +} + +void SAL_CALL OShape::setPosition( const awt::Point& aPosition ) +{ + OShapeHelper::setPosition(aPosition,this); +} + +awt::Size SAL_CALL OShape::getSize( ) +{ + return OShapeHelper::getSize(this); +} + +void SAL_CALL OShape::setSize( const awt::Size& aSize ) +{ + OShapeHelper::setSize(aSize,this); +} + + +// XShapeDescriptor +OUString SAL_CALL OShape::getShapeType( ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_aProps.aComponent.m_xShape.is() ) + return m_aProps.aComponent.m_xShape->getShapeType(); + return "com.sun.star.drawing.CustomShape"; +} + +::sal_Int32 SAL_CALL OShape::getZOrder() +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->getPropertyValue(PROPERTY_ZORDER) >>= m_nZOrder; + return m_nZOrder; +} + +void SAL_CALL OShape::setZOrder( ::sal_Int32 _zorder ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->setPropertyValue(PROPERTY_ZORDER,uno::Any(_zorder)); + set(PROPERTY_ZORDER,_zorder,m_nZOrder); +} + +sal_Bool SAL_CALL OShape::getOpaque() +{ + ::osl::MutexGuard aGuard(m_aMutex); + return m_bOpaque; +} + +void SAL_CALL OShape::setOpaque( sal_Bool _opaque ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + set(PROPERTY_OPAQUE,_opaque,m_bOpaque); +} + +drawing::HomogenMatrix3 SAL_CALL OShape::getTransformation() +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->getPropertyValue(PROPERTY_TRANSFORMATION) >>= m_Transformation; + return m_Transformation; +} + +void SAL_CALL OShape::setTransformation( const drawing::HomogenMatrix3& _transformation ) +{ + m_aProps.aComponent.m_xProperty->setPropertyValue(PROPERTY_TRANSFORMATION,uno::Any(_transformation)); + set(PROPERTY_TRANSFORMATION,_transformation,m_Transformation); +} + +OUString SAL_CALL OShape::getCustomShapeEngine() +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->getPropertyValue(PROPERTY_CUSTOMSHAPEENGINE) >>= m_CustomShapeEngine; + + return m_CustomShapeEngine; +} + +void SAL_CALL OShape::setCustomShapeEngine( const OUString& _customshapeengine ) +{ + m_aProps.aComponent.m_xProperty->setPropertyValue(PROPERTY_CUSTOMSHAPEENGINE,uno::Any(_customshapeengine)); + set(PROPERTY_CUSTOMSHAPEENGINE,_customshapeengine,m_CustomShapeEngine); +} + +OUString SAL_CALL OShape::getCustomShapeData() +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->getPropertyValue(PROPERTY_CUSTOMSHAPEDATA) >>= m_CustomShapeData; + return m_CustomShapeData; +} + +void SAL_CALL OShape::setCustomShapeData( const OUString& _customshapedata ) +{ + m_aProps.aComponent.m_xProperty->setPropertyValue(PROPERTY_CUSTOMSHAPEDATA,uno::Any(_customshapedata)); + set(PROPERTY_CUSTOMSHAPEDATA,_customshapedata,m_CustomShapeData); +} + +uno::Sequence< beans::PropertyValue > SAL_CALL OShape::getCustomShapeGeometry() +{ + ::osl::MutexGuard aGuard(m_aMutex); + m_aProps.aComponent.m_xProperty->getPropertyValue(PROPERTY_CUSTOMSHAPEGEOMETRY) >>= m_CustomShapeGeometry; + return m_CustomShapeGeometry; +} + +void SAL_CALL OShape::setCustomShapeGeometry( const uno::Sequence< beans::PropertyValue >& _customshapegeometry ) +{ + m_aProps.aComponent.m_xProperty->setPropertyValue(PROPERTY_CUSTOMSHAPEGEOMETRY,uno::Any(_customshapegeometry)); + set(PROPERTY_CUSTOMSHAPEGEOMETRY,_customshapegeometry,m_CustomShapeGeometry); +} + + +}// namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/Tools.cxx b/reportdesign/source/core/api/Tools.cxx new file mode 100644 index 000000000..8f066a68d --- /dev/null +++ b/reportdesign/source/core/api/Tools.cxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <Tools.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <comphelper/property.hxx> + + +namespace reportdesign +{ + +using namespace com::sun::star; + +uno::Reference< report::XSection> lcl_getSection(const uno::Reference< uno::XInterface>& _xReportComponent) +{ + uno::Reference< container::XChild> xChild(_xReportComponent,uno::UNO_QUERY); + uno::Reference< report::XSection> xRet(_xReportComponent,uno::UNO_QUERY); + while( !xRet.is() && xChild.is() ) + { + uno::Reference< uno::XInterface> xTemp = xChild->getParent(); + xChild.set(xTemp,uno::UNO_QUERY); + xRet.set(xTemp,uno::UNO_QUERY); + } + return xRet; +} + +void throwIllegallArgumentException( std::u16string_view _sTypeName + ,const uno::Reference< uno::XInterface >& ExceptionContext_ + ,sal_Int16 ArgumentPosition_ + ) +{ + OUString sErrorMessage(RptResId(RID_STR_ERROR_WRONG_ARGUMENT)); + sErrorMessage = sErrorMessage.replaceAt(sErrorMessage.indexOf('#'),2,_sTypeName); + throw lang::IllegalArgumentException(sErrorMessage,ExceptionContext_,ArgumentPosition_); +} + +uno::Reference< util::XCloneable > cloneObject(const uno::Reference< report::XReportComponent>& _xReportComponent + ,const uno::Reference< lang::XMultiServiceFactory>& _xFactory + ,const OUString& _sServiceName) +{ + OSL_ENSURE(_xReportComponent.is() && _xFactory.is() ,"reportcomponent is null -> GPF"); + uno::Reference< report::XReportComponent> xClone(_xFactory->createInstance(_sServiceName),uno::UNO_QUERY_THROW); + ::comphelper::copyProperties(_xReportComponent, xClone); + return xClone; +} + + +} // namespace reportdesign + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/api/services.cxx b/reportdesign/source/core/api/services.cxx new file mode 100644 index 000000000..de07c51e8 --- /dev/null +++ b/reportdesign/source/core/api/services.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <sal/types.h> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <ReportDefinition.hxx> +#include <FormattedField.hxx> +#include <FixedText.hxx> +#include <ImageControl.hxx> +#include <FormatCondition.hxx> +#include <ReportEngineJFree.hxx> +#include <Function.hxx> +#include <Shape.hxx> +#include <FixedLine.hxx> + +/********************************************************************************************/ + +using namespace ::reportdesign; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +// registry functions +namespace +{ +cppu::ImplementationEntry const entries[] + = { { &OReportDefinition::create, &OReportDefinition::getImplementationName_Static, + &OReportDefinition::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OFormattedField::create, &OFormattedField::getImplementationName_Static, + &OFormattedField::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OFixedText::create, &OFixedText::getImplementationName_Static, + &OFixedText::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OImageControl::create, &OImageControl::getImplementationName_Static, + &OImageControl::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OFormatCondition::create, &OFormatCondition::getImplementationName_Static, + &OFormatCondition::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OReportEngineJFree::create, &OReportEngineJFree::getImplementationName_Static, + &OReportEngineJFree::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { &OFunction::create, &OFunction::getImplementationName_Static, + &OFunction::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, nullptr, + 0 }, + { &OShape::create, &OShape::getImplementationName_Static, + &OShape::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, nullptr, + 0 }, + { &OFixedLine::create, &OFixedLine::getImplementationName_Static, + &OFixedLine::getSupportedServiceNames_Static, &cppu::createSingleComponentFactory, + nullptr, 0 }, + { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } }; +} + +extern "C" { +SAL_DLLPUBLIC_EXPORT void* rpt_component_getFactory(char const* implName, void* serviceManager, + void* registryKey) +{ + return cppu::component_getFactoryHelper(implName, serviceManager, registryKey, entries); +} + +} // extern "C" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/FixedLine.hxx b/reportdesign/source/core/inc/FixedLine.hxx new file mode 100644 index 000000000..7014ef153 --- /dev/null +++ b/reportdesign/source/core/inc/FixedLine.hxx @@ -0,0 +1,169 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDLINE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDLINE_HXX + +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XFixedLine.hpp> +#include "ReportControlModel.hxx" +#include <comphelper/uno3.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> + + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XFixedLine > FixedLinePropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XFixedLine + ,css::lang::XServiceInfo > FixedLineBase; + + /** \class OFixedLine Defines the implementation of a \interface com:::sun::star::report::XFixedLine + * \ingroup reportdesign_api + * + */ + class OFixedLine final : public cppu::BaseMutex, + public FixedLineBase, + public FixedLinePropertySet + { + friend class OShapeHelper; + OReportControlModel m_aProps; + css::drawing::LineStyle m_LineStyle; + css::drawing::LineDash m_LineDash; + sal_Int32 m_nOrientation; + ::sal_Int32 m_LineColor; + ::sal_Int16 m_LineTransparence; + ::sal_Int32 m_LineWidth; + + private: + OFixedLine(const OFixedLine&) = delete; + OFixedLine& operator=(const OFixedLine&) = delete; + + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + virtual ~OFixedLine() override; + public: + explicit OFixedLine(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + explicit OFixedLine(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ,const css::uno::Reference< css::lang::XMultiServiceFactory > & _xFactory + ,css::uno::Reference< css::drawing::XShape >& _xShape + ,sal_Int32 _nOrientation); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XReportComponent + REPORTCOMPONENT_HEADER() + + // XShape + SHAPE_HEADER() + + // XShapeDescriptor + virtual OUString SAL_CALL getShapeType( ) override; + + // XReportControlModel + REPORTCONTROLMODEL_HEADER() + + // XFixedLine + virtual ::sal_Int32 SAL_CALL getOrientation() override; + virtual void SAL_CALL setOrientation( ::sal_Int32 _orientation ) override; + virtual css::drawing::LineStyle SAL_CALL getLineStyle() override; + virtual void SAL_CALL setLineStyle( css::drawing::LineStyle _linestyle ) override; + virtual css::drawing::LineDash SAL_CALL getLineDash() override; + virtual void SAL_CALL setLineDash( const css::drawing::LineDash& _linedash ) override; + virtual ::sal_Int32 SAL_CALL getLineColor() override; + virtual void SAL_CALL setLineColor( ::sal_Int32 _linecolor ) override; + virtual ::sal_Int16 SAL_CALL getLineTransparence() override; + virtual void SAL_CALL setLineTransparence( ::sal_Int16 _linetransparence ) override; + virtual ::sal_Int32 SAL_CALL getLineWidth() override; + virtual void SAL_CALL setLineWidth( ::sal_Int32 _linewidth ) override; + + // css::report::XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + + // XCloneable + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDLINE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/FixedText.hxx b/reportdesign/source/core/inc/FixedText.hxx new file mode 100644 index 000000000..6cc63bfeb --- /dev/null +++ b/reportdesign/source/core/inc/FixedText.hxx @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDTEXT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDTEXT_HXX + +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XFixedText.hpp> +#include "ReportControlModel.hxx" +#include <comphelper/uno3.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> + + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XFixedText > FixedTextPropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XFixedText + ,css::lang::XServiceInfo > FixedTextBase; + + /** \class OFixedText Defines the implementation of a \interface com:::sun::star::report::XFixedText + * \ingroup reportdesign_api + * + */ + class OFixedText final : public cppu::BaseMutex, + public FixedTextBase, + public FixedTextPropertySet + { + friend class OShapeHelper; + OReportControlModel m_aProps; + OUString m_sLabel; + private: + OFixedText(const OFixedText&) = delete; + OFixedText& operator=(const OFixedText&) = delete; + + // internally, we store PROPERTY_PARAADJUST as css::style::ParagraphAdjust, but externally the property is visible as a sal_Int16 + void set( const OUString& _sProperty + ,sal_Int16 Value + ,css::style::ParagraphAdjust& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( static_cast<sal_Int16>(_member) != Value ) + { + prepareSet(_sProperty, css::uno::Any(static_cast<sal_Int16>(_member)), css::uno::Any(Value), &l); + _member = static_cast<css::style::ParagraphAdjust>(Value); + } + } + l.notify(); + } + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + virtual ~OFixedText() override; + public: + explicit OFixedText(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + explicit OFixedText(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ,const css::uno::Reference< css::lang::XMultiServiceFactory > & _xFactory + ,css::uno::Reference< css::drawing::XShape >& _xShape); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XReportComponent + REPORTCOMPONENT_HEADER() + // XShape + SHAPE_HEADER() + + // XShapeDescriptor + virtual OUString SAL_CALL getShapeType( ) override; + + // XReportControlModel + REPORTCONTROLMODEL_HEADER() + + // XCloneable + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + + // XFixedText + virtual OUString SAL_CALL getLabel() override; + virtual void SAL_CALL setLabel( const OUString& _label ) override; + + // css::report::XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FIXEDTEXT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/FormatCondition.hxx b/reportdesign/source/core/inc/FormatCondition.hxx new file mode 100644 index 000000000..07b2db006 --- /dev/null +++ b/reportdesign/source/core/inc/FormatCondition.hxx @@ -0,0 +1,146 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATCONDITION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATCONDITION_HXX + +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XFormatCondition.hpp> +#include "ReportControlModel.hxx" +#include <comphelper/uno3.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XFormatCondition > FormatConditionPropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XFormatCondition + ,css::lang::XServiceInfo > FormatConditionBase; + + /** \class OFormatCondition Defines the implementation of a \interface com:::sun::star::report::XFormatCondition + * \ingroup reportdesign_api + * + */ + class OFormatCondition final : public cppu::BaseMutex, + public FormatConditionBase, + public FormatConditionPropertySet + { + OFormatProperties m_aFormatProperties; + OUString m_sFormula; + bool m_bEnabled; + private: + OFormatCondition(const OFormatCondition&) = delete; + OFormatCondition& operator=(const OFormatCondition&) = delete; + + // internally, we store PROPERTY_PARAADJUST as css::style::ParagraphAdjust, but externally the property is visible as a sal_Int16 + void set( const OUString& _sProperty + ,sal_Int16 Value + ,css::style::ParagraphAdjust& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( static_cast<sal_Int16>(_member) != Value ) + { + prepareSet(_sProperty, css::uno::Any(static_cast<sal_Int16>(_member)), css::uno::Any(Value), &l); + _member = static_cast<css::style::ParagraphAdjust>(Value); + } + } + l.notify(); + } + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + virtual ~OFormatCondition() override; + public: + explicit OFormatCondition(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XFormatCondition + virtual sal_Bool SAL_CALL getEnabled() override; + virtual void SAL_CALL setEnabled( sal_Bool _enabled ) override; + virtual OUString SAL_CALL getFormula() override; + virtual void SAL_CALL setFormula( const OUString& _formula ) override; + + // XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATCONDITION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/FormattedField.hxx b/reportdesign/source/core/inc/FormattedField.hxx new file mode 100644 index 000000000..e777f7b5e --- /dev/null +++ b/reportdesign/source/core/inc/FormattedField.hxx @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATTEDFIELD_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATTEDFIELD_HXX + +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XFormattedField.hpp> +#include "ReportControlModel.hxx" +#include <comphelper/uno3.hxx> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> + + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XFormattedField > FormattedFieldPropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XFormattedField + ,css::lang::XServiceInfo > FormattedFieldBase; + + /** \class OFormattedField Defines the implementation of a \interface com:::sun::star::report::XFormattedField + * \ingroup reportdesign_api + * + */ + class OFormattedField final : public cppu::BaseMutex, + public FormattedFieldBase, + public FormattedFieldPropertySet + { + friend class OShapeHelper; + + OReportControlModel m_aProps; + css::uno::Reference< css::util::XNumberFormatsSupplier > + m_xFormatsSupplier; + ::sal_Int32 m_nFormatKey; + + private: + OFormattedField(const OFormattedField&) = delete; + OFormattedField& operator=(const OFormattedField&) = delete; + + // internally, we store PROPERTY_PARAADJUST as css::style::ParagraphAdjust, but externally the property is visible as a sal_Int16 + void set( const OUString& _sProperty + ,sal_Int16 Value + ,css::style::ParagraphAdjust& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( static_cast<sal_Int16>(_member) != Value ) + { + prepareSet(_sProperty, css::uno::Any(static_cast<sal_Int16>(_member)), css::uno::Any(Value), &l); + _member = static_cast<css::style::ParagraphAdjust>(Value); + } + } + l.notify(); + } + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + virtual ~OFormattedField() override; + public: + explicit OFormattedField(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + explicit OFormattedField(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ,const css::uno::Reference< css::lang::XMultiServiceFactory > & _xFactory + ,css::uno::Reference< css::drawing::XShape >& _xShape); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + + // XReportComponent + REPORTCOMPONENT_HEADER() + + // XShape + SHAPE_HEADER() + + // XShapeDescriptor + virtual OUString SAL_CALL getShapeType( ) override; + + // XReportControlModel + REPORTCONTROLMODEL_HEADER() + + // XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + + // XCloneable + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + + // XFormattedField + virtual ::sal_Int32 SAL_CALL getFormatKey() override; + virtual void SAL_CALL setFormatKey(::sal_Int32 the_value) override; + virtual css::uno::Reference< css::util::XNumberFormatsSupplier > SAL_CALL getFormatsSupplier() override; + virtual void SAL_CALL setFormatsSupplier( const css::uno::Reference< css::util::XNumberFormatsSupplier >& _formatssupplier ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FORMATTEDFIELD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Function.hxx b/reportdesign/source/core/inc/Function.hxx new file mode 100644 index 000000000..891b5427d --- /dev/null +++ b/reportdesign/source/core/inc/Function.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTION_HXX + +#include <comphelper/uno3.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XFunction.hpp> +#include <com/sun/star/report/XFunctions.hpp> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XFunction > FunctionPropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XFunction + ,css::lang::XServiceInfo > FunctionBase; + + /** \class OFunction Defines the implementation of a \interface com:::sun::star::report::XFunction + * \ingroup reportdesign_api + * + */ + class OFunction : public cppu::BaseMutex, + public FunctionBase, + public FunctionPropertySet + { + css::beans::Optional< OUString> m_sInitialFormula; + css::uno::WeakReference< css::report::XFunctions > m_xParent; + OUString m_sName; + OUString m_sFormula; + bool m_bPreEvaluated; + bool m_bDeepTraversing; + private: + OFunction(const OFunction&) = delete; + OFunction& operator=(const OFunction&) = delete; + + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + protected: + virtual ~OFunction() override; + public: + explicit OFunction(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // css::report::XFunction: + virtual sal_Bool SAL_CALL getPreEvaluated() override; + virtual void SAL_CALL setPreEvaluated(sal_Bool the_value) override; + virtual sal_Bool SAL_CALL getDeepTraversing() override; + virtual void SAL_CALL setDeepTraversing(sal_Bool the_value) override; + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName(const OUString & the_value) override; + virtual OUString SAL_CALL getFormula() override; + virtual void SAL_CALL setFormula(const OUString & the_value) override; + virtual css::beans::Optional< OUString> SAL_CALL getInitialFormula() override; + virtual void SAL_CALL setInitialFormula(const css::beans::Optional< OUString> & the_value) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Functions.hxx b/reportdesign/source/core/inc/Functions.hxx new file mode 100644 index 000000000..94a54beeb --- /dev/null +++ b/reportdesign/source/core/inc/Functions.hxx @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTIONS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTIONS_HXX + +#include <com/sun/star/report/XFunctions.hpp> +#include <com/sun/star/report/XFunctionsSupplier.hpp> +#include <cppuhelper/compbase.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <vector> + + +namespace reportdesign +{ + typedef ::cppu::WeakComponentImplHelper< css::report::XFunctions> FunctionsBase; + /** \class OFunctions Defines the implementation of a \interface com:::sun::star::report::XFunctions + * \ingroup reportdesign_api + * + */ + class OFunctions : public cppu::BaseMutex, + public FunctionsBase + { + typedef ::std::vector< css::uno::Reference< css::report::XFunction > > TFunctions; + ::comphelper::OInterfaceContainerHelper3<css::container::XContainerListener> m_aContainerListeners; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::WeakReference< css::report::XFunctionsSupplier > m_xParent; + TFunctions m_aFunctions; + private: + OFunctions& operator=(const OFunctions&) = delete; + OFunctions(const OFunctions&) = delete; + void checkIndex(sal_Int32 _nIndex); + protected: + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual ~OFunctions() override; + + /** this function is called upon disposing the component + */ + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual void SAL_CALL disposing() override; + public: + explicit OFunctions( const css::uno::Reference< css::report::XFunctionsSupplier >& _xParent + ,const css::uno::Reference< css::uno::XComponentContext >& context); + + // XFunctions + // Methods + virtual css::uno::Reference< css::report::XFunction > SAL_CALL createFunction( ) override; + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_FUNCTIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Group.hxx b/reportdesign/source/core/inc/Group.hxx new file mode 100644 index 000000000..a30debf41 --- /dev/null +++ b/reportdesign/source/core/inc/Group.hxx @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_GROUP_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_GROUP_HXX + +#include <com/sun/star/report/XGroup.hpp> +#include <cppuhelper/compbase.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <GroupProperties.hxx> +#include <comphelper/uno3.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace reportdesign +{ + typedef ::cppu::WeakComponentImplHelper< css::report::XGroup + , css::lang::XServiceInfo> GroupBase; + typedef ::cppu::PropertySetMixin< css::report::XGroup> GroupPropertySet; + + /** \class OGroup Defines the implementation of a \interface com:::sun::star::report::XGroup + * \ingroup reportdesign_api + * + */ + class OGroup : public comphelper::OMutexAndBroadcastHelper + ,public GroupBase + ,public GroupPropertySet + { + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::WeakReference< css::report::XGroups > m_xParent; + css::uno::Reference< css::report::XSection> m_xHeader; + css::uno::Reference< css::report::XSection> m_xFooter; + css::uno::Reference< css::report::XFunctions > m_xFunctions; + ::rptshared::GroupProperties m_aProps; + + private: + OGroup& operator=(const OGroup&) = delete; + OGroup(const OGroup&) = delete; + + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void setSection( const OUString& _sProperty + ,bool _bOn + ,const OUString& _sName + ,css::uno::Reference< css::report::XSection>& _member); + protected: + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual ~OGroup() override; + + /** this function is called upon disposing the component + */ + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual void SAL_CALL disposing() override; + public: + OGroup(const css::uno::Reference< css::report::XGroups >& _xParent + ,const css::uno::Reference< css::uno::XComponentContext >& context); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XGroup + virtual sal_Bool SAL_CALL getSortAscending() override; + virtual void SAL_CALL setSortAscending( sal_Bool _sortascending ) override; + virtual sal_Bool SAL_CALL getHeaderOn() override; + virtual void SAL_CALL setHeaderOn( sal_Bool _headeron ) override; + virtual sal_Bool SAL_CALL getFooterOn() override; + virtual void SAL_CALL setFooterOn( sal_Bool _footeron ) override; + virtual css::uno::Reference< css::report::XSection > SAL_CALL getHeader() override; + virtual css::uno::Reference< css::report::XSection > SAL_CALL getFooter() override; + virtual ::sal_Int16 SAL_CALL getGroupOn() override; + virtual void SAL_CALL setGroupOn( ::sal_Int16 _groupon ) override; + virtual ::sal_Int32 SAL_CALL getGroupInterval() override; + virtual void SAL_CALL setGroupInterval( ::sal_Int32 _groupinterval ) override; + virtual ::sal_Int16 SAL_CALL getKeepTogether() override; + virtual void SAL_CALL setKeepTogether( ::sal_Int16 _keeptogether ) override; + virtual css::uno::Reference< css::report::XGroups > SAL_CALL getGroups() override; + virtual OUString SAL_CALL getExpression() override; + virtual void SAL_CALL setExpression( const OUString& _expression ) override; + virtual sal_Bool SAL_CALL getStartNewColumn() override; + virtual void SAL_CALL setStartNewColumn( sal_Bool _startnewcolumn ) override; + virtual sal_Bool SAL_CALL getResetPageNumber() override; + virtual void SAL_CALL setResetPageNumber( sal_Bool _resetpagenumber ) override; + + //XFunctionsSupplier + virtual css::uno::Reference< css::report::XFunctions > SAL_CALL getFunctions() override; + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + }; + +} // namespace reportdesign + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Groups.hxx b/reportdesign/source/core/inc/Groups.hxx new file mode 100644 index 000000000..9897abd3a --- /dev/null +++ b/reportdesign/source/core/inc/Groups.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_GROUPS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_GROUPS_HXX + +#include <com/sun/star/report/XGroups.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <vector> + + +namespace reportdesign +{ + typedef ::cppu::WeakComponentImplHelper< css::report::XGroups> GroupsBase; + /** \class OGroups Defines the implementation of a \interface com:::sun::star::report::XGroups + * \ingroup reportdesign_api + * + */ + class OGroups : public cppu::BaseMutex, + public GroupsBase + { + typedef ::std::vector< css::uno::Reference< css::report::XGroup > > TGroups; + ::comphelper::OInterfaceContainerHelper3<css::container::XContainerListener> m_aContainerListeners; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::WeakReference< css::report::XReportDefinition > m_xParent; + TGroups m_aGroups; + private: + OGroups& operator=(const OGroups&) = delete; + OGroups(const OGroups&) = delete; + void checkIndex(sal_Int32 _nIndex); + protected: + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual ~OGroups() override; + + /** this function is called upon disposing the component + */ + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual void SAL_CALL disposing() override; + public: + OGroups( const css::uno::Reference< css::report::XReportDefinition >& _xParent + ,const css::uno::Reference< css::uno::XComponentContext >& context); + + // XGroups + // Attributes + virtual css::uno::Reference< css::report::XReportDefinition > SAL_CALL getReportDefinition() override; + // Methods + virtual css::uno::Reference< css::report::XGroup > SAL_CALL createGroup( ) override; + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_GROUPS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ImageControl.hxx b/reportdesign/source/core/inc/ImageControl.hxx new file mode 100644 index 000000000..748659913 --- /dev/null +++ b/reportdesign/source/core/inc/ImageControl.hxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_IMAGECONTROL_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_IMAGECONTROL_HXX + +#include <comphelper/uno3.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XImageControl.hpp> +#include "ReportControlModel.hxx" +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XImageControl > ImageControlPropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XImageControl + ,css::lang::XServiceInfo > ImageControlBase; + + /** \class OImageControl Defines the implementation of a \interface com:::sun::star::report::XImageControl + * \ingroup reportdesign_api + * + */ + class OImageControl : public cppu::BaseMutex, + public ImageControlBase, + public ImageControlPropertySet + { + friend class OShapeHelper; + OReportControlModel m_aProps; + OUString m_aImageURL; + sal_Int16 m_nScaleMode; + bool m_bPreserveIRI; + private: + OImageControl(const OImageControl&) = delete; + OImageControl& operator=(const OImageControl&) = delete; + + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + protected: + virtual ~OImageControl() override; + public: + explicit OImageControl(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + explicit OImageControl(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ,const css::uno::Reference< css::lang::XMultiServiceFactory > & _xFactory + ,css::uno::Reference< css::drawing::XShape >& _xShape); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XReportComponent + REPORTCOMPONENT_HEADER() + // XShape + SHAPE_HEADER() + + // XShapeDescriptor + virtual OUString SAL_CALL getShapeType( ) override; + + // XReportControlModel + REPORTCONTROLMODEL_HEADER() + + // XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + + // XCloneable + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + + // XImageControl + virtual OUString SAL_CALL getImageURL() override; + virtual void SAL_CALL setImageURL( const OUString& _imageurl ) override; + virtual sal_Bool SAL_CALL getPreserveIRI() override; + virtual void SAL_CALL setPreserveIRI( sal_Bool _preserveiri ) override; + virtual ::sal_Int16 SAL_CALL getScaleMode() override; + virtual void SAL_CALL setScaleMode( ::sal_Int16 _scalemode ) override; + + // XImageProducerSupplier + virtual css::uno::Reference< css::awt::XImageProducer > SAL_CALL getImageProducer( ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_IMAGECONTROL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportComponent.hxx b/reportdesign/source/core/inc/ReportComponent.hxx new file mode 100644 index 000000000..b6f966040 --- /dev/null +++ b/reportdesign/source/core/inc/ReportComponent.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCOMPONENT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCOMPONENT_HXX + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/uno/XAggregation.hpp> +#include <com/sun/star/report/XReportComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <cppuhelper/weakref.hxx> + +namespace reportdesign +{ + class OReportComponentProperties + { + public: + css::uno::WeakReference<css::container::XChild> m_xParent; + css::uno::Reference<css::uno::XComponentContext> m_xContext; + css::uno::Reference<css::lang::XMultiServiceFactory> m_xFactory; + css::uno::Reference<css::drawing::XShape> m_xShape; + css::uno::Reference<css::uno::XAggregation> m_xProxy; + css::uno::Reference<css::beans::XPropertySet> m_xProperty; + css::uno::Reference<css::lang::XTypeProvider> m_xTypeProvider; + css::uno::Reference<css::lang::XUnoTunnel> m_xUnoTunnel; + css::uno::Reference<css::lang::XServiceInfo> m_xServiceInfo; + css::uno::Sequence<OUString> m_aMasterFields; + css::uno::Sequence<OUString> m_aDetailFields; + OUString m_sName; + ::sal_Int32 m_nHeight; + ::sal_Int32 m_nWidth; + ::sal_Int32 m_nPosX; + ::sal_Int32 m_nPosY; + ::sal_Int32 m_nBorderColor; + ::sal_Int16 m_nBorder; + bool m_bPrintRepeatedValues; + bool m_bAutoGrow; + + OReportComponentProperties( + css::uno::Reference<css::uno::XComponentContext> const& xContext) + : m_xContext(xContext) + , m_nHeight(0) + , m_nWidth(0) + , m_nPosX(0) + , m_nPosY(0) + , m_nBorderColor(0) + , m_nBorder(2) + , m_bPrintRepeatedValues(true) + , m_bAutoGrow(false) + {} + ~OReportComponentProperties(); + + void setShape(css::uno::Reference<css::drawing::XShape>& xShape, + const css::uno::Reference<css::report::XReportComponent>& xTunnel, + oslInterlockedCount& rRefCount); + }; +} + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCOMPONENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportControlModel.hxx b/reportdesign/source/core/inc/ReportControlModel.hxx new file mode 100644 index 000000000..98d209fc6 --- /dev/null +++ b/reportdesign/source/core/inc/ReportControlModel.hxx @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCONTROLMODEL_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCONTROLMODEL_HXX + +#include "ReportComponent.hxx" +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/report/XFormatCondition.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <comphelper/interfacecontainer3.hxx> + + +namespace reportdesign +{ + struct OFormatProperties + { + css::style::ParagraphAdjust nAlign; + css::awt::FontDescriptor aFontDescriptor; + css::awt::FontDescriptor aAsianFontDescriptor; + css::awt::FontDescriptor aComplexFontDescriptor; + css::lang::Locale aCharLocale; + css::lang::Locale aCharLocaleAsian; + css::lang::Locale aCharLocaleComplex; + ::sal_Int16 nFontEmphasisMark; + ::sal_Int16 nFontRelief; + ::sal_Int32 nTextColor; + ::sal_Int32 nTextLineColor; + ::sal_Int32 nBackgroundColor; + OUString sCharCombinePrefix; + OUString sCharCombineSuffix; + OUString sHyperLinkURL; + OUString sHyperLinkTarget; + OUString sHyperLinkName; + OUString sVisitedCharStyleName; + OUString sUnvisitedCharStyleName; + css::style::VerticalAlignment aVerticalAlignment; + ::sal_Int16 nCharEscapement; + ::sal_Int16 nCharCaseMap; + ::sal_Int16 nCharKerning; + ::sal_Int8 nCharEscapementHeight; + bool m_bBackgroundTransparent; + bool bCharFlash; + bool bCharAutoKerning; + bool bCharCombineIsOn; + bool bCharHidden; + bool bCharShadowed; + bool bCharContoured; + OFormatProperties(); + }; + class OReportControlModel + { + void checkIndex(sal_Int32 _nIndex); + OReportControlModel(OReportControlModel const &) = delete; + void operator =(OReportControlModel const &) = delete; + public: + ::comphelper::OInterfaceContainerHelper3<css::container::XContainerListener> aContainerListeners; + OReportComponentProperties aComponent; + OFormatProperties aFormatProperties; + css::container::XContainer* m_pOwner; + ::std::vector< css::uno::Reference< css::report::XFormatCondition> > + m_aFormatConditions; + osl::Mutex& m_rMutex; + OUString aDataField; + OUString aConditionalPrintExpression; + bool bPrintWhenGroupChange; + + OReportControlModel(osl::Mutex& _rMutex + ,css::container::XContainer* _pOwner + ,css::uno::Reference< css::uno::XComponentContext > const & _xContext) + :aContainerListeners(_rMutex) + ,aComponent(_xContext) + ,m_pOwner(_pOwner) + ,m_rMutex(_rMutex) + ,bPrintWhenGroupChange(true) + {} + + // XContainer + /// @throws css::uno::RuntimeException + void addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ); + /// @throws css::uno::RuntimeException + void removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ); + + // XElementAccess + /// @throws css::uno::RuntimeException + bool hasElements( ); + + // XIndexReplace + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + void replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ); + + // XIndexContainer + /// @throws css::lang::IllegalArgumentException + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + void insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + void removeByIndex( ::sal_Int32 Index ); + + // XIndexAccess + /// @throws css::uno::RuntimeException + ::sal_Int32 getCount( ); + /// @throws css::lang::IndexOutOfBoundsException + /// @throws css::lang::WrappedTargetException + /// @throws css::uno::RuntimeException + css::uno::Any getByIndex( ::sal_Int32 Index ); + + static bool isInterfaceForbidden(const css::uno::Type& _rType); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTCONTROLMODEL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportDrawPage.hxx b/reportdesign/source/core/inc/ReportDrawPage.hxx new file mode 100644 index 000000000..e1b432247 --- /dev/null +++ b/reportdesign/source/core/inc/ReportDrawPage.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTDRAWPAGE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTDRAWPAGE_HXX + +#include <svx/unopage.hxx> +#include <com/sun/star/report/XSection.hpp> + +namespace reportdesign +{ + class OReportDrawPage : public SvxDrawPage + { + css::uno::WeakReference< css::report::XSection > m_xSection; + OReportDrawPage(const OReportDrawPage&) = delete; + void operator =(const OReportDrawPage&) = delete; + protected: + virtual SdrObject *CreateSdrObject_( const css::uno::Reference< css::drawing::XShape > & xShape ) override; + virtual css::uno::Reference< css::drawing::XShape > CreateShape( SdrObject *pObj ) const override; + public: + OReportDrawPage(SdrPage* pPage,const css::uno::Reference< css::report::XSection >& _xSection); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTDRAWPAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportEngineJFree.hxx b/reportdesign/source/core/inc/ReportEngineJFree.hxx new file mode 100644 index 000000000..e0ab1d60b --- /dev/null +++ b/reportdesign/source/core/inc/ReportEngineJFree.hxx @@ -0,0 +1,133 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTENGINEJFREE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTENGINEJFREE_HXX + +#include <sal/config.h> + +#include <com/sun/star/report/XReportEngine.hpp> +#include <cppuhelper/compbase.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace reportdesign +{ + typedef ::cppu::WeakComponentImplHelper< css::report::XReportEngine + ,css::lang::XServiceInfo> ReportEngineBase; + typedef ::cppu::PropertySetMixin<css::report::XReportEngine> ReportEnginePropertySet; + + class OReportEngineJFree : public comphelper::OMutexAndBroadcastHelper, + public ReportEngineBase, + public ReportEnginePropertySet + { + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::report::XReportDefinition > m_xReport; + css::uno::Reference< css::task::XStatusIndicator> m_StatusIndicator; + css::uno::Reference< css::sdbc::XConnection > m_xActiveConnection; + ::sal_Int32 m_nMaxRows; + private: + OReportEngineJFree(const OReportEngineJFree&) = delete; + OReportEngineJFree& operator=(const OReportEngineJFree&) = delete; + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + l.notify(); + } + + /** returns the file url for a new model + * + * \return The new file url. + */ + OUString getNewOutputName(); + + protected: + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual ~OReportEngineJFree() override; + public: + OReportEngineJFree(const css::uno::Reference< css::uno::XComponentContext >& context); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + private: + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XReportEngine + // Attributes + virtual css::uno::Reference< css::report::XReportDefinition > SAL_CALL getReportDefinition() override ; + virtual void SAL_CALL setReportDefinition( const css::uno::Reference< css::report::XReportDefinition >& _reportdefinition ) override; + virtual css::uno::Reference< css::sdbc::XConnection > SAL_CALL getActiveConnection() override; + virtual void SAL_CALL setActiveConnection( const css::uno::Reference< css::sdbc::XConnection >& _activeconnection ) override; + virtual css::uno::Reference< css::task::XStatusIndicator > SAL_CALL getStatusIndicator() override ; + virtual void SAL_CALL setStatusIndicator( const css::uno::Reference< css::task::XStatusIndicator >& _statusindicator ) override ; + virtual ::sal_Int32 SAL_CALL getMaxRows() override; + virtual void SAL_CALL setMaxRows( ::sal_Int32 MaxRows ) override; + // Methods + virtual css::uno::Reference< css::frame::XModel > SAL_CALL createDocumentModel( ) override ; + virtual css::uno::Reference< css::frame::XModel > SAL_CALL createDocumentAlive( const css::uno::Reference< css::frame::XFrame >& _frame ) override ; + /// @throws css::lang::DisposedException + /// @throws css::lang::IllegalArgumentException + /// @throws css::uno::Exception + /// @throws css::uno::RuntimeException + css::uno::Reference< css::frame::XModel > createDocumentAlive( const css::uno::Reference< css::frame::XFrame >& _frame ,bool _bHidden) ; + virtual css::util::URL SAL_CALL createDocument( ) override ; + virtual void SAL_CALL interrupt( ) override ; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTENGINEJFREE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportHelperImpl.hxx b/reportdesign/source/core/inc/ReportHelperImpl.hxx new file mode 100644 index 000000000..4d5a1f41e --- /dev/null +++ b/reportdesign/source/core/inc/ReportHelperImpl.hxx @@ -0,0 +1,1293 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTHELPERIMPL_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTHELPERIMPL_HXX +// css::report::XReportComponent: +#define REPORTCOMPONENT_IMPL3(clazz,arg) \ +OUString SAL_CALL clazz::getName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_sName; \ +} \ +void SAL_CALL clazz::setName( const OUString& _name ) \ +{ \ + set(PROPERTY_NAME,_name,(arg).m_sName); \ +} \ +::sal_Int32 SAL_CALL clazz::getHeight() \ +{ \ + return getSize().Height; \ +} \ +void SAL_CALL clazz::setHeight( ::sal_Int32 _height ) \ +{ \ + awt::Size aSize = getSize(); \ + aSize.Height = _height; \ + setSize(aSize); \ +} \ +::sal_Int32 SAL_CALL clazz::getPositionX() \ +{ \ + return getPosition().X; \ +} \ +void SAL_CALL clazz::setPositionX( ::sal_Int32 _positionx ) \ +{ \ + awt::Point aPos = getPosition(); \ + aPos.X = _positionx; \ + setPosition(aPos); \ +} \ +::sal_Int32 SAL_CALL clazz::getPositionY() \ +{ \ + return getPosition().Y; \ +} \ +void SAL_CALL clazz::setPositionY( ::sal_Int32 _positiony ) \ +{ \ + awt::Point aPos = getPosition(); \ + aPos.Y = _positiony; \ + setPosition(aPos); \ +} \ +::sal_Int32 SAL_CALL clazz::getWidth() \ +{ \ + return getSize().Width; \ +} \ +void SAL_CALL clazz::setWidth( ::sal_Int32 _width ) \ +{ \ + awt::Size aSize = getSize(); \ + aSize.Width = _width; \ + setSize(aSize); \ +} \ +uno::Reference< report::XSection > SAL_CALL clazz::getSection() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + uno::Reference< container::XChild > xParent(getParent( ),uno::UNO_QUERY); \ + return lcl_getSection(xParent); \ +} \ +sal_Bool SAL_CALL clazz::getAutoGrow() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_bAutoGrow; \ +} \ +void SAL_CALL clazz::setAutoGrow(sal_Bool _autogrow) \ +{ \ + set(PROPERTY_AUTOGROW,static_cast<bool>(_autogrow),(arg).m_bAutoGrow); \ +} + +#define REPORTCOMPONENT_IMPL(clazz,arg) \ +REPORTCOMPONENT_IMPL3(clazz,arg)\ +sal_Bool SAL_CALL clazz::getPrintRepeatedValues() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_bPrintRepeatedValues; \ +} \ +void SAL_CALL clazz::setPrintRepeatedValues( sal_Bool _printrepeatedvalues ) \ +{ \ + set(PROPERTY_PRINTREPEATEDVALUES,_printrepeatedvalues,(arg).m_bPrintRepeatedValues); \ +} + +#define REPORTCOMPONENT_IMPL2(clazz,arg) \ +::sal_Int16 SAL_CALL clazz::getControlBorder() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_nBorder; \ +} \ +void SAL_CALL clazz::setControlBorder( ::sal_Int16 _border )\ +{ \ + set(PROPERTY_CONTROLBORDER,_border,(arg).m_nBorder); \ +} \ +::sal_Int32 SAL_CALL clazz::getControlBorderColor() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_nBorderColor; \ +} \ +void SAL_CALL clazz::setControlBorderColor( ::sal_Int32 _bordercolor ) \ +{ \ + set(PROPERTY_CONTROLBORDERCOLOR,_bordercolor,(arg).m_nBorderColor); \ +} + +#define REPORTCOMPONENT_MASTERDETAIL(clazz,arg) \ +css::uno::Sequence< OUString > SAL_CALL clazz::getMasterFields() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_aMasterFields; \ +} \ +void SAL_CALL clazz::setMasterFields( const css::uno::Sequence< OUString >& _masterfields )\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + set(PROPERTY_MASTERFIELDS,_masterfields,(arg).m_aMasterFields); \ +} \ +css::uno::Sequence< OUString > SAL_CALL clazz::getDetailFields()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return (arg).m_aDetailFields; \ +} \ +void SAL_CALL clazz::setDetailFields( const css::uno::Sequence< OUString >& _detailfields )\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + set(PROPERTY_DETAILFIELDS,_detailfields,(arg).m_aDetailFields); \ +} + +#define REPORTCOMPONENT_NOMASTERDETAIL(clazz) \ +css::uno::Sequence< OUString > SAL_CALL clazz::getMasterFields() \ +{ \ + throw css::beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setMasterFields( const css::uno::Sequence< OUString >& )\ +{ \ + throw css::beans::UnknownPropertyException();\ +} \ +css::uno::Sequence< OUString > SAL_CALL clazz::getDetailFields()\ +{ \ + throw css::beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setDetailFields( const css::uno::Sequence< OUString >& )\ +{ \ + throw css::beans::UnknownPropertyException();\ +} + +// css::report::XReportControlFormat: +#define REPORTCONTROLFORMAT_IMPL1(clazz,varName) \ +::sal_Int32 SAL_CALL clazz::getControlBackground() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.m_bBackgroundTransparent ? sal_Int32(COL_TRANSPARENT) : varName.nBackgroundColor; \ +} \ + \ +void SAL_CALL clazz::setControlBackground( ::sal_Int32 _backgroundcolor )\ +{ \ + bool bTransparent = _backgroundcolor == static_cast<sal_Int32>(COL_TRANSPARENT);\ + setControlBackgroundTransparent(bTransparent);\ + if ( !bTransparent )\ + set(PROPERTY_CONTROLBACKGROUND,_backgroundcolor,varName.nBackgroundColor);\ +} \ + \ +sal_Bool SAL_CALL clazz::getControlBackgroundTransparent() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.m_bBackgroundTransparent; \ +} \ + \ +void SAL_CALL clazz::setControlBackgroundTransparent( sal_Bool _controlbackgroundtransparent ) \ +{ \ + set(PROPERTY_CONTROLBACKGROUNDTRANSPARENT,_controlbackgroundtransparent,varName.m_bBackgroundTransparent);\ + if ( _controlbackgroundtransparent )\ + set(PROPERTY_CONTROLBACKGROUND,static_cast<sal_Int32>(COL_TRANSPARENT),varName.nBackgroundColor);\ +} + +#define REPORTCONTROLFORMAT_IMPL2(clazz,varName) \ +::sal_Int16 SAL_CALL clazz::getCharStrikeout() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Strikeout; \ +} \ + \ +void SAL_CALL clazz::setCharStrikeout(::sal_Int16 the_value) \ +{ \ + set(PROPERTY_CHARSTRIKEOUT,the_value,varName.aFontDescriptor.Strikeout); \ +} \ + \ +sal_Bool SAL_CALL clazz::getCharWordMode() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.WordLineMode; \ +} \ + \ +void SAL_CALL clazz::setCharWordMode(sal_Bool the_value) \ +{ \ + set(PROPERTY_CHARWORDMODE,the_value,varName.aFontDescriptor.WordLineMode); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharRotation() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return static_cast<sal_Int16>(varName.aFontDescriptor.Orientation); \ +} \ + \ +void SAL_CALL clazz::setCharRotation(::sal_Int16 the_value) \ +{ \ + float newValue = the_value; \ + set(PROPERTY_CHARROTATION,newValue,varName.aFontDescriptor.Orientation); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharScaleWidth() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return static_cast<sal_Int16>(varName.aFontDescriptor.CharacterWidth); \ +} \ + \ +void SAL_CALL clazz::setCharScaleWidth(::sal_Int16 the_value) \ +{ \ + float newValue = the_value; \ + set(PROPERTY_CHARSCALEWIDTH,newValue,varName.aFontDescriptor.CharacterWidth); \ +} \ +sal_Int16 SAL_CALL clazz::getParaAdjust() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return static_cast<sal_Int16>(varName.nAlign); \ +} \ + \ +void SAL_CALL clazz::setParaAdjust( sal_Int16 _align ) \ +{ \ + set(PROPERTY_PARAADJUST,_align,varName.nAlign); \ +} \ + \ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptor() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor; \ +} \ + \ +void SAL_CALL clazz::setFontDescriptor( const awt::FontDescriptor& _fontdescriptor ) \ +{ \ + set(PROPERTY_FONTDESCRIPTOR,_fontdescriptor,varName.aFontDescriptor); \ +} \ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptorAsian() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor; \ +} \ + \ +void SAL_CALL clazz::setFontDescriptorAsian( const awt::FontDescriptor& _fontdescriptor ) \ +{ \ + set(PROPERTY_FONTDESCRIPTORASIAN,_fontdescriptor,varName.aAsianFontDescriptor); \ +} \ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptorComplex() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor; \ +} \ + \ +void SAL_CALL clazz::setFontDescriptorComplex( const awt::FontDescriptor& _fontdescriptor ) \ +{ \ + set(PROPERTY_FONTDESCRIPTORCOMPLEX,_fontdescriptor,varName.aComplexFontDescriptor); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getControlTextEmphasis() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nFontEmphasisMark; \ +} \ + \ +void SAL_CALL clazz::setControlTextEmphasis( ::sal_Int16 _fontemphasismark ) \ +{ \ + set(PROPERTY_CONTROLTEXTEMPHASISMARK,_fontemphasismark,varName.nFontEmphasisMark); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharRelief() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nFontRelief; \ +} \ + \ +void SAL_CALL clazz::setCharRelief( ::sal_Int16 _fontrelief ) \ +{ \ + set(PROPERTY_CHARRELIEF,_fontrelief,varName.nFontRelief); \ +} \ + \ +::sal_Int32 SAL_CALL clazz::getCharColor() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nTextColor; \ +} \ + \ +void SAL_CALL clazz::setCharColor( ::sal_Int32 _textcolor ) \ +{ \ + set(PROPERTY_CHARCOLOR,_textcolor,varName.nTextColor); \ +} \ + \ +::sal_Int32 SAL_CALL clazz::getCharUnderlineColor() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nTextLineColor; \ +} \ + \ +void SAL_CALL clazz::setCharUnderlineColor( ::sal_Int32 _textlinecolor ) \ +{ \ + set(PROPERTY_CHARUNDERLINECOLOR,_textlinecolor,varName.nTextLineColor); \ +} \ + \ +style::VerticalAlignment SAL_CALL clazz::getVerticalAlign() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aVerticalAlignment; \ +} \ + \ +void SAL_CALL clazz::setVerticalAlign( style::VerticalAlignment _verticalalign ) \ +{ \ + set(PROPERTY_VERTICALALIGN,_verticalalign,varName.aVerticalAlignment); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharEmphasis() \ +{ \ + return getControlTextEmphasis(); \ +} \ + \ +void SAL_CALL clazz::setCharEmphasis( ::sal_Int16 _charemphasis ) \ +{ \ + set(PROPERTY_CHAREMPHASIS,_charemphasis,varName.nFontEmphasisMark); \ +} \ + \ +OUString SAL_CALL clazz::getCharFontName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Name; \ +} \ + \ +void SAL_CALL clazz::setCharFontName( const OUString& _charfontname ) \ +{ \ + set(PROPERTY_CHARFONTNAME,_charfontname,varName.aFontDescriptor.Name); \ +} \ + \ +OUString SAL_CALL clazz::getCharFontStyleName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.StyleName; \ +} \ + \ +void SAL_CALL clazz::setCharFontStyleName( const OUString& _charfontstylename ) \ +{ \ + set(PROPERTY_CHARFONTSTYLENAME,_charfontstylename,varName.aFontDescriptor.StyleName); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharFontFamily() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Family; \ +} \ + \ +void SAL_CALL clazz::setCharFontFamily( ::sal_Int16 _charfontfamily ) \ +{ \ + set(PROPERTY_CHARFONTFAMILY,_charfontfamily,varName.aFontDescriptor.Family); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharFontCharSet() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.CharSet; \ +} \ + \ +void SAL_CALL clazz::setCharFontCharSet( ::sal_Int16 _charfontcharset ) \ +{ \ + set(PROPERTY_CHARFONTCHARSET,_charfontcharset,varName.aFontDescriptor.CharSet); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharFontPitch() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Pitch; \ +} \ + \ +void SAL_CALL clazz::setCharFontPitch( ::sal_Int16 _charfontpitch ) \ +{ \ + set(PROPERTY_CHARFONTPITCH,_charfontpitch,varName.aFontDescriptor.Pitch); \ +} \ + \ +float SAL_CALL clazz::getCharHeight() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Height; \ +} \ + \ +void SAL_CALL clazz::setCharHeight( float _charheight ) \ +{ \ + set(PROPERTY_CHARHEIGHT,static_cast<sal_Int16>(_charheight),varName.aFontDescriptor.Height); \ +} \ + \ +::sal_Int16 SAL_CALL clazz::getCharUnderline() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Underline; \ +} \ + \ +void SAL_CALL clazz::setCharUnderline( ::sal_Int16 _charunderline ) \ +{ \ + set(PROPERTY_CHARUNDERLINE,_charunderline,varName.aFontDescriptor.Underline); \ +} \ + \ +float SAL_CALL clazz::getCharWeight() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Weight; \ +} \ + \ +void SAL_CALL clazz::setCharWeight( float _charweight ) \ +{ \ + set(PROPERTY_CHARWEIGHT,_charweight,varName.aFontDescriptor.Weight); \ +} \ + \ +awt::FontSlant SAL_CALL clazz::getCharPosture() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aFontDescriptor.Slant; \ +} \ + \ +void SAL_CALL clazz::setCharPosture( awt::FontSlant _charposture ) \ +{ \ + set(PROPERTY_CHARPOSTURE,_charposture,varName.aFontDescriptor.Slant); \ +}\ +sal_Bool SAL_CALL clazz::getCharFlash()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharFlash; \ +} \ +void SAL_CALL clazz::setCharFlash(sal_Bool the_value)\ +{ \ + set(PROPERTY_CHARFLASH,the_value,varName.bCharFlash); \ +}\ +sal_Bool SAL_CALL clazz::getCharAutoKerning()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharAutoKerning; \ +} \ +void SAL_CALL clazz::setCharAutoKerning(sal_Bool the_value)\ +{ \ + set(PROPERTY_CHARAUTOKERNING,the_value,varName.bCharAutoKerning); \ +}\ +::sal_Int8 SAL_CALL clazz::getCharEscapementHeight() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nCharEscapementHeight; \ +} \ +void SAL_CALL clazz::setCharEscapementHeight(::sal_Int8 the_value) \ +{ \ + set(PROPERTY_CHARESCAPEMENTHEIGHT,the_value,varName.nCharEscapementHeight); \ +}\ +lang::Locale SAL_CALL clazz::getCharLocale() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aCharLocale; \ +} \ +void SAL_CALL clazz::setCharLocale(const lang::Locale & the_value) \ +{ \ + BoundListeners l; \ + { \ + ::osl::MutexGuard aGuard(m_aMutex); \ + if ( varName.aCharLocale.Language != the_value.Language \ + || varName.aCharLocale.Country != the_value.Country \ + || varName.aCharLocale.Variant != the_value.Variant ) \ + { \ + prepareSet(PROPERTY_CHARLOCALE, css::uno::Any(varName.aCharLocale), css::uno::Any(the_value), &l); \ + varName.aCharLocale = the_value; \ + } \ + } \ + l.notify(); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharEscapement() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nCharEscapement; \ +} \ +void SAL_CALL clazz::setCharEscapement(::sal_Int16 the_value) \ +{ \ + set(PROPERTY_CHARESCAPEMENT,the_value,varName.nCharEscapement); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharCaseMap() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nCharCaseMap; \ +} \ +void SAL_CALL clazz::setCharCaseMap(::sal_Int16 the_value) \ +{ \ + set(PROPERTY_CHARCASEMAP,the_value,varName.nCharCaseMap); \ +}\ +sal_Bool SAL_CALL clazz::getCharCombineIsOn() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharCombineIsOn; \ +} \ +void SAL_CALL clazz::setCharCombineIsOn(sal_Bool the_value) \ +{ \ + set(PROPERTY_CHARCOMBINEISON,the_value,varName.bCharCombineIsOn); \ +}\ +OUString SAL_CALL clazz::getCharCombinePrefix() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sCharCombinePrefix; \ +} \ +void SAL_CALL clazz::setCharCombinePrefix(const OUString & the_value) \ +{ \ + set(PROPERTY_CHARCOMBINEPREFIX,the_value,varName.sCharCombinePrefix); \ +}\ +OUString SAL_CALL clazz::getCharCombineSuffix() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sCharCombineSuffix; \ +} \ +void SAL_CALL clazz::setCharCombineSuffix(const OUString & the_value) \ +{ \ + set(PROPERTY_CHARCOMBINESUFFIX,the_value,varName.sCharCombineSuffix); \ +}\ +sal_Bool SAL_CALL clazz::getCharHidden() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharHidden; \ +} \ +void SAL_CALL clazz::setCharHidden(sal_Bool the_value) \ +{ \ + set(PROPERTY_CHARHIDDEN,the_value,varName.bCharHidden); \ +}\ +sal_Bool SAL_CALL clazz::getCharShadowed() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharShadowed; \ +} \ +void SAL_CALL clazz::setCharShadowed(sal_Bool the_value) \ +{ \ + set(PROPERTY_CHARSHADOWED,the_value,varName.bCharShadowed); \ +}\ +sal_Bool SAL_CALL clazz::getCharContoured() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.bCharContoured; \ +} \ +void SAL_CALL clazz::setCharContoured(sal_Bool the_value) \ +{ \ + set(PROPERTY_CHARCONTOURED,the_value,varName.bCharContoured); \ +}\ +OUString SAL_CALL clazz::getHyperLinkURL() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sHyperLinkURL; \ +} \ +void SAL_CALL clazz::setHyperLinkURL(const OUString & the_value) \ +{ \ + set(PROPERTY_HYPERLINKURL,the_value,varName.sHyperLinkURL); \ +}\ +OUString SAL_CALL clazz::getHyperLinkTarget() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sHyperLinkTarget; \ +} \ +void SAL_CALL clazz::setHyperLinkTarget(const OUString & the_value) \ +{ \ + set(PROPERTY_HYPERLINKTARGET,the_value,varName.sHyperLinkTarget); \ +}\ +OUString SAL_CALL clazz::getHyperLinkName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sHyperLinkName; \ +} \ +void SAL_CALL clazz::setHyperLinkName(const OUString & the_value) \ +{ \ + set(PROPERTY_HYPERLINKNAME,the_value,varName.sHyperLinkName); \ +}\ +OUString SAL_CALL clazz::getVisitedCharStyleName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sVisitedCharStyleName; \ +} \ +void SAL_CALL clazz::setVisitedCharStyleName(const OUString & the_value) \ +{ \ + set(PROPERTY_VISITEDCHARSTYLENAME,the_value,varName.sVisitedCharStyleName); \ +}\ +OUString SAL_CALL clazz::getUnvisitedCharStyleName() \ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.sUnvisitedCharStyleName; \ +} \ +void SAL_CALL clazz::setUnvisitedCharStyleName(const OUString & the_value) \ +{ \ + set(PROPERTY_UNVISITEDCHARSTYLENAME,the_value,varName.sUnvisitedCharStyleName); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharKerning()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.nCharKerning; \ +}\ +void SAL_CALL clazz::setCharKerning(::sal_Int16 the_value)\ +{ \ + set(PROPERTY_CHARKERNING,the_value,varName.nCharKerning); \ +}\ +float SAL_CALL clazz::getCharHeightAsian()\ + { \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Height; \ +}\ +void SAL_CALL clazz::setCharHeightAsian( float the_value )\ +{ \ + set(PROPERTY_CHARHEIGHTASIAN,static_cast<sal_Int16>(the_value),varName.aAsianFontDescriptor.Height); \ +}\ +float SAL_CALL clazz::getCharWeightAsian()\ + { \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Weight; \ +}\ +void SAL_CALL clazz::setCharWeightAsian( float the_value )\ +{ \ + set(PROPERTY_CHARWEIGHTASIAN,the_value,varName.aAsianFontDescriptor.Weight); \ +}\ +OUString SAL_CALL clazz::getCharFontNameAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Name; \ +}\ +void SAL_CALL clazz::setCharFontNameAsian( const OUString& the_value )\ +{ \ + set(PROPERTY_CHARFONTNAMEASIAN,the_value,varName.aAsianFontDescriptor.Name); \ +}\ +OUString SAL_CALL clazz::getCharFontStyleNameAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.StyleName; \ +}\ +void SAL_CALL clazz::setCharFontStyleNameAsian( const OUString& the_value )\ +{ \ + set(PROPERTY_CHARFONTSTYLENAMEASIAN,the_value,varName.aAsianFontDescriptor.StyleName); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontFamilyAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Family; \ +}\ +void SAL_CALL clazz::setCharFontFamilyAsian( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTFAMILYASIAN,the_value,varName.aAsianFontDescriptor.Family); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontCharSetAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.CharSet; \ +}\ +void SAL_CALL clazz::setCharFontCharSetAsian( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTCHARSETASIAN,the_value,varName.aAsianFontDescriptor.CharSet); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontPitchAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Pitch; \ +}\ +void SAL_CALL clazz::setCharFontPitchAsian( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTPITCHASIAN,the_value,varName.aAsianFontDescriptor.Pitch); \ +}\ +css::awt::FontSlant SAL_CALL clazz::getCharPostureAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aAsianFontDescriptor.Slant; \ +}\ +void SAL_CALL clazz::setCharPostureAsian( css::awt::FontSlant the_value )\ +{ \ + set(PROPERTY_CHARPOSTUREASIAN,the_value,varName.aAsianFontDescriptor.Slant); \ +}\ +css::lang::Locale SAL_CALL clazz::getCharLocaleAsian()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aCharLocaleAsian; \ +}\ +void SAL_CALL clazz::setCharLocaleAsian( const css::lang::Locale& the_value )\ +{ \ + BoundListeners l; \ + { \ + ::osl::MutexGuard aGuard(m_aMutex); \ + if ( varName.aCharLocaleAsian.Language != the_value.Language \ + || varName.aCharLocaleAsian.Country != the_value.Country \ + || varName.aCharLocaleAsian.Variant != the_value.Variant ) \ + { \ + prepareSet(PROPERTY_CHARLOCALEASIAN, css::uno::Any(varName.aCharLocaleAsian), css::uno::Any(the_value), &l); \ + varName.aCharLocaleAsian = the_value; \ + } \ + } \ + l.notify(); \ +}\ +float SAL_CALL clazz::getCharHeightComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Height; \ +}\ +void SAL_CALL clazz::setCharHeightComplex( float the_value )\ +{ \ + set(PROPERTY_CHARHEIGHTCOMPLEX,static_cast<sal_Int16>(the_value),varName.aComplexFontDescriptor.Height); \ +}\ +float SAL_CALL clazz::getCharWeightComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Weight; \ +}\ +void SAL_CALL clazz::setCharWeightComplex( float the_value )\ +{ \ + set(PROPERTY_CHARWEIGHTCOMPLEX,the_value,varName.aComplexFontDescriptor.Weight); \ +}\ +OUString SAL_CALL clazz::getCharFontNameComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Name; \ +}\ +void SAL_CALL clazz::setCharFontNameComplex( const OUString& the_value )\ +{ \ + set(PROPERTY_CHARFONTNAMECOMPLEX,the_value,varName.aComplexFontDescriptor.Name); \ +}\ +OUString SAL_CALL clazz::getCharFontStyleNameComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.StyleName; \ +}\ +void SAL_CALL clazz::setCharFontStyleNameComplex( const OUString& the_value )\ +{ \ + set(PROPERTY_CHARFONTSTYLENAMECOMPLEX,the_value,varName.aComplexFontDescriptor.StyleName); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontFamilyComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Family; \ +}\ +void SAL_CALL clazz::setCharFontFamilyComplex( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTFAMILYCOMPLEX,the_value,varName.aComplexFontDescriptor.Family); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontCharSetComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.CharSet; \ +}\ +void SAL_CALL clazz::setCharFontCharSetComplex( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTCHARSETCOMPLEX,the_value,varName.aComplexFontDescriptor.CharSet); \ +}\ +::sal_Int16 SAL_CALL clazz::getCharFontPitchComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Pitch; \ +}\ +void SAL_CALL clazz::setCharFontPitchComplex( ::sal_Int16 the_value )\ +{ \ + set(PROPERTY_CHARFONTPITCHCOMPLEX,the_value,varName.aComplexFontDescriptor.Pitch); \ +}\ +css::awt::FontSlant SAL_CALL clazz::getCharPostureComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aComplexFontDescriptor.Slant; \ +}\ +void SAL_CALL clazz::setCharPostureComplex( css::awt::FontSlant the_value )\ +{ \ + set(PROPERTY_CHARPOSTURECOMPLEX,the_value,varName.aComplexFontDescriptor.Slant); \ +}\ +css::lang::Locale SAL_CALL clazz::getCharLocaleComplex()\ +{ \ + ::osl::MutexGuard aGuard(m_aMutex); \ + return varName.aCharLocaleComplex; \ +}\ +void SAL_CALL clazz::setCharLocaleComplex( const css::lang::Locale& the_value )\ +{ \ + BoundListeners l; \ + { \ + ::osl::MutexGuard aGuard(m_aMutex); \ + if ( varName.aCharLocaleComplex.Language != the_value.Language \ + || varName.aCharLocaleComplex.Country != the_value.Country \ + || varName.aCharLocaleComplex.Variant != the_value.Variant ) \ + { \ + prepareSet(PROPERTY_CHARLOCALECOMPLEX, css::uno::Any(varName.aCharLocaleComplex), css::uno::Any(the_value), &l); \ + varName.aCharLocaleComplex = the_value; \ + } \ + } \ + l.notify(); \ +}\ + + +#define NO_REPORTCONTROLFORMAT_IMPL(clazz) \ +sal_Int16 SAL_CALL clazz::getParaAdjust()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setParaAdjust(sal_Int16 /*the_value*/)\ +{\ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharStrikeout()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setCharStrikeout(::sal_Int16 /*the_value*/)\ +{\ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharWordMode()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setCharWordMode(sal_Bool /*the_value*/)\ +{\ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharRotation()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setCharRotation(::sal_Int16 /*the_value*/)\ +{\ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharScaleWidth()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setCharScaleWidth(::sal_Int16 /*the_value*/)\ +{\ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharFlash()\ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharFlash(sal_Bool /*the_value*/)\ +{ \ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharAutoKerning()\ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharAutoKerning(sal_Bool /*the_value*/)\ +{ \ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int8 SAL_CALL clazz::getCharEscapementHeight() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharEscapementHeight(::sal_Int8 /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +lang::Locale SAL_CALL clazz::getCharLocale() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharLocale(const lang::Locale & /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharEscapement() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharEscapement(::sal_Int16 /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharCaseMap() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharCaseMap(::sal_Int16 /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharCombineIsOn() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharCombineIsOn(sal_Bool /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +OUString SAL_CALL clazz::getCharCombinePrefix() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharCombinePrefix(const OUString & /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +OUString SAL_CALL clazz::getCharCombineSuffix() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharCombineSuffix(const OUString & /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharHidden() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharHidden(sal_Bool /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharShadowed() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharShadowed(sal_Bool /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +sal_Bool SAL_CALL clazz::getCharContoured() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setCharContoured(sal_Bool /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +OUString SAL_CALL clazz::getVisitedCharStyleName() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setVisitedCharStyleName(const OUString & /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +OUString SAL_CALL clazz::getUnvisitedCharStyleName() \ +{ \ + throw beans::UnknownPropertyException();\ +} \ +void SAL_CALL clazz::setUnvisitedCharStyleName(const OUString & /*the_value*/) \ +{ \ + throw beans::UnknownPropertyException();\ +}\ +::sal_Int16 SAL_CALL clazz::getCharKerning()\ +{ \ + throw beans::UnknownPropertyException();\ +}\ +void SAL_CALL clazz::setCharKerning(::sal_Int16 /*the_value*/)\ +{ \ + throw beans::UnknownPropertyException();\ +}\ +\ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptor()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setFontDescriptor( const awt::FontDescriptor& /*_fontdescriptor*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptorAsian()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setFontDescriptorAsian( const awt::FontDescriptor& /*_fontdescriptor*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +awt::FontDescriptor SAL_CALL clazz::getFontDescriptorComplex()\ +{\ +throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setFontDescriptorComplex( const awt::FontDescriptor& /*_fontdescriptor*/ )\ +{\ +throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getControlTextEmphasis()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setControlTextEmphasis( ::sal_Int16 /*_fontemphasismark*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharRelief()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharRelief( ::sal_Int16 /*_fontrelief*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int32 SAL_CALL clazz::getCharColor()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharColor( ::sal_Int32 /*_textcolor*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int32 SAL_CALL clazz::getCharUnderlineColor()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharUnderlineColor( ::sal_Int32 /*_textlinecolor*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +style::VerticalAlignment SAL_CALL clazz::getVerticalAlign()\ +{\ + ::osl::MutexGuard aGuard(m_aMutex);\ + return m_aProps.aFormatProperties.aVerticalAlignment;\ +}\ +\ +void SAL_CALL clazz::setVerticalAlign( style::VerticalAlignment _verticalalign )\ +{\ + set(PROPERTY_VERTICALALIGN,_verticalalign,m_aProps.aFormatProperties.aVerticalAlignment);\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharEmphasis()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharEmphasis( ::sal_Int16 /*_charemphasis*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +OUString SAL_CALL clazz::getCharFontName()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharFontName( const OUString& /*_charfontname*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +OUString SAL_CALL clazz::getCharFontStyleName()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharFontStyleName( const OUString& /*_charfontstylename*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharFontFamily()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharFontFamily( ::sal_Int16 /*_charfontfamily*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharFontCharSet()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharFontCharSet( ::sal_Int16 /*_charfontcharset*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharFontPitch()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharFontPitch( ::sal_Int16 /*_charfontpitch*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +float SAL_CALL clazz::getCharHeight()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharHeight( float /*_charheight*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +::sal_Int16 SAL_CALL clazz::getCharUnderline()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharUnderline( ::sal_Int16 /*_charunderline*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +float SAL_CALL clazz::getCharWeight()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharWeight( float /*_charweight*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +awt::FontSlant SAL_CALL clazz::getCharPosture()\ +{\ + throw beans::UnknownPropertyException();\ +}\ +\ +void SAL_CALL clazz::setCharPosture( awt::FontSlant /*_charposture*/ )\ +{\ + throw beans::UnknownPropertyException();\ +}\ + float SAL_CALL clazz::getCharHeightAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharHeightAsian( float )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + float SAL_CALL clazz::getCharWeightAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharWeightAsian( float )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + OUString SAL_CALL clazz::getCharFontNameAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontNameAsian( const OUString& )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + OUString SAL_CALL clazz::getCharFontStyleNameAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontStyleNameAsian( const OUString& )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontFamilyAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontFamilyAsian( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontCharSetAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontCharSetAsian( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontPitchAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontPitchAsian( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + css::awt::FontSlant SAL_CALL clazz::getCharPostureAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharPostureAsian( css::awt::FontSlant )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + css::lang::Locale SAL_CALL clazz::getCharLocaleAsian()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharLocaleAsian( const css::lang::Locale& )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + float SAL_CALL clazz::getCharHeightComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharHeightComplex( float )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + float SAL_CALL clazz::getCharWeightComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharWeightComplex( float )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + OUString SAL_CALL clazz::getCharFontNameComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontNameComplex( const OUString& )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + OUString SAL_CALL clazz::getCharFontStyleNameComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontStyleNameComplex( const OUString& )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontFamilyComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontFamilyComplex( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontCharSetComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontCharSetComplex( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + ::sal_Int16 SAL_CALL clazz::getCharFontPitchComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharFontPitchComplex( ::sal_Int16 )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + css::awt::FontSlant SAL_CALL clazz::getCharPostureComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharPostureComplex( css::awt::FontSlant )\ + {\ + throw beans::UnknownPropertyException();\ +}\ + css::lang::Locale SAL_CALL clazz::getCharLocaleComplex()\ + {\ + throw beans::UnknownPropertyException();\ +}\ + void SAL_CALL clazz::setCharLocaleComplex( const css::lang::Locale& )\ + {\ + throw beans::UnknownPropertyException();\ +} + + +// css::report::XReportControlFormat: +#define REPORTCONTROLFORMAT_IMPL(clazz,varName) \ + REPORTCONTROLFORMAT_IMPL1(clazz,varName) \ + REPORTCONTROLFORMAT_IMPL2(clazz,varName) + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTHELPERIMPL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/ReportUndoFactory.hxx b/reportdesign/source/core/inc/ReportUndoFactory.hxx new file mode 100644 index 000000000..c5721c0bc --- /dev/null +++ b/reportdesign/source/core/inc/ReportUndoFactory.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTUNDOFACTORY_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTUNDOFACTORY_HXX + +#include <svx/svdundo.hxx> +#include <memory> + +namespace rptui +{ + class OReportUndoFactory : public SdrUndoFactory + { + ::std::unique_ptr<SdrUndoFactory> m_pUndoFactory; + + OReportUndoFactory(const OReportUndoFactory&) = delete; + OReportUndoFactory& operator=(const OReportUndoFactory&) = delete; + public: + OReportUndoFactory(); + virtual ~OReportUndoFactory() override; + + // shapes + virtual std::unique_ptr<SdrUndoAction> CreateUndoMoveObject( SdrObject& rObject, const Size& rDist ) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoGeoObject( SdrObject& rObject ) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1 = false, bool bSaveText = false ) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoRemoveObject(SdrObject& rObject) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoInsertObject( SdrObject& rObject, bool bOrdNumDirect = false) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoDeleteObject( SdrObject& rObject, bool bOrdNumDirect = false) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoNewObject( SdrObject& rObject, bool bOrdNumDirect = false) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoCopyObject( SdrObject& rObject, bool bOrdNumDirect = false) override; + + virtual std::unique_ptr<SdrUndoAction> CreateUndoObjectOrdNum( SdrObject& rObject, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1) override; + + virtual std::unique_ptr<SdrUndoAction> CreateUndoReplaceObject( SdrObject& rOldObject, SdrObject& rNewObject ) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoObjectLayerChange( SdrObject& rObject, SdrLayerID aOldLayer, SdrLayerID aNewLayer ) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoObjectSetText( SdrObject& rNewObj, sal_Int32 nText ) override; + + // layer + virtual std::unique_ptr<SdrUndoAction> CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoDeleteLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel) override; + + // page + virtual std::unique_ptr<SdrUndoAction> CreateUndoDeletePage(SdrPage& rPage) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoNewPage(SdrPage& rPage) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoCopyPage(SdrPage& rPage) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoSetPageNum(SdrPage& rNewPg, sal_uInt16 nOldPageNum1, sal_uInt16 nNewPageNum1) override; + + // master page + virtual std::unique_ptr<SdrUndoAction> CreateUndoPageRemoveMasterPage(SdrPage& rChangedPage) override; + virtual std::unique_ptr<SdrUndoAction> CreateUndoPageChangeMasterPage(SdrPage& rChangedPage) override; + + }; + +} // rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_REPORTUNDOFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/RptObjectListener.hxx b/reportdesign/source/core/inc/RptObjectListener.hxx new file mode 100644 index 000000000..d27a4bf33 --- /dev/null +++ b/reportdesign/source/core/inc/RptObjectListener.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_RPTOBJECTLISTENER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_RPTOBJECTLISTENER_HXX + +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> + +namespace rptui +{ +class OObjectBase; + +class OObjectListener: public ::cppu::WeakImplHelper< css::beans::XPropertyChangeListener > +{ +private: + OObjectBase* m_pObject; + OObjectListener(const OObjectListener&) = delete; + void operator =(const OObjectListener&) = delete; +protected: + virtual ~OObjectListener() override; +public: + OObjectListener(OObjectBase* _pObject); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override; +}; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_RPTOBJECTLISTENER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Section.hxx b/reportdesign/source/core/inc/Section.hxx new file mode 100644 index 000000000..5417af2a9 --- /dev/null +++ b/reportdesign/source/core/inc/Section.hxx @@ -0,0 +1,232 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SECTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SECTION_HXX + +#include <com/sun/star/report/XSection.hpp> +#include <cppuhelper/compbase.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/propertysetmixin.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XShapeGrouper.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/form/XFormsSupplier2.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +namespace reportdesign +{ + typedef ::cppu::WeakComponentImplHelper + < css::report::XSection + , css::lang::XServiceInfo + , css::lang::XUnoTunnel + // SvxDrawPage forward + , css::drawing::XDrawPage + , css::drawing::XShapeGrouper + // SvxFmDrawPage forward + , css::form::XFormsSupplier2 + > SectionBase; + typedef ::cppu::PropertySetMixin<css::report::XSection> SectionPropertySet; + + class OSection : public comphelper::OMutexAndBroadcastHelper, + public SectionBase, + public SectionPropertySet + { + ::comphelper::OInterfaceContainerHelper3<css::container::XContainerListener> m_aContainerListeners; + css::uno::Reference< css::drawing::XDrawPage > m_xDrawPage; + css::uno::Reference< css::drawing::XShapeGrouper > m_xDrawPage_ShapeGrouper; + css::uno::Reference< css::form::XFormsSupplier2 > m_xDrawPage_FormSupplier; + css::uno::Reference< css::lang::XUnoTunnel > m_xDrawPage_Tunnel; + css::uno::WeakReference< css::report::XGroup > m_xGroup; + css::uno::WeakReference< css::report::XReportDefinition > m_xReportDefinition; + OUString m_sName; + OUString m_sConditionalPrintExpression; + ::sal_uInt32 m_nHeight; + ::sal_Int32 m_nBackgroundColor; + ::sal_Int16 m_nForceNewPage; + ::sal_Int16 m_nNewRowOrCol; + bool m_bKeepTogether; + bool m_bRepeatSection; + bool m_bVisible; + bool m_bBacktransparent; + bool m_bInRemoveNotify; + bool m_bInInsertNotify; + + private: + OSection(const OSection&) = delete; + OSection& operator=(const OSection&) = delete; + + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + + /** checks if this section is either the page header or footer and if so it throws an UnknownPropertyException + * + */ + void checkNotPageHeaderFooter(); + + void init(); + protected: + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual ~OSection() override; + + /** this function is called upon disposing the component + */ + // TODO: VirtualFunctionFinder: This is virtual function! + + virtual void SAL_CALL disposing() override; + private: + OSection(const css::uno::Reference< css::report::XReportDefinition >& xParentDef + ,const css::uno::Reference< css::report::XGroup >& xParentGroup + ,const css::uno::Reference< css::uno::XComponentContext >& context, + css::uno::Sequence< OUString> const&); + public: + static css::uno::Reference< css::report::XSection> + createOSection(const css::uno::Reference< css::report::XReportDefinition >& _xParent + ,const css::uno::Reference< css::uno::XComponentContext >& context,bool _bPageSection=false); + static css::uno::Reference< css::report::XSection> + createOSection(const css::uno::Reference< css::report::XGroup >& _xParent + ,const css::uno::Reference< css::uno::XComponentContext >& context); + + DECLARE_XINTERFACE( ) + + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XSection + virtual sal_Bool SAL_CALL getVisible() override; + virtual void SAL_CALL setVisible( sal_Bool _visible ) override; + virtual OUString SAL_CALL getName() override; + virtual void SAL_CALL setName( const OUString& _name ) override; + virtual ::sal_uInt32 SAL_CALL getHeight() override; + virtual void SAL_CALL setHeight( ::sal_uInt32 _height ) override; + virtual ::sal_Int32 SAL_CALL getBackColor() override; + virtual void SAL_CALL setBackColor( ::sal_Int32 _backgroundcolor ) override; + virtual sal_Bool SAL_CALL getBackTransparent() override; + virtual void SAL_CALL setBackTransparent( sal_Bool _backtransparent ) override; + virtual OUString SAL_CALL getConditionalPrintExpression() override; + virtual void SAL_CALL setConditionalPrintExpression( const OUString& _conditionalprintexpression ) override; + virtual ::sal_Int16 SAL_CALL getForceNewPage() override; + virtual void SAL_CALL setForceNewPage( ::sal_Int16 _forcenewpage ) override; + virtual ::sal_Int16 SAL_CALL getNewRowOrCol() override; + virtual void SAL_CALL setNewRowOrCol( ::sal_Int16 _newroworcol ) override; + virtual sal_Bool SAL_CALL getKeepTogether() override; + virtual void SAL_CALL setKeepTogether( sal_Bool _keeptogether ) override; + virtual sal_Bool SAL_CALL getCanGrow() override; + virtual void SAL_CALL setCanGrow( sal_Bool _cangrow ) override; + virtual sal_Bool SAL_CALL getCanShrink() override; + virtual void SAL_CALL setCanShrink( sal_Bool _canshrink ) override; + virtual sal_Bool SAL_CALL getRepeatSection() override; + virtual void SAL_CALL setRepeatSection( sal_Bool _repeatsection ) override; + virtual css::uno::Reference< css::report::XGroup > SAL_CALL getGroup() override; + virtual css::uno::Reference< css::report::XReportDefinition > SAL_CALL getReportDefinition() override; + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + // XShapes + virtual void SAL_CALL add( const css::uno::Reference< css::drawing::XShape >& xShape ) override; + virtual void SAL_CALL remove( const css::uno::Reference< css::drawing::XShape >& xShape ) override; + // XShapeGrouper + virtual css::uno::Reference< css::drawing::XShapeGroup > SAL_CALL group( const css::uno::Reference< css::drawing::XShapes >& xShapes ) override; + virtual void SAL_CALL ungroup( const css::uno::Reference< css::drawing::XShapeGroup >& aGroup ) override; + + // XFormsSupplier + virtual css::uno::Reference< css::container::XNameContainer > SAL_CALL getForms() override; + // XFormsSupplier2 + virtual sal_Bool SAL_CALL hasForms() override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration( ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // css::lang::XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override; + static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId(); + + void notifyElementAdded(const css::uno::Reference< css::drawing::XShape >& xShape); + void notifyElementRemoved(const css::uno::Reference< css::drawing::XShape >& xShape); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Shape.hxx b/reportdesign/source/core/inc/Shape.hxx new file mode 100644 index 000000000..73f6c63f6 --- /dev/null +++ b/reportdesign/source/core/inc/Shape.hxx @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SHAPE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SHAPE_HXX + +#include <cppuhelper/propertysetmixin.hxx> +#include <com/sun/star/report/XShape.hpp> +#include "ReportControlModel.hxx" +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <ReportHelperDefines.hxx> +#include <comphelper/propagg.hxx> +#include <memory> + +namespace reportdesign +{ + typedef ::cppu::PropertySetMixin< css::report::XShape > ShapePropertySet; + typedef ::cppu::WeakComponentImplHelper< css::report::XShape + ,css::lang::XServiceInfo > ShapeBase; + + /** \class OShape Defines the implementation of a \interface com:::sun::star::report::XShape + * \ingroup reportdesign_api + * + */ + class OShape : public cppu::BaseMutex, + public ShapeBase, + public ShapePropertySet + { + friend class OShapeHelper; + ::std::unique_ptr< ::comphelper::OPropertyArrayAggregationHelper> m_pAggHelper; + OReportControlModel m_aProps; + css::drawing::HomogenMatrix3 m_Transformation; + sal_Int32 m_nZOrder; + bool m_bOpaque; + + OUString m_sServiceName; + OUString m_CustomShapeEngine; + OUString m_CustomShapeData; + css::uno::Sequence< css::beans::PropertyValue > m_CustomShapeGeometry; + + private: + OShape(const OShape&) = delete; + OShape& operator=(const OShape&) = delete; + + // internally, we store PROPERTY_PARAADJUST as css::style::ParagraphAdjust, but externally the property is visible as a sal_Int16 + void set( const OUString& _sProperty + ,sal_Int16 Value + ,css::style::ParagraphAdjust& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( static_cast<sal_Int16>(_member) != Value ) + { + prepareSet(_sProperty, css::uno::Any(static_cast<sal_Int16>(_member)), css::uno::Any(Value), &l); + _member = static_cast<css::style::ParagraphAdjust>(Value); + } + } + l.notify(); + } + template <typename T> void set( const OUString& _sProperty + ,const T& Value + ,T& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + void set( const OUString& _sProperty + ,bool Value + ,bool& _member) + { + BoundListeners l; + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( _member != Value ) + { + prepareSet(_sProperty, css::uno::Any(_member), css::uno::Any(Value), &l); + _member = Value; + } + } + l.notify(); + } + cppu::IPropertyArrayHelper& getInfoHelper(); + protected: + virtual ~OShape() override; + public: + explicit OShape(css::uno::Reference< css::uno::XComponentContext > const & _xContext); + explicit OShape(css::uno::Reference< css::uno::XComponentContext > const & _xContext + ,const css::uno::Reference< css::lang::XMultiServiceFactory > & _xFactory + ,css::uno::Reference< css::drawing::XShape >& _xShape + ,const OUString& _sServiceName); + + DECLARE_XINTERFACE( ) + // css::lang::XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + /// @throws css::uno::RuntimeException + static css::uno::Sequence< OUString > getSupportedServiceNames_Static(); + /// @throws css::uno::RuntimeException + static OUString getImplementationName_Static(); + static css::uno::Reference< css::uno::XInterface > + create(css::uno::Reference< css::uno::XComponentContext > const & xContext); + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; + virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; + virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override; + virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener ) override; + virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener >& aListener ) override; + virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener >& aListener ) override; + + // XReportComponent + REPORTCOMPONENT_HEADER() + + // XShape + SHAPE_HEADER() + + virtual OUString SAL_CALL getCustomShapeEngine() override; + virtual void SAL_CALL setCustomShapeEngine( const OUString& _customshapeengine ) override; + virtual OUString SAL_CALL getCustomShapeData() override; + virtual void SAL_CALL setCustomShapeData( const OUString& _customshapedata ) override; + virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCustomShapeGeometry() override; + virtual void SAL_CALL setCustomShapeGeometry( const css::uno::Sequence< css::beans::PropertyValue >& _customshapegeometry ) override; + + virtual sal_Bool SAL_CALL getOpaque() override; + virtual void SAL_CALL setOpaque( sal_Bool _opaque ) override; + + // XShapeDescriptor + virtual OUString SAL_CALL getShapeType( ) override; + + // XReportControlModel + REPORTCONTROLMODEL_HEADER() + + // XReportControlFormat + REPORTCONTROLFORMAT_HEADER() + // XShape + virtual ::sal_Int32 SAL_CALL getZOrder() override; + virtual void SAL_CALL setZOrder( ::sal_Int32 _zorder ) override; + virtual css::drawing::HomogenMatrix3 SAL_CALL getTransformation() override; + virtual void SAL_CALL setTransformation( const css::drawing::HomogenMatrix3& _transformation ) override; + + // XCloneable + virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone( ) override; + + // XComponent + virtual void SAL_CALL dispose() override; + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::addEventListener(aListener); + } + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override + { + cppu::WeakComponentImplHelperBase::removeEventListener(aListener); + } + + // XChild + virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent( ) override; + virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& Parent ) override; + + // XContainer + virtual void SAL_CALL addContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + virtual void SAL_CALL removeContainerListener( const css::uno::Reference< css::container::XContainerListener >& xListener ) override; + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType( ) override; + virtual sal_Bool SAL_CALL hasElements( ) override; + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + + // XIndexContainer + virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const css::uno::Any& Element ) override; + virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) override; + + // XIndexAccess + virtual ::sal_Int32 SAL_CALL getCount( ) override; + virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_SHAPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/Tools.hxx b/reportdesign/source/core/inc/Tools.hxx new file mode 100644 index 000000000..3e0a699ce --- /dev/null +++ b/reportdesign/source/core/inc/Tools.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_TOOLS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_TOOLS_HXX + +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + + +#include <strings.hxx> +#include <osl/diagnose.h> +#include <comphelper/uno3.hxx> + +namespace reportdesign +{ + /** uses the XChild interface to get the section from any child of it. + * + * \param _xReportComponent A report component which is a child of the section. + * \return The section where this report component resists in. + */ + css::uno::Reference< css::report::XSection> lcl_getSection(const css::uno::Reference< css::uno::XInterface>& _xReportComponent); + + /** throws an illegal argument exception. The message text is the resource RID_STR_ERROR_WRONG_ARGUMENT + the type as reference. + * + * \param _sTypeName The reference where to look for the correct values. + * \param ExceptionContext_ The exception context. + * \param ArgumentPosition_ The argument position. + */ + void throwIllegallArgumentException(std::u16string_view _sTypeName + ,const css::uno::Reference< css::uno::XInterface >& ExceptionContext_ + ,sal_Int16 ArgumentPosition_); + + /** clones the given object + * + * \param _xReportComponent the object to be cloned + * \param _xFactory the factory to create the clone + * \param _sServiceName the service of the to be cloned object + * \return the clone + */ + css::uno::Reference< css::util::XCloneable > cloneObject( + const css::uno::Reference< css::report::XReportComponent>& _xReportComponent + ,const css::uno::Reference< css::lang::XMultiServiceFactory>& _xFactory + ,const OUString& _sServiceName); + + class OShapeHelper + { + public: + template<typename T> static void setSize(const css::awt::Size& aSize,T* _pShape) + { + OSL_ENSURE(aSize.Width >= 0 && aSize.Height >= 0,"Illegal width or height!"); + + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + if ( _pShape->m_aProps.aComponent.m_xShape.is() ) + { + css::awt::Size aOldSize = _pShape->m_aProps.aComponent.m_xShape->getSize(); + if ( aOldSize.Height != aSize.Height || aOldSize.Width != aSize.Width ) + { + _pShape->m_aProps.aComponent.m_nWidth = aOldSize.Width; + _pShape->m_aProps.aComponent.m_nHeight = aOldSize.Height; + _pShape->m_aProps.aComponent.m_xShape->setSize(aSize); + } + } + _pShape->set(PROPERTY_WIDTH,aSize.Width,_pShape->m_aProps.aComponent.m_nWidth); + _pShape->set(PROPERTY_HEIGHT,aSize.Height,_pShape->m_aProps.aComponent.m_nHeight); + } + template<typename T> static css::awt::Size getSize( T* _pShape ) + { + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + if ( _pShape->m_aProps.aComponent.m_xShape.is() ) + { + css::awt::Size aSize = _pShape->m_aProps.aComponent.m_xShape->getSize(); + OSL_ENSURE(aSize.Width >= 0 && aSize.Height >= 0,"Illegal width or height!"); + return aSize; + } + return css::awt::Size(_pShape->m_aProps.aComponent.m_nWidth,_pShape->m_aProps.aComponent.m_nHeight); + } + + template<typename T> static void setPosition( const css::awt::Point& _aPosition ,T* _pShape) + { + // we know it is not allowed that the position in smaller 0, but in NbcMove() it will handled right. + // only at 'Undo' it is possible to short set the position smaller 0 + // OSL_ENSURE(_aPosition.X >= 0 && _aPosition.Y >= 0,"set to Illegal position!"); + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + css::awt::Point aOldPos; + aOldPos.X = _pShape->m_aProps.aComponent.m_nPosX; + aOldPos.Y = _pShape->m_aProps.aComponent.m_nPosY; + + css::awt::Point aPosition(_aPosition); + if ( _pShape->m_aProps.aComponent.m_xShape.is() ) + { + aOldPos = _pShape->m_aProps.aComponent.m_xShape->getPosition(); + if ( aOldPos.X != aPosition.X || aOldPos.Y != aPosition.Y ) + { + _pShape->m_aProps.aComponent.m_nPosX = aOldPos.X; + _pShape->m_aProps.aComponent.m_nPosY = aOldPos.Y; + _pShape->m_aProps.aComponent.m_xShape->setPosition(aPosition); + } + } + _pShape->set(PROPERTY_POSITIONX,aPosition.X,aOldPos.X); + _pShape->set(PROPERTY_POSITIONY,aPosition.Y,aOldPos.Y); + } + template<typename T> static css::awt::Point getPosition(T* _pShape) + { + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + if ( _pShape->m_aProps.aComponent.m_xShape.is() ) + { + css::awt::Point aPosition = _pShape->m_aProps.aComponent.m_xShape->getPosition(); + return aPosition; + } + return css::awt::Point(_pShape->m_aProps.aComponent.m_nPosX,_pShape->m_aProps.aComponent.m_nPosY); + } + template<typename T> static void setParent( const css::uno::Reference< css::uno::XInterface >& Parent, T* _pShape) + { + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + _pShape->m_aProps.aComponent.m_xParent = css::uno::Reference< css::container::XChild >(Parent,css::uno::UNO_QUERY); + css::uno::Reference< css::container::XChild > xChild; + comphelper::query_aggregation(_pShape->m_aProps.aComponent.m_xProxy,xChild); + if ( xChild.is() ) + xChild->setParent(Parent); + } + template<typename T> static css::uno::Reference< css::uno::XInterface > getParent( T* _pShape ) + { + ::osl::MutexGuard aGuard(_pShape->m_aMutex); + css::uno::Reference< css::container::XChild > xChild; + comphelper::query_aggregation(_pShape->m_aProps.aComponent.m_xProxy,xChild); + if ( xChild.is() ) + return xChild->getParent(); + return _pShape->m_aProps.aComponent.m_xParent; + } + }; + +} // namespace reportdesign + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_TOOLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/inc/conditionupdater.hxx b/reportdesign/source/core/inc/conditionupdater.hxx new file mode 100644 index 000000000..8102f6766 --- /dev/null +++ b/reportdesign/source/core/inc/conditionupdater.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_CONDITIONUPDATER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_CONDITIONUPDATER_HXX + +#include <conditionalexpression.hxx> + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/report/XReportControlModel.hpp> + + +namespace rptui +{ + + class ConditionUpdater + { + public: + ConditionUpdater(); + ~ConditionUpdater(); + ConditionUpdater(const ConditionUpdater&) = delete; + ConditionUpdater& operator=(const ConditionUpdater&) = delete; + + /// notifies the object about the change of a property value, somewhere in the report definition + void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ); + + private: + /// does late initializations, return whether or not successful + void impl_lateInit_nothrow(); + + void impl_adjustFormatConditions_nothrow( + const css::uno::Reference< css::report::XReportControlModel >& _rxRptControlModel, + const OUString& _rOldDataSource, + const OUString& _rNewDataSource + ); + + private: + ConditionalExpressions m_aConditionalExpressions; + }; + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_INC_CONDITIONUPDATER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/misc/conditionalexpression.cxx b/reportdesign/source/core/misc/conditionalexpression.cxx new file mode 100644 index 000000000..0fe6dbb40 --- /dev/null +++ b/reportdesign/source/core/misc/conditionalexpression.cxx @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <conditionalexpression.hxx> + +#include <o3tl/safeint.hxx> +#include <osl/diagnose.h> + + +namespace rptui +{ + + // = ConditionalExpression + + + ConditionalExpression::ConditionalExpression( const char* _pAsciiPattern ) + :m_sPattern( OUString::createFromAscii( _pAsciiPattern ) ) + { + } + + + OUString ConditionalExpression::assembleExpression( const OUString& _rFieldDataSource, const OUString& _rLHS, const OUString& _rRHS ) const + { + OUString sExpression( m_sPattern ); + + sal_Int32 nPatternIndex = sExpression.indexOf( '$' ); + while ( nPatternIndex > -1 ) + { + const OUString* pReplace = nullptr; + switch ( sExpression[ nPatternIndex + 1 ] ) + { + case '$': pReplace = &_rFieldDataSource; break; + case '1': pReplace = &_rLHS; break; + case '2': pReplace = &_rRHS; break; + default: break; + } + + if ( pReplace == nullptr ) + { + OSL_FAIL( "ConditionalExpression::assembleExpression: illegal pattern!" ); + break; + } + + sExpression = sExpression.replaceAt( nPatternIndex, 2, *pReplace ); + nPatternIndex = sExpression.indexOf( '$', nPatternIndex + pReplace->getLength() + 1 ); + } + return sExpression; + } + + + bool ConditionalExpression::matchExpression( const OUString& _rExpression, const OUString& _rFieldDataSource, OUString& _out_rLHS, OUString& _out_rRHS ) const + { + // if we had regular expression, the matching would be pretty easy ... + // just replace $1 and $2 in the pattern with (.*), and then get them with \1 resp. \2. + // Unfortunately, we don't have such a regexp engine ... + + // Okay, let's start with replacing all $$ in our pattern with the actual field data source + OUString sMatchExpression( m_sPattern ); + static const OUStringLiteral sFieldDataPattern( u"$$" ); + sal_Int32 nIndex( sMatchExpression.indexOf( sFieldDataPattern ) ); + while ( nIndex != -1 ) + { + sMatchExpression = sMatchExpression.replaceAt( nIndex, sFieldDataPattern.getLength(), _rFieldDataSource ); + nIndex = sMatchExpression.indexOf( sFieldDataPattern, nIndex + _rFieldDataSource.getLength() ); + } + + static const OUStringLiteral sLHSPattern( u"$1" ); + static const OUStringLiteral sRHSPattern( u"$2" ); + sal_Int32 nLHSIndex( sMatchExpression.indexOf( sLHSPattern ) ); + sal_Int32 nRHSIndex( sMatchExpression.indexOf( sRHSPattern ) ); + + // now we should have at most one occurrence of $1 and $2, resp. + OSL_ENSURE( sMatchExpression.indexOf( sLHSPattern, nLHSIndex + 1 ) == -1, + "ConditionalExpression::matchExpression: unsupported pattern (more than one LHS occurrence)!" ); + OSL_ENSURE( sMatchExpression.indexOf( sRHSPattern, nRHSIndex + 1 ) == -1, + "ConditionalExpression::matchExpression: unsupported pattern (more than one RHS occurrence)!" ); + // Also, an LHS must be present, and precede the RHS (if present) + OSL_ENSURE( ( nLHSIndex != -1 ) && ( ( nLHSIndex < nRHSIndex ) || ( nRHSIndex == -1 ) ), + "ConditionalExpression::matchExpression: no LHS, or an RHS preceding the LHS - this is not supported!" ); + + // up to the occurrence of the LHS (which must exist, see above), the two expressions + // must be identical + if ( _rExpression.getLength() < nLHSIndex ) + return false; + const std::u16string_view sExprPart1( _rExpression.subView( 0, nLHSIndex ) ); + const std::u16string_view sMatchExprPart1( sMatchExpression.subView( 0, nLHSIndex ) ); + if ( sExprPart1 != sMatchExprPart1 ) + // the left-most expression parts do not match + return false; + + // after the occurrence of the RHS (or the LHS, if there is no RHS), the two expressions + // must be identical, too + bool bHaveRHS( nRHSIndex != -1 ); + sal_Int32 nRightMostIndex( bHaveRHS ? nRHSIndex : nLHSIndex ); + const std::u16string_view sMatchExprPart3( sMatchExpression.subView( nRightMostIndex + 2 ) ); + if ( o3tl::make_unsigned(_rExpression.getLength()) < sMatchExprPart3.size() ) + // the expression is not even long enough to hold the right-most part of the match expression + return false; + const std::u16string_view sExprPart3( _rExpression.subView( _rExpression.getLength() - sMatchExprPart3.size() ) ); + if ( sExprPart3 != sMatchExprPart3 ) + // the right-most expression parts do not match + return false; + + // if we don't have an RHS, we're done + if ( !bHaveRHS ) + { + _out_rLHS = _rExpression.copy( sExprPart1.size(), _rExpression.getLength() - sExprPart1.size() - sExprPart3.size() ); + return true; + } + + // strip the match expression by its right-most and left-most part, and by the placeholders $1 and $2 + sal_Int32 nMatchExprPart2Start( nLHSIndex + sLHSPattern.getLength() ); + std::u16string_view sMatchExprPart2 = sMatchExpression.subView( + nMatchExprPart2Start, + sMatchExpression.getLength() - nMatchExprPart2Start - sMatchExprPart3.size() - 2 + ); + // strip the expression by its left-most and right-most part + const std::u16string_view sExpression( _rExpression.subView( + sExprPart1.size(), + _rExpression.getLength() - sExprPart1.size() - sExprPart3.size() + ) ); + + size_t nPart2Index = sExpression.find( sMatchExprPart2 ); + if ( nPart2Index == std::u16string_view::npos ) + // the "middle" part of the match expression does not exist in the expression at all + return false; + + OSL_ENSURE( sExpression.find( sMatchExprPart2, nPart2Index + 1 ) == std::u16string_view::npos, + "ConditionalExpression::matchExpression: ambiguous matching!" ); + // if this fires, then we're lost: The middle part exists two times in the expression, + // so we cannot reliably determine what's the LHS and what's the RHS. + // Well, the whole mechanism is flawed, anyway: + // Encoding the field content in the conditional expression will break as soon + // as somebody + // - assigns a Data Field to a control + // - creates a conditional format expression for the control + // - assigns another Data Field to the control + // - opens the Conditional Format Dialog, again + // Here, at the latest, you can see that we need another mechanism, anyway, which does not + // rely on those strange expression building/matching + + _out_rLHS = sExpression.substr( 0, nPart2Index ); + _out_rRHS = sExpression.substr( nPart2Index + sMatchExprPart2.size() ); + + return true; + } + + + // = ConditionalExpressionFactory + + + size_t ConditionalExpressionFactory::getKnownConditionalExpressions( ConditionalExpressions& _out_rCondExp ) + { + ConditionalExpressions().swap(_out_rCondExp); + + _out_rCondExp[ eBetween ] = std::make_shared<ConditionalExpression>( "AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) )" ); + _out_rCondExp[ eNotBetween ] = std::make_shared<ConditionalExpression>( "NOT( AND( ( $$ ) >= ( $1 ); ( $$ ) <= ( $2 ) ) )" ); + _out_rCondExp[ eEqualTo ] = std::make_shared<ConditionalExpression>( "( $$ ) = ( $1 )" ); + _out_rCondExp[ eNotEqualTo ] = std::make_shared<ConditionalExpression>( "( $$ ) <> ( $1 )" ); + _out_rCondExp[ eGreaterThan ] = std::make_shared<ConditionalExpression>( "( $$ ) > ( $1 )" ); + _out_rCondExp[ eLessThan ] = std::make_shared<ConditionalExpression>( "( $$ ) < ( $1 )" ); + _out_rCondExp[ eGreaterOrEqual ] = std::make_shared<ConditionalExpression>( "( $$ ) >= ( $1 )" ); + _out_rCondExp[ eLessOrEqual ] = std::make_shared<ConditionalExpression>( "( $$ ) <= ( $1 )" ); + + return _out_rCondExp.size(); + } + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/misc/conditionupdater.cxx b/reportdesign/source/core/misc/conditionupdater.cxx new file mode 100644 index 000000000..428c3b3e7 --- /dev/null +++ b/reportdesign/source/core/misc/conditionupdater.cxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <conditionupdater.hxx> +#include <reportformula.hxx> + +#include <com/sun/star/report/XFormatCondition.hpp> + +#include <tools/diagnose_ex.h> + + +namespace rptui +{ + + + using ::com::sun::star::beans::PropertyChangeEvent; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::report::XReportControlModel; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::report::XFormatCondition; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + + + //= ConditionUpdater + + + ConditionUpdater::ConditionUpdater() + { + } + + + ConditionUpdater::~ConditionUpdater() + { + } + + + void ConditionUpdater::notifyPropertyChange( const PropertyChangeEvent& _rEvent ) + { + impl_lateInit_nothrow(); + + Reference< XReportControlModel > xRptControlModel( _rEvent.Source, UNO_QUERY ); + if ( xRptControlModel.is() && _rEvent.PropertyName == "DataField" ) + { + OUString sOldDataSource, sNewDataSource; + OSL_VERIFY( _rEvent.OldValue >>= sOldDataSource ); + OSL_VERIFY( _rEvent.NewValue >>= sNewDataSource ); + impl_adjustFormatConditions_nothrow( xRptControlModel, sOldDataSource, sNewDataSource ); + } + } + + + void ConditionUpdater::impl_lateInit_nothrow() + { + if ( !m_aConditionalExpressions.empty() ) + return; + + ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions ); + } + + + void ConditionUpdater::impl_adjustFormatConditions_nothrow( const Reference< XReportControlModel >& _rxRptControlModel, + const OUString& _rOldDataSource, const OUString& _rNewDataSource ) + { + try + { + ReportFormula aOldContentFormula( _rOldDataSource ); + OUString sOldUnprefixed( aOldContentFormula.getBracketedFieldOrExpression() ); + ReportFormula aNewContentFormula( _rNewDataSource ); + OUString sNewUnprefixed( aNewContentFormula.getBracketedFieldOrExpression() ); + + sal_Int32 nCount( _rxRptControlModel->getCount() ); + Reference< XFormatCondition > xFormatCondition; + OUString sFormulaExpression, sLHS, sRHS; + for ( sal_Int32 i=0; i<nCount; ++i ) + { + xFormatCondition.set( _rxRptControlModel->getByIndex( i ), UNO_QUERY_THROW ); + sFormulaExpression = ReportFormula(xFormatCondition->getFormula()).getExpression(); + + for (const auto& rEntry : m_aConditionalExpressions) + { + if ( !rEntry.second->matchExpression( sFormulaExpression, sOldUnprefixed, sLHS, sRHS ) ) + continue; + + // the expression matches -> translate it to the new data source of the report control model + sFormulaExpression = rEntry.second->assembleExpression( sNewUnprefixed, sLHS, sRHS ); + ReportFormula aFormula(ReportFormula(ReportFormula::Expression, sFormulaExpression)); + xFormatCondition->setFormula(aFormula.getCompleteFormula()); + break; + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/misc/reportformula.cxx b/reportdesign/source/core/misc/reportformula.cxx new file mode 100644 index 000000000..cd6ae4df5 --- /dev/null +++ b/reportdesign/source/core/misc/reportformula.cxx @@ -0,0 +1,124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <reportformula.hxx> + +#include <rtl/ustrbuf.hxx> + + +namespace rptui +{ + namespace + { + + const char sExpressionPrefix[] = "rpt:"; + const char sFieldPrefix[] = "field:"; + } + + + //= ReportFormula + + + ReportFormula::ReportFormula( const OUString& _rFormula ) + :m_eType( Invalid ) + { + m_sCompleteFormula = _rFormula; + + // is it an ordinary expression? + if ( m_sCompleteFormula.startsWith( sExpressionPrefix, &m_sUndecoratedContent ) ) + { + m_eType = Expression; + return; + } + + /// does it refer to a field? + if ( m_sCompleteFormula.startsWith( sFieldPrefix ) ) + { + sal_Int32 nPrefixLen = strlen(sFieldPrefix); + if ( ( m_sCompleteFormula.getLength() >= nPrefixLen + 2 ) + && ( m_sCompleteFormula[ nPrefixLen ] == '[' ) + && ( m_sCompleteFormula[ m_sCompleteFormula.getLength() - 1 ] == ']' ) + ) + { + m_eType = Field; + m_sUndecoratedContent = m_sCompleteFormula.copy( nPrefixLen + 1, m_sCompleteFormula.getLength() - nPrefixLen - 2 ); + return; + } + } + + m_eType = Invalid; + } + + + ReportFormula::ReportFormula( const BindType _eType, const OUString& _rFieldOrExpression ) + :m_eType( _eType ) + { + switch ( m_eType ) + { + case Expression: + { + if ( _rFieldOrExpression.startsWith( sExpressionPrefix ) ) + m_sCompleteFormula = _rFieldOrExpression; + else + m_sCompleteFormula = sExpressionPrefix + _rFieldOrExpression; + } + break; + + case Field: + { + m_sCompleteFormula = sFieldPrefix + OUString::Concat(u"[") + _rFieldOrExpression + "]"; + } + break; + default: + OSL_FAIL( "ReportFormula::ReportFormula: illegal bind type!" ); + return; + } + + m_sUndecoratedContent = _rFieldOrExpression; + } + + ReportFormula::~ReportFormula() + { + } + + OUString ReportFormula::getBracketedFieldOrExpression() const + { + bool bIsField = ( getType() == Field ); + OUStringBuffer aFieldContent; + if ( bIsField ) + aFieldContent.append( "[" ); + aFieldContent.append( getUndecoratedContent() ); + if ( bIsField ) + aFieldContent.append( "]" ); + + return aFieldContent.makeStringAndClear(); + } + + bool ReportFormula::isValid() const { return getType() != Invalid; } + + OUString ReportFormula::getEqualUndecoratedContent() const + { + return "=" + getUndecoratedContent(); + } + + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/resource/core_resource.cxx b/reportdesign/source/core/resource/core_resource.cxx new file mode 100644 index 000000000..e11d536dc --- /dev/null +++ b/reportdesign/source/core/resource/core_resource.cxx @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <core_resource.hxx> + +OUString RptResId(TranslateId aId) { return Translate::get(aId, Translate::Create("rpt")); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/PropertyForward.cxx b/reportdesign/source/core/sdr/PropertyForward.cxx new file mode 100644 index 000000000..394edfc12 --- /dev/null +++ b/reportdesign/source/core/sdr/PropertyForward.cxx @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <PropertyForward.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <comphelper/property.hxx> +#include <tools/diagnose_ex.h> +#include <strings.hxx> + +namespace rptui +{ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + +OPropertyMediator::OPropertyMediator(const Reference< XPropertySet>& _xSource + ,const Reference< XPropertySet>& _xDest + ,TPropertyNamePair&& _aNameMap + ,bool _bReverse) + : OPropertyForward_Base(m_aMutex) + ,m_aNameMap(std::move(_aNameMap)) + ,m_xSource(_xSource) + ,m_xDest(_xDest) + ,m_bInChange(false) +{ + osl_atomic_increment(&m_refCount); + OSL_ENSURE(m_xDest.is(),"Dest is NULL!"); + OSL_ENSURE(m_xSource.is(),"Source is NULL!"); + if ( m_xDest.is() && m_xSource.is() ) + { + try + { + m_xDestInfo = m_xDest->getPropertySetInfo(); + m_xSourceInfo = m_xSource->getPropertySetInfo(); + if ( _bReverse ) + { + ::comphelper::copyProperties(m_xDest,m_xSource); + for (const auto& [rName, rPropConv] : m_aNameMap) + { + Property aProp = m_xSourceInfo->getPropertyByName(rName); + if (0 == (aProp.Attributes & PropertyAttribute::READONLY)) + { + Any aValue = _xDest->getPropertyValue(rPropConv.first); + if ( 0 != (aProp.Attributes & PropertyAttribute::MAYBEVOID) || aValue.hasValue() ) + _xSource->setPropertyValue(rName, rPropConv.second->operator()(rPropConv.first, aValue)); + } + } + } + else + { + ::comphelper::copyProperties(m_xSource,m_xDest); + for (const auto& [rName, rPropConv] : m_aNameMap) + _xDest->setPropertyValue(rPropConv.first, rPropConv.second->operator()(rPropConv.first, _xSource->getPropertyValue(rName))); + } + startListening(); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + osl_atomic_decrement(&m_refCount); +} + +OPropertyMediator::~OPropertyMediator() +{ +} + +void SAL_CALL OPropertyMediator::propertyChange( const PropertyChangeEvent& evt ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_bInChange ) + return; + + m_bInChange = true; + try + { + bool bDest = (evt.Source == m_xDest); + Reference<XPropertySet> xProp = bDest ? m_xSource : m_xDest; + Reference<XPropertySetInfo> xPropInfo = bDest ? m_xSourceInfo : m_xDestInfo; + if ( xProp.is() && xPropInfo.is() ) + { + if ( xPropInfo->hasPropertyByName(evt.PropertyName) ) + xProp->setPropertyValue(evt.PropertyName,evt.NewValue); + else + { + TPropertyNamePair::const_iterator aFind = m_aNameMap.find(evt.PropertyName); + OUString sPropName; + if ( aFind != m_aNameMap.end() ) + sPropName = aFind->second.first; + else + { + aFind = ::std::find_if( + m_aNameMap.begin(), + m_aNameMap.end(), + [&evt] (const TPropertyNamePair::value_type& namePair) { + return namePair.second.first == evt.PropertyName; + }); + if ( aFind != m_aNameMap.end() ) + sPropName = aFind->first; + } + if (aFind != m_aNameMap.end() && !sPropName.isEmpty() && xPropInfo->hasPropertyByName(sPropName)) + xProp->setPropertyValue(sPropName,aFind->second.second->operator()(sPropName,evt.NewValue)); + else if ( evt.PropertyName == PROPERTY_CHARFONTNAME + || evt.PropertyName == PROPERTY_CHARFONTSTYLENAME + || evt.PropertyName == PROPERTY_CHARSTRIKEOUT + || evt.PropertyName == PROPERTY_CHARWORDMODE + || evt.PropertyName == PROPERTY_CHARROTATION + || evt.PropertyName == PROPERTY_CHARSCALEWIDTH + || evt.PropertyName == PROPERTY_CHARFONTFAMILY + || evt.PropertyName == PROPERTY_CHARFONTCHARSET + || evt.PropertyName == PROPERTY_CHARFONTPITCH + || evt.PropertyName == PROPERTY_CHARHEIGHT + || evt.PropertyName == PROPERTY_CHARUNDERLINE + || evt.PropertyName == PROPERTY_CHARWEIGHT + || evt.PropertyName == PROPERTY_CHARPOSTURE) + { + xProp->setPropertyValue(PROPERTY_FONTDESCRIPTOR,m_xSource->getPropertyValue(PROPERTY_FONTDESCRIPTOR)); + } + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + m_bInChange = false; +} + +void SAL_CALL OPropertyMediator::disposing( const css::lang::EventObject& /*_rSource*/ ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + disposing(); +} + +void SAL_CALL OPropertyMediator::disposing() +{ + stopListening(); + m_xSource.clear(); + m_xSourceInfo.clear(); + m_xDest.clear(); + m_xDestInfo.clear(); +} + +void OPropertyMediator::stopListening() +{ + if ( m_xSource.is() ) + m_xSource->removePropertyChangeListener(OUString(), this); + if ( m_xDest.is() ) + m_xDest->removePropertyChangeListener(OUString(), this); +} + +void OPropertyMediator::startListening() +{ + if ( m_xSource.is() ) + m_xSource->addPropertyChangeListener(OUString(), this); + if ( m_xDest.is() ) + m_xDest->addPropertyChangeListener(OUString(), this); +} + + +} // namespace dbaccess + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/ReportDrawPage.cxx b/reportdesign/source/core/sdr/ReportDrawPage.cxx new file mode 100644 index 000000000..b89c3dac2 --- /dev/null +++ b/reportdesign/source/core/sdr/ReportDrawPage.cxx @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportDrawPage.hxx> +#include <RptObject.hxx> +#include <RptModel.hxx> +#include <strings.hxx> +#include <comphelper/mimeconfighelper.hxx> +#include <comphelper/embeddedobjectcontainer.hxx> + +#include <svx/svdmodel.hxx> +#include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <tools/diagnose_ex.h> +#include <svx/unoshape.hxx> +#include <svx/svdpage.hxx> + +namespace reportdesign +{ + using namespace ::com::sun::star; + using namespace rptui; + +OReportDrawPage::OReportDrawPage(SdrPage* _pPage + ,const uno::Reference< report::XSection >& _xSection) +: SvxDrawPage(_pPage) +,m_xSection(_xSection) +{ +} + +SdrObject* OReportDrawPage::CreateSdrObject_(const uno::Reference< drawing::XShape > & xDescr) +{ + uno::Reference< report::XReportComponent> xReportComponent(xDescr,uno::UNO_QUERY); + if ( xReportComponent.is() ) + { + return OObjectBase::createObject( + GetSdrPage()->getSdrModelFromSdrPage(), + xReportComponent); + } + + return SvxDrawPage::CreateSdrObject_( xDescr ); +} + +uno::Reference< drawing::XShape > OReportDrawPage::CreateShape( SdrObject *pObj ) const +{ + OObjectBase* pBaseObj = dynamic_cast<OObjectBase*>(pObj); + if ( !pBaseObj ) + return SvxDrawPage::CreateShape( pObj ); + + uno::Reference< report::XSection> xSection = m_xSection; + uno::Reference< lang::XMultiServiceFactory> xFactory; + if ( xSection.is() ) + xFactory.set(xSection->getReportDefinition(),uno::UNO_QUERY); + uno::Reference< drawing::XShape > xRet; + uno::Reference< drawing::XShape > xShape; + if ( xFactory.is() ) + { + bool bChangeOrientation = false; + const OUString& sServiceName = pBaseObj->getServiceName(); + OSL_ENSURE(!sServiceName.isEmpty(),"No Service Name given!"); + + if (dynamic_cast< const OUnoObject* >(pObj) != nullptr) + { + OUnoObject& rUnoObj = dynamic_cast<OUnoObject&>(*pObj); + if (rUnoObj.GetObjIdentifier() == SdrObjKind::ReportDesignFixedText) + { + uno::Reference<beans::XPropertySet> xControlModel(rUnoObj.GetUnoControlModel(),uno::UNO_QUERY); + if ( xControlModel.is() ) + xControlModel->setPropertyValue( PROPERTY_MULTILINE,uno::Any(true)); + } + else + bChangeOrientation = rUnoObj.GetObjIdentifier() == SdrObjKind::ReportDesignHorizontalFixedLine; + rtl::Reference<SvxShapeControl> pShape = new SvxShapeControl( pObj ); + xShape = static_cast<SvxShape_UnoImplHelper *>(pShape.get()); + pShape->setShapeKind(pObj->GetObjIdentifier()); + } + else if (dynamic_cast< const OCustomShape* >(pObj) != nullptr) + { + rtl::Reference<SvxCustomShape> pShape = new SvxCustomShape( pObj ); + xShape = pShape; + pShape->setShapeKind(pObj->GetObjIdentifier()); + } + else if (dynamic_cast< const SdrOle2Obj* >(pObj) != nullptr) + { + SdrOle2Obj& rOle2Obj = dynamic_cast<SdrOle2Obj&>(*pObj); + if (!rOle2Obj.GetObjRef().is()) + { + sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; + uno::Reference < embed::XEmbeddedObject > xObj; + OUString sName; + xObj = pObj->getSdrModelFromSdrObject().GetPersist()->getEmbeddedObjectContainer().CreateEmbeddedObject( + ::comphelper::MimeConfigurationHelper::GetSequenceClassIDRepresentation( + u"80243D39-6741-46C5-926E-069164FF87BB"), sName ); + OSL_ENSURE(xObj.is(),"Embedded Object could not be created!"); + + /************************************************** + * The empty OLE object gets a new IPObj + **************************************************/ + pObj->SetEmptyPresObj(false); + rOle2Obj.SetOutlinerParaObject(std::nullopt); + rOle2Obj.SetObjRef(xObj); + rOle2Obj.SetPersistName(sName); + rOle2Obj.SetName(sName); + rOle2Obj.SetAspect(nAspect); + tools::Rectangle aRect = rOle2Obj.GetLogicRect(); + + Size aTmp = aRect.GetSize(); + awt::Size aSz( aTmp.Width(), aTmp.Height() ); + xObj->setVisualAreaSize( nAspect, aSz ); + } + rtl::Reference<SvxOle2Shape> pShape = new SvxOle2Shape( pObj ); + xShape = pShape; + pShape->setShapeKind(pObj->GetObjIdentifier()); + } + + if ( !xShape.is() ) + xShape.set( SvxDrawPage::CreateShape( pObj ) ); + + try + { + OReportModel& rRptModel(static_cast< OReportModel& >(pObj->getSdrModelFromSdrObject())); + xRet.set( rRptModel.createShape(sServiceName,xShape,bChangeOrientation ? 0 : 1), uno::UNO_QUERY_THROW ); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + return xRet; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/ReportUndoFactory.cxx b/reportdesign/source/core/sdr/ReportUndoFactory.cxx new file mode 100644 index 000000000..1c36d836b --- /dev/null +++ b/reportdesign/source/core/sdr/ReportUndoFactory.cxx @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportUndoFactory.hxx> +#include <RptObject.hxx> +#include <UndoActions.hxx> +#include <strings.hrc> + +namespace rptui +{ + using namespace ::com::sun::star; + +static std::unique_ptr<SdrUndoAction> lcl_createUndo(SdrObject& rObject, Action _eAction, TranslateId pCommentId) +{ + OObjectBase* pObj = dynamic_cast<OObjectBase*>(&rObject); + if ( !pObj ) + return nullptr; + uno::Reference< report::XReportComponent> xReportComponent = pObj->getReportComponent(); + uno::Reference< report::XSection> xSection = pObj->getSection(); + uno::Reference< report::XGroup> xGroup = xSection->getGroup(); + if ( xGroup.is() ) + return std::make_unique<OUndoGroupSectionAction>(rObject.getSdrModelFromSdrObject(),_eAction,OGroupHelper::getMemberFunction(xSection),xGroup,xReportComponent,pCommentId); + else + return std::make_unique<OUndoReportSectionAction>(rObject.getSdrModelFromSdrObject(),_eAction,OReportHelper::getMemberFunction(xSection),xSection->getReportDefinition(),xReportComponent,pCommentId); +} + + +OReportUndoFactory::OReportUndoFactory() : m_pUndoFactory(new SdrUndoFactory) +{ +} + +OReportUndoFactory::~OReportUndoFactory() +{ +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoMoveObject( SdrObject& rObject, const Size& rDist ) +{ + return m_pUndoFactory->CreateUndoMoveObject( rObject, rDist ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoGeoObject( SdrObject& rObject ) +{ + return m_pUndoFactory->CreateUndoGeoObject( rObject ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoAttrObject( SdrObject& rObject, bool bStyleSheet1, bool bSaveText ) +{ + return m_pUndoFactory->CreateUndoAttrObject( rObject, bStyleSheet1, bSaveText ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoRemoveObject(SdrObject& rObject) +{ + return m_pUndoFactory->CreateUndoRemoveObject(rObject); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoInsertObject( SdrObject& rObject, bool /*bOrdNumDirect*/ ) +{ + return lcl_createUndo(rObject,rptui::Inserted,RID_STR_UNDO_INSERT_CONTROL); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoDeleteObject( SdrObject& rObject, bool /*bOrdNumDirect*/ ) +{ + return lcl_createUndo(rObject,rptui::Removed,RID_STR_UNDO_DELETE_CONTROL); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoNewObject( SdrObject& rObject, bool /*bOrdNumDirect*/ ) +{ + return lcl_createUndo(rObject,rptui::Inserted,RID_STR_UNDO_INSERT_CONTROL); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoCopyObject( SdrObject& rObject, bool bOrdNumDirect ) +{ + return m_pUndoFactory->CreateUndoCopyObject( rObject, bOrdNumDirect ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoObjectOrdNum( SdrObject& rObject, sal_uInt32 nOldOrdNum1, sal_uInt32 nNewOrdNum1) +{ + return m_pUndoFactory->CreateUndoObjectOrdNum( rObject, nOldOrdNum1, nNewOrdNum1 ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoReplaceObject( SdrObject& rOldObject, SdrObject& rNewObject ) +{ + return m_pUndoFactory->CreateUndoReplaceObject( rOldObject, rNewObject ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoObjectLayerChange( SdrObject& rObject, SdrLayerID aOldLayer, SdrLayerID aNewLayer ) +{ + return m_pUndoFactory->CreateUndoObjectLayerChange( rObject, aOldLayer, aNewLayer ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoObjectSetText( SdrObject& rNewObj, sal_Int32 nText ) +{ + return m_pUndoFactory->CreateUndoObjectSetText( rNewObj, nText ); +} + +// layer +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoNewLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel) +{ + return m_pUndoFactory->CreateUndoNewLayer( nLayerNum, rNewLayerAdmin, rNewModel ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoDeleteLayer(sal_uInt16 nLayerNum, SdrLayerAdmin& rNewLayerAdmin, SdrModel& rNewModel) +{ + return m_pUndoFactory->CreateUndoDeleteLayer( nLayerNum, rNewLayerAdmin, rNewModel ); +} + +// page +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoDeletePage(SdrPage& rPage) +{ + return m_pUndoFactory->CreateUndoDeletePage(rPage); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoNewPage(SdrPage& rPage) +{ + return m_pUndoFactory->CreateUndoNewPage( rPage ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoCopyPage(SdrPage& rPage) +{ + return m_pUndoFactory->CreateUndoCopyPage( rPage ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoSetPageNum(SdrPage& rNewPg, sal_uInt16 nOldPageNum1, sal_uInt16 nNewPageNum1) +{ + return m_pUndoFactory->CreateUndoSetPageNum( rNewPg, nOldPageNum1, nNewPageNum1 ); +} + // master page +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoPageRemoveMasterPage(SdrPage& rChangedPage) +{ + return m_pUndoFactory->CreateUndoPageRemoveMasterPage( rChangedPage ); +} + +std::unique_ptr<SdrUndoAction> OReportUndoFactory::CreateUndoPageChangeMasterPage(SdrPage& rChangedPage) +{ + return m_pUndoFactory->CreateUndoPageChangeMasterPage(rChangedPage); +} + + +} //rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/RptModel.cxx b/reportdesign/source/core/sdr/RptModel.cxx new file mode 100644 index 000000000..e7fa935f8 --- /dev/null +++ b/reportdesign/source/core/sdr/RptModel.cxx @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <RptModel.hxx> +#include <RptPage.hxx> +#include <dbaccess/dbsubcomponentcontroller.hxx> +#include <vcl/svapp.hxx> + +#include <UndoEnv.hxx> +#include <ReportUndoFactory.hxx> +#include <ReportDefinition.hxx> + +#include <RptDef.hxx> +#include <strings.hxx> +#include <FixedLine.hxx> +#include <FormattedField.hxx> +#include <FixedText.hxx> +#include <ImageControl.hxx> +#include <Shape.hxx> + +namespace rptui +{ +using namespace reportdesign; +using namespace com::sun::star; + + +OReportModel::OReportModel(::reportdesign::OReportDefinition* _pReportDefinition) +: SdrModel( + nullptr, + _pReportDefinition) + ,m_pController(nullptr) + ,m_pReportDefinition(_pReportDefinition) +{ + m_xUndoEnv = new OXUndoEnvironment(*this); + SetSdrUndoFactory(new OReportUndoFactory); +} + + +OReportModel::~OReportModel() +{ + detachController(); +} + +void OReportModel::detachController() +{ + m_pReportDefinition = nullptr; + m_pController = nullptr; + m_xUndoEnv->EndListening( *this ); + ClearUndoBuffer(); + m_xUndoEnv->Clear(OXUndoEnvironment::Accessor()); +} + +rtl::Reference<SdrPage> OReportModel::AllocPage(bool /*bMasterPage*/) +{ + OSL_FAIL("Who called me!"); + return nullptr; +} + + +void OReportModel::SetChanged( bool bChanged ) +{ + SdrModel::SetChanged( bChanged ); + SetModified( bChanged ); +} + + +void OReportModel::SetModified(bool _bModified) +{ + if ( m_pController ) + m_pController->setModified(_bModified); +} + +rtl::Reference<SdrPage> OReportModel::RemovePage(sal_uInt16 nPgNum) +{ + rtl::Reference<OReportPage> pPage = dynamic_cast<OReportPage*>(SdrModel::RemovePage(nPgNum).get()); + return pPage; +} + +OReportPage* OReportModel::createNewPage(const uno::Reference< report::XSection >& _xSection) +{ + SolarMutexGuard aSolarGuard; + rtl::Reference<OReportPage> pPage = new OReportPage( *this ,_xSection); + InsertPage(pPage.get()); + m_xUndoEnv->AddSection(_xSection); + return pPage.get(); +} + +OReportPage* OReportModel::getPage(const uno::Reference< report::XSection >& _xSection) +{ + OReportPage* pPage = nullptr; + sal_uInt16 nCount = GetPageCount(); + for (sal_uInt16 i = 0; i < nCount && !pPage ; ++i) + { + OReportPage* pRptPage = dynamic_cast<OReportPage*>( GetPage(i) ); + if ( pRptPage && pRptPage->getSection() == _xSection ) + pPage = pRptPage; + } + return pPage; +} + +SvxNumType OReportModel::GetPageNumType() const +{ + uno::Reference< report::XReportDefinition > xReportDefinition( getReportDefinition() ); + if ( xReportDefinition.is() ) + return static_cast<SvxNumType>(getStyleProperty<sal_Int16>(xReportDefinition,PROPERTY_NUMBERINGTYPE)); + return SVX_NUM_ARABIC; +} + + +uno::Reference< report::XReportDefinition > OReportModel::getReportDefinition() const +{ + uno::Reference< report::XReportDefinition > xReportDefinition = m_pReportDefinition; + OSL_ENSURE( xReportDefinition.is(), "OReportModel::getReportDefinition: invalid model at our controller!" ); + return xReportDefinition; +} + +uno::Reference< uno::XInterface > OReportModel::createUnoModel() +{ + return uno::Reference< uno::XInterface >(getReportDefinition(),uno::UNO_QUERY); +} + +uno::Reference< uno::XInterface > OReportModel::createShape(const OUString& aServiceSpecifier,uno::Reference< drawing::XShape >& _rShape,sal_Int32 nOrientation) +{ + uno::Reference< uno::XInterface > xRet; + if ( _rShape.is() ) + { + if ( aServiceSpecifier == SERVICE_FORMATTEDFIELD ) + { + uno::Reference<report::XFormattedField> xProp = new OFormattedField(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape); + xRet = xProp; + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + xProp->setPropertyValue( PROPERTY_FORMATSSUPPLIER, uno::Any(uno::Reference< util::XNumberFormatsSupplier >(*m_pReportDefinition,uno::UNO_QUERY)) ); + } + else if ( aServiceSpecifier == SERVICE_FIXEDTEXT) + { + xRet = static_cast<cppu::OWeakObject*>(new OFixedText(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape)); + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + } + else if ( aServiceSpecifier == SERVICE_FIXEDLINE) + { + xRet = static_cast<cppu::OWeakObject*>(new OFixedLine(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape,nOrientation)); + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + } + else if ( aServiceSpecifier == SERVICE_IMAGECONTROL ) + { + xRet = static_cast<cppu::OWeakObject*>(new OImageControl(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape)); + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + } + else if ( aServiceSpecifier == SERVICE_REPORTDEFINITION ) + { + xRet = static_cast<cppu::OWeakObject*>(new OReportDefinition(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape)); + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + } + else if ( _rShape.is() ) + { + xRet = static_cast<cppu::OWeakObject*>(new OShape(m_pReportDefinition->getContext(),m_pReportDefinition,_rShape,aServiceSpecifier)); + if ( _rShape.is() ) + throw uno::Exception("no shape", nullptr); + } + } + return xRet; +} + +} //rptui + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/RptObject.cxx b/reportdesign/source/core/sdr/RptObject.cxx new file mode 100644 index 000000000..1972e892e --- /dev/null +++ b/reportdesign/source/core/sdr/RptObject.cxx @@ -0,0 +1,1219 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <RptObject.hxx> +#include <algorithm> + +#include <RptDef.hxx> +#include <svx/unoshape.hxx> +#include <RptModel.hxx> +#include <RptObjectListener.hxx> +#include <RptPage.hxx> + +#include <strings.hxx> +#include <svtools/embedhlp.hxx> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/awt/TextAlign.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/embed/XComponentSupplier.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <com/sun/star/chart/ChartDataRowSource.hpp> +#include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/report/XFormattedField.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/property.hxx> +#include <svx/svdundo.hxx> +#include <tools/diagnose_ex.h> +#include <PropertyForward.hxx> +#include <UndoEnv.hxx> + +namespace rptui +{ + +using namespace ::com::sun::star; +using namespace uno; +using namespace beans; +using namespace reportdesign; +using namespace container; +using namespace report; + +SdrObjKind OObjectBase::getObjectType(const uno::Reference< report::XReportComponent>& _xComponent) +{ + uno::Reference< lang::XServiceInfo > xServiceInfo( _xComponent , uno::UNO_QUERY ); + OSL_ENSURE(xServiceInfo.is(),"Who deletes the XServiceInfo interface!"); + if ( !xServiceInfo ) + return SdrObjKind::NONE; + + if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT )) + return SdrObjKind::ReportDesignFixedText; + if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE )) + { + uno::Reference< report::XFixedLine> xFixedLine(_xComponent,uno::UNO_QUERY); + return xFixedLine->getOrientation() ? SdrObjKind::ReportDesignHorizontalFixedLine : SdrObjKind::ReportDesignVerticalFixedLine; + } + if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL)) + return SdrObjKind::ReportDesignImageControl; + if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD )) + return SdrObjKind::ReportDesignFormattedField; + if ( xServiceInfo->supportsService("com.sun.star.drawing.OLE2Shape") ) + return SdrObjKind::OLE2; + if ( xServiceInfo->supportsService( SERVICE_SHAPE )) + return SdrObjKind::CustomShape; + if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) ) + return SdrObjKind::ReportDesignSubReport; + return SdrObjKind::OLE2; +} + +SdrObject* OObjectBase::createObject( + SdrModel& rTargetModel, + const uno::Reference< report::XReportComponent>& _xComponent) +{ + SdrObject* pNewObj = nullptr; + SdrObjKind nType = OObjectBase::getObjectType(_xComponent); + switch( nType ) + { + case SdrObjKind::ReportDesignFixedText: + { + OUnoObject* pUnoObj = new OUnoObject( + rTargetModel, + _xComponent, + OUString("com.sun.star.form.component.FixedText"), + SdrObjKind::ReportDesignFixedText); + pNewObj = pUnoObj; + + uno::Reference<beans::XPropertySet> xControlModel(pUnoObj->GetUnoControlModel(),uno::UNO_QUERY); + if ( xControlModel.is() ) + xControlModel->setPropertyValue( PROPERTY_MULTILINE,uno::Any(true)); + } + break; + case SdrObjKind::ReportDesignImageControl: + pNewObj = new OUnoObject( + rTargetModel, + _xComponent, + OUString("com.sun.star.form.component.DatabaseImageControl"), + SdrObjKind::ReportDesignImageControl); + break; + case SdrObjKind::ReportDesignFormattedField: + pNewObj = new OUnoObject( + rTargetModel, + _xComponent, + OUString("com.sun.star.form.component.FormattedField"), + SdrObjKind::ReportDesignFormattedField); + break; + case SdrObjKind::ReportDesignHorizontalFixedLine: + case SdrObjKind::ReportDesignVerticalFixedLine: + pNewObj = new OUnoObject( + rTargetModel, + _xComponent, + OUString("com.sun.star.awt.UnoControlFixedLineModel"), + nType); + break; + case SdrObjKind::CustomShape: + pNewObj = OCustomShape::Create( + rTargetModel, + _xComponent); + try + { + bool bOpaque = false; + _xComponent->getPropertyValue(PROPERTY_OPAQUE) >>= bOpaque; + pNewObj->NbcSetLayer(bOpaque ? RPT_LAYER_FRONT : RPT_LAYER_BACK); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + break; + case SdrObjKind::ReportDesignSubReport: + case SdrObjKind::OLE2: + pNewObj = OOle2Obj::Create( + rTargetModel, + _xComponent, + nType); + break; + default: + OSL_FAIL("Unknown object id"); + break; + } + + if ( pNewObj ) + pNewObj->SetDoNotInsertIntoPageAutomatically( true ); + + ensureSdrObjectOwnership( _xComponent ); + + return pNewObj; +} + +namespace +{ + class ParaAdjust : public AnyConverter + { + public: + virtual css::uno::Any operator() (const OUString& _sPropertyName,const css::uno::Any& lhs) const override + { + uno::Any aRet; + if (_sPropertyName == PROPERTY_PARAADJUST) + { + sal_Int16 nTextAlign = 0; + lhs >>= nTextAlign; + style::ParagraphAdjust eAdjust; + switch(nTextAlign) + { + case awt::TextAlign::LEFT: + eAdjust = style::ParagraphAdjust_LEFT; + break; + case awt::TextAlign::CENTER: + eAdjust = style::ParagraphAdjust_CENTER; + break; + case awt::TextAlign::RIGHT: + eAdjust = style::ParagraphAdjust_RIGHT; + break; + default: + OSL_FAIL("Illegal text alignment value!"); + break; + } + aRet <<= eAdjust; + } + else + { + sal_Int16 nTextAlign = 0; + sal_Int16 eParagraphAdjust = 0; + lhs >>= eParagraphAdjust; + switch(static_cast<style::ParagraphAdjust>(eParagraphAdjust)) + { + case style::ParagraphAdjust_LEFT: + case style::ParagraphAdjust_BLOCK: + nTextAlign = awt::TextAlign::LEFT; + break; + case style::ParagraphAdjust_CENTER: + nTextAlign = awt::TextAlign::CENTER; + break; + case style::ParagraphAdjust_RIGHT: + nTextAlign = awt::TextAlign::RIGHT; + break; + default: + OSL_FAIL("Illegal text alignment value!"); + break; + } + aRet <<= nTextAlign; + } + return aRet; + } + }; +} + +const TPropertyNamePair& getPropertyNameMap(SdrObjKind _nObjectId) +{ + switch(_nObjectId) + { + case SdrObjKind::ReportDesignImageControl: + { + static TPropertyNamePair s_aNameMap = []() + { + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair tmp; + tmp.emplace(PROPERTY_CONTROLBACKGROUND,TPropertyConverter(PROPERTY_BACKGROUNDCOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDER,TPropertyConverter(PROPERTY_BORDER,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDERCOLOR,TPropertyConverter(PROPERTY_BORDERCOLOR,aNoConverter)); + return tmp; + }(); + return s_aNameMap; + } + + case SdrObjKind::ReportDesignFixedText: + { + static TPropertyNamePair s_aNameMap = []() + { + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair tmp; + tmp.emplace(PROPERTY_CHARCOLOR,TPropertyConverter(PROPERTY_TEXTCOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBACKGROUND,TPropertyConverter(PROPERTY_BACKGROUNDCOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CHARUNDERLINECOLOR,TPropertyConverter(PROPERTY_TEXTLINECOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CHARRELIEF,TPropertyConverter(PROPERTY_FONTRELIEF,aNoConverter)); + tmp.emplace(PROPERTY_CHARFONTHEIGHT,TPropertyConverter(PROPERTY_FONTHEIGHT,aNoConverter)); + tmp.emplace(PROPERTY_CHARSTRIKEOUT,TPropertyConverter(PROPERTY_FONTSTRIKEOUT,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLTEXTEMPHASISMARK,TPropertyConverter(PROPERTY_FONTEMPHASISMARK,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDER,TPropertyConverter(PROPERTY_BORDER,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDERCOLOR,TPropertyConverter(PROPERTY_BORDERCOLOR,aNoConverter)); + + auto aParaAdjust = std::make_shared<ParaAdjust>(); + tmp.emplace(PROPERTY_PARAADJUST,TPropertyConverter(PROPERTY_ALIGN,aParaAdjust)); + return tmp; + }(); + return s_aNameMap; + } + case SdrObjKind::ReportDesignFormattedField: + { + static TPropertyNamePair s_aNameMap = []() + { + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair tmp; + tmp.emplace(PROPERTY_CHARCOLOR,TPropertyConverter(PROPERTY_TEXTCOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBACKGROUND,TPropertyConverter(PROPERTY_BACKGROUNDCOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CHARUNDERLINECOLOR,TPropertyConverter(PROPERTY_TEXTLINECOLOR,aNoConverter)); + tmp.emplace(PROPERTY_CHARRELIEF,TPropertyConverter(PROPERTY_FONTRELIEF,aNoConverter)); + tmp.emplace(PROPERTY_CHARFONTHEIGHT,TPropertyConverter(PROPERTY_FONTHEIGHT,aNoConverter)); + tmp.emplace(PROPERTY_CHARSTRIKEOUT,TPropertyConverter(PROPERTY_FONTSTRIKEOUT,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLTEXTEMPHASISMARK,TPropertyConverter(PROPERTY_FONTEMPHASISMARK,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDER,TPropertyConverter(PROPERTY_BORDER,aNoConverter)); + tmp.emplace(PROPERTY_CONTROLBORDERCOLOR,TPropertyConverter(PROPERTY_BORDERCOLOR,aNoConverter)); + auto aParaAdjust = std::make_shared<ParaAdjust>(); + tmp.emplace(PROPERTY_PARAADJUST,TPropertyConverter(PROPERTY_ALIGN,aParaAdjust)); + return tmp; + }(); + return s_aNameMap; + } + + case SdrObjKind::CustomShape: + { + static TPropertyNamePair s_aNameMap = []() + { + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair tmp; + tmp.emplace(OUString("FillColor"),TPropertyConverter(PROPERTY_CONTROLBACKGROUND,aNoConverter)); + tmp.emplace(PROPERTY_PARAADJUST,TPropertyConverter(PROPERTY_ALIGN,aNoConverter)); + return tmp; + }(); + return s_aNameMap; + } + + default: + break; + } + static TPropertyNamePair s_aEmptyNameMap; + return s_aEmptyNameMap; +} + + +OObjectBase::OObjectBase(const uno::Reference< report::XReportComponent>& _xComponent) +:m_bIsListening(false) +{ + m_xReportComponent = _xComponent; +} + +OObjectBase::OObjectBase(const OUString& _sComponentName) +:m_sComponentName(_sComponentName) +,m_bIsListening(false) +{ +} + +OObjectBase::~OObjectBase() +{ + m_xMediator.clear(); + if ( isListening() ) + EndListening(); + m_xReportComponent.clear(); +} + +uno::Reference< report::XSection> OObjectBase::getSection() const +{ + uno::Reference< report::XSection> xSection; + OReportPage* pPage = dynamic_cast<OReportPage*>(GetImplPage()); + if ( pPage ) + xSection = pPage->getSection(); + return xSection; +} + + +uno::Reference< beans::XPropertySet> OObjectBase::getAwtComponent() +{ + return uno::Reference< beans::XPropertySet>(); +} + +void OObjectBase::StartListening() +{ + OSL_ENSURE(!isListening(), "OUnoObject::StartListening: already listening!"); + + if ( !isListening() && m_xReportComponent.is() ) + { + m_bIsListening = true; + + if ( !m_xPropertyChangeListener.is() ) + { + m_xPropertyChangeListener = new OObjectListener( this ); + // register listener to all properties + m_xReportComponent->addPropertyChangeListener( OUString() , m_xPropertyChangeListener ); + } + } +} + +void OObjectBase::EndListening() +{ + OSL_ENSURE(!m_xReportComponent.is() || isListening(), "OUnoObject::EndListening: not listening currently!"); + + if ( isListening() && m_xReportComponent.is() ) + { + // XPropertyChangeListener + if ( m_xPropertyChangeListener.is() ) + { + // remove listener + try + { + m_xReportComponent->removePropertyChangeListener( OUString() , m_xPropertyChangeListener ); + } + catch(const uno::Exception &) + { + TOOLS_WARN_EXCEPTION( "package", "OObjectBase::EndListening"); + } + } + m_xPropertyChangeListener.clear(); + } + m_bIsListening = false; +} + +void OObjectBase::SetPropsFromRect(const tools::Rectangle& _rRect) +{ + // set properties + OReportPage* pPage = dynamic_cast<OReportPage*>(GetImplPage()); + if ( pPage && !_rRect.IsEmpty() ) + { + const uno::Reference<report::XSection>& xSection = pPage->getSection(); + assert(_rRect.getHeight() >= 0); + const sal_uInt32 newHeight( ::std::max(tools::Long(0), _rRect.getHeight()+_rRect.Top()) ); + if ( xSection.is() && ( newHeight > xSection->getHeight() ) ) + xSection->setHeight( newHeight ); + + // TODO + //pModel->GetRefDevice()->Invalidate(InvalidateFlags::Children); + } +} + +void OObjectBase::_propertyChange( const beans::PropertyChangeEvent& /*evt*/ ) +{ +} + +bool OObjectBase::supportsService( const OUString& _sServiceName ) const +{ + // TODO: cache xServiceInfo as member? + Reference< lang::XServiceInfo > xServiceInfo( m_xReportComponent , UNO_QUERY ); + + if ( xServiceInfo.is() ) + return cppu::supportsService(xServiceInfo.get(), _sServiceName); + else + return false; +} + + +void OObjectBase::ensureSdrObjectOwnership( const uno::Reference< uno::XInterface >& _rxShape ) +{ + // UNDO in the report designer is implemented at the level of the XShapes, not + // at the level of SdrObjects. That is, if an object is removed from the report + // design, then this happens by removing the XShape from the UNO DrawPage, and + // putting this XShape (resp. the ReportComponent which wraps it) into an UNDO + // action. + // Unfortunately, the SvxDrawPage implementation usually deletes SdrObjects + // which are removed from it, which is deadly for us. To prevent this, + // we give the XShape implementation the ownership of the SdrObject, which + // ensures the SvxDrawPage won't delete it. + SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( _rxShape ); + OSL_ENSURE( pShape, "OObjectBase::ensureSdrObjectOwnership: can't access the SvxShape!" ); + if ( pShape ) + { + OSL_ENSURE( !pShape->HasSdrObjectOwnership(), "OObjectBase::ensureSdrObjectOwnership: called twice?" ); + pShape->TakeSdrObjectOwnership(); + } +} + + +uno::Reference< drawing::XShape > OObjectBase::getUnoShapeOf( SdrObject& _rSdrObject ) +{ + uno::Reference< drawing::XShape > xShape( _rSdrObject.getWeakUnoShape() ); + if ( xShape.is() ) + return xShape; + + xShape = _rSdrObject.SdrObject::getUnoShape(); + if ( !xShape.is() ) + return xShape; + + ensureSdrObjectOwnership( xShape ); + + m_xKeepShapeAlive = xShape; + return xShape; +} + +OCustomShape::OCustomShape( + SdrModel& rSdrModel, + const uno::Reference< report::XReportComponent>& _xComponent) +: SdrObjCustomShape(rSdrModel) + ,OObjectBase(_xComponent) +{ + setUnoShape( uno::Reference< drawing::XShape >(_xComponent,uno::UNO_QUERY_THROW) ); + m_bIsListening = true; +} + +OCustomShape::OCustomShape( + SdrModel& rSdrModel, + const OUString& _sComponentName) +: SdrObjCustomShape(rSdrModel) + ,OObjectBase(_sComponentName) +{ + m_bIsListening = true; +} + + +OCustomShape::~OCustomShape() +{ +} + +SdrObjKind OCustomShape::GetObjIdentifier() const +{ + return SdrObjKind::CustomShape; +} + +SdrInventor OCustomShape::GetObjInventor() const +{ + return SdrInventor::ReportDesign; +} + +SdrPage* OCustomShape::GetImplPage() const +{ + return getSdrPageFromSdrObject(); +} + +void OCustomShape::NbcMove( const Size& rSize ) +{ + if ( m_bIsListening ) + { + m_bIsListening = false; + + if ( m_xReportComponent.is() ) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + m_xReportComponent->setPositionX(m_xReportComponent->getPositionX() + rSize.Width()); + m_xReportComponent->setPositionY(m_xReportComponent->getPositionY() + rSize.Height()); + } + + // set geometry properties + SetPropsFromRect(GetSnapRect()); + + m_bIsListening = true; + } + else + SdrObjCustomShape::NbcMove( rSize ); +} + +void OCustomShape::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract) +{ + SdrObjCustomShape::NbcResize( rRef, xFract, yFract ); + + SetPropsFromRect(GetSnapRect()); +} + +void OCustomShape::NbcSetLogicRect(const tools::Rectangle& rRect) +{ + SdrObjCustomShape::NbcSetLogicRect(rRect); + SetPropsFromRect(rRect); +} + +bool OCustomShape::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + bool bResult = SdrObjCustomShape::EndCreate(rStat, eCmd); + if ( bResult ) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + if ( !m_xReportComponent.is() ) + m_xReportComponent.set(getUnoShape(),uno::UNO_QUERY); + + SetPropsFromRect(GetSnapRect()); + } + + return bResult; +} + + +uno::Reference< beans::XPropertySet> OCustomShape::getAwtComponent() +{ + return m_xReportComponent; +} + + +uno::Reference< drawing::XShape > OCustomShape::getUnoShape() +{ + uno::Reference<drawing::XShape> xShape = OObjectBase::getUnoShapeOf( *this ); + if ( !m_xReportComponent.is() ) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + m_xReportComponent.set(xShape,uno::UNO_QUERY); + } + return xShape; +} + +void OCustomShape::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) +{ + SdrObjCustomShape::setUnoShape( rxUnoShape ); + releaseUnoShape(); + m_xReportComponent.clear(); +} + +OUnoObject::OUnoObject( + SdrModel& rSdrModel, + const OUString& _sComponentName, + const OUString& rModelName, + SdrObjKind _nObjectType) +: SdrUnoObj(rSdrModel, rModelName) + ,OObjectBase(_sComponentName) + ,m_nObjectType(_nObjectType) + // tdf#119067 + ,m_bSetDefaultLabel(false) +{ + if ( !rModelName.isEmpty() ) + impl_initializeModel_nothrow(); +} + +OUnoObject::OUnoObject( + SdrModel& rSdrModel, OUnoObject const & rSource) +: SdrUnoObj(rSdrModel, rSource) + ,OObjectBase(rSource.getServiceName()) + ,m_nObjectType(rSource.m_nObjectType) + // tdf#119067 + ,m_bSetDefaultLabel(rSource.m_bSetDefaultLabel) +{ + if ( !rSource.getUnoControlModelTypeName().isEmpty() ) + impl_initializeModel_nothrow(); + Reference<XPropertySet> xSource(const_cast<OUnoObject&>(rSource).getUnoShape(), uno::UNO_QUERY); + Reference<XPropertySet> xDest(getUnoShape(), uno::UNO_QUERY); + if ( xSource.is() && xDest.is() ) + comphelper::copyProperties(xSource, xDest); +} + +OUnoObject::OUnoObject( + SdrModel& rSdrModel, + const uno::Reference< report::XReportComponent>& _xComponent, + const OUString& rModelName, + SdrObjKind _nObjectType) +: SdrUnoObj(rSdrModel, rModelName) + ,OObjectBase(_xComponent) + ,m_nObjectType(_nObjectType) + // tdf#119067 + ,m_bSetDefaultLabel(false) +{ + setUnoShape( uno::Reference< drawing::XShape >( _xComponent, uno::UNO_QUERY_THROW ) ); + + if ( !rModelName.isEmpty() ) + impl_initializeModel_nothrow(); + +} + +OUnoObject::~OUnoObject() +{ +} + +void OUnoObject::impl_initializeModel_nothrow() +{ + try + { + Reference< XFormattedField > xFormatted( m_xReportComponent, UNO_QUERY ); + if ( xFormatted.is() ) + { + const Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW ); + xModelProps->setPropertyValue( "TreatAsNumber", Any( false ) ); + xModelProps->setPropertyValue( PROPERTY_VERTICALALIGN,m_xReportComponent->getPropertyValue(PROPERTY_VERTICALALIGN)); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +SdrObjKind OUnoObject::GetObjIdentifier() const +{ + return m_nObjectType; +} + +SdrInventor OUnoObject::GetObjInventor() const +{ + return SdrInventor::ReportDesign; +} + +SdrPage* OUnoObject::GetImplPage() const +{ + return getSdrPageFromSdrObject(); +} + +void OUnoObject::NbcMove( const Size& rSize ) +{ + + if ( m_bIsListening ) + { + // stop listening + OObjectBase::EndListening(); + + bool bPositionFixed = false; + Size aUndoSize(0,0); + if ( m_xReportComponent.is() ) + { + bool bUndoMode = false; + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + + if (rRptModel.GetUndoEnv().IsUndoMode()) + { + // if we are locked from outside, then we must not handle wrong moves, we are in UNDO mode + bUndoMode = true; + } + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + // LLA: why there exists getPositionX and getPositionY and NOT getPosition() which return a Point? + int nNewX = m_xReportComponent->getPositionX() + rSize.Width(); + m_xReportComponent->setPositionX(nNewX); + int nNewY = m_xReportComponent->getPositionY() + rSize.Height(); + if (nNewY < 0 && !bUndoMode) + { + aUndoSize.setHeight( abs(nNewY) ); + bPositionFixed = true; + nNewY = 0; + } + m_xReportComponent->setPositionY(nNewY); + } + if (bPositionFixed) + { + getSdrModelFromSdrObject().AddUndo(getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoMoveObject(*this, aUndoSize)); + } + // set geometry properties + SetPropsFromRect(GetLogicRect()); + + // start listening + OObjectBase::StartListening(); + } + else + SdrUnoObj::NbcMove( rSize ); +} + + +void OUnoObject::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract) +{ + SdrUnoObj::NbcResize( rRef, xFract, yFract ); + + // stop listening + OObjectBase::EndListening(); + + // set geometry properties + SetPropsFromRect(GetLogicRect()); + + // start listening + OObjectBase::StartListening(); +} + +void OUnoObject::NbcSetLogicRect(const tools::Rectangle& rRect) +{ + SdrUnoObj::NbcSetLogicRect(rRect); + // stop listening + OObjectBase::EndListening(); + + // set geometry properties + SetPropsFromRect(rRect); + + // start listening + OObjectBase::StartListening(); +} + +bool OUnoObject::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + const bool bResult(SdrUnoObj::EndCreate(rStat, eCmd)); + + if(bResult) + { + // tdf#118730 remember if this object was created interactively (due to ::EndCreate being called) + m_bSetDefaultLabel = true; + + // set geometry properties + SetPropsFromRect(GetLogicRect()); + } + + return bResult; +} + +OUString OUnoObject::GetDefaultName(const OUnoObject* _pObj) +{ + OUString aDefaultName = "HERE WE HAVE TO INSERT OUR NAME!"; + if ( _pObj->supportsService( SERVICE_FIXEDTEXT ) ) + { + aDefaultName = RID_STR_CLASS_FIXEDTEXT; + } + else if ( _pObj->supportsService( SERVICE_FIXEDLINE ) ) + { + aDefaultName = RID_STR_CLASS_FIXEDLINE; + } + else if ( _pObj->supportsService( SERVICE_IMAGECONTROL ) ) + { + aDefaultName = RID_STR_CLASS_IMAGECONTROL; + } + else if ( _pObj->supportsService( SERVICE_FORMATTEDFIELD ) ) + { + aDefaultName = RID_STR_CLASS_FORMATTEDFIELD; + } + + return aDefaultName; +} + +void OUnoObject::_propertyChange( const beans::PropertyChangeEvent& evt ) +{ + OObjectBase::_propertyChange(evt); + if (!isListening()) + return; + + if ( evt.PropertyName == PROPERTY_CHARCOLOR ) + { + Reference<XPropertySet> xControlModel(GetUnoControlModel(),uno::UNO_QUERY); + if ( xControlModel.is() ) + { + OObjectBase::EndListening(); + try + { + xControlModel->setPropertyValue(PROPERTY_TEXTCOLOR,evt.NewValue); + } + catch(uno::Exception&) + { + } + OObjectBase::StartListening(); + } + } + else if ( evt.PropertyName == PROPERTY_NAME ) + { + Reference<XPropertySet> xControlModel(GetUnoControlModel(),uno::UNO_QUERY); + if ( xControlModel.is() && xControlModel->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) ) + { + // get old name + OUString aOldName; + evt.OldValue >>= aOldName; + + // get new name + OUString aNewName; + evt.NewValue >>= aNewName; + + if ( aNewName != aOldName ) + { + // set old name property + OObjectBase::EndListening(); + if ( m_xMediator.is() ) + m_xMediator->stopListening(); + try + { + xControlModel->setPropertyValue( PROPERTY_NAME, evt.NewValue ); + } + catch(uno::Exception&) + { + } + if ( m_xMediator.is() ) + m_xMediator->startListening(); + OObjectBase::StartListening(); + } + } + } +} + +void OUnoObject::CreateMediator(bool _bReverse) +{ + if ( m_xMediator.is() ) + return; + + // tdf#118730 Directly do things formerly done in + // OUnoObject::impl_setReportComponent_nothrow here + if(!m_xReportComponent.is()) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock( rRptModel.GetUndoEnv() ); + m_xReportComponent.set(getUnoShape(),uno::UNO_QUERY); + + impl_initializeModel_nothrow(); + } + + if(m_xReportComponent.is() && m_bSetDefaultLabel) + { + // tdf#118730 Directly do things formerly done in + // OUnoObject::EndCreate here + // tdf#119067 ...but *only* if result of interactive + // creation in Report DesignView + m_bSetDefaultLabel = false; + + try + { + if ( supportsService( SERVICE_FIXEDTEXT ) ) + { + m_xReportComponent->setPropertyValue( + PROPERTY_LABEL, + uno::Any(GetDefaultName(this))); + } + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + if(!m_xMediator.is() && m_xReportComponent.is()) + { + Reference<XPropertySet> xControlModel(GetUnoControlModel(),uno::UNO_QUERY); + + if(xControlModel.is()) + { + m_xMediator = new OPropertyMediator( + m_xReportComponent, + xControlModel, + TPropertyNamePair(getPropertyNameMap(GetObjIdentifier())), + _bReverse); + } + } + + OObjectBase::StartListening(); +} + +uno::Reference< beans::XPropertySet> OUnoObject::getAwtComponent() +{ + return Reference<XPropertySet>(GetUnoControlModel(),uno::UNO_QUERY); +} + + +uno::Reference< drawing::XShape > OUnoObject::getUnoShape() +{ + return OObjectBase::getUnoShapeOf( *this ); +} + +void OUnoObject::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) +{ + SdrUnoObj::setUnoShape( rxUnoShape ); + releaseUnoShape(); +} + +OUnoObject* OUnoObject::CloneSdrObject(SdrModel& rTargetModel) const +{ + return new OUnoObject(rTargetModel, *this); +} + +// OOle2Obj +OOle2Obj::OOle2Obj( + SdrModel& rSdrModel, + const uno::Reference< report::XReportComponent>& _xComponent, + SdrObjKind _nType) +: SdrOle2Obj(rSdrModel) + ,OObjectBase(_xComponent) + ,m_nType(_nType) + ,m_bOnlyOnce(true) +{ + setUnoShape( uno::Reference< drawing::XShape >( _xComponent, uno::UNO_QUERY_THROW ) ); + m_bIsListening = true; +} + +OOle2Obj::OOle2Obj( + SdrModel& rSdrModel, + const OUString& _sComponentName, + SdrObjKind _nType) +: SdrOle2Obj(rSdrModel) + ,OObjectBase(_sComponentName) + ,m_nType(_nType) + ,m_bOnlyOnce(true) +{ + m_bIsListening = true; +} + +static uno::Reference< chart2::data::XDatabaseDataProvider > lcl_getDataProvider(const uno::Reference < embed::XEmbeddedObject >& _xObj); + +OOle2Obj::OOle2Obj(SdrModel& rSdrModel, OOle2Obj const & rSource) +: SdrOle2Obj(rSdrModel, rSource) + ,OObjectBase(rSource.getServiceName()) + ,m_nType(rSource.m_nType) + ,m_bOnlyOnce(rSource.m_bOnlyOnce) +{ + m_bIsListening = true; + + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + svt::EmbeddedObjectRef::TryRunningState( GetObjRef() ); + impl_createDataProvider_nothrow(rRptModel.getReportDefinition()); + + uno::Reference< chart2::data::XDatabaseDataProvider > xSource( lcl_getDataProvider(rSource.GetObjRef()) ); + uno::Reference< chart2::data::XDatabaseDataProvider > xDest( lcl_getDataProvider(GetObjRef()) ); + if ( xSource.is() && xDest.is() ) + comphelper::copyProperties(xSource, xDest); + + initializeChart(rRptModel.getReportDefinition()); +} + +OOle2Obj::~OOle2Obj() +{ +} + +SdrObjKind OOle2Obj::GetObjIdentifier() const +{ + return m_nType; +} + +SdrInventor OOle2Obj::GetObjInventor() const +{ + return SdrInventor::ReportDesign; +} + +SdrPage* OOle2Obj::GetImplPage() const +{ + return getSdrPageFromSdrObject(); +} + +void OOle2Obj::NbcMove( const Size& rSize ) +{ + + if ( m_bIsListening ) + { + // stop listening + OObjectBase::EndListening(); + + bool bPositionFixed = false; + Size aUndoSize(0,0); + if ( m_xReportComponent.is() ) + { + bool bUndoMode = false; + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + + if (rRptModel.GetUndoEnv().IsUndoMode()) + { + // if we are locked from outside, then we must not handle wrong moves, we are in UNDO mode + bUndoMode = true; + } + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + // LLA: why there exists getPositionX and getPositionY and NOT getPosition() which return a Point? + int nNewX = m_xReportComponent->getPositionX() + rSize.Width(); + // can this hinder us to set components outside the area? + // if (nNewX < 0) + // { + // nNewX = 0; + // } + m_xReportComponent->setPositionX(nNewX); + int nNewY = m_xReportComponent->getPositionY() + rSize.Height(); + if (nNewY < 0 && !bUndoMode) + { + aUndoSize.setHeight( abs(nNewY) ); + bPositionFixed = true; + nNewY = 0; + } + m_xReportComponent->setPositionY(nNewY); + } + if (bPositionFixed) + { + getSdrModelFromSdrObject().AddUndo(getSdrModelFromSdrObject().GetSdrUndoFactory().CreateUndoMoveObject(*this, aUndoSize)); + } + // set geometry properties + SetPropsFromRect(GetLogicRect()); + + // start listening + OObjectBase::StartListening(); + } + else + SdrOle2Obj::NbcMove( rSize ); +} + + +void OOle2Obj::NbcResize(const Point& rRef, const Fraction& xFract, const Fraction& yFract) +{ + SdrOle2Obj::NbcResize( rRef, xFract, yFract ); + + // stop listening + OObjectBase::EndListening(); + + // set geometry properties + SetPropsFromRect(GetLogicRect()); + + // start listening + OObjectBase::StartListening(); +} + +void OOle2Obj::NbcSetLogicRect(const tools::Rectangle& rRect) +{ + SdrOle2Obj::NbcSetLogicRect(rRect); + // stop listening + OObjectBase::EndListening(); + + // set geometry properties + SetPropsFromRect(rRect); + + // start listening + OObjectBase::StartListening(); +} + + +bool OOle2Obj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + bool bResult = SdrOle2Obj::EndCreate(rStat, eCmd); + if ( bResult ) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + if ( !m_xReportComponent.is() ) + m_xReportComponent.set(getUnoShape(),uno::UNO_QUERY); + + // set geometry properties + SetPropsFromRect(GetLogicRect()); + } + + return bResult; +} + +uno::Reference< beans::XPropertySet> OOle2Obj::getAwtComponent() +{ + return m_xReportComponent; +} + + +uno::Reference< drawing::XShape > OOle2Obj::getUnoShape() +{ + uno::Reference< drawing::XShape> xShape = OObjectBase::getUnoShapeOf( *this ); + if ( !m_xReportComponent.is() ) + { + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + m_xReportComponent.set(xShape,uno::UNO_QUERY); + } + return xShape; +} + +void OOle2Obj::setUnoShape( const uno::Reference< drawing::XShape >& rxUnoShape ) +{ + SdrOle2Obj::setUnoShape( rxUnoShape ); + releaseUnoShape(); + m_xReportComponent.clear(); +} + + +static uno::Reference< chart2::data::XDatabaseDataProvider > lcl_getDataProvider(const uno::Reference < embed::XEmbeddedObject >& _xObj) +{ + uno::Reference< chart2::data::XDatabaseDataProvider > xSource; + uno::Reference< embed::XComponentSupplier > xCompSupp(_xObj); + if( xCompSupp.is()) + { + uno::Reference< chart2::XChartDocument> xChartDoc( xCompSupp->getComponent(), uno::UNO_QUERY ); + if ( xChartDoc.is() ) + { + xSource.set(xChartDoc->getDataProvider(),uno::UNO_QUERY); + } + } + return xSource; +} + +// Clone() should make a complete copy of the object. +OOle2Obj* OOle2Obj::CloneSdrObject(SdrModel& rTargetModel) const +{ + return new OOle2Obj(rTargetModel, *this); +} + +void OOle2Obj::impl_createDataProvider_nothrow(const uno::Reference< frame::XModel>& _xModel) +{ + try + { + uno::Reference < embed::XEmbeddedObject > xObj = GetObjRef(); + uno::Reference< chart2::data::XDataReceiver > xReceiver; + uno::Reference< embed::XComponentSupplier > xCompSupp( xObj ); + if( xCompSupp.is()) + xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY ); + OSL_ASSERT( xReceiver.is()); + if( xReceiver.is() ) + { + uno::Reference< lang::XMultiServiceFactory> xFac(_xModel,uno::UNO_QUERY); + uno::Reference< chart2::data::XDatabaseDataProvider > xDataProvider( xFac->createInstance("com.sun.star.chart2.data.DataProvider"),uno::UNO_QUERY); + xReceiver->attachDataProvider( xDataProvider ); + } + } + catch(const uno::Exception &) + { + } +} + +void OOle2Obj::initializeOle() +{ + if ( !m_bOnlyOnce ) + return; + + m_bOnlyOnce = false; + uno::Reference < embed::XEmbeddedObject > xObj = GetObjRef(); + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + rRptModel.GetUndoEnv().AddElement(lcl_getDataProvider(xObj)); + + uno::Reference< embed::XComponentSupplier > xCompSupp( xObj ); + if( xCompSupp.is() ) + { + uno::Reference< beans::XPropertySet > xChartProps( xCompSupp->getComponent(), uno::UNO_QUERY ); + if ( xChartProps.is() ) + xChartProps->setPropertyValue("NullDate", + uno::Any(util::DateTime(0,0,0,0,30,12,1899,false))); + } +} + +void OOle2Obj::initializeChart( const uno::Reference< frame::XModel>& _xModel) +{ + uno::Reference < embed::XEmbeddedObject > xObj = GetObjRef(); + uno::Reference< chart2::data::XDataReceiver > xReceiver; + uno::Reference< embed::XComponentSupplier > xCompSupp( xObj ); + if( xCompSupp.is()) + xReceiver.set( xCompSupp->getComponent(), uno::UNO_QUERY ); + OSL_ASSERT( xReceiver.is()); + if( !xReceiver.is() ) + return; + + // lock the model to suppress any internal updates + uno::Reference< frame::XModel > xChartModel( xReceiver, uno::UNO_QUERY ); + if( xChartModel.is() ) + xChartModel->lockControllers(); + + if ( !lcl_getDataProvider(xObj).is() ) + impl_createDataProvider_nothrow(_xModel); + + OReportModel& rRptModel(static_cast< OReportModel& >(getSdrModelFromSdrObject())); + rRptModel.GetUndoEnv().AddElement(lcl_getDataProvider(xObj)); + + ::comphelper::NamedValueCollection aArgs; + aArgs.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) ); + aArgs.put( "HasCategories", uno::Any( true ) ); + aArgs.put( "FirstCellAsLabel", uno::Any( true ) ); + aArgs.put( "DataRowSource", uno::Any( chart::ChartDataRowSource_COLUMNS ) ); + xReceiver->setArguments( aArgs.getPropertyValues() ); + + if( xChartModel.is() ) + xChartModel->unlockControllers(); +} + +uno::Reference< style::XStyle> getUsedStyle(const uno::Reference< report::XReportDefinition>& _xReport) +{ + uno::Reference<container::XNameAccess> xStyles = _xReport->getStyleFamilies(); + uno::Reference<container::XNameAccess> xPageStyles(xStyles->getByName("PageStyles"),uno::UNO_QUERY); + + uno::Reference< style::XStyle> xReturn; + const uno::Sequence< OUString> aSeq = xPageStyles->getElementNames(); + for(const OUString& rName : aSeq) + { + uno::Reference< style::XStyle> xStyle(xPageStyles->getByName(rName),uno::UNO_QUERY); + if ( xStyle->isInUse() ) + { + xReturn = xStyle; + break; + } + } + return xReturn; +} + + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/RptObjectListener.cxx b/reportdesign/source/core/sdr/RptObjectListener.cxx new file mode 100644 index 000000000..0cc6a42b2 --- /dev/null +++ b/reportdesign/source/core/sdr/RptObjectListener.cxx @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <RptObjectListener.hxx> +#include <RptObject.hxx> + +namespace rptui +{ + +// OObjectListener + + +OObjectListener::OObjectListener(OObjectBase* _pObject) + :m_pObject(_pObject) +{ +} + + +OObjectListener::~OObjectListener() +{ +} + +// XEventListener + + +void SAL_CALL OObjectListener::disposing( const css::lang::EventObject& ) +{ +} + +// XPropertyChangeListener + + +void SAL_CALL OObjectListener::propertyChange( const css::beans::PropertyChangeEvent& evt ) +{ + m_pObject->_propertyChange( evt ); +} + + +// DlgEdHint + + +DlgEdHint::DlgEdHint(DlgEdHintKind eHint) + : eHintKind(eHint) +{ +} + + +DlgEdHint::~DlgEdHint() +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/RptPage.cxx b/reportdesign/source/core/sdr/RptPage.cxx new file mode 100644 index 000000000..1ad1cb8e1 --- /dev/null +++ b/reportdesign/source/core/sdr/RptPage.cxx @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <RptPage.hxx> +#include <RptModel.hxx> +#include <Section.hxx> +#include <RptObject.hxx> +#include <ReportDrawPage.hxx> + +namespace rptui +{ +using namespace ::com::sun::star; + +OReportPage::OReportPage( + OReportModel& _rModel, + const uno::Reference< report::XSection >& _xSection) +: SdrPage(_rModel, false/*bMasterPage*/) + ,rModel(_rModel) + ,m_xSection(_xSection) + ,m_bSpecialInsertMode(false) +{ +} + +OReportPage::~OReportPage() +{ +} + +rtl::Reference<SdrPage> OReportPage::CloneSdrPage(SdrModel& rTargetModel) const +{ + OReportModel& rOReportModel(static_cast< OReportModel& >(rTargetModel)); + rtl::Reference<OReportPage> pClonedOReportPage( + new OReportPage( + rOReportModel, + m_xSection)); + pClonedOReportPage->SdrPage::lateInit(*this); + return pClonedOReportPage; +} + + +size_t OReportPage::getIndexOf(const uno::Reference< report::XReportComponent >& _xObject) +{ + const size_t nCount = GetObjCount(); + size_t i = 0; + for (; i < nCount; ++i) + { + OObjectBase* pObj = dynamic_cast<OObjectBase*>(GetObj(i)); + OSL_ENSURE(pObj,"Invalid object found!"); + if ( pObj && pObj->getReportComponent() == _xObject ) + { + break; + } + } + return i; +} + +void OReportPage::removeSdrObject(const uno::Reference< report::XReportComponent >& _xObject) +{ + size_t nPos = getIndexOf(_xObject); + if ( nPos < GetObjCount() ) + { + OObjectBase* pBase = dynamic_cast<OObjectBase*>(GetObj(nPos)); + OSL_ENSURE(pBase,"Why is this not an OObjectBase?"); + if ( pBase ) + pBase->EndListening(); + RemoveObject(nPos); + } +} + +SdrObject* OReportPage::RemoveObject(size_t nObjNum) +{ + SdrObject* pObj = SdrPage::RemoveObject(nObjNum); + if (getSpecialMode()) + { + return pObj; + } + + // this code is evil, but what else shall I do + reportdesign::OSection* pSection = comphelper::getFromUnoTunnel<reportdesign::OSection>(m_xSection); + uno::Reference< drawing::XShape> xShape(pObj->getUnoShape(),uno::UNO_QUERY); + pSection->notifyElementRemoved(xShape); + if (dynamic_cast< const OUnoObject *>( pObj ) != nullptr) + { + OUnoObject& rUnoObj = dynamic_cast<OUnoObject&>(*pObj); + uno::Reference< container::XChild> xChild(rUnoObj.GetUnoControlModel(),uno::UNO_QUERY); + if ( xChild.is() ) + xChild->setParent(nullptr); + } + return pObj; +} + +void OReportPage::insertObject(const uno::Reference< report::XReportComponent >& _xObject) +{ + OSL_ENSURE(_xObject.is(),"Object is not valid to create a SdrObject!"); + if ( !_xObject.is() ) + return; + size_t nPos = getIndexOf(_xObject); + if ( nPos < GetObjCount() ) + return; // Object already in list + + OObjectBase* pObject = dynamic_cast< OObjectBase* >(SdrObject::getSdrObjectFromXShape( _xObject )); + OSL_ENSURE( pObject, "OReportPage::insertObject: no implementation object found for the given shape/component!" ); + if ( pObject ) + pObject->StartListening(); +} + + +uno::Reference< uno::XInterface > OReportPage::createUnoPage() +{ + return static_cast<cppu::OWeakObject*>( new reportdesign::OReportDrawPage(this,m_xSection) ); +} + +void OReportPage::removeTempObject(SdrObject const *_pToRemoveObj) +{ + if (_pToRemoveObj) + { + for (size_t i=0; i<GetObjCount(); ++i) + { + SdrObject *aObj = GetObj(i); + if (aObj && aObj == _pToRemoveObj) + { + (void) RemoveObject(i); + break; + } + } + } +} + +void OReportPage::resetSpecialMode() +{ + const bool bChanged = rModel.IsChanged(); + + for (const auto& pTemporaryObject : m_aTemporaryObjectList) + { + removeTempObject(pTemporaryObject); + } + m_aTemporaryObjectList.clear(); + rModel.SetChanged(bChanged); + + m_bSpecialInsertMode = false; +} + +void OReportPage::NbcInsertObject(SdrObject* pObj, size_t nPos) +{ + SdrPage::NbcInsertObject(pObj, nPos); + + OUnoObject* pUnoObj = dynamic_cast< OUnoObject* >( pObj ); + if (getSpecialMode()) + { + m_aTemporaryObjectList.push_back(pObj); + return; + } + + if ( pUnoObj ) + { + pUnoObj->CreateMediator(); + uno::Reference< container::XChild> xChild(pUnoObj->GetUnoControlModel(),uno::UNO_QUERY); + if ( xChild.is() && !xChild->getParent().is() ) + xChild->setParent(m_xSection); + } + + // this code is evil, but what else shall I do + reportdesign::OSection* pSection = comphelper::getFromUnoTunnel<reportdesign::OSection>(m_xSection); + uno::Reference< drawing::XShape> xShape(pObj->getUnoShape(),uno::UNO_QUERY); + pSection->notifyElementAdded(xShape); + + // now that the shape is inserted into its structures, we can allow the OObjectBase + // to release the reference to it + OObjectBase* pObjectBase = dynamic_cast< OObjectBase* >( pObj ); + OSL_ENSURE( pObjectBase, "OReportPage::NbcInsertObject: what is being inserted here?" ); + if ( pObjectBase ) + pObjectBase->releaseUnoShape(); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/UndoActions.cxx b/reportdesign/source/core/sdr/UndoActions.cxx new file mode 100644 index 000000000..78d59e541 --- /dev/null +++ b/reportdesign/source/core/sdr/UndoActions.cxx @@ -0,0 +1,407 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <UndoActions.hxx> +#include <UndoEnv.hxx> +#include <core_resource.hxx> +#include <strings.hrc> +#include <RptModel.hxx> + +#include <com/sun/star/container/XChild.hpp> + +#include <comphelper/types.hxx> +#include <tools/diagnose_ex.h> +#include <utility> +#include <dbaccess/dbsubcomponentcontroller.hxx> +#include <svx/unoshape.hxx> + +namespace rptui +{ + using namespace ::com::sun::star; + using namespace uno; + using namespace lang; + using namespace script; + using namespace beans; + using namespace awt; + using namespace util; + using namespace container; + using namespace report; + +::std::function<uno::Reference<report::XSection>(OGroupHelper *)> OGroupHelper::getMemberFunction(const Reference< XSection >& _xSection) +{ + ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter); + uno::Reference< report::XGroup> xGroup = _xSection->getGroup(); + if ( xGroup->getHeaderOn() && xGroup->getHeader() == _xSection ) + pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader); + return pMemFunSection; +} + +::std::function<uno::Reference<report::XSection>(OReportHelper *)> OReportHelper::getMemberFunction(const Reference< XSection >& _xSection) +{ + uno::Reference< report::XReportDefinition> xReportDefinition(_xSection->getReportDefinition()); + ::std::function<uno::Reference<report::XSection>(OReportHelper *)> pMemFunSection = ::std::mem_fn(&OReportHelper::getReportFooter); + if ( xReportDefinition->getReportHeaderOn() && xReportDefinition->getReportHeader() == _xSection ) + pMemFunSection = ::std::mem_fn(&OReportHelper::getReportHeader); + else if ( xReportDefinition->getPageHeaderOn() && xReportDefinition->getPageHeader() == _xSection ) + pMemFunSection = ::std::mem_fn(&OReportHelper::getPageHeader); + else if ( xReportDefinition->getPageFooterOn() && xReportDefinition->getPageFooter() == _xSection ) + pMemFunSection = ::std::mem_fn(&OReportHelper::getPageFooter); + else if ( xReportDefinition->getDetail() == _xSection ) + pMemFunSection = ::std::mem_fn(&OReportHelper::getDetail); + return pMemFunSection; +} + + +OCommentUndoAction::OCommentUndoAction(SdrModel& _rMod, TranslateId pCommentID) + :SdrUndoAction(_rMod) +{ + m_pController = static_cast< OReportModel& >( _rMod ).getController(); + if (pCommentID) + m_strComment = RptResId(pCommentID); +} +OCommentUndoAction::~OCommentUndoAction() +{ +} + +void OCommentUndoAction::Undo() +{ +} + +void OCommentUndoAction::Redo() +{ +} + +OUndoContainerAction::OUndoContainerAction(SdrModel& _rMod + ,Action _eAction + ,const uno::Reference< container::XIndexContainer >& rContainer + ,const Reference< XInterface > & xElem + ,TranslateId pCommentId) + :OCommentUndoAction(_rMod, pCommentId) + ,m_xElement(xElem) + ,m_xContainer(rContainer) + ,m_eAction( _eAction ) +{ + // normalize + if ( m_eAction == Removed ) + // we now own the element + m_xOwnElement = m_xElement; +} + +OUndoContainerAction::~OUndoContainerAction() +{ + // if we own the object... + Reference< XComponent > xComp( m_xOwnElement, UNO_QUERY ); + if ( !xComp.is() ) + return; + + // and the object does not have a parent + Reference< XChild > xChild( m_xOwnElement, UNO_QUERY ); + if ( !xChild.is() || xChild->getParent().is() ) + return; + + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + rEnv.RemoveElement( m_xOwnElement ); + +#if OSL_DEBUG_LEVEL > 0 + SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xChild ); + SdrObject* pObject = pShape ? pShape->GetSdrObject() : nullptr; + OSL_ENSURE( pObject == nullptr || (pShape->HasSdrObjectOwnership() && !pObject->IsInserted()), + "OUndoContainerAction::~OUndoContainerAction: inconsistency in the shape/object ownership!" ); +#endif + // -> dispose it + try + { + comphelper::disposeComponent( xComp ); + } + catch ( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void OUndoContainerAction::implReInsert( ) +{ + if ( m_xContainer.is() ) + { + // insert the element + m_xContainer->insertByIndex( m_xContainer->getCount(),uno::Any(m_xElement) ); + } + // we don't own the object anymore + m_xOwnElement = nullptr; +} + + +void OUndoContainerAction::implReRemove( ) +{ + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + try + { + OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + if ( m_xContainer.is() ) + { + const sal_Int32 nCount = m_xContainer->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference< uno::XInterface> xObj(m_xContainer->getByIndex(i),uno::UNO_QUERY); + if ( xObj == m_xElement ) + { + m_xContainer->removeByIndex( i ); + break; + } + } + } + } + catch(uno::Exception&){} + // from now on, we own this object + m_xOwnElement = m_xElement; +} + + +void OUndoContainerAction::Undo() +{ + if ( !m_xElement.is() ) + return; + + // prevents that an undo action will be created for elementInserted + try + { + switch ( m_eAction ) + { + case Inserted: + implReRemove(); + break; + + case Removed: + implReInsert(); + break; + default: + OSL_FAIL("Illegal case value"); + break; + } + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OUndoContainerAction::Undo" ); + } +} + + +void OUndoContainerAction::Redo() +{ + if ( !m_xElement.is() ) + return; + + try + { + switch ( m_eAction ) + { + case Inserted: + implReInsert(); + break; + + case Removed: + implReRemove(); + break; + default: + OSL_FAIL("Illegal case value"); + break; + } + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OUndoContainerAction::Redo" ); + } +} + +OUndoGroupSectionAction::OUndoGroupSectionAction( + SdrModel& _rMod, Action _eAction, + ::std::function<uno::Reference<report::XSection>(OGroupHelper*)> _pMemberFunction, + const uno::Reference<report::XGroup>& _xGroup, const Reference<XInterface>& xElem, + TranslateId pCommentId) + : OUndoContainerAction(_rMod, _eAction, nullptr, xElem, pCommentId) + , m_aGroupHelper(_xGroup) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ +} + +void OUndoGroupSectionAction::implReInsert( ) +{ + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + try + { + OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aGroupHelper); + if ( xSection.is() ) + xSection->add(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY)); + } + catch(uno::Exception&){} + + // we don't own the object anymore + m_xOwnElement = nullptr; +} + + +void OUndoGroupSectionAction::implReRemove( ) +{ + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + try + { + OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aGroupHelper); + if ( xSection.is() ) + xSection->remove(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY)); + } + catch(uno::Exception&){} + + // from now on, we own this object + m_xOwnElement = m_xElement; +} + +OUndoReportSectionAction::OUndoReportSectionAction( + SdrModel& _rMod, Action _eAction, + ::std::function<uno::Reference<report::XSection>(OReportHelper*)> _pMemberFunction, + const uno::Reference<report::XReportDefinition>& _xReport, const Reference<XInterface>& xElem, + TranslateId pCommentId) + : OUndoContainerAction(_rMod, _eAction, nullptr, xElem, pCommentId) + , m_aReportHelper(_xReport) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ +} + +void OUndoReportSectionAction::implReInsert( ) +{ + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + try + { + OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aReportHelper); + if ( xSection.is() ) + { + uno::Reference< drawing::XShape> xShape(m_xElement,uno::UNO_QUERY_THROW); + awt::Point aPos = xShape->getPosition(); + awt::Size aSize = xShape->getSize(); + xSection->add(xShape); + xShape->setPosition( aPos ); + xShape->setSize( aSize ); + } + } + catch(uno::Exception&){} + // we don't own the object anymore + m_xOwnElement = nullptr; +} + + +void OUndoReportSectionAction::implReRemove( ) +{ + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + try + { + OXUndoEnvironment::OUndoEnvLock aLock(rEnv); + uno::Reference< report::XSection> xSection = m_pMemberFunction(&m_aReportHelper); + if ( xSection.is() ) + xSection->remove(uno::Reference< drawing::XShape>(m_xElement,uno::UNO_QUERY)); + } + catch(uno::Exception&){} + // from now on, we own this object + m_xOwnElement = m_xElement; +} + +ORptUndoPropertyAction::ORptUndoPropertyAction(SdrModel& rNewMod, const PropertyChangeEvent& evt) + :OCommentUndoAction(rNewMod,{}) + ,m_xObj(evt.Source, UNO_QUERY) + ,m_aPropertyName(evt.PropertyName) + ,m_aNewValue(evt.NewValue) + ,m_aOldValue(evt.OldValue) +{ +} + +void ORptUndoPropertyAction::Undo() +{ + setProperty(true); +} + + +void ORptUndoPropertyAction::Redo() +{ + setProperty(false); +} + +Reference< XPropertySet> ORptUndoPropertyAction::getObject() +{ + return m_xObj; +} + +void ORptUndoPropertyAction::setProperty(bool _bOld) +{ + Reference< XPropertySet> xObj = getObject(); + + if (xObj.is() ) + { + try + { + xObj->setPropertyValue( m_aPropertyName, _bOld ? m_aOldValue : m_aNewValue ); + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "ORptUndoPropertyAction::Redo" ); + } + } +} + +OUString ORptUndoPropertyAction::GetComment() const +{ + OUString aStr( RptResId(RID_STR_UNDO_PROPERTY) ); + + return aStr.replaceFirst("#", m_aPropertyName); +} + +OUndoPropertyGroupSectionAction::OUndoPropertyGroupSectionAction( + SdrModel& _rMod, const PropertyChangeEvent& evt, + ::std::function<uno::Reference<report::XSection>(OGroupHelper*)> _pMemberFunction, + const uno::Reference<report::XGroup>& _xGroup) + : ORptUndoPropertyAction(_rMod, evt) + , m_aGroupHelper(_xGroup) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ +} + +Reference< XPropertySet> OUndoPropertyGroupSectionAction::getObject() +{ + return m_pMemberFunction(&m_aGroupHelper); +} + +OUndoPropertyReportSectionAction::OUndoPropertyReportSectionAction( + SdrModel& _rMod, const PropertyChangeEvent& evt, + ::std::function<uno::Reference<report::XSection>(OReportHelper*)> _pMemberFunction, + const uno::Reference<report::XReportDefinition>& _xReport) + : ORptUndoPropertyAction(_rMod, evt) + , m_aReportHelper(_xReport) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ +} + +Reference< XPropertySet> OUndoPropertyReportSectionAction::getObject() +{ + return m_pMemberFunction(&m_aReportHelper); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/UndoEnv.cxx b/reportdesign/source/core/sdr/UndoEnv.cxx new file mode 100644 index 000000000..2585d4a20 --- /dev/null +++ b/reportdesign/source/core/sdr/UndoEnv.cxx @@ -0,0 +1,619 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <UndoActions.hxx> +#include <UndoEnv.hxx> +#include "formatnormalizer.hxx" +#include <conditionupdater.hxx> +#include <RptPage.hxx> +#include <strings.hrc> +#include <RptModel.hxx> + +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/beans/theIntrospection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> +#include <com/sun/star/beans/XIntrospectionAccess.hpp> +#include <com/sun/star/beans/XIntrospection.hpp> + +#include <svl/hint.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <dbaccess/dbsubcomponentcontroller.hxx> +#include <osl/mutex.hxx> + +#include <unordered_map> + +namespace rptui +{ + using namespace ::com::sun::star; + using namespace uno; + using namespace lang; + using namespace script; + using namespace beans; + using namespace awt; + using namespace util; + using namespace container; + using namespace report; + +namespace { + +struct PropertyInfo +{ + bool bIsReadonlyOrTransient; + + explicit PropertyInfo( const bool i_bIsTransientOrReadOnly ) + :bIsReadonlyOrTransient( i_bIsTransientOrReadOnly ) + { + } +}; + +} + +typedef std::unordered_map< OUString, PropertyInfo > PropertiesInfo; + +namespace { + +struct ObjectInfo +{ + PropertiesInfo aProperties; + Reference< XPropertySet > xPropertyIntrospection; + + ObjectInfo() + { + } +}; + +} + +typedef ::std::map< Reference< XPropertySet >, ObjectInfo > PropertySetInfoCache; + + +class OXUndoEnvironmentImpl +{ +public: + OReportModel& m_rModel; + PropertySetInfoCache m_aPropertySetCache; + FormatNormalizer m_aFormatNormalizer; + ConditionUpdater m_aConditionUpdater; + ::osl::Mutex m_aMutex; + ::std::vector< uno::Reference< container::XChild> > m_aSections; + Reference< XIntrospection > m_xIntrospection; + oslInterlockedCount m_nLocks; + bool m_bReadOnly; + bool m_bIsUndo; + + explicit OXUndoEnvironmentImpl(OReportModel& _rModel); + OXUndoEnvironmentImpl(const OXUndoEnvironmentImpl&) = delete; + OXUndoEnvironmentImpl& operator=(const OXUndoEnvironmentImpl&) = delete; +}; + +OXUndoEnvironmentImpl::OXUndoEnvironmentImpl(OReportModel& _rModel) : m_rModel(_rModel) + ,m_aFormatNormalizer( _rModel ) + ,m_nLocks(0) + ,m_bReadOnly(false) + ,m_bIsUndo(false) +{ +} + + +OXUndoEnvironment::OXUndoEnvironment(OReportModel& _rModel) + :m_pImpl(new OXUndoEnvironmentImpl(_rModel) ) +{ + StartListening(m_pImpl->m_rModel); +} + + +OXUndoEnvironment::~OXUndoEnvironment() +{ +} + +void OXUndoEnvironment::Lock() +{ + OSL_ENSURE(m_refCount,"Illegal call to dead object!"); + osl_atomic_increment( &m_pImpl->m_nLocks ); +} +void OXUndoEnvironment::UnLock() +{ + OSL_ENSURE(m_refCount,"Illegal call to dead object!"); + + osl_atomic_decrement( &m_pImpl->m_nLocks ); +} +bool OXUndoEnvironment::IsLocked() const { return m_pImpl->m_nLocks != 0; } + +void OXUndoEnvironment::RemoveSection(OReportPage const * _pPage) +{ + if ( _pPage ) + { + Reference< XInterface > xSection(_pPage->getSection()); + if ( xSection.is() ) + RemoveElement( xSection ); + } +} + +void OXUndoEnvironment::Clear(const Accessor& /*_r*/) +{ + OUndoEnvLock aLock(*this); + + m_pImpl->m_aPropertySetCache.clear(); + + sal_uInt16 nCount = m_pImpl->m_rModel.GetPageCount(); + sal_uInt16 i; + for (i = 0; i < nCount; i++) + { + OReportPage* pPage = dynamic_cast<OReportPage*>( m_pImpl->m_rModel.GetPage(i) ); + RemoveSection(pPage); + } + + nCount = m_pImpl->m_rModel.GetMasterPageCount(); + for (i = 0; i < nCount; i++) + { + OReportPage* pPage = dynamic_cast<OReportPage*>( m_pImpl->m_rModel.GetMasterPage(i) ); + RemoveSection(pPage); + } + + m_pImpl->m_aSections.clear(); + + if (IsListening(m_pImpl->m_rModel)) + EndListening(m_pImpl->m_rModel); +} + + +void OXUndoEnvironment::ModeChanged() +{ + m_pImpl->m_bReadOnly = !m_pImpl->m_bReadOnly; + + if (!m_pImpl->m_bReadOnly) + StartListening(m_pImpl->m_rModel); + else + EndListening(m_pImpl->m_rModel); +} + + +void OXUndoEnvironment::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) +{ + if (rHint.GetId() == SfxHintId::ModeChanged ) + ModeChanged(); +} + +// XEventListener + +void SAL_CALL OXUndoEnvironment::disposing(const EventObject& e) +{ + // check if it's an object we have cached information about + Reference< XPropertySet > xSourceSet(e.Source, UNO_QUERY); + if ( xSourceSet.is() ) + { + uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY); + if ( xSection.is() ) + RemoveSection(xSection); + else + RemoveElement(xSourceSet); + } +} + +// XPropertyChangeListener + +void SAL_CALL OXUndoEnvironment::propertyChange( const PropertyChangeEvent& _rEvent ) +{ + + ::osl::ClearableMutexGuard aGuard( m_pImpl->m_aMutex ); + + if ( IsLocked() ) + return; + + Reference< XPropertySet > xSet( _rEvent.Source, UNO_QUERY ); + if (!xSet.is()) + return; + + dbaui::DBSubComponentController* pController = m_pImpl->m_rModel.getController(); + if ( !pController ) + return; + + // no Undo for transient and readonly props. + // let's see if we know something about the set + PropertySetInfoCache::iterator objectPos = m_pImpl->m_aPropertySetCache.find(xSet); + if (objectPos == m_pImpl->m_aPropertySetCache.end()) + { + objectPos = m_pImpl->m_aPropertySetCache.emplace( xSet, ObjectInfo() ).first; + DBG_ASSERT(objectPos != m_pImpl->m_aPropertySetCache.end(), "OXUndoEnvironment::propertyChange : just inserted it... why it's not there?"); + } + if ( objectPos == m_pImpl->m_aPropertySetCache.end() ) + return; + + // now we have access to the cached info about the set + // let's see what we know about the property + ObjectInfo& rObjectInfo = objectPos->second; + PropertiesInfo::const_iterator aPropertyPos = rObjectInfo.aProperties.find( _rEvent.PropertyName ); + if ( aPropertyPos == rObjectInfo.aProperties.end() ) + { // nothing 'til now... have to change this... + // the attributes + Reference< XPropertySetInfo > xPSI( xSet->getPropertySetInfo(), UNO_SET_THROW ); + sal_Int32 nPropertyAttributes = 0; + try + { + if ( xPSI->hasPropertyByName( _rEvent.PropertyName ) ) + { + nPropertyAttributes = xPSI->getPropertyByName( _rEvent.PropertyName ).Attributes; + } + else + { + // it's perfectly valid for a component to notify a change in a property which it doesn't have - as long + // as it has an attribute with this name + if ( !rObjectInfo.xPropertyIntrospection.is() ) + { + if ( !m_pImpl->m_xIntrospection.is() ) + { + m_pImpl->m_xIntrospection = theIntrospection::get( m_pImpl->m_rModel.getController()->getORB() ); + } + Reference< XIntrospectionAccess > xIntrospection( + m_pImpl->m_xIntrospection->inspect( Any( _rEvent.Source ) ), + UNO_SET_THROW + ); + rObjectInfo.xPropertyIntrospection.set( xIntrospection->queryAdapter( cppu::UnoType<XPropertySet>::get() ), UNO_QUERY_THROW ); + } + if ( rObjectInfo.xPropertyIntrospection.is() ) + { + xPSI.set( rObjectInfo.xPropertyIntrospection->getPropertySetInfo(), UNO_SET_THROW ); + nPropertyAttributes = xPSI->getPropertyByName( _rEvent.PropertyName ).Attributes; + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + const bool bTransReadOnly = + ( ( nPropertyAttributes & PropertyAttribute::READONLY ) != 0 ) + || ( ( nPropertyAttributes & PropertyAttribute::TRANSIENT ) != 0 ); + + // insert the new entry + aPropertyPos = rObjectInfo.aProperties.emplace( + _rEvent.PropertyName, + PropertyInfo( bTransReadOnly ) + ).first; + DBG_ASSERT(aPropertyPos != rObjectInfo.aProperties.end(), "OXUndoEnvironment::propertyChange : just inserted it ... why it's not there ?"); + } + + implSetModified(); + + // now we have access to the cached info about the property affected + // and are able to decide whether or not we need an undo action + + // no UNDO for transient/readonly properties + if ( aPropertyPos->second.bIsReadonlyOrTransient ) + return; + + // give components with sub responsibilities a chance + m_pImpl->m_aFormatNormalizer.notifyPropertyChange( _rEvent ); + m_pImpl->m_aConditionUpdater.notifyPropertyChange( _rEvent ); + + aGuard.clear(); + // TODO: this is a potential race condition: two threads here could in theory + // add their undo actions out-of-order + + SolarMutexGuard aSolarGuard; + std::unique_ptr<ORptUndoPropertyAction> pUndo; + try + { + uno::Reference< report::XSection> xSection( xSet, uno::UNO_QUERY ); + if ( xSection.is() ) + { + uno::Reference< report::XGroup> xGroup = xSection->getGroup(); + if ( xGroup.is() ) + pUndo.reset(new OUndoPropertyGroupSectionAction( m_pImpl->m_rModel, _rEvent, OGroupHelper::getMemberFunction( xSection ), xGroup )); + else + pUndo.reset(new OUndoPropertyReportSectionAction( m_pImpl->m_rModel, _rEvent, OReportHelper::getMemberFunction( xSection ), xSection->getReportDefinition() )); + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + if ( pUndo == nullptr ) + pUndo.reset(new ORptUndoPropertyAction( m_pImpl->m_rModel, _rEvent )); + + m_pImpl->m_rModel.GetSdrUndoManager()->AddUndoAction( std::move(pUndo) ); + pController->InvalidateAll(); +} + +::std::vector< uno::Reference< container::XChild> >::const_iterator OXUndoEnvironment::getSection(const Reference<container::XChild>& _xContainer) const +{ + ::std::vector< uno::Reference< container::XChild> >::const_iterator aFind = m_pImpl->m_aSections.end(); + if ( _xContainer.is() ) + { + aFind = ::std::find(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(),_xContainer); + + if ( aFind == m_pImpl->m_aSections.end() ) + { + Reference<container::XChild> xParent(_xContainer->getParent(),uno::UNO_QUERY); + aFind = getSection(xParent); + } + } + return aFind; +} +// XContainerListener + +void SAL_CALL OXUndoEnvironment::elementInserted(const ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + // new listener object + Reference< uno::XInterface > xIface( evt.Element, UNO_QUERY ); + if ( !IsLocked() ) + { + Reference< report::XReportComponent > xReportComponent( xIface, UNO_QUERY ); + if ( xReportComponent.is() ) + { + Reference< report::XSection > xContainer(evt.Source,uno::UNO_QUERY); + + ::std::vector< uno::Reference< container::XChild> >::const_iterator aFind = getSection(xContainer); + + if ( aFind != m_pImpl->m_aSections.end() ) + { + OUndoEnvLock aLock(*this); + try + { + OReportPage* pPage = m_pImpl->m_rModel.getPage(uno::Reference< report::XSection>(*aFind,uno::UNO_QUERY)); + OSL_ENSURE(pPage,"No page could be found for section!"); + if ( pPage ) + pPage->insertObject(xReportComponent); + } + catch(uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + } + } + else + { + uno::Reference< report::XFunctions> xContainer(evt.Source,uno::UNO_QUERY); + if ( xContainer.is() ) + { + m_pImpl->m_rModel.GetSdrUndoManager()->AddUndoAction( + std::make_unique<OUndoContainerAction>( m_pImpl->m_rModel, rptui::Inserted, xContainer.get(), + xIface, RID_STR_UNDO_ADDFUNCTION ) ); + } + } + } + + AddElement(xIface); + + implSetModified(); +} + + +void OXUndoEnvironment::implSetModified() +{ + m_pImpl->m_rModel.SetModified( true ); +} + + +void SAL_CALL OXUndoEnvironment::elementReplaced(const ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + Reference< XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY); + OSL_ENSURE(xIface.is(), "OXUndoEnvironment::elementReplaced: invalid container notification!"); + RemoveElement(xIface); + + xIface.set(evt.Element,uno::UNO_QUERY); + AddElement(xIface); + + implSetModified(); +} + + +void SAL_CALL OXUndoEnvironment::elementRemoved(const ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + Reference< uno::XInterface > xIface( evt.Element, UNO_QUERY ); + if ( !IsLocked() ) + { + Reference< report::XSection > xContainer(evt.Source,uno::UNO_QUERY); + ::std::vector< uno::Reference< container::XChild> >::const_iterator aFind = getSection(xContainer); + + Reference< report::XReportComponent > xReportComponent( xIface, UNO_QUERY ); + if ( aFind != m_pImpl->m_aSections.end() && xReportComponent.is() ) + { + OXUndoEnvironment::OUndoEnvLock aLock(*this); + try + { + OReportPage* pPage = m_pImpl->m_rModel.getPage(uno::Reference< report::XSection >( *aFind, uno::UNO_QUERY_THROW ) ); + OSL_ENSURE( pPage, "OXUndoEnvironment::elementRemoved: no page for the section!" ); + if ( pPage ) + pPage->removeSdrObject(xReportComponent); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + else + { + uno::Reference< report::XFunctions> xFunctions(evt.Source,uno::UNO_QUERY); + if ( xFunctions.is() ) + { + m_pImpl->m_rModel.GetSdrUndoManager()->AddUndoAction( std::make_unique<OUndoContainerAction>( + m_pImpl->m_rModel, rptui::Removed, xFunctions.get(), xIface, RID_STR_UNDO_ADDFUNCTION ) ); + } + } + } + + if ( xIface.is() ) + RemoveElement(xIface); + + implSetModified(); +} + + +void SAL_CALL OXUndoEnvironment::modified( const EventObject& /*aEvent*/ ) +{ + implSetModified(); +} + + +void OXUndoEnvironment::AddSection(const Reference< report::XSection > & _xSection) +{ + OUndoEnvLock aLock(*this); + try + { + uno::Reference<container::XChild> xChild = _xSection; + m_pImpl->m_aSections.push_back(xChild); + Reference< XInterface > xInt(_xSection); + AddElement(xInt); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OXUndoEnvironment::RemoveSection(const Reference< report::XSection > & _xSection) +{ + OUndoEnvLock aLock(*this); + try + { + uno::Reference<container::XChild> xChild(_xSection); + m_pImpl->m_aSections.erase(::std::remove(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(), + xChild), m_pImpl->m_aSections.end()); + Reference< XInterface > xInt(_xSection); + RemoveElement(xInt); + } + catch(uno::Exception&){} +} + + +void OXUndoEnvironment::switchListening( const Reference< XIndexAccess >& _rxContainer, bool _bStartListening ) +{ + OSL_PRECOND( _rxContainer.is(), "OXUndoEnvironment::switchListening: invalid container!" ); + if ( !_rxContainer.is() ) + return; + + try + { + // also handle all children of this element + Reference< XInterface > xInterface; + sal_Int32 nCount = _rxContainer->getCount(); + for(sal_Int32 i = 0;i != nCount;++i) + { + xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY); + if ( _bStartListening ) + AddElement( xInterface ); + else + RemoveElement( xInterface ); + } + + // be notified of any changes in the container elements + Reference< XContainer > xSimpleContainer( _rxContainer, UNO_QUERY ); + if ( xSimpleContainer.is() ) + { + if ( _bStartListening ) + xSimpleContainer->addContainerListener( this ); + else + xSimpleContainer->removeContainerListener( this ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OXUndoEnvironment::switchListening( const Reference< XInterface >& _rxObject, bool _bStartListening ) +{ + OSL_PRECOND( _rxObject.is(), "OXUndoEnvironment::switchListening: how should I listen at a NULL object?" ); + + try + { + if ( !m_pImpl->m_bReadOnly ) + { + Reference< XPropertySet > xProps( _rxObject, UNO_QUERY ); + if ( xProps.is() ) + { + if ( _bStartListening ) + xProps->addPropertyChangeListener( OUString(), this ); + else + xProps->removePropertyChangeListener( OUString(), this ); + } + } + + Reference< XModifyBroadcaster > xBroadcaster( _rxObject, UNO_QUERY ); + if ( xBroadcaster.is() ) + { + if ( _bStartListening ) + xBroadcaster->addModifyListener( this ); + else + xBroadcaster->removeModifyListener( this ); + } + } + catch( const Exception& ) + { + } +} + + +void OXUndoEnvironment::AddElement(const Reference< XInterface >& _rxElement ) +{ + if ( !IsLocked() ) + m_pImpl->m_aFormatNormalizer.notifyElementInserted( _rxElement ); + + // if it's a container, start listening at all elements + Reference< XIndexAccess > xContainer( _rxElement, UNO_QUERY ); + if ( xContainer.is() ) + switchListening( xContainer, true ); + + switchListening( _rxElement, true ); +} + + +void OXUndoEnvironment::RemoveElement(const Reference< XInterface >& _rxElement) +{ + uno::Reference<beans::XPropertySet> xProp(_rxElement,uno::UNO_QUERY); + if (!m_pImpl->m_aPropertySetCache.empty()) + m_pImpl->m_aPropertySetCache.erase(xProp); + switchListening( _rxElement, false ); + + Reference< XIndexAccess > xContainer( _rxElement, UNO_QUERY ); + if ( xContainer.is() ) + switchListening( xContainer, false ); +} + +void OXUndoEnvironment::SetUndoMode(bool _bUndo) +{ + m_pImpl->m_bIsUndo = _bUndo; +} + +bool OXUndoEnvironment::IsUndoMode() const +{ + return m_pImpl->m_bIsUndo; +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/formatnormalizer.cxx b/reportdesign/source/core/sdr/formatnormalizer.cxx new file mode 100644 index 000000000..ae576bc40 --- /dev/null +++ b/reportdesign/source/core/sdr/formatnormalizer.cxx @@ -0,0 +1,258 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "formatnormalizer.hxx" +#include <RptModel.hxx> + +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbc/SQLException.hpp> +#include <com/sun/star/sdb/XParametersSupplier.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/util/XNumberFormatTypes.hpp> + +#include <dbaccess/dbsubcomponentcontroller.hxx> +#include <unotools/syslocale.hxx> +#include <connectivity/statementcomposer.hxx> +#include <connectivity/dbtools.hxx> +#include <tools/diagnose_ex.h> +#include <i18nlangtag/languagetag.hxx> + + +namespace rptui +{ + + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::report::XFormattedField; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::sdb::XSingleSelectQueryComposer; + using ::com::sun::star::sdbcx::XColumnsSupplier; + using ::com::sun::star::container::XIndexAccess; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::sdb::XParametersSupplier; + using ::com::sun::star::sdbc::SQLException; + using ::com::sun::star::util::XNumberFormatsSupplier; + using ::com::sun::star::util::XNumberFormatTypes; + + + //= FormatNormalizer + + + FormatNormalizer::FormatNormalizer( const OReportModel& _rModel ) + :m_rModel( _rModel ) + ,m_bFieldListDirty( true ) + { + } + + + FormatNormalizer::~FormatNormalizer() + { + } + + + void FormatNormalizer::notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) + { + if ( !impl_lateInit() ) + return; + + if ( ( _rEvent.Source == m_xReportDefinition ) && m_xReportDefinition.is() ) + { + impl_onDefinitionPropertyChange( _rEvent.PropertyName ); + return; + } + + Reference< XFormattedField > xFormatted( _rEvent.Source, UNO_QUERY ); + if ( xFormatted.is() ) + impl_onFormattedProperttyChange( xFormatted, _rEvent.PropertyName ); + } + + + void FormatNormalizer::notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) + { + if ( !impl_lateInit() ) + return; + + Reference< XFormattedField > xFormatted( _rxElement, UNO_QUERY ); + if ( !xFormatted.is() ) + return; + + impl_adjustFormatToDataFieldType_nothrow( xFormatted ); + } + + + bool FormatNormalizer::impl_lateInit() + { + if ( m_xReportDefinition.is() ) + return true; + + m_xReportDefinition = m_rModel.getReportDefinition(); + return m_xReportDefinition.is(); + } + + + void FormatNormalizer::impl_onDefinitionPropertyChange( std::u16string_view _rChangedPropName ) + { + if ( _rChangedPropName != u"Command" && _rChangedPropName != u"CommandType" && _rChangedPropName != u"EscapeProcessing" ) + // nothing we're interested in + return; + m_bFieldListDirty = true; + } + + + void FormatNormalizer::impl_onFormattedProperttyChange( const Reference< XFormattedField >& _rxFormatted, std::u16string_view _rChangedPropName ) + { + if ( _rChangedPropName != u"DataField" ) + // nothing we're interested in + return; + + impl_adjustFormatToDataFieldType_nothrow( _rxFormatted ); + } + + + namespace + { + void lcl_collectFields_throw( const Reference< XIndexAccess >& _rxColumns, FormatNormalizer::FieldList& _inout_rFields ) + { + try + { + sal_Int32 nCount( _rxColumns->getCount() ); + _inout_rFields.reserve( _inout_rFields.size() + static_cast<size_t>(nCount) ); + + Reference< XPropertySet > xColumn; + FormatNormalizer::Field aField; + + for ( sal_Int32 i=0; i<nCount; ++i ) + { + xColumn.set( _rxColumns->getByIndex( i ), UNO_QUERY_THROW ); + OSL_VERIFY( xColumn->getPropertyValue("Name") >>= aField.sName ); + OSL_VERIFY( xColumn->getPropertyValue("Type") >>= aField.nDataType ); + OSL_VERIFY( xColumn->getPropertyValue("Scale") >>= aField.nScale ); + OSL_VERIFY( xColumn->getPropertyValue("IsCurrency") >>= aField.bIsCurrency ); + _inout_rFields.push_back( aField ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + } + + + bool FormatNormalizer::impl_ensureUpToDateFieldList_nothrow() + { + if ( !m_bFieldListDirty ) + return true; + m_aFields.resize( 0 ); + + OSL_PRECOND( m_xReportDefinition.is(), "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no report definition!" ); + if ( !m_xReportDefinition.is() ) + return false; + + ::dbaui::DBSubComponentController* pController( m_rModel.getController() ); + OSL_ENSURE( pController, "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no controller? how can *this* happen?!" ); + if ( !pController ) + return false; + + try + { + ::dbtools::StatementComposer aComposer( pController->getConnection(), m_xReportDefinition->getCommand(), + m_xReportDefinition->getCommandType(), m_xReportDefinition->getEscapeProcessing() ); + + Reference< XSingleSelectQueryComposer > xComposer( aComposer.getComposer() ); + if ( !xComposer.is() ) + return false; + + + Reference< XColumnsSupplier > xSuppCols( xComposer, UNO_QUERY_THROW ); + Reference< XIndexAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW ); + lcl_collectFields_throw( xColumns, m_aFields ); + + Reference< XParametersSupplier > xSuppParams( xComposer, UNO_QUERY_THROW ); + Reference< XIndexAccess > xParams( xSuppParams->getParameters(), css::uno::UNO_SET_THROW ); + lcl_collectFields_throw( xParams, m_aFields ); + } + catch( const SQLException& ) + { + // silence it. This might happen for instance when the user sets a non-existent table, + // or things like this + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + m_bFieldListDirty = false; + return true; + } + + + void FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow( const Reference< XFormattedField >& _rxFormatted ) + { + if ( !impl_ensureUpToDateFieldList_nothrow() ) + // unable to obtain a recent field list + return; + + try + { + sal_Int32 nFormatKey = _rxFormatted->getFormatKey(); + if ( nFormatKey != 0 ) + // it's not the "standard numeric" format -> not interested in + return; + + OUString sDataField( _rxFormatted->getDataField() ); + static const OUStringLiteral sFieldPrefix( u"field:[" ); + if ( sDataField.indexOf( sFieldPrefix ) != 0 ) + // not bound to a table field + // TODO: we might also do this kind of thing for functions and expressions ... + return; + if ( !sDataField.endsWith("]") ) + { + // last character is not the closing brace + OSL_FAIL( "FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow: suspicious data field value!" ); + return; + } + sDataField = sDataField.copy( sFieldPrefix.getLength(), sDataField.getLength() - sFieldPrefix.getLength() - 1 ); + + FieldList::const_iterator field = std::find_if(m_aFields.begin(), m_aFields.end(), + [&sDataField](const Field& rField) { return rField.sName == sDataField; }); + if ( field == m_aFields.end() ) + // unknown field + return; + + Reference< XNumberFormatsSupplier > xSuppNumFmts( _rxFormatted->getFormatsSupplier(), css::uno::UNO_SET_THROW ); + Reference< XNumberFormatTypes > xNumFmtTypes( xSuppNumFmts->getNumberFormats(), UNO_QUERY_THROW ); + + nFormatKey = ::dbtools::getDefaultNumberFormat( field->nDataType, field->nScale, field->bIsCurrency, xNumFmtTypes, + SvtSysLocale().GetLanguageTag().getLocale() ); + _rxFormatted->setFormatKey( nFormatKey ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/core/sdr/formatnormalizer.hxx b/reportdesign/source/core/sdr/formatnormalizer.hxx new file mode 100644 index 000000000..0ed30df3e --- /dev/null +++ b/reportdesign/source/core/sdr/formatnormalizer.hxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_CORE_SDR_FORMATNORMALIZER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_CORE_SDR_FORMATNORMALIZER_HXX + +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/report/XFormattedField.hpp> + +#include <vector> + + +namespace rptui +{ + + + class OReportModel; + + //= FormatNormalizer + + class FormatNormalizer + { + public: + struct Field + { + OUString sName; + sal_Int32 nDataType; + sal_Int32 nScale; + bool bIsCurrency; + + Field() : sName(), nDataType( 0 ), nScale( 0 ), bIsCurrency( false ) { } + }; + typedef ::std::vector< Field > FieldList; + + private: + const OReportModel& m_rModel; + css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition; + + /// is our field list dirty? + FieldList m_aFields; + bool m_bFieldListDirty; + + public: + explicit FormatNormalizer( const OReportModel& _rModel ); + ~FormatNormalizer(); + FormatNormalizer(const FormatNormalizer&) = delete; + FormatNormalizer& operator=(const FormatNormalizer&) = delete; + + void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ); + void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ); + + private: + bool impl_lateInit(); + + void impl_onDefinitionPropertyChange( std::u16string_view _rChangedPropName ); + void impl_onFormattedProperttyChange( const css::uno::Reference< css::report::XFormattedField >& _rxFormatted, std::u16string_view _rChangedPropName ); + + bool impl_ensureUpToDateFieldList_nothrow(); + + void impl_adjustFormatToDataFieldType_nothrow( const css::uno::Reference< css::report::XFormattedField >& _rxFormatted ); + }; + + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_CORE_SDR_FORMATNORMALIZER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/dbloader2.cxx b/reportdesign/source/filter/xml/dbloader2.cxx new file mode 100644 index 000000000..67ba9b489 --- /dev/null +++ b/reportdesign/source/filter/xml/dbloader2.cxx @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "dbloader2.hxx" +#include <tools/urlobj.hxx> +#include <comphelper/documentconstants.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/storagehelper.hxx> +#include <comphelper/types.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/embed/XStorage.hpp> + +namespace rptxml +{ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::ui::dialogs; + + +ORptTypeDetection::ORptTypeDetection(Reference< XComponentContext > const & xContext) +: m_xContext(xContext) +{ +} + +OUString SAL_CALL ORptTypeDetection::detect( Sequence< css::beans::PropertyValue >& Descriptor ) +{ + + ::comphelper::SequenceAsHashMap aTemp(Descriptor); + OUString sTemp = aTemp.getUnpackedValueOrDefault("URL",OUString()); + + if ( !sTemp.isEmpty() ) + { + INetURLObject aURL(sTemp); + if ( aURL.GetFileExtension().equalsIgnoreAsciiCase("orp") ) + return "StarBaseReport"; + else + { + try + { + Reference<XPropertySet> xProp(::comphelper::OStorageHelper::GetStorageFromURL(sTemp,ElementModes::READ, m_xContext),UNO_QUERY); + if ( xProp.is() ) + { + OUString sMediaType; + xProp->getPropertyValue("MediaType") >>= sMediaType; + if ( sMediaType == MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) + return "StarBaseReport"; + ::comphelper::disposeComponent(xProp); + } + } + catch(Exception&) + { + } + } + } + return OUString(); +} + +// XServiceInfo +OUString SAL_CALL ORptTypeDetection::getImplementationName() +{ + return "com.sun.star.comp.report.ORptTypeDetection"; +} + + +// XServiceInfo +sal_Bool SAL_CALL ORptTypeDetection::supportsService(const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +// XServiceInfo +Sequence< OUString > SAL_CALL ORptTypeDetection::getSupportedServiceNames() +{ + return { "com.sun.star.document.ExtendedTypeDetection" }; +} + + +}//rptxml + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ORptTypeDetection_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptxml::ORptTypeDetection(context)); +} + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/dbloader2.hxx b/reportdesign/source/filter/xml/dbloader2.hxx new file mode 100644 index 000000000..3f5d3d877 --- /dev/null +++ b/reportdesign/source/filter/xml/dbloader2.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_DBLOADER2_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_DBLOADER2_HXX + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/document/XExtendedFilterDetection.hpp> +#include <cppuhelper/implbase.hxx> +#include <vcl/svapp.hxx> + + +namespace rptxml +{ + +class ORptTypeDetection : public ::cppu::WeakImplHelper< css::document::XExtendedFilterDetection, css::lang::XServiceInfo> +{ + css::uno::Reference< css::uno::XComponentContext > m_xContext; +public: + explicit ORptTypeDetection(css::uno::Reference< css::uno::XComponentContext > const & xContext); + + // XServiceInfo + OUString SAL_CALL getImplementationName() override; + sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; + css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + virtual OUString SAL_CALL detect( css::uno::Sequence< css::beans::PropertyValue >& Descriptor ) override; +}; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlAutoStyle.cxx b/reportdesign/source/filter/xml/xmlAutoStyle.cxx new file mode 100644 index 000000000..0e2fbb5a4 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlAutoStyle.cxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlAutoStyle.hxx" +#include "xmlHelper.hxx" +#include "xmlExport.hxx" +#include <xmloff/families.hxx> + +namespace rptxml +{ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + +void OXMLAutoStylePoolP::exportStyleAttributes( + SvXMLAttributeList& rAttrList, + XmlStyleFamily nFamily, + const ::std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp + , const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const +{ + SvXMLAutoStylePoolP::exportStyleAttributes( rAttrList, nFamily, rProperties, rPropExp, rUnitConverter, rNamespaceMap ); + if ( nFamily != XmlStyleFamily::TABLE_CELL ) + return; + + rtl::Reference< XMLPropertySetMapper > aPropMapper = rORptExport.GetCellStylePropertyMapper(); + for (const auto& rProp : rProperties) + { + sal_Int16 nContextID = aPropMapper->GetEntryContextId(rProp.mnIndex); + switch (nContextID) + { + case CTF_RPT_NUMBERFORMAT : + { + OUString sAttrValue; + if ( rProp.maValue >>= sAttrValue ) + { + if ( !sAttrValue.isEmpty() ) + { + rORptExport.AddAttribute( + aPropMapper->GetEntryNameSpace(rProp.mnIndex), + aPropMapper->GetEntryXMLName(rProp.mnIndex), + sAttrValue ); + } + } + break; + } + default: + break; + } + } +} + +OXMLAutoStylePoolP::OXMLAutoStylePoolP(ORptExport& rTempORptExport): + SvXMLAutoStylePoolP(rTempORptExport), + rORptExport(rTempORptExport) +{ +} + +OXMLAutoStylePoolP::~OXMLAutoStylePoolP() +{ +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlAutoStyle.hxx b/reportdesign/source/filter/xml/xmlAutoStyle.hxx new file mode 100644 index 000000000..4f0643878 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlAutoStyle.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLAUTOSTYLE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLAUTOSTYLE_HXX + +#include <xmloff/maptype.hxx> +#include <xmloff/xmlaustp.hxx> + +namespace rptxml +{ + class ORptExport; + class OXMLAutoStylePoolP : public SvXMLAutoStylePoolP + { + ORptExport& rORptExport; + + virtual void exportStyleAttributes( + SvXMLAttributeList& rAttrList, + XmlStyleFamily nFamily, + const ::std::vector< XMLPropertyState >& rProperties, + const SvXMLExportPropertyMapper& rPropExp, + const SvXMLUnitConverter& rUnitConverter, + const SvXMLNamespaceMap& rNamespaceMap + ) const override; + + OXMLAutoStylePoolP(const OXMLAutoStylePoolP&) = delete; + void operator =(const OXMLAutoStylePoolP&) = delete; + public: + explicit OXMLAutoStylePoolP(ORptExport& rXMLExport); + virtual ~OXMLAutoStylePoolP() override; + }; + +} // rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLAUTOSTYLE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlCell.cxx b/reportdesign/source/filter/xml/xmlCell.cxx new file mode 100644 index 000000000..82fddb7a7 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlCell.cxx @@ -0,0 +1,262 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlCell.hxx" +#include "xmlHelper.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/xmlstyle.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <osl/diagnose.h> +#include <sal/log.hxx> +#include <tools/diagnose_ex.h> +#include <strings.hxx> +#include "xmlTable.hxx" +#include "xmlFormattedField.hxx" +#include "xmlImage.hxx" +#include "xmlFixedContent.hxx" +#include "xmlSubDocument.hxx" + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace uno; + using namespace beans; + using namespace xml::sax; + + +OXMLCell::OXMLCell( ORptFilter& rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,OXMLTable* _pContainer + ,OXMLCell* _pCell) : + SvXMLImportContext( rImport ) + ,m_pContainer(_pContainer) + ,m_pCell(_pCell) + ,m_nCurrentCount(0) + ,m_bContainsShape(false) +{ + if ( !m_pCell ) + m_pCell = this; + + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(TABLE, XML_STYLE_NAME): + m_sStyleName = aIter.toString(); + break; + case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_SPANNED): + m_pContainer->setColumnSpanned(aIter.toInt32()); + break; + case XML_ELEMENT(TABLE, XML_NUMBER_ROWS_SPANNED): + m_pContainer->setRowSpanned(aIter.toInt32()); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } +} + +OXMLCell::~OXMLCell() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLCell::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + Reference<XMultiServiceFactory> xFactor(rImport.GetModel(),uno::UNO_QUERY); + static constexpr char16_t s_sStringConcat[] = u" & "; + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_FIXED_CONTENT): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLFixedContent( rImport,*m_pCell,m_pContainer); + } + break; + case XML_ELEMENT(TEXT, XML_PAGE_NUMBER): + m_sText += OUString::Concat(s_sStringConcat) + " PageNumber()"; + break; + case XML_ELEMENT(TEXT, XML_PAGE_COUNT): + m_sText += OUString::Concat(s_sStringConcat) + " PageCount()"; + break; + case XML_ELEMENT(REPORT, XML_FORMATTED_TEXT): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + uno::Reference< uno::XInterface> xInt = xFactor->createInstance(SERVICE_FORMATTEDFIELD); + Reference< report::XFormattedField > xControl(xInt,uno::UNO_QUERY); + + OSL_ENSURE(xControl.is(),"Could not create FormattedField!"); + setComponent(xControl); + if ( xControl.is() ) + xContext = new OXMLFormattedField( rImport,xAttrList,xControl,m_pContainer, false); + } + break; + case XML_ELEMENT(REPORT, XML_IMAGE): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + Reference< XImageControl > xControl(xFactor->createInstance(SERVICE_IMAGECONTROL),uno::UNO_QUERY); + + OSL_ENSURE(xControl.is(),"Could not create ImageControl!"); + setComponent(xControl); + if ( xControl.is() ) + xContext = new OXMLImage( rImport,xAttrList,xControl,m_pContainer); + } + break; + case XML_ELEMENT(REPORT, XML_SUB_DOCUMENT): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + if ( !m_bContainsShape ) + m_nCurrentCount = m_pContainer->getSection()->getCount(); + uno::Reference< uno::XInterface> xInt = xFactor->createInstance(SERVICE_FORMATTEDFIELD); + Reference< report::XFormattedField > xControl(xInt,uno::UNO_QUERY); + xContext = new OXMLSubDocument( rImport,xControl,m_pContainer, this /* give the current cell as parent*/ ); + } + break; + + case XML_ELEMENT(TEXT, XML_P): + xContext = new OXMLCell( rImport,xAttrList ,m_pContainer,this); + break; + + case XML_ELEMENT(DRAW, XML_CUSTOM_SHAPE): + case XML_ELEMENT(DRAW, XML_FRAME): + { + if ( !m_bContainsShape ) + m_nCurrentCount = m_pContainer->getSection()->getCount(); + uno::Reference< drawing::XShapes > xShapes = m_pContainer->getSection(); + xContext = XMLShapeImportHelper::CreateGroupChildContext(rImport,nElement,xAttrList,xShapes); + m_bContainsShape = true; + } + break; + + default: + SAL_WARN("reportdesign", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement)); + } + + if ( m_xComponent.is() ) + m_pContainer->addCell(m_xComponent); + + return xContext; +} + +void OXMLCell::endFastElement(sal_Int32) +{ + if ( m_bContainsShape ) + { + const sal_Int32 nCount = m_pContainer->getSection()->getCount(); + for (sal_Int32 i = m_nCurrentCount; i < nCount; ++i) + { + uno::Reference<report::XShape> xShape(m_pContainer->getSection()->getByIndex(i),uno::UNO_QUERY); + if ( xShape.is() ) + m_pContainer->addCell(xShape); + } + } + if ( m_pCell != this && !m_sText.isEmpty() ) + { + ORptFilter& rImport = GetOwnImport(); + Reference<XMultiServiceFactory> xFactor(rImport.GetModel(),uno::UNO_QUERY); + uno::Reference< uno::XInterface> xInt = xFactor->createInstance(SERVICE_FORMATTEDFIELD); + Reference< report::XFormattedField > xControl(xInt,uno::UNO_QUERY); + xControl->setDataField("rpt:" + m_sText); + + OSL_ENSURE(xControl.is(),"Could not create FormattedField!"); + setComponent(xControl); + m_xComponent = xControl.get(); + m_pContainer->getSection()->add(m_xComponent); + m_pContainer->addCell(m_xComponent); + } + // check if we have a FixedLine + else if ( !m_sStyleName.isEmpty() && !m_xComponent.is() && m_pCell == this ) + { + ORptFilter& rImport = GetOwnImport(); + Reference<XMultiServiceFactory> xFactor(rImport.GetModel(),uno::UNO_QUERY); + Reference<XFixedLine> xFixedLine(xFactor->createInstance(SERVICE_FIXEDLINE),uno::UNO_QUERY); + m_xComponent = xFixedLine.get(); + m_pContainer->getSection()->add(m_xComponent); + m_pContainer->addCell(m_xComponent); + XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(GetImport().GetAutoStyles()->FindStyleChildContext(XmlStyleFamily::TABLE_CELL,m_sStyleName))); + if ( pAutoStyle ) + { + uno::Reference<beans::XPropertySet> xBorderProp = OXMLHelper::createBorderPropertySet(); + try + { + pAutoStyle->FillPropertySet(xBorderProp); + table::BorderLine2 aRight,aLeft; + xBorderProp->getPropertyValue(PROPERTY_BORDERRIGHT) >>= aRight; + xBorderProp->getPropertyValue(PROPERTY_BORDERLEFT) >>= aLeft; + const sal_Int16 rWidth = (aRight.LineWidth == 0) ? aRight.OuterLineWidth : aRight.LineWidth; + const sal_Int16 lWidth = (aLeft.LineWidth == 0) ? aLeft.OuterLineWidth : aLeft.LineWidth; + xFixedLine->setOrientation( (rWidth != 0 || lWidth != 0) ? 1 : 0); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OXMLCell::EndElement -> exception caught"); + } + } + } + else + OXMLHelper::copyStyleElements(GetOwnImport().isOldFormat(),m_sStyleName,GetImport().GetAutoStyles(),m_xComponent); +} + +ORptFilter& OXMLCell::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +void OXMLCell::setComponent(const uno::Reference< report::XReportComponent >& _xComponent) +{ + m_pCell->m_xComponent = _xComponent; + m_xComponent = _xComponent; +} + +void OXMLCell::characters( const OUString& rChars ) +{ + if ( !rChars.isEmpty() ) + { + static const char s_Quote[] = "\""; + if ( !m_sText.isEmpty() ) + { + m_sText += " & "; + } + + m_sText += s_Quote + rChars + s_Quote; + } +} + +void OXMLCell::setContainsShape(bool _bContainsShape) +{ + m_bContainsShape = _bContainsShape; +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlCell.hxx b/reportdesign/source/filter/xml/xmlCell.hxx new file mode 100644 index 000000000..065af60d7 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlCell.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCELL_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCELL_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XReportComponent.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLTable; + class OXMLCell : public SvXMLImportContext + { + css::uno::Reference< css::report::XReportComponent > m_xComponent; + OXMLTable* m_pContainer; + OXMLCell* m_pCell; + OUString m_sStyleName; + OUString m_sText; + sal_Int32 m_nCurrentCount; + bool m_bContainsShape; + + ORptFilter& GetOwnImport(); + OXMLCell(const OXMLCell&) = delete; + OXMLCell& operator =(const OXMLCell&) = delete; + public: + + OXMLCell( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,OXMLTable* _pContainer + ,OXMLCell* _pCell = nullptr); + virtual ~OXMLCell() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL characters( const OUString& rChars ) override; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + void setComponent(const css::uno::Reference< css::report::XReportComponent >& _xComponent); + void setContainsShape(bool _bContainsShapes); + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCELL_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlColumn.cxx b/reportdesign/source/filter/xml/xmlColumn.cxx new file mode 100644 index 000000000..43464a276 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlColumn.cxx @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "xmlColumn.hxx" +#include <xmloff/xmluconv.hxx> +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmlstyle.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include "xmlCell.hxx" +#include "xmlTable.hxx" +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <strings.hxx> + +#define PROPERTY_ID_WIDTH 1 +#define PROPERTY_ID_HEIGHT 2 +#define PROPERTY_ID_MINHEIGHT 3 + +namespace rptxml +{ + using namespace ::comphelper; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::xml::sax; + + +OXMLRowColumn::OXMLRowColumn( ORptFilter& rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,OXMLTable* _pContainer + ) : + SvXMLImportContext( rImport ) + ,m_pContainer(_pContainer) +{ + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(TABLE, XML_STYLE_NAME): + fillStyle(aIter.toString()); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } +} + + +OXMLRowColumn::~OXMLRowColumn() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLRowColumn::createFastChildContext( + sal_Int32 nElement, + const Reference< XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(TABLE, XML_TABLE_COLUMN): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLRowColumn( rImport,xAttrList,m_pContainer); + break; + case XML_ELEMENT(TABLE, XML_TABLE_ROW): + m_pContainer->incrementRowIndex(); + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLRowColumn( rImport,xAttrList,m_pContainer); + break; + case XML_ELEMENT(TABLE, XML_TABLE_CELL): + m_pContainer->incrementColumnIndex(); + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLCell( rImport,xAttrList,m_pContainer); + break; + case XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL): + m_pContainer->incrementColumnIndex(); + m_pContainer->addCell(nullptr); + break; + default: + break; + } + + return xContext; +} + +void OXMLRowColumn::fillStyle(const OUString& _sStyleName) +{ + if ( _sStyleName.isEmpty() ) + return; + + const SvXMLStylesContext* pAutoStyles = GetOwnImport().GetAutoStyles(); + if ( !pAutoStyles ) + return; + + rtl::Reference<PropertySetInfo> pInfo = new PropertySetInfo(); + static PropertyMapEntry const pMap[] = + { + {OUString(PROPERTY_WIDTH), PROPERTY_ID_WIDTH, ::cppu::UnoType<sal_Int32>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_HEIGHT), PROPERTY_ID_HEIGHT, ::cppu::UnoType<sal_Int32>::get() ,PropertyAttribute::BOUND,0 }, + {OUString(PROPERTY_MINHEIGHT), PROPERTY_ID_MINHEIGHT, ::cppu::UnoType<sal_Int32>::get() ,PropertyAttribute::BOUND,0 }, + }; + pInfo->add(pMap); + Reference<XPropertySet> xProp = GenericPropertySet_CreateInstance(pInfo.get()); + XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext*>(pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_COLUMN,_sStyleName))); + if ( pAutoStyle ) + { + pAutoStyle->FillPropertySet(xProp); + sal_Int32 nWidth = 0; + xProp->getPropertyValue(PROPERTY_WIDTH) >>= nWidth; + m_pContainer->addWidth(nWidth); + } + else + { + pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext* >(pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_ROW,_sStyleName))); + if ( pAutoStyle ) + { + pAutoStyle->FillPropertySet(xProp); + sal_Int32 nHeight = 0; + sal_Int32 nMinHeight = 0; + xProp->getPropertyValue(PROPERTY_HEIGHT) >>= nHeight; + xProp->getPropertyValue(PROPERTY_MINHEIGHT) >>= nMinHeight; + if (nHeight == 0 && nMinHeight > 0) + { + m_pContainer->addHeight(nMinHeight); + m_pContainer->addAutoHeight(true); + } + else + { + m_pContainer->addHeight(nHeight); + m_pContainer->addAutoHeight(false); + } + } + } +} + +ORptFilter& OXMLRowColumn::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlColumn.hxx b/reportdesign/source/filter/xml/xmlColumn.hxx new file mode 100644 index 000000000..e5bed54f7 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlColumn.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOLUMN_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOLUMN_HXX + +#include <xmloff/xmlictxt.hxx> + +namespace rptxml +{ + class ORptFilter; + class OXMLTable; + class OXMLRowColumn : public SvXMLImportContext + { + OXMLTable* m_pContainer; + + ORptFilter& GetOwnImport(); + + void fillStyle(const OUString& _sStyleName); + OXMLRowColumn(const OXMLRowColumn&) = delete; + void operator =(const OXMLRowColumn&) = delete; + public: + + OXMLRowColumn( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,OXMLTable* _pContainer + ); + virtual ~OXMLRowColumn() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOLUMN_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlComponent.cxx b/reportdesign/source/filter/xml/xmlComponent.cxx new file mode 100644 index 000000000..68111bb04 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlComponent.cxx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlComponent.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::xml::sax; +OXMLComponent::OXMLComponent( ORptFilter& _rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XReportComponent > & _xComponent + ) : + SvXMLImportContext( _rImport ) + ,m_xComponent(_xComponent) +{ + OSL_ENSURE(m_xComponent.is(),"Component is NULL!"); + + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + try + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(DRAW, XML_NAME): + m_xComponent->setName(aIter.toString()); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + } + } + catch(const Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while putting props into report component!"); + } + } +} + + +OXMLComponent::~OXMLComponent() +{ +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlComponent.hxx b/reportdesign/source/filter/xml/xmlComponent.hxx new file mode 100644 index 000000000..d48d7dcef --- /dev/null +++ b/reportdesign/source/filter/xml/xmlComponent.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOMPONENT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOMPONENT_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XReportComponent.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLComponent final : public SvXMLImportContext + { + css::uno::Reference< css::report::XReportComponent > m_xComponent; + + OXMLComponent(const OXMLComponent&); + OXMLComponent& operator =(const OXMLComponent&); + public: + + OXMLComponent( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XReportComponent >& _xComponent + ); + virtual ~OXMLComponent() override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCOMPONENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlCondPrtExpr.cxx b/reportdesign/source/filter/xml/xmlCondPrtExpr.cxx new file mode 100644 index 000000000..369d1f564 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlCondPrtExpr.cxx @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlCondPrtExpr.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <strings.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace report; + using namespace uno; + using namespace xml::sax; + +OXMLCondPrtExpr::OXMLCondPrtExpr( ORptFilter& _rImport + ,const uno::Reference< xml::sax::XFastAttributeList > & _xAttrList + ,const Reference< XPropertySet > & _xComponent ) : + SvXMLImportContext( _rImport ) +,m_xComponent(_xComponent) +{ + OSL_ENSURE(m_xComponent.is(),"Component is NULL!"); + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_FORMULA): + m_xComponent->setPropertyValue(PROPERTY_CONDITIONALPRINTEXPRESSION,uno::Any(ORptFilter::convertFormula(aIter.toString()))); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + + } + } + catch(const Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while putting Function props!"); + } +} + + +OXMLCondPrtExpr::~OXMLCondPrtExpr() +{ +} + + +void OXMLCondPrtExpr::characters( const OUString& rChars ) +{ + m_aCharBuffer.append(rChars); +} + +void OXMLCondPrtExpr::endFastElement( sal_Int32 ) +{ + if (m_aCharBuffer.getLength()) + m_xComponent->setPropertyValue(PROPERTY_CONDITIONALPRINTEXPRESSION,Any(m_aCharBuffer.makeStringAndClear())); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlCondPrtExpr.hxx b/reportdesign/source/filter/xml/xmlCondPrtExpr.hxx new file mode 100644 index 000000000..a69c5a493 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlCondPrtExpr.hxx @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONDPRTEXPR_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONDPRTEXPR_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <rtl/ustrbuf.hxx> + +namespace rptxml +{ + class ORptFilter; + class OXMLCondPrtExpr : public SvXMLImportContext + { + css::uno::Reference< css::beans::XPropertySet > m_xComponent; + OUStringBuffer m_aCharBuffer; + + OXMLCondPrtExpr(const OXMLCondPrtExpr&) = delete; + void operator =(const OXMLCondPrtExpr&) = delete; + public: + + OXMLCondPrtExpr( ORptFilter& _rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & _xAttrList + ,const css::uno::Reference< css::beans::XPropertySet >& _xComponent); + virtual ~OXMLCondPrtExpr() override; + + virtual void SAL_CALL characters( const OUString& rChars ) override; + virtual void SAL_CALL endFastElement( sal_Int32 nElement ) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONDPRTEXPR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlControlProperty.cxx b/reportdesign/source/filter/xml/xmlControlProperty.cxx new file mode 100644 index 000000000..95415257a --- /dev/null +++ b/reportdesign/source/filter/xml/xmlControlProperty.cxx @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <cmath> +#include <map> + +#include "xmlControlProperty.hxx" + +#include <o3tl/temporary.hxx> +#include <rtl/strbuf.hxx> +#include <sax/tools/converter.hxx> +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include <tools/date.hxx> +#include <unotools/datetime.hxx> +#include <com/sun/star/util/DateTime.hpp> +#include <rtl/math.hxx> +#include <osl/diagnose.h> + +#define TYPE_DATE 1 +#define TYPE_TIME 2 +#define TYPE_DATETIME 3 + +namespace rptxml +{ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::xml::sax; + +OXMLControlProperty::OXMLControlProperty( ORptFilter& rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XPropertySet >& _xControl + ,OXMLControlProperty* _pContainer) : + SvXMLImportContext( rImport ) + ,m_xControl(_xControl) + ,m_pContainer(_pContainer) + ,m_bIsList(false) +{ + m_aPropType = cppu::UnoType<void>::get(); + + OSL_ENSURE(m_xControl.is(),"Control is NULL!"); + + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(FORM, XML_LIST_PROPERTY): + m_bIsList = aIter.toView() == "true"; + break; + case XML_ELEMENT(OOO, XML_VALUE_TYPE): + { + // needs to be translated into a css::uno::Type + static std::map< OUString, css::uno::Type > const s_aTypeNameMap + { + { GetXMLToken( XML_BOOLEAN) , cppu::UnoType<bool>::get() }, + // Not a copy paste error, see comment xmloff/source/forms/propertyimport.cxx lines 244-248 + { GetXMLToken( XML_FLOAT) , cppu::UnoType<double>::get() }, + { GetXMLToken( XML_DOUBLE) , cppu::UnoType<double>::get() }, + { GetXMLToken( XML_STRING) , cppu::UnoType<OUString>::get() }, + { GetXMLToken( XML_INT) , cppu::UnoType<sal_Int32>::get() }, + { GetXMLToken( XML_SHORT) , cppu::UnoType<sal_Int16>::get() }, + { GetXMLToken( XML_DATE) , cppu::UnoType<css::util::Date>::get() }, + { GetXMLToken( XML_TIME) , cppu::UnoType<css::util::Time>::get() }, + { GetXMLToken( XML_VOID) , cppu::UnoType<void>::get() }, + }; + + const std::map< OUString, css::uno::Type >::const_iterator aTypePos = s_aTypeNameMap.find(aIter.toString()); + OSL_ENSURE(s_aTypeNameMap.end() != aTypePos, "OXMLControlProperty::OXMLControlProperty: invalid type!"); + if (s_aTypeNameMap.end() != aTypePos) + m_aPropType = aTypePos->second; + } + break; + case XML_ELEMENT(FORM, XML_PROPERTY_NAME): + m_aSetting.Name = aIter.toString(); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + +} + + +OXMLControlProperty::~OXMLControlProperty() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLControlProperty::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(FORM, XML_LIST_PROPERTY): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLControlProperty( rImport,xAttrList,m_xControl); + break; + case XML_ELEMENT(OOO, XML_VALUE): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLControlProperty( rImport,xAttrList,m_xControl,this ); + break; + default: + break; + } + + return xContext; +} + +void OXMLControlProperty::endFastElement(sal_Int32 ) +{ + if ( m_pContainer ) + m_pContainer->addValue(m_aCharBuffer.makeStringAndClear()); + if ( m_aSetting.Name.isEmpty() || !m_xControl.is() ) + return; + + if ( m_bIsList && !m_aSequence.hasElements() ) + m_aSetting.Value <<= m_aSequence; + try + { + m_xControl->setPropertyValue(m_aSetting.Name,m_aSetting.Value); + } + catch(const Exception&) + { + OSL_FAIL("Unknown property found!"); + } +} + +void OXMLControlProperty::characters( const OUString& rChars ) +{ + m_aCharBuffer.append(rChars); +} + +void OXMLControlProperty::addValue(const OUString& _sValue) +{ + Any aValue; + if( TypeClass_VOID != m_aPropType.getTypeClass() ) + aValue = convertString(m_aPropType, _sValue); + + if ( !m_bIsList ) + m_aSetting.Value = aValue; + else + { + sal_Int32 nPos = m_aSequence.getLength(); + m_aSequence.realloc(nPos+1); + m_aSequence.getArray()[nPos] = aValue; + } +} + +ORptFilter& OXMLControlProperty::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +Any OXMLControlProperty::convertString(const css::uno::Type& _rExpectedType, const OUString& _rReadCharacters) +{ + Any aReturn; + switch (_rExpectedType.getTypeClass()) + { + case TypeClass_BOOLEAN: // sal_Bool + { + bool bValue(false); + bool bSuccess = + ::sax::Converter::convertBool(bValue, _rReadCharacters); + OSL_ENSURE(bSuccess, + OStringBuffer("OXMLControlProperty::convertString: could not convert \"" + + OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) + + "\" into a boolean!").getStr()); + aReturn <<= bValue; + } + break; + case TypeClass_SHORT: // sal_Int16 + case TypeClass_LONG: // sal_Int32 + { // it's a real int32/16 property + sal_Int32 nValue(0); + bool bSuccess = + ::sax::Converter::convertNumber(nValue, _rReadCharacters); + OSL_ENSURE(bSuccess, + OStringBuffer("OXMLControlProperty::convertString: could not convert \"" + + OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) + + "\" into an integer!").getStr()); + if (TypeClass_SHORT == _rExpectedType.getTypeClass()) + aReturn <<= static_cast<sal_Int16>(nValue); + else + aReturn <<= nValue; + break; + } + case TypeClass_HYPER: + { + OSL_FAIL("OXMLControlProperty::convertString: 64-bit integers not implemented yet!"); + } + break; + case TypeClass_DOUBLE: + { + double nValue = 0.0; + bool bSuccess = + ::sax::Converter::convertDouble(nValue, _rReadCharacters); + OSL_ENSURE(bSuccess, + OStringBuffer("OXMLControlProperty::convertString: could not convert \"" + + OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) + + "\" into a double!").getStr()); + aReturn <<= nValue; + } + break; + case TypeClass_STRING: + aReturn <<= _rReadCharacters; + break; + case TypeClass_STRUCT: + { + // recognized structs: + static css::uno::Type s_aDateType = ::cppu::UnoType<css::util::Date>::get(); + static css::uno::Type s_aTimeType = ::cppu::UnoType<css::util::Time>::get(); + static css::uno::Type s_aDateTimeType = ::cppu::UnoType<css::util::DateTime>::get(); + sal_Int32 nType = 0; + if ( _rExpectedType.equals(s_aDateType) ) + nType = TYPE_DATE; + else if ( _rExpectedType.equals(s_aTimeType) ) + nType = TYPE_TIME; + else if ( _rExpectedType.equals(s_aDateTimeType) ) + nType = TYPE_DATETIME; + if ( nType ) + { + // first extract the double + double nValue = 0; + bool bSuccess = + ::sax::Converter::convertDouble(nValue, _rReadCharacters); + OSL_ENSURE(bSuccess, + OStringBuffer("OPropertyImport::convertString: could not convert \"" + + OUStringToOString(_rReadCharacters, RTL_TEXTENCODING_ASCII_US) + + "\" into a double!").getStr()); + + // then convert it into the target type + switch (nType) + { + case TYPE_DATE: + { + OSL_ENSURE(std::modf(nValue, &o3tl::temporary(double())) == 0, + "OPropertyImport::convertString: a Date value with a fractional part?"); + aReturn <<= implGetDate(nValue); + } + break; + case TYPE_TIME: + { + OSL_ENSURE((static_cast<sal_uInt32>(nValue)) == 0, + "OPropertyImport::convertString: a tools::Time value with more than a fractional part?"); + aReturn <<= implGetTime(nValue); + } + break; + case TYPE_DATETIME: + { + css::util::Time aTime = implGetTime(nValue); + css::util::Date aDate = implGetDate(nValue); + + css::util::DateTime aDateTime; + aDateTime.NanoSeconds = aTime.NanoSeconds; + aDateTime.Seconds = aTime.Seconds; + aDateTime.Minutes = aTime.Minutes; + aDateTime.Hours = aTime.Hours; + aDateTime.Day = aDate.Day; + aDateTime.Month = aDate.Month; + aDateTime.Year = aDate.Year; + aReturn <<= aDateTime; + } + break; + default: + break; + } + } + else + OSL_FAIL("OPropertyImport::convertString: unsupported property type!"); + } + break; + default: + OSL_FAIL("OXMLControlProperty::convertString: invalid type class!"); + } + + return aReturn; +} + +css::util::Time OXMLControlProperty::implGetTime(double _nValue) +{ + css::util::Time aTime; + sal_uInt64 nIntValue = ::rtl::math::round(_nValue * 86400000000000.0); + aTime.NanoSeconds = static_cast<sal_uInt16>( nIntValue % 1000000000 ); + nIntValue /= 1000000000; + aTime.Seconds = static_cast<sal_uInt16>( nIntValue % 60 ); + nIntValue /= 60; + aTime.Minutes = static_cast<sal_uInt16>( nIntValue % 60 ); + nIntValue /= 60; + OSL_ENSURE(nIntValue < 24, "OPropertyImport::implGetTime: more than a day?"); + aTime.Hours = static_cast< sal_uInt16 >( nIntValue ); + + return aTime; +} + + +css::util::Date OXMLControlProperty::implGetDate(double _nValue) +{ + Date aToolsDate(static_cast<sal_uInt32>(_nValue)); + css::util::Date aDate; + ::utl::typeConvert(aToolsDate, aDate); + return aDate; +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlControlProperty.hxx b/reportdesign/source/filter/xml/xmlControlProperty.hxx new file mode 100644 index 000000000..019ec8063 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlControlProperty.hxx @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONTROLPROPERTY_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONTROLPROPERTY_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Time.hpp> +#include <rtl/ustrbuf.hxx> + +namespace rptxml +{ + class ORptFilter; + class OXMLControlProperty : public SvXMLImportContext + { + css::uno::Reference< css::beans::XPropertySet > m_xControl; + css::beans::PropertyValue m_aSetting; + css::uno::Sequence< css::uno::Any> m_aSequence; + OXMLControlProperty* m_pContainer; + css::uno::Type m_aPropType; // the type of the property the instance imports currently + bool m_bIsList; + OUStringBuffer m_aCharBuffer; + + ORptFilter& GetOwnImport(); + static css::uno::Any convertString(const css::uno::Type& _rExpectedType, const OUString& _rReadCharacters); + OXMLControlProperty(const OXMLControlProperty&) = delete; + void operator =(const OXMLControlProperty&) = delete; + public: + + OXMLControlProperty( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::beans::XPropertySet >& _xControl + ,OXMLControlProperty* _pContainer = nullptr); + virtual ~OXMLControlProperty() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + virtual void SAL_CALL characters( const OUString& rChars ) override; + + + /** adds value to property + @param _sValue + The value to add. + */ + void addValue(const OUString& _sValue); + + private: + static css::util::Time implGetTime(double _nValue); + static css::util::Date implGetDate(double _nValue); + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLCONTROLPROPERTY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlEnums.hxx b/reportdesign/source/filter/xml/xmlEnums.hxx new file mode 100644 index 000000000..36b7379ba --- /dev/null +++ b/reportdesign/source/filter/xml/xmlEnums.hxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLENUMS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLENUMS_HXX + +#define PROGRESS_BAR_STEP 20 + +namespace rptxml +{ + enum XMLReportToken + { + XML_TOK_REPORT_HEADER, + XML_TOK_PAGE_HEADER , + XML_TOK_GROUP, + XML_TOK_DETAIL , + XML_TOK_PAGE_FOOTER , + XML_TOK_REPORT_FOOTER, + XML_TOK_HEADER_ON_NEW_PAGE , + XML_TOK_FOOTER_ON_NEW_PAGE , + XML_TOK_COMMAND_TYPE , + XML_TOK_COMMAND , + XML_TOK_FILTER , + XML_TOK_CAPTION , + XML_TOK_ESCAPE_PROCESSING , + XML_TOK_REPORT_FUNCTION , + XML_TOK_REPORT_ELEMENT , + XML_TOK_REPORT_MIMETYPE , + XML_TOK_REPORT_NAME , + XML_TOK_MASTER_DETAIL_FIELDS , + XML_TOK_SUB_FRAME , + XML_TOK_SUB_BODY , + }; + + enum XMLSubDocument + { + XML_TOK_MASTER_DETAIL_FIELD + ,XML_TOK_MASTER + ,XML_TOK_SUB_DETAIL + }; + + +} // namespace rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLENUMS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlExport.cxx b/reportdesign/source/filter/xml/xmlExport.cxx new file mode 100644 index 000000000..7472b549e --- /dev/null +++ b/reportdesign/source/filter/xml/xmlExport.cxx @@ -0,0 +1,1537 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include "xmlExport.hxx" +#include "xmlAutoStyle.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/namespacemap.hxx> +#include <xmloff/txtprmap.hxx> +#include <xmloff/numehelp.hxx> +#include "xmlHelper.hxx" +#include <strings.hxx> +#include "xmlPropertyHandler.hxx" +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/report/GroupOn.hpp> +#include <com/sun/star/report/XFixedText.hpp> +#include <com/sun/star/report/XImageControl.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/report/XFunction.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/table/BorderLineStyle.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <RptDef.hxx> +#include <vcl/svapp.hxx> +#include <osl/diagnose.h> +#include <tools/color.hxx> +#include <o3tl/string_view.hxx> + +#define DEFAULT_LINE_WIDTH 2 + +namespace rptxml +{ + using namespace xmloff; + using namespace comphelper; + using namespace ::com::sun::star; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::xml; + + + /** Exports only settings + * \ingroup reportdesign_source_filter_xml + * + */ + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* + reportdesign_ORptExportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) + { + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.XMLSettingsExporter", + SvXMLExportFlags::SETTINGS )); + } + + /** Exports only content + * \ingroup reportdesign_source_filter_xml + * + */ + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* + reportdesign_ORptContentExportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) + { + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.XMLContentExporter", + SvXMLExportFlags::CONTENT )); + } + + /** Exports only styles + * \ingroup reportdesign_source_filter_xml + * + */ + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* + reportdesign_ORptStylesExportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) + { + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.XMLStylesExporter", + SvXMLExportFlags::STYLES | SvXMLExportFlags::MASTERSTYLES | SvXMLExportFlags::AUTOSTYLES | + SvXMLExportFlags::FONTDECLS|SvXMLExportFlags::OASIS )); + } + + /** Exports only meta data + * \ingroup reportdesign_source_filter_xml + * + */ + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* + reportdesign_ORptMetaExportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) + { + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.XMLMetaExporter", + SvXMLExportFlags::META )); + } + + /** Exports all + * \ingroup reportdesign_source_filter_xml + * + */ + extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* + reportdesign_ODBFullExportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) + { + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.XMLFullExporter", + SvXMLExportFlags::ALL)); + } + + namespace { + + class OSpecialHandleXMLExportPropertyMapper : public SvXMLExportPropertyMapper + { + public: + explicit OSpecialHandleXMLExportPropertyMapper(const rtl::Reference< XMLPropertySetMapper >& rMapper) : SvXMLExportPropertyMapper(rMapper ) + { + } + /** this method is called for every item that has the + MID_FLAG_SPECIAL_ITEM_EXPORT flag set */ + virtual void handleSpecialItem( + SvXMLAttributeList& /*rAttrList*/, + const XMLPropertyState& /*rProperty*/, + const SvXMLUnitConverter& /*rUnitConverter*/, + const SvXMLNamespaceMap& /*rNamespaceMap*/, + const ::std::vector< XMLPropertyState >* /*pProperties*/ = nullptr, + sal_uInt32 /*nIdx*/ = 0 ) const override + { + // nothing to do here + } + }; + + } + +static void lcl_adjustColumnSpanOverRows(ORptExport::TSectionsGrid& _rGrid) +{ + for (auto& rEntry : _rGrid) + { + ORptExport::TGrid::iterator aRowIter = rEntry.second.begin(); + ORptExport::TGrid::const_iterator aRowEnd = rEntry.second.end(); + for (; aRowIter != aRowEnd; ++aRowIter) + { + if ( aRowIter->first ) + { + sal_Int32 nColIndex = 0; + for (const auto& rCell : aRowIter->second) + { + if ( rCell.nRowSpan > 1 ) + { + sal_Int32 nColSpan = rCell.nColSpan; + for (sal_Int32 i = 1; i < rCell.nRowSpan; ++i) + { + (aRowIter+i)->second[nColIndex].nColSpan = nColSpan; + } + } + ++nColIndex; + } + } + } + } +} + +ORptExport::ORptExport(const Reference< XComponentContext >& _rxContext, OUString const & implementationName, SvXMLExportFlags nExportFlag) +: SvXMLExport( _rxContext, implementationName, util::MeasureUnit::MM_100TH, XML_REPORT, SvXMLExportFlags::OASIS) +,m_bAllreadyFilled(false) +{ + setExportFlags( SvXMLExportFlags::OASIS | nExportFlag); + GetMM100UnitConverter().SetCoreMeasureUnit(css::util::MeasureUnit::MM_100TH); + GetMM100UnitConverter().SetXMLMeasureUnit(css::util::MeasureUnit::CM); + + // (getExportFlags() & EXPORT_CONTENT) != 0 ? : XML_N_OOO + GetNamespaceMap_().Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE ), XML_NAMESPACE_OFFICE ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO ); + + GetNamespaceMap_().Add( GetXMLToken(XML_NP_RPT), GetXMLToken(XML_N_RPT), XML_NAMESPACE_REPORT ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_FORM), GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_DRAW), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_TEXT), GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT ); + + + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) ) + GetNamespaceMap_().Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO ); + + if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) ) + { + GetNamespaceMap_().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK ); + } + if( getExportFlags() & SvXMLExportFlags::SETTINGS ) + { + GetNamespaceMap_().Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG ); + } + + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) ) + { + GetNamespaceMap_().Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE ); + } + // RDFa: needed for content and header/footer styles + if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + GetNamespaceMap_().Add( GetXMLToken(XML_NP_XHTML),GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML ); + // loext, needed for paragraphs inside shapes + if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) + { + GetNamespaceMap_().Add( + GetXMLToken(XML_NP_LO_EXT), GetXMLToken(XML_N_LO_EXT), + XML_NAMESPACE_LO_EXT); + } + } + // GRDDL: to convert RDFa and meta.xml to RDF + if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) ) + { + GetNamespaceMap_().Add( GetXMLToken(XML_NP_GRDDL),GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL ); + } + + GetNamespaceMap_().Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE ); + GetNamespaceMap_().Add( GetXMLToken(XML_NP_NUMBER), GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER ); + + m_sTableStyle = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TABLE, GetXMLToken(XML_STYLE_NAME) ); + m_sCellStyle = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_REPORT, GetXMLToken(XML_STYLE_NAME) ); + + + m_xPropHdlFactory = new OXMLRptPropHdlFactory(); + rtl::Reference < XMLPropertyHandlerFactory> xFac = new ::xmloff::OControlPropertyHandlerFactory(); + rtl::Reference < XMLPropertySetMapper > xTableStylesPropertySetMapper1 = new XMLPropertySetMapper(OXMLHelper::GetTableStyleProps(),xFac, true); + rtl::Reference < XMLPropertySetMapper > xTableStylesPropertySetMapper2 = new XMLTextPropertySetMapper(TextPropMap::TABLE_DEFAULTS, true ); + xTableStylesPropertySetMapper1->AddMapperEntry(xTableStylesPropertySetMapper2); + + m_xTableStylesExportPropertySetMapper = new SvXMLExportPropertyMapper(xTableStylesPropertySetMapper1); + + m_xCellStylesPropertySetMapper = OXMLHelper::GetCellStylePropertyMap( false, true); + m_xCellStylesExportPropertySetMapper = new OSpecialHandleXMLExportPropertyMapper(m_xCellStylesPropertySetMapper); + m_xCellStylesExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this)); + + rtl::Reference < XMLPropertySetMapper > xColumnStylesPropertySetMapper = new XMLPropertySetMapper(OXMLHelper::GetColumnStyleProps(), m_xPropHdlFactory, true); + m_xColumnStylesExportPropertySetMapper = new OSpecialHandleXMLExportPropertyMapper(xColumnStylesPropertySetMapper); + + rtl::Reference < XMLPropertySetMapper > xRowStylesPropertySetMapper = new XMLPropertySetMapper(OXMLHelper::GetRowStyleProps(), m_xPropHdlFactory, true); + m_xRowStylesExportPropertySetMapper = new OSpecialHandleXMLExportPropertyMapper(xRowStylesPropertySetMapper); + + rtl::Reference < XMLPropertySetMapper > xPropMapper(new XMLTextPropertySetMapper( TextPropMap::PARA, true )); + m_xParaPropMapper = new OSpecialHandleXMLExportPropertyMapper( xPropMapper); + + const OUString& sFamily( GetXMLToken(XML_PARAGRAPH) ); + GetAutoStylePool()->AddFamily( XmlStyleFamily::TEXT_PARAGRAPH, sFamily, + m_xParaPropMapper, "P" ); + + GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_CELL, XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME, + m_xCellStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX); + GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_COLUMN, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME, + m_xColumnStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX); + GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_ROW, XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME, + m_xRowStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX); + GetAutoStylePool()->AddFamily(XmlStyleFamily::TABLE_TABLE, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME, + m_xTableStylesExportPropertySetMapper, XML_STYLE_FAMILY_TABLE_TABLE_STYLES_PREFIX); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ORptExport_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptExport(context, + "com.sun.star.comp.report.ExportFilter", + SvXMLExportFlags::CONTENT | SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::FONTDECLS)); +} + + +void ORptExport::exportFunctions(const Reference<XIndexAccess>& _xFunctions) +{ + const sal_Int32 nCount = _xFunctions->getCount(); + for (sal_Int32 i = 0; i< nCount; ++i) + { + uno::Reference< report::XFunction> xFunction(_xFunctions->getByIndex(i),uno::UNO_QUERY_THROW); + exportFunction(xFunction); + } +} + +void ORptExport::exportFunction(const uno::Reference< XFunction>& _xFunction) +{ + exportFormula(XML_FORMULA,_xFunction->getFormula()); + beans::Optional< OUString> aInitial = _xFunction->getInitialFormula(); + if ( aInitial.IsPresent && !aInitial.Value.isEmpty() ) + exportFormula(XML_INITIAL_FORMULA ,aInitial.Value ); + AddAttribute( XML_NAMESPACE_REPORT, XML_NAME , _xFunction->getName() ); + if ( _xFunction->getPreEvaluated() ) + AddAttribute( XML_NAMESPACE_REPORT, XML_PRE_EVALUATED , XML_TRUE ); + if ( _xFunction->getDeepTraversing() ) + AddAttribute( XML_NAMESPACE_REPORT, XML_DEEP_TRAVERSING , XML_TRUE ); + + SvXMLElementExport aFunction(*this,XML_NAMESPACE_REPORT, XML_FUNCTION, true, true); +} + +void ORptExport::exportMasterDetailFields(const Reference<XReportComponent>& _xReportComponent) +{ + const uno::Sequence< OUString> aMasterFields = _xReportComponent->getMasterFields(); + if ( !aMasterFields.hasElements() ) + return; + + SvXMLElementExport aElement(*this,XML_NAMESPACE_REPORT, XML_MASTER_DETAIL_FIELDS, true, true); + const uno::Sequence< OUString> aDetailFields = _xReportComponent->getDetailFields(); + + OSL_ENSURE(aDetailFields.getLength() == aMasterFields.getLength(),"not equal length for master and detail fields!"); + + const OUString* pDetailFieldsIter = aDetailFields.getConstArray(); + for(const OUString& rMasterField : aMasterFields) + { + AddAttribute( XML_NAMESPACE_REPORT, XML_MASTER , rMasterField ); + if ( !pDetailFieldsIter->isEmpty() ) + AddAttribute( XML_NAMESPACE_REPORT, XML_DETAIL , *pDetailFieldsIter ); + SvXMLElementExport aPair(*this,XML_NAMESPACE_REPORT, XML_MASTER_DETAIL_FIELD, true, true); + ++pDetailFieldsIter; + } +} + +void ORptExport::exportReport(const Reference<XReportDefinition>& _xReportDefinition) +{ + if ( !_xReportDefinition.is() ) + return; + + exportFunctions(_xReportDefinition->getFunctions()); + exportGroupsExpressionAsFunction(_xReportDefinition->getGroups()); + + if ( _xReportDefinition->getReportHeaderOn() ) + { + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_REPORT_HEADER, true, true); + exportSection(_xReportDefinition->getReportHeader()); + } + if ( _xReportDefinition->getPageHeaderOn() ) + { + OUStringBuffer sValue; + sal_Int16 nRet = _xReportDefinition->getPageHeaderOption(); + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetReportPrintOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, nRet,aXML_EnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_PAGE_PRINT_OPTION,sValue.makeStringAndClear()); + + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_PAGE_HEADER, true, true); + exportSection(_xReportDefinition->getPageHeader(),true); + } + + exportGroup(_xReportDefinition,0); + + if ( _xReportDefinition->getPageFooterOn() ) + { + OUStringBuffer sValue; + sal_Int16 nRet = _xReportDefinition->getPageFooterOption(); + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetReportPrintOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, nRet,aXML_EnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_PAGE_PRINT_OPTION,sValue.makeStringAndClear()); + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_PAGE_FOOTER, true, true); + exportSection(_xReportDefinition->getPageFooter(),true); + } + if ( _xReportDefinition->getReportFooterOn() ) + { + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_REPORT_FOOTER, true, true); + exportSection(_xReportDefinition->getReportFooter()); + } +} + +void ORptExport::exportComponent(const Reference<XReportComponent>& _xReportComponent) +{ + OSL_ENSURE(_xReportComponent.is(),"No component interface!"); + if ( !_xReportComponent.is() ) + return; + + AddAttribute(XML_NAMESPACE_DRAW, XML_NAME,_xReportComponent->getName()); + + SvXMLElementExport aElem(*this,XML_NAMESPACE_REPORT, XML_REPORT_COMPONENT, false, false); +} + +void ORptExport::exportFormatConditions(const Reference<XReportControlModel>& _xReportElement) +{ + OSL_ENSURE(_xReportElement.is(),"_xReportElement is NULL -> GPF"); + const sal_Int32 nCount = _xReportElement->getCount(); + try + { + for (sal_Int32 i = 0; i < nCount ; ++i) + { + uno::Reference< report::XFormatCondition > xCond(_xReportElement->getByIndex(i),uno::UNO_QUERY); + if ( !xCond->getEnabled() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_ENABLED,XML_FALSE); + + AddAttribute(XML_NAMESPACE_REPORT, XML_FORMULA,xCond->getFormula()); + + exportStyleName(xCond.get(),GetAttrList(),m_sCellStyle); + SvXMLElementExport aElem(*this,XML_NAMESPACE_REPORT, XML_FORMAT_CONDITION, true, true); + } + } + catch(uno::Exception&) + { + OSL_FAIL("Can not access format condition!"); + } +} + +void ORptExport::exportReportElement(const Reference<XReportControlModel>& _xReportElement) +{ + OSL_ENSURE(_xReportElement.is(),"_xReportElement is NULL -> GPF"); + if ( !_xReportElement->getPrintWhenGroupChange() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_PRINT_WHEN_GROUP_CHANGE, XML_FALSE ); + + if ( !_xReportElement->getPrintRepeatedValues() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_PRINT_REPEATED_VALUES,XML_FALSE); + + SvXMLElementExport aElem(*this,XML_NAMESPACE_REPORT, XML_REPORT_ELEMENT, true, true); + if ( _xReportElement->getCount() ) + { + exportFormatConditions(_xReportElement); + } + + OUString sExpr = _xReportElement->getConditionalPrintExpression(); + if ( !sExpr.isEmpty() ) + { + exportFormula(XML_FORMULA,sExpr); + SvXMLElementExport aPrintExpr(*this,XML_NAMESPACE_REPORT, XML_CONDITIONAL_PRINT_EXPRESSION, true, true); + } + + // only export when parent exists + uno::Reference< report::XSection> xParent(_xReportElement->getParent(),uno::UNO_QUERY); + if ( xParent.is() ) + exportComponent(_xReportElement); +} + +static void lcl_calculate(const ::std::vector<sal_Int32>& _aPosX,const ::std::vector<sal_Int32>& _aPosY,ORptExport::TGrid& _rColumns) +{ + sal_Int32 nCountX = _aPosX.size() - 1; + sal_Int32 nCountY = _aPosY.size() - 1; + for (sal_Int32 j = 0; j < nCountY; ++j) + { + sal_Int32 nHeight = _aPosY[j+1] - _aPosY[j]; + if ( nHeight ) + for (sal_Int32 i = 0; i < nCountX ; ++i) + { + _rColumns[j].second[i] = ORptExport::TCell(1,1); + _rColumns[j].second[i].bSet = true; + } + } +} + +void ORptExport::collectStyleNames(XmlStyleFamily _nFamily,const ::std::vector< sal_Int32>& _aSize, std::vector<OUString>& _rStyleNames) +{ + ::std::vector<sal_Int32>::const_iterator aIter = _aSize.begin(); + ::std::vector<sal_Int32>::const_iterator aIter2 = aIter + 1; + ::std::vector<sal_Int32>::const_iterator aEnd = _aSize.end(); + for (;aIter2 != aEnd ; ++aIter,++aIter2) + { + ::std::vector< XMLPropertyState > aPropertyStates(1, 0); + sal_Int32 nValue = static_cast<sal_Int32>(*aIter2 - *aIter); + aPropertyStates[0].maValue <<= nValue; + _rStyleNames.push_back(GetAutoStylePool()->Add(_nFamily, std::move(aPropertyStates) )); + } +} + +void ORptExport::collectStyleNames(XmlStyleFamily _nFamily, const ::std::vector< sal_Int32>& _aSize, const ::std::vector< sal_Int32>& _aSizeAutoGrow, std::vector<OUString>& _rStyleNames) +{ + ::std::vector<sal_Int32>::const_iterator aIter = _aSize.begin(); + ::std::vector<sal_Int32>::const_iterator aIter2 = aIter + 1; + ::std::vector<sal_Int32>::const_iterator aEnd = _aSize.end(); + for (;aIter2 != aEnd; ++aIter, ++aIter2) + { + ::std::vector< XMLPropertyState > aPropertyStates(1, 0); + sal_Int32 nValue = static_cast<sal_Int32>(*aIter2 - *aIter); + aPropertyStates[0].maValue <<= nValue; + // note: there cannot be 0-height rows, because a call to std::unique has removed them + // it cannot be predicted that the size of _aSizeAutoGrow has any relation to the size of + // _aSize, because of the same std::unique operation (and _aSizeAutoGrow wasn't even the same + // size before that), so the matching element in _aSizeAutoGrow has to be found by lookup. + ::std::vector<sal_Int32>::const_iterator aAutoGrow = ::std::find(_aSizeAutoGrow.begin(), _aSizeAutoGrow.end(), *aIter2); + bool bAutoGrow = aAutoGrow != _aSizeAutoGrow.end(); + // the mnIndex is into the array returned by OXMLHelper::GetRowStyleProps() + aPropertyStates[0].mnIndex = bAutoGrow ? 1 : 0; + _rStyleNames.push_back(GetAutoStylePool()->Add(_nFamily, std::move(aPropertyStates))); + } +} + +void ORptExport::exportSectionAutoStyle(const Reference<XSection>& _xProp) +{ + OSL_ENSURE(_xProp != nullptr,"Section is NULL -> GPF"); + exportAutoStyle(_xProp); + + Reference<XReportDefinition> xReport = _xProp->getReportDefinition(); + const awt::Size aSize = rptui::getStyleProperty<awt::Size>(xReport,PROPERTY_PAPERSIZE); + const sal_Int32 nOffset = rptui::getStyleProperty<sal_Int32>(xReport,PROPERTY_LEFTMARGIN); + const sal_Int32 nCount = _xProp->getCount(); + + ::std::vector<sal_Int32> aColumnPos; + aColumnPos.reserve(2*(nCount + 1)); + aColumnPos.push_back(nOffset); + aColumnPos.push_back(aSize.Width - rptui::getStyleProperty<sal_Int32>(xReport,PROPERTY_RIGHTMARGIN)); + + ::std::vector<sal_Int32> aRowPos; + aRowPos.reserve(2*(nCount + 1)); + aRowPos.push_back(0); + aRowPos.push_back(_xProp->getHeight()); + + + ::std::vector<sal_Int32> aRowPosAutoGrow; + aRowPosAutoGrow.reserve(2 * (nCount + 1)); + + + sal_Int32 i; + for (i = 0 ; i< nCount ; ++i) + { + Reference<XReportComponent> xReportElement(_xProp->getByIndex(i),uno::UNO_QUERY); + uno::Reference< XShape> xShape(xReportElement,uno::UNO_QUERY); + if ( xShape.is() ) + continue; + OSL_ENSURE( xReportElement.is(),"NULL Element in Section!" ); + if ( !xReportElement.is() ) + continue; + sal_Int32 nX = xReportElement->getPositionX(); + aColumnPos.push_back(nX); + Reference<XFixedLine> xFixedLine(xReportElement,uno::UNO_QUERY); + if ( xFixedLine.is() && xFixedLine->getOrientation() == 1 ) // vertical + { + sal_Int32 nWidth = static_cast<sal_Int32>(xReportElement->getWidth()*0.5); + nX += nWidth; + aColumnPos.push_back(nX); + nX += xReportElement->getWidth() - nWidth; + } + else + nX += xReportElement->getWidth(); + aColumnPos.push_back(nX); // --nX why? + + sal_Int32 nY = xReportElement->getPositionY(); + aRowPos.push_back(nY); + nY += xReportElement->getHeight(); + aRowPos.push_back(nY); // --nY why? + bool bAutoGrow = xReportElement->getAutoGrow(); + if (bAutoGrow) + { + // the resulting table row ending at nY should auto-grow + aRowPosAutoGrow.push_back(nY); + } + } + + ::std::sort(aColumnPos.begin(),aColumnPos.end(),::std::less<sal_Int32>()); + aColumnPos.erase(::std::unique(aColumnPos.begin(),aColumnPos.end()),aColumnPos.end()); + + // note: the aRowPos contains top and bottom position of every report control; we now compute the + // top of every row in the resulting table, by sorting and eliminating unnecessary duplicate + // positions. (the same for the columns in the preceding lines.) + ::std::sort(aRowPos.begin(),aRowPos.end(),::std::less<sal_Int32>()); + aRowPos.erase(::std::unique(aRowPos.begin(),aRowPos.end()),aRowPos.end()); + + TSectionsGrid::iterator aInsert = m_aSectionsGrid.emplace( + _xProp.get(), + TGrid(aRowPos.size() - 1,TGrid::value_type(false,TRow(aColumnPos.size() - 1))) + ).first; + lcl_calculate(aColumnPos,aRowPos,aInsert->second); + + TGridStyleMap::iterator aPos = m_aColumnStyleNames.emplace(_xProp.get(),std::vector<OUString>()).first; + collectStyleNames(XmlStyleFamily::TABLE_COLUMN,aColumnPos,aPos->second); + aPos = m_aRowStyleNames.emplace(_xProp.get(),std::vector<OUString>()).first; + collectStyleNames(XmlStyleFamily::TABLE_ROW, aRowPos, aRowPosAutoGrow, aPos->second); + + sal_Int32 x1 = 0; + sal_Int32 y1 = 0; + sal_Int32 x2 = 0; + sal_Int32 y2 = 0; + sal_Int32 xi = 0; + sal_Int32 yi = 0; + bool isOverlap = false; + + for (i = 0 ; i< nCount ; ++i) + { + Reference<XReportComponent> xReportElement(_xProp->getByIndex(i),uno::UNO_QUERY); + uno::Reference< XShape> xShape(xReportElement,uno::UNO_QUERY); + if ( xShape.is() ) + continue; + sal_Int32 nPos = xReportElement->getPositionX(); + x1 = (::std::find(aColumnPos.begin(),aColumnPos.end(),nPos) - aColumnPos.begin()); + Reference<XFixedLine> xFixedLine(xReportElement,uno::UNO_QUERY); + if ( xFixedLine.is() && xFixedLine->getOrientation() == 1 ) // vertical + nPos += static_cast<sal_Int32>(xReportElement->getWidth()*0.5); + else + nPos += xReportElement->getWidth(); // -1 why + x2 = (::std::find(aColumnPos.begin(),aColumnPos.end(),nPos) - aColumnPos.begin()); + + nPos = xReportElement->getPositionY(); + y1 = (::std::find(aRowPos.begin(),aRowPos.end(),nPos) - aRowPos.begin()); + nPos += xReportElement->getHeight(); // -1 why? + y2 = (::std::find(aRowPos.begin(),aRowPos.end(),nPos) - aRowPos.begin()); + + isOverlap = false; + yi = y1; + while(yi < y2 && !isOverlap) // find overlapping controls + { + xi = x1; + while(xi < x2 && !isOverlap) + { + if ( aInsert->second[yi].second[xi].xElement.is() ) + { + isOverlap = true; + } + ++xi; + } + ++yi; + } + + if (!isOverlap) + { + yi = y1; + while(yi < y2) + { + xi = x1; + while(xi < x2) + { + aInsert->second[yi].second[xi] = TCell(); + ++xi; + } + aInsert->second[yi].first = true; + ++yi; + } + + if (x2 - x1 != 0 && y2 - y1 != 0) + { + sal_Int32 nColSpan = x2 - x1; + sal_Int32 nRowSpan = y2 - y1; + aInsert->second[y1].second[x1] = + TCell( + nColSpan, + nRowSpan, + xReportElement + ); + } + } + } + + lcl_adjustColumnSpanOverRows(m_aSectionsGrid); + exportReportComponentAutoStyles(_xProp); +} + +void ORptExport::exportReportComponentAutoStyles(const Reference<XSection>& _xProp) +{ + const sal_Int32 nCount = _xProp->getCount(); + for (sal_Int32 i = 0 ; i< nCount ; ++i) + { + const Reference<XReportComponent> xReportElement(_xProp->getByIndex(i),uno::UNO_QUERY); + const Reference< report::XShape > xShape(xReportElement,uno::UNO_QUERY); + if ( xShape.is() ) + { + rtl::Reference< XMLShapeExport > xShapeExport = GetShapeExport(); + xShapeExport->seekShapes(_xProp); + SolarMutexGuard aGuard; + xShapeExport->collectShapeAutoStyles(xShape); + } + else + { + exportAutoStyle(xReportElement.get()); + + Reference<XFormattedField> xFormattedField(xReportElement,uno::UNO_QUERY); + if ( xFormattedField.is() ) + { + try + { + const sal_Int32 nFormatCount = xFormattedField->getCount(); + for (sal_Int32 j = 0; j < nFormatCount ; ++j) + { + uno::Reference< report::XFormatCondition > xCond(xFormattedField->getByIndex(j),uno::UNO_QUERY); + exportAutoStyle(xCond.get(),xFormattedField); + } + } + catch(uno::Exception&) + { + OSL_FAIL("Can not access format condition!"); + } + } + } + } +} + +void ORptExport::exportSection(const Reference<XSection>& _xSection,bool bHeader) +{ + OSL_ENSURE(_xSection.is(),"Section is NULL -> GPF"); + AddAttribute(XML_NAMESPACE_TABLE, XML_NAME,_xSection->getName()); + + if ( !_xSection->getVisible() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_VISIBLE,XML_FALSE); + + if ( !bHeader ) + { + OUStringBuffer sValue; + sal_Int16 nRet = _xSection->getForceNewPage(); + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetForceNewPageOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, nRet,aXML_EnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_FORCE_NEW_PAGE,sValue.makeStringAndClear()); + + nRet = _xSection->getNewRowOrCol(); + if ( SvXMLUnitConverter::convertEnum( sValue, nRet,aXML_EnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_FORCE_NEW_COLUMN,sValue.makeStringAndClear()); + if ( _xSection->getKeepTogether() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_KEEP_TOGETHER, XML_TRUE ); + } + + exportStyleName(_xSection.get(),GetAttrList(),m_sTableStyle); + + /// TODO export as table layout + SvXMLElementExport aComponents(*this,XML_NAMESPACE_TABLE, XML_TABLE, true, true); + + OUString sExpr = _xSection->getConditionalPrintExpression(); + if ( !sExpr.isEmpty() ) + { + exportFormula(XML_FORMULA,sExpr); + SvXMLElementExport aPrintExpr(*this,XML_NAMESPACE_REPORT, XML_CONDITIONAL_PRINT_EXPRESSION, true, false); + } + + exportContainer(_xSection); +} + +void ORptExport::exportTableColumns(const Reference< XSection>& _xSection) +{ + SvXMLElementExport aColumns(*this,XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, true, true); + TGridStyleMap::const_iterator aColFind = m_aColumnStyleNames.find(_xSection); + OSL_ENSURE(aColFind != m_aColumnStyleNames.end(),"ORptExport::exportTableColumns: Section not found in m_aColumnStyleNames!"); + if ( aColFind == m_aColumnStyleNames.end() ) + return; + + for (auto& aCol : aColFind->second) + { + AddAttribute(m_sTableStyle, aCol); + SvXMLElementExport aColumn(*this,XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, true, true); + } +} + +void ORptExport::exportContainer(const Reference< XSection>& _xSection) +{ + OSL_ENSURE(_xSection.is(),"Section is NULL -> GPF"); + + exportTableColumns(_xSection); + + TSectionsGrid::const_iterator aFind = m_aSectionsGrid.find(_xSection); + OSL_ENSURE(aFind != m_aSectionsGrid.end(),"ORptExport::exportContainer: Section not found in grid!"); + if ( aFind == m_aSectionsGrid.end() ) + return; + TGrid::const_iterator aRowIter = aFind->second.begin(); + TGrid::const_iterator aRowEnd = aFind->second.end(); + + TGridStyleMap::const_iterator aRowFind = m_aRowStyleNames.find(_xSection); + auto aHeightIter = aRowFind->second.cbegin(); + OSL_ENSURE(aRowFind->second.size() == aFind->second.size(),"Different count for rows"); + + bool bShapeHandled = false; + ::std::map<sal_Int32,sal_Int32> aRowSpan; + for (sal_Int32 j = 0; aRowIter != aRowEnd; ++aRowIter,++j,++aHeightIter) + { + AddAttribute( m_sTableStyle,*aHeightIter ); + SvXMLElementExport aRow(*this,XML_NAMESPACE_TABLE, XML_TABLE_ROW, true, true); + if ( aRowIter->first ) + { + ::std::vector< TCell >::const_iterator aColIter = aRowIter->second.begin(); + ::std::vector< TCell >::const_iterator aColEnd = aRowIter->second.end(); + sal_Int32 nEmptyCellColSpan = 0; + for (; aColIter != aColEnd; ++aColIter) + { + bool bCoveredCell = false; + sal_Int32 nColSpan = 0; + sal_Int32 nColIndex = aColIter - aRowIter->second.begin(); + ::std::map<sal_Int32,sal_Int32>::iterator aRowSpanFind = aRowSpan.find(nColIndex); + if ( aRowSpanFind != aRowSpan.end() ) + { + nColSpan = 1; + if ( !--(aRowSpanFind->second) ) + aRowSpan.erase(aRowSpanFind); + + if ( aColIter->nColSpan > 1 ) + nColSpan += aColIter->nColSpan - 1; + + bCoveredCell = true; + aColIter = aColIter + (aColIter->nColSpan - 1); + } + else if ( aColIter->bSet ) + { + if ( nEmptyCellColSpan > 0 ) + { + AddAttribute( XML_NAMESPACE_TABLE,XML_NUMBER_COLUMNS_SPANNED, OUString::number(nEmptyCellColSpan) ); + bCoveredCell = true; + nColSpan = nEmptyCellColSpan - 1; + nEmptyCellColSpan = 0; + } + sal_Int32 nSpan = aColIter->nColSpan; + if ( nSpan > 1 ) + { + AddAttribute( XML_NAMESPACE_TABLE,XML_NUMBER_COLUMNS_SPANNED, OUString::number(nSpan) ); + nColSpan = nSpan - 1; + bCoveredCell = true; + } + nSpan = aColIter->nRowSpan; + if ( nSpan > 1 ) + { + AddAttribute( XML_NAMESPACE_TABLE,XML_NUMBER_ROWS_SPANNED, OUString::number(nSpan) ); + aRowSpan[nColIndex] = nSpan - 1; + } + if ( aColIter->xElement.is() ) + exportStyleName(aColIter->xElement.get(),GetAttrList(),m_sTableStyle); + + // start <table:table-cell> + Reference<XFormattedField> xFormattedField(aColIter->xElement,uno::UNO_QUERY); + if ( xFormattedField.is() ) + { + sal_Int32 nFormatKey = xFormattedField->getFormatKey(); + XMLNumberFormatAttributesExportHelper aHelper(GetNumberFormatsSupplier(),*this); + bool bIsStandard = false; + sal_Int16 nCellType = aHelper.GetCellType(nFormatKey,bIsStandard); + // "Standard" means "no format set, value could be anything", + // so don't set a format attribute in this case. + // P.S.: "Standard" is called "General" in some languages + if (!bIsStandard) + { + if ( nCellType == util::NumberFormat::TEXT ) + aHelper.SetNumberFormatAttributes("", u""); + else + aHelper.SetNumberFormatAttributes(nFormatKey, 0.0, false); + } + } + SvXMLElementExport aCell(*this,XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, false); + + if ( aColIter->xElement.is() ) + { + // start <text:p> + SvXMLElementExport aParagraphContent(*this,XML_NAMESPACE_TEXT, XML_P, true, false); + Reference<XServiceInfo> xElement(aColIter->xElement,uno::UNO_QUERY); + + if ( !bShapeHandled ) + { + bShapeHandled = true; + exportShapes(_xSection,false); + } + uno::Reference< XShape > xShape(xElement,uno::UNO_QUERY); + uno::Reference< XFixedLine > xFixedLine(xElement,uno::UNO_QUERY); + if ( !xShape.is() && !xFixedLine.is() ) + { + Reference<XReportControlModel> xReportElement(xElement,uno::UNO_QUERY); + Reference<XReportDefinition> xReportDefinition(xElement,uno::UNO_QUERY); + Reference< XImageControl > xImage(xElement,uno::UNO_QUERY); + Reference<XSection> xSection(xElement,uno::UNO_QUERY); + + XMLTokenEnum eToken = XML_SECTION; + bool bExportData = false; + if ( xElement->supportsService(SERVICE_FIXEDTEXT) ) + { + eToken = XML_FIXED_CONTENT; + } + else if ( xElement->supportsService(SERVICE_FORMATTEDFIELD) ) + { + eToken = XML_FORMATTED_TEXT; + bExportData = true; + } + else if ( xElement->supportsService(SERVICE_IMAGECONTROL) ) + { + eToken = XML_IMAGE; + OUString sTargetLocation = xImage->getImageURL(); + if ( !sTargetLocation.isEmpty() ) + { + sTargetLocation = GetRelativeReference(sTargetLocation); + AddAttribute(XML_NAMESPACE_FORM, XML_IMAGE_DATA,sTargetLocation); + } + bExportData = true; + OUStringBuffer sValue; + const SvXMLEnumMapEntry<sal_Int16>* aXML_ImageScaleEnumMap = OXMLHelper::GetImageScaleOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, xImage->getScaleMode(),aXML_ImageScaleEnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_SCALE, sValue.makeStringAndClear() ); + } + else if ( xReportDefinition.is() ) + { + eToken = XML_SUB_DOCUMENT; + } + + if ( bExportData ) + { + const bool bPageSet = exportFormula(XML_FORMULA,xReportElement->getDataField()); + if ( bPageSet ) + eToken = XML_FIXED_CONTENT; + else if ( eToken == XML_IMAGE ) + AddAttribute(XML_NAMESPACE_REPORT, XML_PRESERVE_IRI, xImage->getPreserveIRI() ? XML_TRUE : XML_FALSE ); + } + + { + // start <report:eToken> + SvXMLElementExport aComponents(*this,XML_NAMESPACE_REPORT, eToken, false, false); + if ( eToken == XML_FIXED_CONTENT ) + exportParagraph(xReportElement); + if ( xReportElement.is() ) + exportReportElement(xReportElement); + + if (eToken == XML_SUB_DOCUMENT && xReportDefinition.is()) + { + SvXMLElementExport aOfficeElement( *this, XML_NAMESPACE_OFFICE, XML_BODY, true, true ); + SvXMLElementExport aElem( *this, true, + XML_NAMESPACE_OFFICE, XML_REPORT, + true, true ); + + exportReportAttributes(xReportDefinition); + exportReport(xReportDefinition); + } + else if ( xSection.is() ) + exportSection(xSection); + } + } + } + else if ( !bShapeHandled ) + { + bShapeHandled = true; + exportShapes(_xSection); + } + aColIter = aColIter + (aColIter->nColSpan - 1); + } + else + ++nEmptyCellColSpan; + if ( bCoveredCell ) + { + for (sal_Int32 k = 0; k < nColSpan; ++k) + { + SvXMLElementExport aCell(*this,XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, true, true); + } + + } + } + if ( nEmptyCellColSpan ) + { + { + AddAttribute( XML_NAMESPACE_TABLE,XML_NUMBER_COLUMNS_SPANNED, OUString::number(nEmptyCellColSpan) ); + SvXMLElementExport aCell(*this,XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); + if ( !bShapeHandled ) + { + bShapeHandled = true; + exportShapes(_xSection); + } + } + for (sal_Int32 k = 0; k < nEmptyCellColSpan; ++k) + { + SvXMLElementExport aCoveredCell(*this,XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, true, true); + } + } + } + else + { // empty rows + sal_Int32 nEmptyCellColSpan = aRowIter->second.size(); + if ( nEmptyCellColSpan ) + { + { + AddAttribute( XML_NAMESPACE_TABLE,XML_NUMBER_COLUMNS_SPANNED, OUString::number(nEmptyCellColSpan) ); + SvXMLElementExport aCell(*this,XML_NAMESPACE_TABLE, XML_TABLE_CELL, true, true); + if ( !bShapeHandled ) + { + bShapeHandled = true; + exportShapes(_xSection); + } + } + for (sal_Int32 k = 1; k < nEmptyCellColSpan; ++k) + { + SvXMLElementExport aCoveredCell(*this,XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL, true, true); + } + } + } + } +} + +OUString ORptExport::convertFormula(const OUString& _sFormula) +{ + OUString sFormula = _sFormula; + if ( _sFormula == "rpt:" ) + sFormula.clear(); + return sFormula; +} + +bool ORptExport::exportFormula(enum ::xmloff::token::XMLTokenEnum eName,const OUString& _sFormula) +{ + const OUString sFieldData = convertFormula(_sFormula); + sal_Int32 nPageNumberIndex = sFieldData.indexOf("PageNumber()"); + sal_Int32 nPageCountIndex = sFieldData.indexOf("PageCount()"); + bool bRet = nPageNumberIndex != -1 || nPageCountIndex != -1; + if ( !bRet ) + AddAttribute(XML_NAMESPACE_REPORT, eName,sFieldData); + + return bRet; +} + +void ORptExport::exportStyleName(XPropertySet* _xProp,SvXMLAttributeList& _rAtt,const OUString& _sName) +{ + Reference<XPropertySet> xFind(_xProp); + TPropertyStyleMap::const_iterator aFind = m_aAutoStyleNames.find(xFind); + if ( aFind != m_aAutoStyleNames.end() ) + { + _rAtt.AddAttribute( _sName, + aFind->second ); + m_aAutoStyleNames.erase(aFind); + } +} + +void ORptExport::exportGroup(const Reference<XReportDefinition>& _xReportDefinition,sal_Int32 _nPos,bool _bExportAutoStyle) +{ + if ( !_xReportDefinition.is() ) + return; + + Reference< XGroups > xGroups = _xReportDefinition->getGroups(); + if ( !xGroups.is() ) + return; + + sal_Int32 nCount = xGroups->getCount(); + if ( _nPos >= 0 && _nPos < nCount ) + { + Reference<XGroup> xGroup(xGroups->getByIndex(_nPos),uno::UNO_QUERY); + OSL_ENSURE(xGroup.is(),"No Group prepare for GPF"); + if ( _bExportAutoStyle ) + { + if ( xGroup->getHeaderOn() ) + exportSectionAutoStyle(xGroup->getHeader()); + exportGroup(_xReportDefinition,_nPos+1,_bExportAutoStyle); + if ( xGroup->getFooterOn() ) + exportSectionAutoStyle(xGroup->getFooter()); + } + else + { + if ( xGroup->getSortAscending() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_SORT_ASCENDING, XML_TRUE ); + + if ( xGroup->getStartNewColumn() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_START_NEW_COLUMN, XML_TRUE); + if ( xGroup->getResetPageNumber() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_RESET_PAGE_NUMBER, XML_TRUE ); + + const OUString sField = xGroup->getExpression(); + OUString sExpression = sField; + if ( !sExpression.isEmpty() ) + { + sal_Int32 nIndex = sExpression.indexOf('"'); + while ( nIndex > -1 ) + { + sExpression = sExpression.replaceAt(nIndex, 1, u"\"\""); + nIndex = sExpression.indexOf('"',nIndex+2); + } + + TGroupFunctionMap::const_iterator aGroupFind = m_aGroupFunctionMap.find(xGroup); + if ( aGroupFind != m_aGroupFunctionMap.end() ) + sExpression = aGroupFind->second->getName(); + sExpression = "rpt:HASCHANGED(\"" + sExpression + "\")"; + } + AddAttribute(XML_NAMESPACE_REPORT, XML_SORT_EXPRESSION, sField); + AddAttribute(XML_NAMESPACE_REPORT, XML_GROUP_EXPRESSION,sExpression); + sal_Int16 nRet = xGroup->getKeepTogether(); + OUStringBuffer sValue; + const SvXMLEnumMapEntry<sal_Int16>* aXML_KeepTogetherEnumMap = OXMLHelper::GetKeepTogetherOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, nRet, aXML_KeepTogetherEnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_KEEP_TOGETHER,sValue.makeStringAndClear()); + + SvXMLElementExport aGroup(*this,XML_NAMESPACE_REPORT, XML_GROUP, true, true); + exportFunctions(xGroup->getFunctions()); + if ( xGroup->getHeaderOn() ) + { + Reference<XSection> xSection = xGroup->getHeader(); + if ( xSection->getRepeatSection() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_REPEAT_SECTION,XML_TRUE ); + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_GROUP_HEADER, true, true); + exportSection(xSection); + } + exportGroup(_xReportDefinition,_nPos+1,_bExportAutoStyle); + if ( xGroup->getFooterOn() ) + { + Reference<XSection> xSection = xGroup->getFooter(); + if ( xSection->getRepeatSection() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_REPEAT_SECTION,XML_TRUE ); + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_GROUP_FOOTER, true, true); + exportSection(xSection); + } + } + } + else if ( _bExportAutoStyle ) + { + exportSectionAutoStyle(_xReportDefinition->getDetail()); + } + else + { + SvXMLElementExport aGroupSection(*this,XML_NAMESPACE_REPORT, XML_DETAIL, true, true); + exportSection(_xReportDefinition->getDetail()); + } +} + +void ORptExport::exportAutoStyle(XPropertySet* _xProp,const Reference<XFormattedField>& _xParentFormattedField) +{ + const uno::Reference<report::XReportControlFormat> xFormat(_xProp,uno::UNO_QUERY); + if ( xFormat.is() ) + { + try + { + const awt::FontDescriptor aFont = xFormat->getFontDescriptor(); + OSL_ENSURE(!aFont.Name.isEmpty(),"No Font Name !"); + GetFontAutoStylePool()->Add(aFont.Name,aFont.StyleName,static_cast<FontFamily>(aFont.Family), + static_cast<FontPitch>(aFont.Pitch),aFont.CharSet ); + } + catch(beans::UnknownPropertyException&) + { + // not interested in + } + } + const uno::Reference< report::XShape> xShape(_xProp,uno::UNO_QUERY); + if ( xShape.is() ) + { + ::std::vector<XMLPropertyState> aPropertyStates(m_xParaPropMapper->Filter(*this, _xProp)); + if ( !aPropertyStates.empty() ) + m_aAutoStyleNames.emplace( _xProp,GetAutoStylePool()->Add( XmlStyleFamily::TEXT_PARAGRAPH, std::move(aPropertyStates) )); + } + ::std::vector<XMLPropertyState> aPropertyStates(m_xCellStylesExportPropertySetMapper->Filter(*this, _xProp)); + Reference<XFixedLine> xFixedLine(_xProp,uno::UNO_QUERY); + if ( xFixedLine.is() ) + { + uno::Reference<beans::XPropertySet> xBorderProp = OXMLHelper::createBorderPropertySet(); + table::BorderLine2 aValue; + aValue.Color = sal_uInt32(COL_BLACK); + aValue.InnerLineWidth = aValue.LineDistance = 0; + aValue.OuterLineWidth = DEFAULT_LINE_WIDTH; + aValue.LineStyle = table::BorderLineStyle::SOLID; + aValue.LineWidth = DEFAULT_LINE_WIDTH; + + awt::Point aPos = xFixedLine->getPosition(); + awt::Size aSize = xFixedLine->getSize(); + sal_Int32 nSectionHeight = xFixedLine->getSection()->getHeight(); + + OUString sBorderProp; + ::std::vector< OUString> aProps; + if ( xFixedLine->getOrientation() == 1 ) // vertical + { + // check if border should be left + if ( !aPos.X ) + { + sBorderProp = PROPERTY_BORDERLEFT; + aProps.emplace_back(PROPERTY_BORDERRIGHT); + } + else + { + sBorderProp = PROPERTY_BORDERRIGHT; + aProps.emplace_back(PROPERTY_BORDERLEFT); + } + aProps.emplace_back(PROPERTY_BORDERTOP); + aProps.emplace_back(PROPERTY_BORDERBOTTOM); + } + else // horizontal + { + // check if border should be bottom + if ( (aPos.Y + aSize.Height) == nSectionHeight ) + { + sBorderProp = PROPERTY_BORDERBOTTOM; + aProps.emplace_back(PROPERTY_BORDERTOP); + } + else + { + sBorderProp = PROPERTY_BORDERTOP; + aProps.emplace_back(PROPERTY_BORDERBOTTOM); + } + aProps.emplace_back(PROPERTY_BORDERRIGHT); + aProps.emplace_back(PROPERTY_BORDERLEFT); + } + + xBorderProp->setPropertyValue(sBorderProp,uno::Any(aValue)); + + aValue.Color = aValue.OuterLineWidth = aValue.LineWidth = 0; + aValue.LineStyle = table::BorderLineStyle::NONE; + uno::Any aEmpty; + aEmpty <<= aValue; + for (auto const& it : aProps) + { + xBorderProp->setPropertyValue(it, aEmpty); + } + + ::std::vector<XMLPropertyState> aBorderStates(m_xCellStylesExportPropertySetMapper->Filter(*this, xBorderProp)); + aPropertyStates.insert( aPropertyStates.end(), aBorderStates.begin(), aBorderStates.end() ); + } + else + { + const Reference<XFormattedField> xFormattedField(_xProp,uno::UNO_QUERY); + if ( (_xParentFormattedField.is() || xFormattedField.is()) && !aPropertyStates.empty() ) + { + sal_Int32 nNumberFormat = 0; + if ( _xParentFormattedField.is() ) + nNumberFormat = _xParentFormattedField->getFormatKey(); + else + nNumberFormat = xFormattedField->getFormatKey(); + { + sal_Int32 nStyleMapIndex = m_xCellStylesExportPropertySetMapper->getPropertySetMapper()->FindEntryIndex( CTF_RPT_NUMBERFORMAT ); + addDataStyle(nNumberFormat); + XMLPropertyState aNumberStyleState( nStyleMapIndex, uno::Any( getDataStyleName(nNumberFormat) ) ); + auto const iter(::std::find_if( + aPropertyStates.begin(), aPropertyStates.end(), + [nStyleMapIndex] (XMLPropertyState const& rItem) + { return rItem.mnIndex == nStyleMapIndex; } )); + if (iter == aPropertyStates.end()) + { + aPropertyStates.push_back( aNumberStyleState ); + } + else + { // there is already a property but it has the wrong type + // (integer not string); TODO: can we prevent it + // getting added earlier? + (*iter) = aNumberStyleState; + } + } + } + } + + if ( !aPropertyStates.empty() ) + m_aAutoStyleNames.emplace( _xProp,GetAutoStylePool()->Add( XmlStyleFamily::TABLE_CELL, std::move(aPropertyStates) )); +} + +void ORptExport::exportAutoStyle(const Reference<XSection>& _xProp) +{ + ::std::vector<XMLPropertyState> aPropertyStates(m_xTableStylesExportPropertySetMapper->Filter(*this, _xProp)); + if ( !aPropertyStates.empty() ) + m_aAutoStyleNames.emplace( _xProp.get(),GetAutoStylePool()->Add( XmlStyleFamily::TABLE_TABLE, std::move(aPropertyStates) )); +} + +void ORptExport::SetBodyAttributes() +{ + Reference<XReportDefinition> xProp(getReportDefinition()); + exportReportAttributes(xProp); +} + +void ORptExport::exportReportAttributes(const Reference<XReportDefinition>& _xReport) +{ + if ( !_xReport.is() ) + return; + + OUStringBuffer sValue; + const SvXMLEnumMapEntry<sal_Int32>* aXML_CommandTypeEnumMap = OXMLHelper::GetCommandTypeOptions(); + if ( SvXMLUnitConverter::convertEnum( sValue, _xReport->getCommandType(), aXML_CommandTypeEnumMap ) ) + AddAttribute(XML_NAMESPACE_REPORT, XML_COMMAND_TYPE,sValue.makeStringAndClear()); + + OUString sCommand = _xReport->getCommand(); + if ( !sCommand.isEmpty() ) + AddAttribute(XML_NAMESPACE_REPORT, XML_COMMAND, sCommand); + + OUString sFilter( _xReport->getFilter() ); + if ( !sFilter.isEmpty() ) + AddAttribute( XML_NAMESPACE_REPORT, XML_FILTER, sFilter ); + + AddAttribute(XML_NAMESPACE_OFFICE, XML_MIMETYPE,_xReport->getMimeType()); + + bool bEscapeProcessing( _xReport->getEscapeProcessing() ); + if ( !bEscapeProcessing ) + AddAttribute( XML_NAMESPACE_REPORT, XML_ESCAPE_PROCESSING, ::xmloff::token::GetXMLToken( XML_FALSE ) ); + + OUString sName = _xReport->getCaption(); + if ( !sName.isEmpty() ) + AddAttribute(XML_NAMESPACE_OFFICE, XML_CAPTION,sName); + sName = _xReport->getName(); + if ( !sName.isEmpty() ) + AddAttribute(XML_NAMESPACE_DRAW, XML_NAME,sName); +} + +void ORptExport::ExportContent_() +{ + exportReport(getReportDefinition()); +} + +void ORptExport::ExportMasterStyles_() +{ + GetPageExport()->exportMasterStyles( true ); +} + +void ORptExport::collectComponentStyles() +{ + if ( m_bAllreadyFilled ) + return; + + m_bAllreadyFilled = true; + Reference<XReportDefinition> xProp(getReportDefinition()); + if ( !xProp.is() ) + return; + + uno::Reference< report::XSection> xParent(xProp->getParent(),uno::UNO_QUERY); + if ( xParent.is() ) + exportAutoStyle(xProp.get()); + + if ( xProp->getReportHeaderOn() ) + exportSectionAutoStyle(xProp->getReportHeader()); + if ( xProp->getPageHeaderOn() ) + exportSectionAutoStyle(xProp->getPageHeader()); + + exportGroup(xProp,0,true); + + if ( xProp->getPageFooterOn() ) + exportSectionAutoStyle(xProp->getPageFooter()); + if ( xProp->getReportFooterOn() ) + exportSectionAutoStyle(xProp->getReportFooter()); +} + +void ORptExport::ExportAutoStyles_() +{ + // there are no styles that require their own autostyles + if ( getExportFlags() & SvXMLExportFlags::CONTENT ) + { + collectComponentStyles(); + GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_TABLE); + GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_COLUMN); + GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_ROW); + GetAutoStylePool()->exportXML(XmlStyleFamily::TABLE_CELL); + exportDataStyles(); + GetShapeExport()->exportAutoStyles(); + } + // exported in _ExportMasterStyles + if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES ) + GetPageExport()->collectAutoStyles( false ); + if( getExportFlags() & SvXMLExportFlags::MASTERSTYLES ) + GetPageExport()->exportAutoStyles(); +} + +void ORptExport::ExportStyles_(bool bUsed) +{ + SvXMLExport::ExportStyles_(bUsed); + + // write draw:style-name for object graphic-styles + GetShapeExport()->ExportGraphicDefaults(); +} + +SvXMLAutoStylePoolP* ORptExport::CreateAutoStylePool() +{ + return new OXMLAutoStylePoolP(*this); +} + +void SAL_CALL ORptExport::setSourceDocument( const Reference< XComponent >& xDoc ) +{ + m_xReportDefinition.set(xDoc,UNO_QUERY_THROW); + SvXMLExport::setSourceDocument(xDoc); +} + +void ORptExport::ExportFontDecls_() +{ + GetFontAutoStylePool(); // make sure the pool is created + collectComponentStyles(); + SvXMLExport::ExportFontDecls_(); +} + +void ORptExport::exportParagraph(const Reference< XReportControlModel >& _xReportElement) +{ + OSL_PRECOND(_xReportElement.is(),"Element is null!"); + // start <text:p> + SvXMLElementExport aParagraphContent(*this,XML_NAMESPACE_TEXT, XML_P, false, false); + if ( Reference<XFormattedField>(_xReportElement,uno::UNO_QUERY).is() ) + { + OUString sFieldData = _xReportElement->getDataField(); + static const sal_Unicode s_sPageNumber[] = u"PageNumber()"; + static const char s_sReportPrefix[] = "rpt:"; + sFieldData = sFieldData.copy(strlen(s_sReportPrefix)); + sal_Int32 nPageNumberIndex = sFieldData.indexOf(s_sPageNumber); + if ( nPageNumberIndex != -1 ) + { + sal_Int32 nIndex = 0; + do + { + std::u16string_view sToken = o3tl::getToken(sFieldData, 0, '&', nIndex ); + sToken = o3tl::trim(sToken); + if ( !sToken.empty() ) + { + if ( sToken == s_sPageNumber ) + { + AddAttribute(XML_NAMESPACE_TEXT, XML_SELECT_PAGE, "current" ); + SvXMLElementExport aPageNumber(*this,XML_NAMESPACE_TEXT, XML_PAGE_NUMBER, false, false); + Characters("1"); + } + else if ( sToken == u"PageCount()" ) + { + SvXMLElementExport aPageNumber(*this,XML_NAMESPACE_TEXT, XML_PAGE_COUNT, false, false); + Characters("1"); + } + else + { + + if ( o3tl::starts_with(sToken, u"\"") && o3tl::ends_with(sToken, u"\"") ) + sToken = sToken.substr(1, sToken.size() - 2); + + bool bPrevCharIsSpace = false; + GetTextParagraphExport()->exportCharacterData(OUString(sToken), bPrevCharIsSpace); + } + } + } + while ( nIndex >= 0 ); + } + } + Reference< XFixedText > xFT(_xReportElement,UNO_QUERY); + if ( xFT.is() ) + { + OUString sExpr = xFT->getLabel(); + bool bPrevCharIsSpace = false; // FIXME this looks quite broken - does the corresponding import filter do whitespace collapsing at all? + GetTextParagraphExport()->exportCharacterData(sExpr, bPrevCharIsSpace); + } +} + +XMLShapeExport* ORptExport::CreateShapeExport() +{ + XMLShapeExport* pShapeExport = new XMLShapeExport( *this, XMLTextParagraphExport::CreateShapeExtPropMapper( *this ) ); + return pShapeExport; +} + +void ORptExport::exportShapes(const Reference< XSection>& _xSection,bool _bAddParagraph) +{ + rtl::Reference< XMLShapeExport > xShapeExport = GetShapeExport(); + xShapeExport->seekShapes(_xSection); + const sal_Int32 nCount = _xSection->getCount(); + ::std::unique_ptr<SvXMLElementExport> pParagraphContent; + if ( _bAddParagraph ) + pParagraphContent.reset(new SvXMLElementExport(*this,XML_NAMESPACE_TEXT, XML_P, true, false)); + + awt::Point aRefPoint; + aRefPoint.X = rptui::getStyleProperty<sal_Int32>(_xSection->getReportDefinition(),PROPERTY_LEFTMARGIN); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference< XShape > xShape(_xSection->getByIndex(i),uno::UNO_QUERY); + if ( xShape.is() ) + { + ::std::unique_ptr<SvXMLElementExport> pSubDocument; + uno::Reference< frame::XModel> xModel(xShape->getPropertyValue("Model"),uno::UNO_QUERY); + if ( xModel.is() ) // special handling for chart object + { + pSubDocument.reset(new SvXMLElementExport(*this,XML_NAMESPACE_REPORT, XML_SUB_DOCUMENT, false, false)); + exportMasterDetailFields(xShape); + exportReportElement(xShape); + } + + AddAttribute( XML_NAMESPACE_TEXT, XML_ANCHOR_TYPE, XML_PARAGRAPH ); + xShapeExport->exportShape(xShape, SEF_DEFAULT|XMLShapeExportFlags::NO_WS,&aRefPoint); + } + } +} + +void ORptExport::exportGroupsExpressionAsFunction(const Reference< XGroups>& _xGroups) +{ + if ( !_xGroups.is() ) + return; + + uno::Reference< XFunctions> xFunctions = _xGroups->getReportDefinition()->getFunctions(); + const sal_Int32 nCount = _xGroups->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference< XGroup> xGroup(_xGroups->getByIndex(i),uno::UNO_QUERY_THROW); + const ::sal_Int16 nGroupOn = xGroup->getGroupOn(); + if ( nGroupOn != report::GroupOn::DEFAULT ) + { + uno::Reference< XFunction> xFunction = xFunctions->createFunction(); + OUString sFunction,sPrefix,sPostfix; + OUString sExpression = xGroup->getExpression(); + OUString sFunctionName; + OUString sInitialFormula; + switch(nGroupOn) + { + case report::GroupOn::PREFIX_CHARACTERS: + sFunction = "LEFT"; + sPrefix = ";" + OUString::number(xGroup->getGroupInterval()); + break; + case report::GroupOn::YEAR: + sFunction = "YEAR"; + break; + case report::GroupOn::QUARTAL: + sFunction = "INT((MONTH"; + sPostfix = "-1)/3)+1"; + sFunctionName = "QUARTAL_" + sExpression; + break; + case report::GroupOn::MONTH: + sFunction = "MONTH"; + break; + case report::GroupOn::WEEK: + sFunction = "WEEK"; + break; + case report::GroupOn::DAY: + sFunction = "DAY"; + break; + case report::GroupOn::HOUR: + sFunction = "HOUR"; + break; + case report::GroupOn::MINUTE: + sFunction = "MINUTE"; + break; + case report::GroupOn::INTERVAL: + { + sFunction = "INT"; + uno::Reference< XFunction> xCountFunction = xFunctions->createFunction(); + xCountFunction->setInitialFormula(beans::Optional< OUString>(true,OUString("rpt:0"))); + OUString sCountName = sFunction + "_count_" + sExpression; + xCountFunction->setName(sCountName); + xCountFunction->setFormula( "rpt:[" + sCountName + "] + 1" ); + exportFunction(xCountFunction); + sExpression = sCountName; + // The reference to sCountName in the formula of sFunctionName refers to the *old* value + // so we need to expand the formula of sCountName + sPrefix = " + 1) / " + OUString::number(xGroup->getGroupInterval()); + sFunctionName = sFunction + "_" + sExpression; + sFunction += "("; + sInitialFormula = "rpt:0"; + } + break; + default: + ; + } + if ( sFunctionName.isEmpty() ) + sFunctionName = sFunction + "_" + sExpression; + if ( !sFunction.isEmpty() ) + { + const sal_Unicode pReplaceChars[] = { '(',')',';',',','+','-','[',']','/','*'}; + for(sal_Unicode ch : pReplaceChars) + sFunctionName = sFunctionName.replace(ch,'_'); + + xFunction->setName(sFunctionName); + if ( !sInitialFormula.isEmpty() ) + xFunction->setInitialFormula(beans::Optional< OUString>(true, sInitialFormula)); + sFunction = "rpt:" + sFunction + "([" + sExpression + "]"; + + if ( !sPrefix.isEmpty() ) + sFunction += sPrefix; + sFunction += ")"; + if ( !sPostfix.isEmpty() ) + sFunction += sPostfix; + xFunction->setFormula(sFunction); + exportFunction(xFunction); + m_aGroupFunctionMap.emplace(xGroup,xFunction); + } + } + } +} + + +}// rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlExport.hxx b/reportdesign/source/filter/xml/xmlExport.hxx new file mode 100644 index 000000000..f82d85aa7 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlExport.hxx @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORT_HXX + +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/report/XReportControlModel.hpp> +#include <com/sun/star/report/XFormattedField.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <xmloff/xmlexp.hxx> +#include <xmloff/xmlexppr.hxx> +#include <xmloff/prhdlfac.hxx> +#include <xmloff/xmlprmap.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <memory> + +namespace rptxml +{ +using namespace ::xmloff::token; +using namespace css::uno; +using namespace css::container; +using namespace css::lang; +using namespace css::beans; +using namespace css::document; +using namespace css::text; +using namespace css::report; +using namespace css::io; +using namespace css::xml::sax; + + +class ORptExport : public SvXMLExport +{ +public: + struct TCell + { + sal_Int32 nColSpan; + sal_Int32 nRowSpan; + Reference<XReportComponent> xElement; + bool bSet; + TCell( sal_Int32 _nColSpan, + sal_Int32 _nRowSpan, + Reference<XReportComponent> const & _xElement = Reference<XReportComponent>()) : + nColSpan(_nColSpan) + ,nRowSpan(_nRowSpan) + ,xElement(_xElement) + ,bSet(xElement.is()) + {} + + TCell( ) : + nColSpan(1) + ,nRowSpan(1) + ,bSet(true) + {} + }; + typedef ::std::pair< OUString ,OUString> TStringPair; + typedef ::std::map< Reference<XPropertySet> ,OUString > TPropertyStyleMap; + typedef ::std::map< Reference<XPropertySet> , std::vector<OUString>> TGridStyleMap; + typedef ::std::vector< TCell > TRow; + typedef ::std::vector< ::std::pair< bool, TRow > > TGrid; + typedef ::std::map< Reference<XPropertySet> ,TGrid > TSectionsGrid; + typedef ::std::map< Reference<XGroup> ,Reference<XFunction> > TGroupFunctionMap; +private: + TSectionsGrid m_aSectionsGrid; + + TPropertyStyleMap m_aAutoStyleNames; + TGridStyleMap m_aColumnStyleNames; + TGridStyleMap m_aRowStyleNames; + TGroupFunctionMap m_aGroupFunctionMap; + + OUString m_sTableStyle; + OUString m_sCellStyle; + rtl::Reference < SvXMLExportPropertyMapper> m_xTableStylesExportPropertySetMapper; + rtl::Reference < SvXMLExportPropertyMapper> m_xCellStylesExportPropertySetMapper; + rtl::Reference < SvXMLExportPropertyMapper> m_xColumnStylesExportPropertySetMapper; + rtl::Reference < SvXMLExportPropertyMapper> m_xRowStylesExportPropertySetMapper; + rtl::Reference < SvXMLExportPropertyMapper > m_xParaPropMapper; + rtl::Reference < XMLPropertyHandlerFactory > m_xPropHdlFactory; + + mutable rtl::Reference < XMLPropertySetMapper > m_xCellStylesPropertySetMapper; + Reference<XReportDefinition> m_xReportDefinition; + bool m_bAllreadyFilled; + + void exportReport(const Reference<XReportDefinition>& _xReportDefinition); /// <element name="office:report"> + void exportReportAttributes(const Reference<XReportDefinition>& _xReport); + void exportFunctions(const Reference<XIndexAccess>& _xFunctions); /// <ref name="rpt-function"/> + void exportFunction(const Reference< XFunction>& _xFunction); + void exportMasterDetailFields(const Reference<XReportComponent>& _xReportComponent); + void exportComponent(const Reference<XReportComponent>& _xReportComponent); + void exportGroup(const Reference<XReportDefinition>& _xReportDefinition,sal_Int32 _nPos,bool _bExportAutoStyle = false); + void exportStyleName(XPropertySet* _xProp,SvXMLAttributeList& _rAtt,const OUString& _sName); + void exportSection(const Reference<XSection>& _xProp,bool bHeader = false); + void exportContainer(const Reference< XSection>& _xSection); + void exportShapes(const Reference< XSection>& _xSection,bool _bAddParagraph = true); + void exportTableColumns(const Reference< XSection>& _xSection); + void exportSectionAutoStyle(const Reference<XSection>& _xProp); + void exportReportElement(const Reference<XReportControlModel>& _xReportElement); + void exportFormatConditions(const Reference<XReportControlModel>& _xReportElement); + void exportAutoStyle(XPropertySet* _xProp,const Reference<XFormattedField>& _xParentFormattedField = Reference<XFormattedField>()); + void exportAutoStyle(const Reference<XSection>& _xProp); + void exportReportComponentAutoStyles(const Reference<XSection>& _xProp); + void collectComponentStyles(); + void collectStyleNames(XmlStyleFamily _nFamily,const ::std::vector< sal_Int32>& _aSize, std::vector<OUString>& _rStyleNames); + void collectStyleNames(XmlStyleFamily _nFamily,const ::std::vector< sal_Int32>& _aSize, const ::std::vector< sal_Int32>& _aSizeAutoGrow, std::vector<OUString>& _rStyleNames); + void exportParagraph(const Reference< XReportControlModel >& _xReportElement); + bool exportFormula(enum ::xmloff::token::XMLTokenEnum eName,const OUString& _sFormula); + void exportGroupsExpressionAsFunction(const Reference< XGroups>& _xGroups); + static OUString convertFormula(const OUString& _sFormula); + + virtual void SetBodyAttributes() override; + +protected: + + virtual void ExportStyles_( bool bUsed ) override; + virtual void ExportAutoStyles_() override; + virtual void ExportContent_() override; + virtual void ExportMasterStyles_() override; + virtual void ExportFontDecls_() override; + virtual SvXMLAutoStylePoolP* CreateAutoStylePool() override; + virtual XMLShapeExport* CreateShapeExport() override; + + virtual ~ORptExport() override {}; +public: + + ORptExport(const Reference< XComponentContext >& _rxContext, OUString const & implementationName, SvXMLExportFlags nExportFlag); + + // XExporter + virtual void SAL_CALL setSourceDocument( const css::uno::Reference< css::lang::XComponent >& xDoc ) override; + + const Reference<XReportDefinition>& getReportDefinition() const { return m_xReportDefinition; } + + const rtl::Reference < XMLPropertySetMapper >& GetCellStylePropertyMapper() const { return m_xCellStylesPropertySetMapper;} +}; + + +} // rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlExportDocumentHandler.cxx b/reportdesign/source/filter/xml/xmlExportDocumentHandler.cxx new file mode 100644 index 000000000..b8b064cc6 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlExportDocumentHandler.cxx @@ -0,0 +1,408 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "xmlExportDocumentHandler.hxx" +#include <officecfg/Office/Common.hxx> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <com/sun/star/chart/XComplexDescriptionAccess.hpp> +#include <com/sun/star/reflection/ProxyFactory.hpp> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/documentconstants.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <xmloff/attrlist.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlement.hxx> +#include <xmloff/xmluconv.hxx> +#include <rtl/ustrbuf.hxx> +#include <connectivity/dbtools.hxx> + +namespace rptxml +{ +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +static void lcl_exportPrettyPrinting(const uno::Reference< xml::sax::XDocumentHandler >& _xDelegatee) +{ + if ( officecfg::Office::Common::Save::Document::PrettyPrinting::get() ) + { + _xDelegatee->ignorableWhitespace(" "); + } +} + +OUString lcl_createAttribute(const xmloff::token::XMLTokenEnum& _eNamespace,const xmloff::token::XMLTokenEnum& _eAttribute) +{ + return + // ...if it's in our map, make the prefix + xmloff::token::GetXMLToken(_eNamespace) + + ":" + + xmloff::token::GetXMLToken(_eAttribute); +} + +static void lcl_correctCellAddress(const OUString & _sName, const uno::Reference< xml::sax::XAttributeList > & xAttribs) +{ + SvXMLAttributeList* pList = comphelper::getFromUnoTunnel<SvXMLAttributeList>(xAttribs); + OUString sCellAddress = pList->getValueByName(_sName); + const sal_Int32 nPos = sCellAddress.lastIndexOf('$'); + if ( nPos != -1 ) + { + sCellAddress = OUString::Concat(sCellAddress.subView(0,nPos)) + "$65535"; + pList->RemoveAttribute(_sName); + pList->AddAttribute(_sName,sCellAddress); + } +} + +ExportDocumentHandler::ExportDocumentHandler(uno::Reference< uno::XComponentContext > const & context) : + m_xContext(context) + ,m_nColumnCount(0) + ,m_bTableRowsStarted(false) + ,m_bFirstRowExported(false) + ,m_bCountColumnHeader(false) +{ +} + +ExportDocumentHandler::~ExportDocumentHandler() +{ + if ( m_xProxy.is() ) + { + m_xProxy->setDelegator( nullptr ); + m_xProxy.clear(); + } +} +IMPLEMENT_GET_IMPLEMENTATION_ID(ExportDocumentHandler) + +OUString SAL_CALL ExportDocumentHandler::getImplementationName( ) +{ + return "com.sun.star.comp.report.ExportDocumentHandler"; +} + +sal_Bool SAL_CALL ExportDocumentHandler::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL ExportDocumentHandler::getSupportedServiceNames( ) +{ + uno::Sequence< OUString > aSupported; + if ( m_xServiceInfo.is() ) + aSupported = m_xServiceInfo->getSupportedServiceNames(); + return ::comphelper::concatSequences(uno::Sequence< OUString > { "com.sun.star.report.ExportDocumentHandler" },aSupported); +} + +// xml::sax::XDocumentHandler: +void SAL_CALL ExportDocumentHandler::startDocument() +{ + m_xDelegatee->startDocument(); +} + +void SAL_CALL ExportDocumentHandler::endDocument() +{ + m_xDelegatee->endDocument(); +} + +void SAL_CALL ExportDocumentHandler::startElement(const OUString & _sName, const uno::Reference< xml::sax::XAttributeList > & xAttribs) +{ + bool bExport = true; + if ( _sName == "office:chart" ) + { + rtl::Reference<SvXMLAttributeList> pList = new SvXMLAttributeList(); + OUStringBuffer sValue; + static const SvXMLEnumMapEntry<sal_uInt16> aXML_CommandTypeEnumMap[] = + { + { XML_TABLE, sdb::CommandType::TABLE }, + { XML_QUERY, sdb::CommandType::QUERY }, + { XML_TOKEN_INVALID, 0 } + }; + if ( SvXMLUnitConverter::convertEnum( sValue, static_cast<sal_uInt16>(m_xDatabaseDataProvider->getCommandType()),aXML_CommandTypeEnumMap ) ) + { + pList->AddAttribute(lcl_createAttribute(XML_NP_RPT,XML_COMMAND_TYPE),sValue.makeStringAndClear()); + } + const OUString sCommand = m_xDatabaseDataProvider->getCommand(); + if ( !sCommand.isEmpty() ) + pList->AddAttribute(lcl_createAttribute(XML_NP_RPT,XML_COMMAND),sCommand); + + const OUString sFilter( m_xDatabaseDataProvider->getFilter() ); + if ( !sFilter.isEmpty() ) + pList->AddAttribute(lcl_createAttribute(XML_NP_RPT,XML_FILTER),sFilter); + + const bool bEscapeProcessing( m_xDatabaseDataProvider->getEscapeProcessing() ); + if ( !bEscapeProcessing ) + pList->AddAttribute(lcl_createAttribute(XML_NP_RPT,XML_ESCAPE_PROCESSING),::xmloff::token::GetXMLToken( XML_FALSE )); + + pList->AddAttribute(lcl_createAttribute(XML_NP_OFFICE,XML_MIMETYPE),MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII); + + m_xDelegatee->startElement(lcl_createAttribute(XML_NP_OFFICE,XML_REPORT),pList); + + const OUString sTableCalc = lcl_createAttribute(XML_NP_TABLE,XML_CALCULATION_SETTINGS); + m_xDelegatee->startElement(sTableCalc,nullptr); + pList = new SvXMLAttributeList(); + pList->AddAttribute(lcl_createAttribute(XML_NP_TABLE,XML_DATE_VALUE),"1899-12-30"); + + const OUString sNullDate = lcl_createAttribute(XML_NP_TABLE,XML_NULL_DATE); + m_xDelegatee->startElement(sNullDate,pList); + m_xDelegatee->endElement(sNullDate); + m_xDelegatee->endElement(sTableCalc); + bExport = false; + } + else if ( _sName == "table:table" ) + { + m_xDelegatee->startElement(lcl_createAttribute(XML_NP_RPT,XML_DETAIL),nullptr); + lcl_exportPrettyPrinting(m_xDelegatee); + } + else if ( _sName == "table:table-header-rows" ) + { + m_bCountColumnHeader = true; + } + else if ( m_bCountColumnHeader && _sName == "table:table-cell" ) + { + ++m_nColumnCount; + } + else if ( _sName == "table:table-rows" ) + { + m_xDelegatee->startElement(_sName,xAttribs); + exportTableRows(); + bExport = false; + m_bTableRowsStarted = true; + m_bFirstRowExported = true; + } + else if ( m_bTableRowsStarted && m_bFirstRowExported && (_sName == "table:table-row" || _sName == "table:table-cell") ) + bExport = false; + else if ( _sName == "chart:plot-area" ) + { + SvXMLAttributeList* pList = comphelper::getFromUnoTunnel<SvXMLAttributeList>(xAttribs); + pList->RemoveAttribute("table:cell-range-address"); + } + else if ( _sName == "chart:categories" ) + { + static OUString s_sCellAddress(lcl_createAttribute(XML_NP_TABLE,XML_CELL_RANGE_ADDRESS)); + lcl_correctCellAddress(s_sCellAddress,xAttribs); + } + else if ( _sName == "chart:series" ) + { + static OUString s_sCellAddress(lcl_createAttribute(XML_NP_CHART,XML_VALUES_CELL_RANGE_ADDRESS)); + lcl_correctCellAddress(s_sCellAddress,xAttribs); + } + else if ( m_bTableRowsStarted && !m_bFirstRowExported && _sName == "table:table-cell" ) + { + SvXMLAttributeList* pList = comphelper::getFromUnoTunnel<SvXMLAttributeList>(xAttribs); + static OUString s_sValue(lcl_createAttribute(XML_NP_OFFICE,XML_VALUE)); + pList->RemoveAttribute(s_sValue); + } + else if ( m_bTableRowsStarted && _sName == "text:p" ) + { + bExport = false; + } + if ( bExport ) + m_xDelegatee->startElement(_sName,xAttribs); +} + +void SAL_CALL ExportDocumentHandler::endElement(const OUString & _sName) +{ + bool bExport = true; + OUString sNewName = _sName; + if ( _sName == "office:chart" ) + { + sNewName = lcl_createAttribute(XML_NP_OFFICE,XML_REPORT); + } + else if ( _sName == "table:table" ) + { + m_xDelegatee->endElement(_sName); + lcl_exportPrettyPrinting(m_xDelegatee); + sNewName = lcl_createAttribute(XML_NP_RPT,XML_DETAIL); + } + else if ( _sName == "table:table-header-rows" ) + { + m_bCountColumnHeader = false; + } + else if ( _sName == "table:table-rows" ) + m_bTableRowsStarted = false; + else if ( m_bTableRowsStarted && m_bFirstRowExported && (_sName == "table:table-row" || _sName == "table:table-cell") ) + bExport = false; + else if ( m_bTableRowsStarted && _sName == "table:table-row" ) + m_bFirstRowExported = true; + else if ( m_bTableRowsStarted && _sName == "text:p" ) + { + bExport = !m_bFirstRowExported; + } + + if ( bExport ) + m_xDelegatee->endElement(sNewName); +} + +void SAL_CALL ExportDocumentHandler::characters(const OUString & aChars) +{ + if ( !(m_bTableRowsStarted || m_bFirstRowExported) ) + { + m_xDelegatee->characters(aChars); + } +} + +void SAL_CALL ExportDocumentHandler::ignorableWhitespace(const OUString & aWhitespaces) +{ + m_xDelegatee->ignorableWhitespace(aWhitespaces); +} + +void SAL_CALL ExportDocumentHandler::processingInstruction(const OUString & aTarget, const OUString & aData) +{ + m_xDelegatee->processingInstruction(aTarget,aData); +} + +void SAL_CALL ExportDocumentHandler::setDocumentLocator(const uno::Reference< xml::sax::XLocator > & xLocator) +{ + m_xDelegatee->setDocumentLocator(xLocator); +} +void SAL_CALL ExportDocumentHandler::initialize( const uno::Sequence< uno::Any >& _aArguments ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + comphelper::SequenceAsHashMap aArgs(_aArguments); + m_xDelegatee = aArgs.getUnpackedValueOrDefault("DocumentHandler",m_xDelegatee); + m_xModel = aArgs.getUnpackedValueOrDefault("Model",m_xModel); + + OSL_ENSURE(m_xDelegatee.is(),"No document handler available!"); + if ( !m_xDelegatee.is() || !m_xModel.is() ) + throw uno::Exception("no delegatee and no model", nullptr); + + m_xDatabaseDataProvider.set(m_xModel->getDataProvider(),uno::UNO_QUERY_THROW); + if ( !m_xDatabaseDataProvider->getActiveConnection().is() ) + throw uno::Exception("no active connection", nullptr); + + uno::Reference< reflection::XProxyFactory > xProxyFactory = reflection::ProxyFactory::create( m_xContext ); + m_xProxy = xProxyFactory->createProxy(m_xDelegatee); + ::comphelper::query_aggregation(m_xProxy,m_xDelegatee); + m_xTypeProvider.set(m_xDelegatee,uno::UNO_QUERY); + m_xServiceInfo.set(m_xDelegatee,uno::UNO_QUERY); + + // set ourself as delegator + m_xProxy->setDelegator( *this ); + const OUString sCommand = m_xDatabaseDataProvider->getCommand(); + if ( !sCommand.isEmpty() ) + m_aColumns = ::dbtools::getFieldNamesByCommandDescriptor(m_xDatabaseDataProvider->getActiveConnection() + ,m_xDatabaseDataProvider->getCommandType() + ,sCommand); + + uno::Reference< chart::XComplexDescriptionAccess > xDataProvider(m_xDatabaseDataProvider,uno::UNO_QUERY); + if ( !xDataProvider.is() ) + return; + + m_aColumns.realloc(1); + const uno::Sequence< OUString > aColumnNames = xDataProvider->getColumnDescriptions(); + for(const auto& rColumnName : aColumnNames) + { + if ( !rColumnName.isEmpty() ) + { + sal_Int32 nCount = m_aColumns.getLength(); + m_aColumns.realloc(nCount+1); + m_aColumns.getArray()[nCount] = rColumnName; + } + } +} + +uno::Any SAL_CALL ExportDocumentHandler::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = ExportDocumentHandler_BASE::queryInterface(_rType); + return aReturn.hasValue() ? aReturn : (m_xProxy.is() ? m_xProxy->queryAggregation(_rType) : aReturn); +} + +uno::Sequence< uno::Type > SAL_CALL ExportDocumentHandler::getTypes( ) +{ + if ( m_xTypeProvider.is() ) + return ::comphelper::concatSequences( + ExportDocumentHandler_BASE::getTypes(), + m_xTypeProvider->getTypes() + ); + return ExportDocumentHandler_BASE::getTypes(); +} + +void ExportDocumentHandler::exportTableRows() +{ + const OUString sRow( lcl_createAttribute(XML_NP_TABLE, XML_TABLE_ROW) ); + m_xDelegatee->startElement(sRow,nullptr); + + const OUString sValueType( lcl_createAttribute(XML_NP_OFFICE, XML_VALUE_TYPE) ); + + const OUString sCell( lcl_createAttribute(XML_NP_TABLE, XML_TABLE_CELL) ); + const OUString sP( lcl_createAttribute(XML_NP_TEXT, XML_P) ); + const OUString sFtext(lcl_createAttribute(XML_NP_RPT,XML_FORMATTED_TEXT) ); + const OUString sRElement(lcl_createAttribute(XML_NP_RPT,XML_REPORT_ELEMENT) ); + const OUString sRComponent( lcl_createAttribute(XML_NP_RPT,XML_REPORT_COMPONENT) ) ; + const OUString sFormulaAttrib( lcl_createAttribute(XML_NP_RPT,XML_FORMULA) ); + static constexpr OUStringLiteral s_sFloat = u"float"; + + rtl::Reference<SvXMLAttributeList> pCellAtt = new SvXMLAttributeList(); + pCellAtt->AddAttribute(sValueType, "string"); + + bool bRemoveString = true; + const sal_Int32 nCount = m_aColumns.getLength(); + if ( m_nColumnCount > nCount ) + { + const sal_Int32 nEmptyCellCount = m_nColumnCount - nCount; + for(sal_Int32 i = 0; i < nEmptyCellCount ; ++i) + { + m_xDelegatee->startElement(sCell,pCellAtt); + if ( bRemoveString ) + { + bRemoveString = false; + pCellAtt->RemoveAttribute(sValueType); + pCellAtt->AddAttribute(sValueType,s_sFloat); + } + m_xDelegatee->startElement(sP,nullptr); + m_xDelegatee->endElement(sP); + m_xDelegatee->endElement(sCell); + } + } + for(const auto& rColumn : std::as_const(m_aColumns)) + { + OUString sFormula = "field:[" + rColumn + "]"; + rtl::Reference<SvXMLAttributeList> pList = new SvXMLAttributeList(); + pList->AddAttribute(sFormulaAttrib,sFormula); + + m_xDelegatee->startElement(sCell,pCellAtt); + if ( bRemoveString ) + { + bRemoveString = false; + pCellAtt->RemoveAttribute(sValueType); + pCellAtt->AddAttribute(sValueType,s_sFloat); + } + m_xDelegatee->startElement(sP,nullptr); + m_xDelegatee->startElement(sFtext,pList); + m_xDelegatee->startElement(sRElement,nullptr); + m_xDelegatee->startElement(sRComponent,nullptr); + + m_xDelegatee->endElement(sRComponent); + m_xDelegatee->endElement(sRElement); + m_xDelegatee->endElement(sFtext); + m_xDelegatee->endElement(sP); + m_xDelegatee->endElement(sCell); + } + + m_xDelegatee->endElement(sRow); +} + +} // namespace rptxml + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ExportDocumentHandler_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptxml::ExportDocumentHandler(context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlExportDocumentHandler.hxx b/reportdesign/source/filter/xml/xmlExportDocumentHandler.hxx new file mode 100644 index 000000000..9e7afe347 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlExportDocumentHandler.hxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORTDOCUMENTHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORTDOCUMENTHANDLER_HXX + +#include <sal/config.h> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <comphelper/uno3.hxx> +#include <xmloff/xmltoken.hxx> + +namespace rptxml +{ + +OUString lcl_createAttribute(const xmloff::token::XMLTokenEnum& _eNamespace,const xmloff::token::XMLTokenEnum& _eAttribute); + +typedef ::cppu::WeakAggImplHelper3< css::xml::sax::XDocumentHandler + , css::lang::XInitialization + , css::lang::XServiceInfo> ExportDocumentHandler_BASE; + +class ExportDocumentHandler : public ExportDocumentHandler_BASE +{ +public: + explicit ExportDocumentHandler(css::uno::Reference< css::uno::XComponentContext > const & context); + +private: + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; + + DECLARE_XTYPEPROVIDER( ) + + // css::xml::sax::XDocumentHandler: + virtual void SAL_CALL startDocument() override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL startElement(const OUString & aName, const css::uno::Reference< css::xml::sax::XAttributeList > & xAttribs) override; + virtual void SAL_CALL endElement(const OUString & aName) override; + virtual void SAL_CALL characters(const OUString & aChars) override; + virtual void SAL_CALL ignorableWhitespace(const OUString & aWhitespaces) override; + virtual void SAL_CALL processingInstruction(const OUString & aTarget, const OUString & aData) override; + virtual void SAL_CALL setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator > & xLocator) override; + + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + void exportTableRows(); +private: + ExportDocumentHandler(ExportDocumentHandler const &) = delete; + void operator =(ExportDocumentHandler const &) = delete; + + virtual ~ExportDocumentHandler() override; + + ::osl::Mutex m_aMutex; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::xml::sax::XDocumentHandler > m_xDelegatee; + css::uno::Reference< css::uno::XAggregation > m_xProxy; + css::uno::Reference< css::lang::XTypeProvider > m_xTypeProvider; + css::uno::Reference< css::lang::XServiceInfo > m_xServiceInfo; + css::uno::Reference< css::chart2::XChartDocument > m_xModel; + css::uno::Reference< css::chart2::data::XDatabaseDataProvider > m_xDatabaseDataProvider; + css::uno::Sequence< OUString > m_aColumns; + sal_Int32 m_nColumnCount; + bool m_bTableRowsStarted; + bool m_bFirstRowExported; + bool m_bCountColumnHeader; +}; + +} // namespace rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLEXPORTDOCUMENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFixedContent.cxx b/reportdesign/source/filter/xml/xmlFixedContent.cxx new file mode 100644 index 000000000..4cffdd300 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFixedContent.cxx @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlFixedContent.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include "xmlCell.hxx" +#include <strings.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/report/XFormattedField.hpp> +#include <com/sun/star/report/XFixedText.hpp> +#include <com/sun/star/text/ControlCharacter.hpp> +#include "xmlTable.hxx" +#include <xmloff/XMLCharContext.hxx> +#include <osl/diagnose.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + +namespace { + +class OXMLCharContent: public XMLCharContext +{ + OXMLFixedContent* m_pFixedContent; + +public: + OXMLCharContent( + SvXMLImport& rImport, + OXMLFixedContent* _pFixedContent, + const uno::Reference< xml::sax::XFastAttributeList > & xAttrList, + sal_Unicode c, + bool bCount ); + OXMLCharContent( + SvXMLImport& rImport, + OXMLFixedContent* _pFixedContent, + sal_Int16 nControl ); + OXMLCharContent(const OXMLCharContent&) = delete; + OXMLCharContent& operator=(const OXMLCharContent&) = delete; + + virtual void InsertControlCharacter(sal_Int16 _nControl) override; + virtual void InsertString(const OUString& _sString) override; +}; + +} + +OXMLCharContent::OXMLCharContent( + SvXMLImport& rImport, + OXMLFixedContent* _pFixedContent, + const uno::Reference< xml::sax::XFastAttributeList > & xAttrList, + sal_Unicode c, + bool bCount ) + : XMLCharContext(rImport,xAttrList,c,bCount) + ,m_pFixedContent(_pFixedContent) +{ +} + +OXMLCharContent::OXMLCharContent( + SvXMLImport& rImport, + OXMLFixedContent* _pFixedContent, + sal_Int16 nControl ) + : XMLCharContext(rImport,nControl) + ,m_pFixedContent(_pFixedContent) +{ +} + +void OXMLCharContent::InsertControlCharacter(sal_Int16 _nControl) +{ + switch( _nControl ) + { + case ControlCharacter::LINE_BREAK: + m_pFixedContent->characters("\n"); + break; + default: + OSL_FAIL("Not supported control character"); + break; + } +} + +void OXMLCharContent::InsertString(const OUString& _sString) +{ + m_pFixedContent->characters(_sString); +} + + +OXMLFixedContent::OXMLFixedContent( ORptFilter& rImport + ,OXMLCell& _rCell + ,OXMLTable* _pContainer + ,OXMLFixedContent* _pInP) : + OXMLReportElementBase( rImport,nullptr,_pContainer) +,m_rCell(_rCell) +,m_pInP(_pInP) +,m_bFormattedField(false) +{ +} + + +OXMLFixedContent::~OXMLFixedContent() +{ + +} + + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLFixedContent::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext = OXMLReportElementBase::createFastChildContext(nElement,xAttrList); + if (xContext) + return xContext; + + static constexpr char16_t s_sStringConcat[] = u" & "; + + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + switch( nElement ) + { + case XML_ELEMENT(TEXT, XML_P): + xContext = new OXMLFixedContent(m_rImport,m_rCell,m_pContainer,this); + break; + case XML_ELEMENT(TEXT, XML_TAB): + xContext = new OXMLCharContent( m_rImport, this, xAttrList, + 0x0009, false ); + break; + + case XML_ELEMENT(TEXT, XML_LINE_BREAK): + xContext = new OXMLCharContent( m_rImport, this, + ControlCharacter::LINE_BREAK ); + break; + + case XML_ELEMENT(TEXT, XML_S): + xContext = new OXMLCharContent( m_rImport, this, xAttrList, + 0x0020, true ); + break; + case XML_ELEMENT(TEXT, XML_PAGE_NUMBER): + m_sPageText += OUString::Concat(s_sStringConcat) + " PageNumber()"; + m_bFormattedField = true; + break; + case XML_ELEMENT(TEXT, XML_PAGE_COUNT): + m_sPageText += OUString::Concat(s_sStringConcat) + " PageCount()"; + m_bFormattedField = true; + break; + default: + ; + } + return xContext; +} + +void OXMLFixedContent::endFastElement(sal_Int32 nElement) +{ + if ( !m_pInP ) + return; + + const Reference<XMultiServiceFactory> xFactor(m_rImport.GetModel(),uno::UNO_QUERY); + if ( m_bFormattedField ) + { + uno::Reference< uno::XInterface> xInt = xFactor->createInstance(SERVICE_FORMATTEDFIELD); + Reference< report::XFormattedField > xControl(xInt,uno::UNO_QUERY); + xControl->setDataField("rpt:" + m_sPageText); + OSL_ENSURE(xControl.is(),"Could not create FormattedField!"); + m_pInP->m_xReportComponent = xControl.get(); + m_xReportComponent = xControl.get(); + } + else + { + Reference< XFixedText > xControl(xFactor->createInstance(SERVICE_FIXEDTEXT),uno::UNO_QUERY); + OSL_ENSURE(xControl.is(),"Could not create FixedContent!"); + m_pInP->m_xReportComponent = xControl.get(); + m_xReportComponent = xControl.get(); + xControl->setLabel(m_sLabel); + } + + m_pContainer->addCell(m_xReportComponent); + m_rCell.setComponent(m_xReportComponent); + + OXMLReportElementBase::endFastElement(nElement); +} + +void OXMLFixedContent::characters( const OUString& rChars ) +{ + m_sLabel += rChars; + if ( !rChars.isEmpty() ) + { + static const char s_Quote[] = "\""; + if ( !m_sPageText.isEmpty() ) + { + m_sPageText += " & "; + } + + m_sPageText += s_Quote + rChars + s_Quote; + } +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFixedContent.hxx b/reportdesign/source/filter/xml/xmlFixedContent.hxx new file mode 100644 index 000000000..916b61fed --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFixedContent.hxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFIXEDCONTENT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFIXEDCONTENT_HXX + +#include "xmlReportElementBase.hxx" + + +namespace rptxml +{ + class ORptFilter; + class OXMLCell; + class OXMLFixedContent : public OXMLReportElementBase + { + OUString m_sPageText; // page count and page number + OUString m_sLabel; + OXMLCell& m_rCell; + OXMLFixedContent* m_pInP; // if set then we are in text-p element + bool m_bFormattedField; + + OXMLFixedContent(const OXMLFixedContent&) = delete; + OXMLFixedContent& operator =(const OXMLFixedContent&) = delete; + public: + + OXMLFixedContent( ORptFilter& rImport + ,OXMLCell& _rCell + ,OXMLTable* _pContainer + ,OXMLFixedContent* _pInP = nullptr); + virtual ~OXMLFixedContent() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override; + + // This method is called for all characters that are contained in the + // current element. The default is to ignore them. + virtual void SAL_CALL characters( const OUString& rChars ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFIXEDCONTENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFormatCondition.cxx b/reportdesign/source/filter/xml/xmlFormatCondition.cxx new file mode 100644 index 000000000..6f5f43032 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFormatCondition.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlFormatCondition.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include "xmlHelper.hxx" +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + using namespace ::com::sun::star::beans; + +OXMLFormatCondition::OXMLFormatCondition( ORptFilter& rImport, + const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XFormatCondition > & _xComponent ) : + SvXMLImportContext( rImport ) +,m_rImport(rImport) +,m_xComponent(_xComponent) +{ + + OSL_ENSURE(m_xComponent.is(),"Component is NULL!"); + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_ENABLED): + m_xComponent->setEnabled(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_FORMULA): + m_xComponent->setFormula(ORptFilter::convertFormula(aIter.toString())); + break; + case XML_ELEMENT(REPORT, XML_STYLE_NAME): + m_sStyleName = aIter.toString(); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the report definition props"); + } +} + + +OXMLFormatCondition::~OXMLFormatCondition() +{ +} + +void OXMLFormatCondition::endFastElement(sal_Int32 ) +{ + OXMLHelper::copyStyleElements(m_rImport.isOldFormat(),m_sStyleName,GetImport().GetAutoStyles(),m_xComponent); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFormatCondition.hxx b/reportdesign/source/filter/xml/xmlFormatCondition.hxx new file mode 100644 index 000000000..56bd5602f --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFormatCondition.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATCONDITION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATCONDITION_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XFormatCondition.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLFormatCondition : public SvXMLImportContext + { + ORptFilter& m_rImport; + OUString m_sStyleName; + css::uno::Reference< css::report::XFormatCondition > m_xComponent; + OXMLFormatCondition(const OXMLFormatCondition&) = delete; + void operator =(const OXMLFormatCondition&) = delete; + public: + + OXMLFormatCondition( ORptFilter& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XFormatCondition >& _xComponent + ); + virtual ~OXMLFormatCondition() override; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATCONDITION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFormattedField.cxx b/reportdesign/source/filter/xml/xmlFormattedField.cxx new file mode 100644 index 000000000..b7fd48ae2 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFormattedField.cxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlFormattedField.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace xml::sax; + +OXMLFormattedField::OXMLFormattedField( ORptFilter& rImport + ,const uno::Reference< xml::sax::XFastAttributeList > & _xAttrList + ,const uno::Reference< XFormattedField > & _xComponent + ,OXMLTable* _pContainer + ,bool _bPageCount) : + OXMLReportElementBase( rImport,_xComponent,_pContainer) +{ + OSL_ENSURE(m_xReportComponent.is(),"Component is NULL!"); + + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_FORMULA): + _xComponent->setDataField(ORptFilter::convertFormula(aIter.toString())); + break; + case XML_ELEMENT(REPORT, XML_SELECT_PAGE): + _xComponent->setDataField("rpt:PageNumber()"); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + if ( _bPageCount ) + { + _xComponent->setDataField("rpt:PageCount()"); + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the report definition props"); + } +} + +OXMLFormattedField::~OXMLFormattedField() +{ +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFormattedField.hxx b/reportdesign/source/filter/xml/xmlFormattedField.hxx new file mode 100644 index 000000000..b181810f2 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFormattedField.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATTEDFIELD_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATTEDFIELD_HXX + +#include "xmlReportElementBase.hxx" +#include <com/sun/star/report/XFormattedField.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLFormattedField : public OXMLReportElementBase + { + OXMLFormattedField(const OXMLFormattedField&) = delete; + void operator =(const OXMLFormattedField&) = delete; + public: + + OXMLFormattedField( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XFormattedField >& _xComponent + ,OXMLTable* _pContainer + ,bool _bPageCount); + virtual ~OXMLFormattedField() override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFORMATTEDFIELD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFunction.cxx b/reportdesign/source/filter/xml/xmlFunction.cxx new file mode 100644 index 000000000..31df344be --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFunction.cxx @@ -0,0 +1,115 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlFunction.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::xml::sax; + + +OXMLFunction::OXMLFunction( ORptFilter& _rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XFunctionsSupplier >& _xFunctions + ,bool _bAddToReport + ) : + SvXMLImportContext( _rImport ) + ,m_xFunctions(_xFunctions->getFunctions()) + ,m_bAddToReport(_bAddToReport) +{ + + OSL_ENSURE(m_xFunctions.is(),"Functions is NULL!"); + m_xFunction = m_xFunctions->createFunction(); + + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + try + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_NAME): + m_xFunction->setName(aIter.toString()); + break; + case XML_ELEMENT(REPORT, XML_FORMULA): + m_xFunction->setFormula(ORptFilter::convertFormula(aIter.toString())); + break; + case XML_ELEMENT(REPORT, XML_PRE_EVALUATED): + m_xFunction->setPreEvaluated(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_INITIAL_FORMULA): + if ( !aIter.isEmpty() ) + m_xFunction->setInitialFormula(beans::Optional< OUString>(true,ORptFilter::convertFormula(aIter.toString()))); + break; + case XML_ELEMENT(REPORT, XML_DEEP_TRAVERSING): + m_xFunction->setDeepTraversing(IsXMLToken(aIter, XML_TRUE)); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + catch(const Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while putting Function props!"); + } + } +} + + +OXMLFunction::~OXMLFunction() +{ +} + +ORptFilter& OXMLFunction::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +void OXMLFunction::endFastElement(sal_Int32 ) +{ + if ( m_bAddToReport ) + { + GetOwnImport().insertFunction(m_xFunction); + m_xFunction.clear(); + } + else + { + try + { + m_xFunctions->insertByIndex(m_xFunctions->getCount(),uno::Any(m_xFunction)); + m_xFunction.clear(); + }catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + } +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlFunction.hxx b/reportdesign/source/filter/xml/xmlFunction.hxx new file mode 100644 index 000000000..fbbc38e3e --- /dev/null +++ b/reportdesign/source/filter/xml/xmlFunction.hxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFUNCTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFUNCTION_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XFunctionsSupplier.hpp> +#include <com/sun/star/report/XFunctions.hpp> + + +namespace rptxml +{ + class ORptFilter; + class OXMLFunction final : public SvXMLImportContext + { + css::uno::Reference< css::report::XFunctions > m_xFunctions; + css::uno::Reference< css::report::XFunction > m_xFunction; + bool m_bAddToReport; + + ORptFilter& GetOwnImport(); + + OXMLFunction(const OXMLFunction&); + OXMLFunction& operator =(const OXMLFunction&); + public: + + OXMLFunction( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XFunctionsSupplier >& _xFunctions + ,bool _bAddToReport = false + ); + virtual ~OXMLFunction() override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + }; + +} // namespace rptxml + + +#endif // RPT_XMLFunction_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlGroup.cxx b/reportdesign/source/filter/xml/xmlGroup.cxx new file mode 100644 index 000000000..249a27229 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlGroup.cxx @@ -0,0 +1,246 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlGroup.hxx" +#include "xmlSection.hxx" +#include "xmlFunction.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlHelper.hxx" +#include "xmlEnums.hxx" +#include <com/sun/star/report/GroupOn.hpp> +#include <com/sun/star/report/KeepTogether.hpp> +#include <o3tl/string_view.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::xml::sax; + + static sal_Int16 lcl_getKeepTogetherOption(std::string_view _sValue) + { + sal_Int16 nRet = report::KeepTogether::NO; + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetKeepTogetherOptions(); + (void)SvXMLUnitConverter::convertEnum( nRet, _sValue, aXML_EnumMap ); + return nRet; + } + +OXMLGroup::OXMLGroup( ORptFilter& _rImport + ,const Reference< XFastAttributeList > & _xAttrList + ) : + SvXMLImportContext( _rImport ) +{ + + m_xGroups = _rImport.getReportDefinition()->getGroups(); + OSL_ENSURE(m_xGroups.is(),"Groups is NULL!"); + m_xGroup = m_xGroups->createGroup(); + + m_xGroup->setSortAscending(false);// the default value has to be set + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + try + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_START_NEW_COLUMN): + m_xGroup->setStartNewColumn(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_RESET_PAGE_NUMBER): + m_xGroup->setResetPageNumber(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_SORT_ASCENDING): + m_xGroup->setSortAscending(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_GROUP_EXPRESSION): + { + OUString sValue = aIter.toString(); + sal_Int32 nLen = sValue.getLength(); + if ( nLen ) + { + + static const char s_sChanged[] = "rpt:HASCHANGED(\""; + sal_Int32 nPos = sValue.indexOf(s_sChanged); + if ( nPos == -1 ) + nPos = 5; + else + { + nPos = strlen(s_sChanged); + static const char s_sQuote[] = "\"\""; + sal_Int32 nIndex = sValue.indexOf(s_sQuote,nPos); + while ( nIndex > -1 ) + { + sValue = sValue.replaceAt(nIndex,2, u"\""); + nIndex = sValue.indexOf(s_sQuote,nIndex+2); + } + nLen = sValue.getLength() - 1; + } + sValue = sValue.copy(nPos,nLen-nPos-1); + const ORptFilter::TGroupFunctionMap& aFunctions = _rImport.getFunctions(); + ORptFilter::TGroupFunctionMap::const_iterator aFind = aFunctions.find(sValue); + if ( aFind != aFunctions.end() ) + { + const OUString sCompleteFormula = aFind->second->getFormula(); + OUString sExpression = sCompleteFormula.getToken(1,'['); + sExpression = sExpression.getToken(0,']'); + sal_Int32 nIndex = 0; + const std::u16string_view sFormula = o3tl::getToken(sCompleteFormula, 0,'(',nIndex); + ::sal_Int16 nGroupOn = report::GroupOn::DEFAULT; + + if ( sFormula == u"rpt:LEFT") + { + nGroupOn = report::GroupOn::PREFIX_CHARACTERS; + std::u16string_view sInterval = o3tl::getToken(sCompleteFormula, 1,';',nIndex); + sInterval = o3tl::getToken(sInterval, 0,')'); + m_xGroup->setGroupInterval(o3tl::toInt32(sInterval)); + } + else if ( sFormula == u"rpt:YEAR") + nGroupOn = report::GroupOn::YEAR; + else if ( sFormula == u"rpt:MONTH") + { + nGroupOn = report::GroupOn::MONTH; + } + else if ( sCompleteFormula.matchIgnoreAsciiCase("rpt:INT((MONTH",0) + && sCompleteFormula.endsWithIgnoreAsciiCase("-1)/3)+1") ) + { + nGroupOn = report::GroupOn::QUARTAL; + } + else if ( sFormula == u"rpt:WEEK") + nGroupOn = report::GroupOn::WEEK; + else if ( sFormula == u"rpt:DAY") + nGroupOn = report::GroupOn::DAY; + else if ( sFormula == u"rpt:HOUR") + nGroupOn = report::GroupOn::HOUR; + else if ( sFormula == u"rpt:MINUTE") + nGroupOn = report::GroupOn::MINUTE; + else if ( sFormula == u"rpt:INT") + { + nGroupOn = report::GroupOn::INTERVAL; + _rImport.removeFunction(sExpression); + sExpression = sExpression.copy(OUString("INT_count_").getLength()); + OUString sInterval = sCompleteFormula.getToken(1,'/'); + sInterval = sInterval.getToken(0,')'); + m_xGroup->setGroupInterval(sInterval.toInt32()); + } + + m_xGroup->setGroupOn(nGroupOn); + + _rImport.removeFunction(sValue); + sValue = sExpression; + } + m_xGroup->setExpression(sValue); + } + } + break; + case XML_ELEMENT(REPORT, XML_KEEP_TOGETHER): + m_xGroup->setKeepTogether(lcl_getKeepTogetherOption(aIter.toView())); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + catch(const Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while putting group props!"); + } + } +} + + +OXMLGroup::~OXMLGroup() +{ + +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLGroup::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_FUNCTION): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLFunction( rImport,xAttrList,m_xGroup); + } + break; + case XML_ELEMENT(REPORT, XML_GROUP_HEADER): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xGroup->setHeaderOn(true); + xContext = new OXMLSection( rImport,xAttrList,m_xGroup->getHeader()); + } + break; + case XML_ELEMENT(REPORT, XML_GROUP): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLGroup( rImport,xAttrList); + break; + case XML_ELEMENT(REPORT, XML_DETAIL): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + Reference<XReportDefinition> xComponent = rImport.getReportDefinition(); + xContext = new OXMLSection( rImport,xAttrList, xComponent->getDetail()); + } + break; + + case XML_ELEMENT(REPORT, XML_GROUP_FOOTER): + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xGroup->setFooterOn(true); + xContext = new OXMLSection( rImport,xAttrList,m_xGroup->getFooter()); + } + break; + default: + break; + } + + return xContext; +} + +ORptFilter& OXMLGroup::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +void OXMLGroup::endFastElement(sal_Int32 ) +{ + try + { + // the group elements end in the reverse order + m_xGroups->insertByIndex(0,uno::Any(m_xGroup)); + }catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlGroup.hxx b/reportdesign/source/filter/xml/xmlGroup.hxx new file mode 100644 index 000000000..92500cc21 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlGroup.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLGROUP_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLGROUP_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XGroups.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLGroup final : public SvXMLImportContext + { + css::uno::Reference< css::report::XGroups > m_xGroups; + css::uno::Reference< css::report::XGroup > m_xGroup; + + ORptFilter& GetOwnImport(); + + OXMLGroup(const OXMLGroup&); + OXMLGroup& operator =(const OXMLGroup&); + public: + + OXMLGroup( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ); + virtual ~OXMLGroup() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLGROUP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlHelper.cxx b/reportdesign/source/filter/xml/xmlHelper.cxx new file mode 100644 index 000000000..491f3e650 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlHelper.cxx @@ -0,0 +1,382 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlHelper.hxx" +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/families.hxx> +#include <xmloff/controlpropertyhdl.hxx> +#include <xmloff/xmltkmap.hxx> +#include <connectivity/dbtools.hxx> +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <xmloff/prstylei.hxx> +#include <strings.hxx> +#include "xmlEnums.hxx" +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/report/ForceNewPage.hpp> +#include <com/sun/star/report/ReportPrintOption.hpp> +#include <com/sun/star/report/KeepTogether.hpp> +#include <xmloff/xmlement.hxx> +#include <xmloff/xmltypes.hxx> +#include <xmloff/maptype.hxx> +#include <com/sun/star/report/XReportControlFormat.hpp> +#include <com/sun/star/form/ListSourceType.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <xmloff/EnumPropertyHdl.hxx> +#include <tools/diagnose_ex.h> + +#define XML_RPT_ALIGNMENT (XML_DB_TYPES_START+1) +namespace rptxml +{ + using namespace ::xmloff::token; + using namespace ::com::sun::star::awt; + using namespace ::com::sun::star; + using namespace ::com::sun::star::sdb; + using namespace ::com::sun::star::form; + using namespace ::com::sun::star::beans; +OPropertyHandlerFactory::OPropertyHandlerFactory() +{ +} + +OPropertyHandlerFactory::~OPropertyHandlerFactory() +{ +} + +const XMLPropertyHandler* OPropertyHandlerFactory::GetPropertyHandler(sal_Int32 _nType) const +{ + const XMLPropertyHandler* pHandler = nullptr; + sal_Int32 nType = _nType; + nType &= MID_FLAG_MASK; + + switch(nType) + { + case XML_RPT_ALIGNMENT: + { + static SvXMLEnumMapEntry<style::VerticalAlignment> const pXML_VerticalAlign_Enum[] = + { + { XML_TOP, style::VerticalAlignment_TOP }, + { XML_MIDDLE, style::VerticalAlignment_MIDDLE }, + { XML_BOTTOM, style::VerticalAlignment_BOTTOM }, + { XML_TOKEN_INVALID, style::VerticalAlignment(0) } + }; + + pHandler = new XMLEnumPropertyHdl( pXML_VerticalAlign_Enum ); + } + break; + case XML_SD_TYPES_START+34: // XML_SD_TYPE_IMAGE_SCALE_MODE + pHandler = new xmloff::ImageScaleModeHandler(); + break; + default: + break; + } + + if ( !pHandler ) + pHandler = OControlPropertyHandlerFactory::GetPropertyHandler(_nType); + else + PutHdlCache(nType, pHandler); + return pHandler; +} + +#define MAP_CONST_T_ASCII( name, prefix, token, type, context ) { name, XML_NAMESPACE_##prefix, XML_##token, type|XML_TYPE_PROP_TABLE, context, SvtSaveOptions::ODFSVER_010, false } +#define MAP_CONST_P_ASCII( name, prefix, token, type, context ) { name, XML_NAMESPACE_##prefix, XML_##token, type|XML_TYPE_PROP_PARAGRAPH, context, SvtSaveOptions::ODFSVER_010, false } +#define MAP_CONST_S( name, prefix, token, type, context ) { name, XML_NAMESPACE_##prefix, XML_##token, type|XML_TYPE_PROP_SECTION, context, SvtSaveOptions::ODFSVER_010, false } +#define MAP_CONST_C_ASCII( name, prefix, token, type, context ) { name, XML_NAMESPACE_##prefix, XML_##token, type|XML_TYPE_PROP_TABLE_CELL, context, SvtSaveOptions::ODFSVER_010, false } +#define MAP_END() { nullptr, 0, XML_TOKEN_INVALID, 0 ,0, SvtSaveOptions::ODFSVER_010, false} + +rtl::Reference < XMLPropertySetMapper > OXMLHelper::GetCellStylePropertyMap(bool _bOldFormat, bool bForExport) +{ + if ( _bOldFormat ) + { + static const XMLPropertyMapEntry s_aXMLCellStylesProperties[] = + { + MAP_CONST_C_ASCII( PROPERTY_FORMATKEY, STYLE, DATA_STYLE_NAME, XML_TYPE_NUMBER | MID_FLAG_SPECIAL_ITEM, CTF_RPT_NUMBERFORMAT ), + + MAP_CONST_C_ASCII( PROPERTY_CONTROLBACKGROUND, + FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), + MAP_CONST_C_ASCII( PROPERTY_VERTICALALIGN, STYLE, VERTICAL_ALIGN, XML_RPT_ALIGNMENT, 0 ), + MAP_CONST_C_ASCII( PROPERTY_CONTROLBACKGROUNDTRANSPARENT, + FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP_CONST_P_ASCII( PROPERTY_CONTROLBACKGROUND, + FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), + MAP_CONST_P_ASCII( PROPERTY_CONTROLBACKGROUNDTRANSPARENT, + FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP_CONST_C_ASCII( "BorderLeft", FO, BORDER_LEFT, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderRight", FO, BORDER_RIGHT, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderTop", FO, BORDER_TOP, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderBottom", FO, BORDER_BOTTOM, XML_TYPE_BORDER, 0 ), + MAP_END() + }; + return new XMLPropertySetMapper(s_aXMLCellStylesProperties,new OPropertyHandlerFactory(), bForExport); + } + else + { + static const XMLPropertyMapEntry s_aXMLCellStylesProperties[] = + { + MAP_CONST_C_ASCII( PROPERTY_FORMATKEY, STYLE, DATA_STYLE_NAME, XML_TYPE_NUMBER | MID_FLAG_SPECIAL_ITEM, CTF_RPT_NUMBERFORMAT ), + + MAP_CONST_C_ASCII( PROPERTY_CONTROLBACKGROUND, + FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), + MAP_CONST_C_ASCII( PROPERTY_CONTROLBACKGROUNDTRANSPARENT, + FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP_CONST_C_ASCII( PROPERTY_VERTICALALIGN, + STYLE, VERTICAL_ALIGN, XML_RPT_ALIGNMENT, 0 ), + MAP_CONST_C_ASCII( "BorderLeft", FO, BORDER_LEFT, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderRight", FO, BORDER_RIGHT, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderTop", FO, BORDER_TOP, XML_TYPE_BORDER, 0 ), + MAP_CONST_C_ASCII( "BorderBottom", FO, BORDER_BOTTOM, XML_TYPE_BORDER, 0 ), + MAP_END() + }; + return new XMLPropertySetMapper(s_aXMLCellStylesProperties,new OPropertyHandlerFactory(), bForExport); + } +} + +const XMLPropertyMapEntry* OXMLHelper::GetTableStyleProps() +{ + static const XMLPropertyMapEntry aXMLTableStylesProperties[] = + { + MAP_CONST_T_ASCII( PROPERTY_BACKCOLOR, FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), + MAP_CONST_T_ASCII( PROPERTY_BACKTRANSPARENT,FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT | MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MAP_END() + }; + return aXMLTableStylesProperties; +} + +const XMLPropertyMapEntry* OXMLHelper::GetRowStyleProps() +{ + static const XMLPropertyMapEntry aXMLStylesProperties[] = + { + MAP_CONST_S("Height", STYLE, ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW | XML_TYPE_MEASURE, 0), + MAP_CONST_S("MinHeight", STYLE, MIN_ROW_HEIGHT, XML_TYPE_PROP_TABLE_ROW | XML_TYPE_MEASURE, 0), + MAP_END() + }; + return aXMLStylesProperties; +} + +const XMLPropertyMapEntry* OXMLHelper::GetColumnStyleProps() +{ + static const XMLPropertyMapEntry aXMLColumnStylesProperties[] = + { + MAP_CONST_S( "Width", STYLE, COLUMN_WIDTH, XML_TYPE_PROP_TABLE_COLUMN|XML_TYPE_MEASURE, 0 ), + MAP_END() + }; + return aXMLColumnStylesProperties; +} + +const SvXMLEnumMapEntry<sal_Int16>* OXMLHelper::GetReportPrintOptions() +{ + static const SvXMLEnumMapEntry<sal_Int16> s_aXML_EnumMap[] = + { + { XML_NOT_WITH_REPORT_HEADER, report::ReportPrintOption::NOT_WITH_REPORT_HEADER }, + { XML_NOT_WITH_REPORT_FOOTER, report::ReportPrintOption::NOT_WITH_REPORT_FOOTER }, + { XML_NOT_WITH_REPORT_HEADER_NOR_FOOTER, report::ReportPrintOption::NOT_WITH_REPORT_HEADER_FOOTER }, + { XML_TOKEN_INVALID, 0 } + }; + return s_aXML_EnumMap; +} + +const SvXMLEnumMapEntry<sal_Int16>* OXMLHelper::GetForceNewPageOptions() +{ + static const SvXMLEnumMapEntry<sal_Int16> s_aXML_EnumMap[] = + { + { XML_BEFORE_SECTION, report::ForceNewPage::BEFORE_SECTION }, + { XML_AFTER_SECTION, report::ForceNewPage::AFTER_SECTION }, + { XML_BEFORE_AFTER_SECTION, report::ForceNewPage::BEFORE_AFTER_SECTION }, + { XML_TOKEN_INVALID, 0 } + }; + return s_aXML_EnumMap; +} + +const SvXMLEnumMapEntry<sal_Int16>* OXMLHelper::GetKeepTogetherOptions() +{ + static const SvXMLEnumMapEntry<sal_Int16> s_aXML_EnumMap[] = + { + { XML_WHOLE_GROUP, report::KeepTogether::WHOLE_GROUP }, + { XML_WITH_FIRST_DETAIL, report::KeepTogether::WITH_FIRST_DETAIL }, + { XML_TOKEN_INVALID, 0 } + }; + return s_aXML_EnumMap; +} + +const SvXMLEnumMapEntry<sal_Int32>* OXMLHelper::GetCommandTypeOptions() +{ + static const SvXMLEnumMapEntry<sal_Int32> s_aXML_EnumMap[] = + { + { XML_TABLE, CommandType::TABLE }, + { XML_QUERY, CommandType::QUERY }, + { XML_TOKEN_INVALID, 0 } + }; + return s_aXML_EnumMap; +} + +#define PROPERTY_ID_FONTNAME 1 +#define PROPERTY_ID_FONTHEIGHT 2 +#define PROPERTY_ID_FONTWIDTH 3 +#define PROPERTY_ID_FONTSTYLENAME 4 +#define PROPERTY_ID_FONTFAMILY 5 +#define PROPERTY_ID_FONTCHARSET 6 +#define PROPERTY_ID_FONTPITCH 7 +#define PROPERTY_ID_FONTCHARWIDTH 8 +#define PROPERTY_ID_FONTWEIGHT 9 +#define PROPERTY_ID_FONTSLANT 10 +#define PROPERTY_ID_FONTUNDERLINE 11 +#define PROPERTY_ID_FONTSTRIKEOUT 12 +#define PROPERTY_ID_FONTORIENTATION 13 +#define PROPERTY_ID_FONTKERNING 14 +#define PROPERTY_ID_FONTWORDLINEMODE 15 +#define PROPERTY_ID_FONTTYPE 16 +void OXMLHelper::copyStyleElements(const bool _bOld,const OUString& _sStyleName,const SvXMLStylesContext* _pAutoStyles,const uno::Reference<beans::XPropertySet>& _xProp) +{ + if ( !_xProp.is() || _sStyleName.isEmpty() || !_pAutoStyles ) + return; + XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext *>(_pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL,_sStyleName))); + if ( !pAutoStyle ) + return; + + css::awt::FontDescriptor aFont; + static comphelper::PropertyMapEntry const pMap[] = + { + {OUString(PROPERTY_FONTNAME), PROPERTY_ID_FONTNAME, cppu::UnoType<decltype(aFont.Name)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_CHARFONTHEIGHT), PROPERTY_ID_FONTHEIGHT, cppu::UnoType<decltype(aFont.Height)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTWIDTH), PROPERTY_ID_FONTWIDTH, cppu::UnoType<decltype(aFont.Width)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTSTYLENAME), PROPERTY_ID_FONTSTYLENAME, cppu::UnoType<decltype(aFont.StyleName)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTFAMILY), PROPERTY_ID_FONTFAMILY, cppu::UnoType<decltype(aFont.Family)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTCHARSET), PROPERTY_ID_FONTCHARSET, cppu::UnoType<decltype(aFont.CharSet)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTPITCH), PROPERTY_ID_FONTPITCH, cppu::UnoType<decltype(aFont.Pitch)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTCHARWIDTH), PROPERTY_ID_FONTCHARWIDTH, cppu::UnoType<decltype(aFont.CharacterWidth)>::get(),PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTWEIGHT), PROPERTY_ID_FONTWEIGHT, cppu::UnoType<decltype(aFont.Weight)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_CHARPOSTURE), PROPERTY_ID_FONTSLANT, cppu::UnoType<decltype(aFont.Slant)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTUNDERLINE), PROPERTY_ID_FONTUNDERLINE, cppu::UnoType<decltype(aFont.Underline)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_CHARSTRIKEOUT), PROPERTY_ID_FONTSTRIKEOUT, cppu::UnoType<decltype(aFont.Strikeout)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTORIENTATION), PROPERTY_ID_FONTORIENTATION, cppu::UnoType<decltype(aFont.Orientation)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTKERNING), PROPERTY_ID_FONTKERNING, cppu::UnoType<decltype(aFont.Kerning)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_CHARWORDMODE), PROPERTY_ID_FONTWORDLINEMODE, cppu::UnoType<decltype(aFont.WordLineMode)>::get() ,PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_FONTTYPE), PROPERTY_ID_FONTTYPE, cppu::UnoType<decltype(aFont.Type)>::get() ,PropertyAttribute::BOUND,0}, + }; + try + { + pAutoStyle->FillPropertySet(_xProp); + if ( _bOld && _xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_CHARHIDDEN) ) + _xProp->setPropertyValue(PROPERTY_CHARHIDDEN,uno::Any(false)); + + uno::Reference<beans::XPropertySet> xProp = comphelper::GenericPropertySet_CreateInstance(new comphelper::PropertySetInfo(pMap)); + pAutoStyle->FillPropertySet(xProp); + xProp->getPropertyValue(PROPERTY_FONTNAME) >>= aFont.Name; + xProp->getPropertyValue(PROPERTY_CHARFONTHEIGHT) >>= aFont.Height; + xProp->getPropertyValue(PROPERTY_FONTWIDTH) >>= aFont.Width; + xProp->getPropertyValue(PROPERTY_FONTSTYLENAME) >>= aFont.StyleName; + xProp->getPropertyValue(PROPERTY_FONTFAMILY) >>= aFont.Family; + xProp->getPropertyValue(PROPERTY_FONTCHARSET) >>= aFont.CharSet; + xProp->getPropertyValue(PROPERTY_FONTPITCH) >>= aFont.Pitch; + xProp->getPropertyValue(PROPERTY_FONTCHARWIDTH) >>= aFont.CharacterWidth; + xProp->getPropertyValue(PROPERTY_FONTWEIGHT) >>= aFont.Weight; + xProp->getPropertyValue(PROPERTY_CHARPOSTURE) >>= aFont.Slant; + xProp->getPropertyValue(PROPERTY_FONTUNDERLINE) >>= aFont.Underline; + xProp->getPropertyValue(PROPERTY_CHARSTRIKEOUT) >>= aFont.Strikeout; + xProp->getPropertyValue(PROPERTY_FONTORIENTATION) >>= aFont.Orientation; + xProp->getPropertyValue(PROPERTY_FONTKERNING) >>= aFont.Kerning; + xProp->getPropertyValue(PROPERTY_CHARWORDMODE) >>= aFont.WordLineMode; + xProp->getPropertyValue(PROPERTY_FONTTYPE) >>= aFont.Type; + uno::Reference<report::XReportControlFormat> xReportControlModel(_xProp,uno::UNO_QUERY); + if ( xReportControlModel.is() && !aFont.Name.isEmpty() ) + { + try + { + xReportControlModel->setFontDescriptor(aFont); + } + catch(const beans::UnknownPropertyException &){} + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OXMLHelper::copyStyleElements"); + } +} + +uno::Reference<beans::XPropertySet> OXMLHelper::createBorderPropertySet() +{ + static comphelper::PropertyMapEntry const pMap[] = + { + {OUString(PROPERTY_BORDERLEFT), 0, cppu::UnoType<table::BorderLine2>::get(),PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_BORDERRIGHT), 1, cppu::UnoType<table::BorderLine2>::get(),PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_BORDERTOP), 2, cppu::UnoType<table::BorderLine2>::get(),PropertyAttribute::BOUND,0}, + {OUString(PROPERTY_BORDERBOTTOM), 3, cppu::UnoType<table::BorderLine2>::get(),PropertyAttribute::BOUND,0}, + }; + return comphelper::GenericPropertySet_CreateInstance(new comphelper::PropertySetInfo(pMap)); +} + +std::unique_ptr<SvXMLTokenMap> OXMLHelper::GetReportElemTokenMap() +{ + static const SvXMLTokenMapEntry aElemTokenMap[]= + { + { XML_NAMESPACE_REPORT, XML_REPORT_HEADER, XML_TOK_REPORT_HEADER }, + { XML_NAMESPACE_REPORT, XML_PAGE_HEADER , XML_TOK_PAGE_HEADER }, + { XML_NAMESPACE_REPORT, XML_GROUP, XML_TOK_GROUP }, + { XML_NAMESPACE_REPORT, XML_DETAIL , XML_TOK_DETAIL }, + { XML_NAMESPACE_REPORT, XML_PAGE_FOOTER , XML_TOK_PAGE_FOOTER }, + { XML_NAMESPACE_REPORT, XML_REPORT_FOOTER, XML_TOK_REPORT_FOOTER }, + { XML_NAMESPACE_REPORT, XML_HEADER_ON_NEW_PAGE, XML_TOK_HEADER_ON_NEW_PAGE }, + { XML_NAMESPACE_REPORT, XML_FOOTER_ON_NEW_PAGE, XML_TOK_FOOTER_ON_NEW_PAGE }, + { XML_NAMESPACE_REPORT, XML_COMMAND_TYPE, XML_TOK_COMMAND_TYPE }, + { XML_NAMESPACE_REPORT, XML_COMMAND, XML_TOK_COMMAND }, + { XML_NAMESPACE_REPORT, XML_FILTER, XML_TOK_FILTER }, + { XML_NAMESPACE_REPORT, XML_CAPTION, XML_TOK_CAPTION }, + { XML_NAMESPACE_REPORT, XML_ESCAPE_PROCESSING, XML_TOK_ESCAPE_PROCESSING }, + { XML_NAMESPACE_REPORT, XML_FUNCTION, XML_TOK_REPORT_FUNCTION }, + { XML_NAMESPACE_OFFICE, XML_MIMETYPE, XML_TOK_REPORT_MIMETYPE }, + { XML_NAMESPACE_DRAW, XML_NAME, XML_TOK_REPORT_NAME }, + { XML_NAMESPACE_REPORT, XML_MASTER_DETAIL_FIELDS, XML_TOK_MASTER_DETAIL_FIELDS }, + { XML_NAMESPACE_DRAW, XML_FRAME, XML_TOK_SUB_FRAME }, + { XML_NAMESPACE_OFFICE, XML_BODY, XML_TOK_SUB_BODY }, + XML_TOKEN_MAP_END + }; + return std::make_unique<SvXMLTokenMap>( aElemTokenMap ); +} + +std::unique_ptr<SvXMLTokenMap> OXMLHelper::GetSubDocumentElemTokenMap() +{ + static const SvXMLTokenMapEntry aElemTokenMap[]= + { + { XML_NAMESPACE_REPORT, XML_MASTER_DETAIL_FIELD, XML_TOK_MASTER_DETAIL_FIELD}, + { XML_NAMESPACE_REPORT, XML_MASTER, XML_TOK_MASTER}, + { XML_NAMESPACE_REPORT, XML_DETAIL, XML_TOK_SUB_DETAIL}, + XML_TOKEN_MAP_END + }; + return std::make_unique<SvXMLTokenMap>( aElemTokenMap ); +} + +const SvXMLEnumMapEntry<sal_Int16>* OXMLHelper::GetImageScaleOptions() +{ + static const SvXMLEnumMapEntry<sal_Int16> s_aXML_EnumMap[] = + { + { XML_ISOTROPIC, awt::ImageScaleMode::ISOTROPIC }, + { XML_ANISOTROPIC, awt::ImageScaleMode::ANISOTROPIC }, + { XML_TOKEN_INVALID, 0 } + }; + return s_aXML_EnumMap; +} + + +} // rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlHelper.hxx b/reportdesign/source/filter/xml/xmlHelper.hxx new file mode 100644 index 000000000..3a9ec4668 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlHelper.hxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLHELPER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLHELPER_HXX + +#include <xmloff/xmlprmap.hxx> +#include <xmloff/contextid.hxx> +#include <xmloff/controlpropertyhdl.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <memory> + +#define CTF_RPT_NUMBERFORMAT (XML_DB_CTF_START + 1) + + +class SvXMLStylesContext; +class SvXMLTokenMap; +namespace rptxml +{ + class OPropertyHandlerFactory : public ::xmloff::OControlPropertyHandlerFactory + { + OPropertyHandlerFactory(const OPropertyHandlerFactory&) = delete; + void operator =(const OPropertyHandlerFactory&) = delete; + public: + OPropertyHandlerFactory(); + virtual ~OPropertyHandlerFactory() override; + + virtual const XMLPropertyHandler* GetPropertyHandler(sal_Int32 _nType) const override; + }; + + class OXMLHelper + { + public: + static rtl::Reference < XMLPropertySetMapper > GetCellStylePropertyMap(bool _bOldFormat, bool bForExport); + + static const SvXMLEnumMapEntry<sal_Int16>* GetReportPrintOptions(); + static const SvXMLEnumMapEntry<sal_Int16>* GetForceNewPageOptions(); + static const SvXMLEnumMapEntry<sal_Int16>* GetKeepTogetherOptions(); + static const SvXMLEnumMapEntry<sal_Int32>* GetCommandTypeOptions(); + static const SvXMLEnumMapEntry<sal_Int16>* GetImageScaleOptions(); + + static const XMLPropertyMapEntry* GetTableStyleProps(); + static const XMLPropertyMapEntry* GetColumnStyleProps(); + + static const XMLPropertyMapEntry* GetRowStyleProps(); + + static void copyStyleElements(const bool _bOld,const OUString& _sStyleName,const SvXMLStylesContext* _pAutoStyles,const css::uno::Reference< css::beans::XPropertySet>& _xProp); + static css::uno::Reference< css::beans::XPropertySet> createBorderPropertySet(); + + static std::unique_ptr<SvXMLTokenMap> GetReportElemTokenMap(); + static std::unique_ptr<SvXMLTokenMap> GetSubDocumentElemTokenMap(); + + }; + +} // rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlImage.cxx b/reportdesign/source/filter/xml/xmlImage.cxx new file mode 100644 index 000000000..c4310d3a8 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlImage.cxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlImage.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmluconv.hxx> +#include "xmlHelper.hxx" +#include <unotools/pathoptions.hxx> +#include <sal/log.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +#include <com/sun/star/awt/ImageScaleMode.hpp> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + + +OXMLImage::OXMLImage( ORptFilter& rImport, + const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XImageControl > & _xComponent + ,OXMLTable* _pContainer) : + OXMLReportElementBase( rImport,_xComponent,_pContainer) +{ + + OSL_ENSURE(m_xReportComponent.is(),"Component is NULL!"); + + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(FORM, XML_IMAGE_DATA): + { + SvtPathOptions aPathOptions; + OUString sValue = aIter.toString(); + sValue = aPathOptions.SubstituteVariable(sValue); + _xComponent->setImageURL(rImport.GetAbsoluteReference( sValue )); + break; + } + case XML_ELEMENT(REPORT, XML_PRESERVE_IRI): + _xComponent->setPreserveIRI(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_SCALE): + { + sal_Int16 nRet = awt::ImageScaleMode::NONE; + if ( IsXMLToken(aIter, XML_TRUE) ) + { + nRet = awt::ImageScaleMode::ANISOTROPIC; + } + else + { + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetImageScaleOptions(); + bool bConvertOk = SvXMLUnitConverter::convertEnum( nRet, aIter.toView(), aXML_EnumMap ); + SAL_WARN_IF(!bConvertOk, "reportdesign", "convertEnum failed"); + } + _xComponent->setScaleMode( nRet ); + break; + } + case XML_ELEMENT(REPORT, XML_FORMULA): + _xComponent->setDataField(ORptFilter::convertFormula(aIter.toString())); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the image props"); + } +} + + +OXMLImage::~OXMLImage() +{ + +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlImage.hxx b/reportdesign/source/filter/xml/xmlImage.hxx new file mode 100644 index 000000000..32be8a8ac --- /dev/null +++ b/reportdesign/source/filter/xml/xmlImage.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMAGE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMAGE_HXX + +#include "xmlReportElementBase.hxx" +#include <com/sun/star/report/XImageControl.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLImage : public OXMLReportElementBase + { + OXMLImage(const OXMLImage&) = delete; + void operator =(const OXMLImage&) = delete; + public: + + OXMLImage( ORptFilter& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XImageControl >& _xComponent + ,OXMLTable* _pContainer); + virtual ~OXMLImage() override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlImportDocumentHandler.cxx b/reportdesign/source/filter/xml/xmlImportDocumentHandler.cxx new file mode 100644 index 000000000..edb4dcaaa --- /dev/null +++ b/reportdesign/source/filter/xml/xmlImportDocumentHandler.cxx @@ -0,0 +1,385 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <memory> +#include "xmlImportDocumentHandler.hxx" +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include <com/sun/star/chart2/data/XDataSource.hpp> +#include <com/sun/star/chart/XComplexDescriptionAccess.hpp> +#include <com/sun/star/chart/ChartDataRowSource.hpp> +#include <com/sun/star/reflection/ProxyFactory.hpp> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <xmloff/attrlist.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlement.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmltkmap.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <tools/diagnose_ex.h> +#include <rtl/ref.hxx> + +#include "xmlHelper.hxx" +#include "xmlEnums.hxx" +#include "xmlExportDocumentHandler.hxx" + +namespace rptxml +{ +using namespace ::com::sun::star; +using namespace ::xmloff::token; + +ImportDocumentHandler::ImportDocumentHandler(uno::Reference< uno::XComponentContext > const & context) + :m_bImportedChart( false ) + ,m_xContext(context) +{ +} + +ImportDocumentHandler::~ImportDocumentHandler() +{ + if ( m_xProxy.is() ) + { + m_xProxy->setDelegator( nullptr ); + m_xProxy.clear(); + } +} +IMPLEMENT_GET_IMPLEMENTATION_ID(ImportDocumentHandler) + +OUString SAL_CALL ImportDocumentHandler::getImplementationName( ) +{ + return "com.sun.star.comp.report.ImportDocumentHandler"; +} + +sal_Bool SAL_CALL ImportDocumentHandler::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL ImportDocumentHandler::getSupportedServiceNames( ) +{ + uno::Sequence< OUString > aSupported; + if ( m_xServiceInfo.is() ) + aSupported = m_xServiceInfo->getSupportedServiceNames(); + return ::comphelper::concatSequences( uno::Sequence<OUString> { "com.sun.star.report.ImportDocumentHandler" }, aSupported); +} + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ImportDocumentHandler_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ImportDocumentHandler(context)); +} + +// xml::sax::XDocumentHandler: +void SAL_CALL ImportDocumentHandler::startDocument() +{ + m_xDelegatee->startDocument(); +} + +void SAL_CALL ImportDocumentHandler::endDocument() +{ + m_xDelegatee->endDocument(); + uno::Reference< chart2::data::XDataReceiver > xReceiver(m_xModel,uno::UNO_QUERY_THROW); + if ( !m_bImportedChart ) + return; + + // this fills the chart again + ::comphelper::NamedValueCollection aArgs; + aArgs.put( "CellRangeRepresentation", OUString("all") ); + aArgs.put( "FirstCellAsLabel", uno::Any( true ) ); + aArgs.put( "DataRowSource", uno::Any( chart::ChartDataRowSource_COLUMNS ) ); + + bool bHasCategories = false; + + uno::Reference< chart2::data::XDataSource > xDataSource(m_xModel, uno::UNO_QUERY); + if( xDataSource.is()) + { + const uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSequences(xDataSource->getDataSequences()); + for( const auto& rSequence : aSequences ) + { + if( rSequence.is() ) + { + uno::Reference< beans::XPropertySet > xSeqProp( rSequence->getValues(), uno::UNO_QUERY ); + OUString aRole; + if ( xSeqProp.is() + && ( xSeqProp->getPropertyValue( "Role" ) >>= aRole ) + && aRole == "categories" + ) + { + bHasCategories = true; + break; + } + } + } + } + aArgs.put( "HasCategories", uno::Any( bHasCategories ) ); + + uno::Reference< chart::XComplexDescriptionAccess > xDataProvider(m_xModel->getDataProvider(),uno::UNO_QUERY); + if ( xDataProvider.is() ) + { + const uno::Sequence< OUString > aColumnNames = xDataProvider->getColumnDescriptions(); + aArgs.put( "ColumnDescriptions", uno::Any( aColumnNames ) ); + } + + xReceiver->attachDataProvider( m_xDatabaseDataProvider ); + xReceiver->setArguments( aArgs.getPropertyValues() ); +} + +void SAL_CALL ImportDocumentHandler::startElement(const OUString & _sName, const uno::Reference< xml::sax::XAttributeList > & _xAttrList) +{ + uno::Reference< xml::sax::XAttributeList > xNewAttribs = _xAttrList; + bool bExport = true; + if ( _sName == "office:report" ) + { + const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0; + static const OUString s_sTRUE = ::xmloff::token::GetXMLToken(XML_TRUE); + try + { + for(sal_Int16 i = 0; i < nLength; ++i) + { + OUString sLocalName; + const OUString sAttrName = _xAttrList->getNameByIndex( i ); + const sal_Int32 nColonPos = sAttrName.indexOf( ':' ); + if( -1 == nColonPos ) + sLocalName = sAttrName; + else + sLocalName = sAttrName.copy( nColonPos + 1 ); + const OUString sValue = _xAttrList->getValueByIndex( i ); + + switch( m_pReportElemTokenMap->Get( XML_NAMESPACE_REPORT, sLocalName ) ) + { + case XML_TOK_COMMAND_TYPE: + { + sal_Int32 nRet = sdb::CommandType::COMMAND; + const SvXMLEnumMapEntry<sal_Int32>* aXML_EnumMap = OXMLHelper::GetCommandTypeOptions(); + (void)SvXMLUnitConverter::convertEnum( nRet, sValue, aXML_EnumMap ); + m_xDatabaseDataProvider->setCommandType(nRet); + } + break; + case XML_TOK_COMMAND: + m_xDatabaseDataProvider->setCommand(sValue); + break; + case XML_TOK_FILTER: + m_xDatabaseDataProvider->setFilter(sValue); + break; + case XML_TOK_ESCAPE_PROCESSING: + m_xDatabaseDataProvider->setEscapeProcessing(sValue == s_sTRUE); + break; + default: + break; + } + } + } + catch(uno::Exception&) + { + } + m_xDelegatee->startElement(lcl_createAttribute(XML_NP_OFFICE,XML_CHART),nullptr); + bExport = false; + m_bImportedChart = true; + } + else if ( _sName == "rpt:master-detail-field" ) + { + const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0; + ::std::unique_ptr<SvXMLTokenMap> pMasterElemTokenMap( OXMLHelper::GetSubDocumentElemTokenMap()); + try + { + OUString sMasterField,sDetailField; + for(sal_Int16 i = 0; i < nLength; ++i) + { + OUString sLocalName; + const OUString sAttrName = _xAttrList->getNameByIndex( i ); + const sal_Int32 nColonPos = sAttrName.indexOf( ':' ); + if( -1 == nColonPos ) + sLocalName = sAttrName; + else + sLocalName = sAttrName.copy( nColonPos + 1 ); + const OUString sValue = _xAttrList->getValueByIndex( i ); + + switch( pMasterElemTokenMap->Get( XML_NAMESPACE_REPORT, sLocalName ) ) + { + case XML_TOK_MASTER: + sMasterField = sValue; + break; + case XML_TOK_SUB_DETAIL: + sDetailField = sValue; + break; + } + } + if ( sDetailField.isEmpty() ) + sDetailField = sMasterField; + m_aMasterFields.push_back(sMasterField); + m_aDetailFields.push_back(sDetailField); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the report definition props"); + } + bExport = false; + } + else if ( _sName == "rpt:detail" + || _sName == "rpt:formatted-text" + || _sName == "rpt:master-detail-fields" + || _sName == "rpt:report-component" + || _sName == "rpt:report-element") + bExport = false; + else if ( _sName == "chart:plot-area" ) + { + bool bHasCategories = true; + const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0; + for(sal_Int16 i = 0; i < nLength; ++i) + { + std::u16string_view sLocalName; + const OUString sAttrName = _xAttrList->getNameByIndex( i ); + const sal_Int32 nColonPos = sAttrName.indexOf( ':' ); + if( -1 == nColonPos ) + sLocalName = sAttrName; + else + sLocalName = sAttrName.subView( nColonPos + 1 ); + if ( sLocalName == u"data-source-has-labels" ) + { + const OUString sValue = _xAttrList->getValueByIndex( i ); + bHasCategories = sValue == "both"; + break; + } + } + for(beans::PropertyValue & propVal : asNonConstRange(m_aArguments)) + { + if ( propVal.Name == "HasCategories" ) + { + propVal.Value <<= bHasCategories; + break; + } + } + + rtl::Reference<SvXMLAttributeList> pList = new SvXMLAttributeList(); + xNewAttribs = pList; + pList->AppendAttributeList(_xAttrList); + pList->AddAttribute("table:cell-range-address","local-table.$A$1:.$Z$65536"); + + } + + if ( bExport ) + m_xDelegatee->startElement(_sName,xNewAttribs); +} + +void SAL_CALL ImportDocumentHandler::endElement(const OUString & _sName) +{ + bool bExport = true; + OUString sNewName = _sName; + if ( _sName == "office:report" ) + { + sNewName = lcl_createAttribute(XML_NP_OFFICE,XML_CHART); + } + else if ( _sName == "rpt:master-detail-fields" ) + { + if ( !m_aMasterFields.empty() ) + m_xDatabaseDataProvider->setMasterFields(uno::Sequence< OUString>(&*m_aMasterFields.begin(),m_aMasterFields.size())); + if ( !m_aDetailFields.empty() ) + m_xDatabaseDataProvider->setDetailFields(uno::Sequence< OUString>(&*m_aDetailFields.begin(),m_aDetailFields.size())); + bExport = false; + } + else if ( _sName == "rpt:detail" + || _sName == "rpt:formatted-text" + || _sName == "rpt:master-detail-field" + || _sName == "rpt:report-component" + || _sName == "rpt:report-element") + bExport = false; + + if ( bExport ) + m_xDelegatee->endElement(sNewName); +} + +void SAL_CALL ImportDocumentHandler::characters(const OUString & aChars) +{ + m_xDelegatee->characters(aChars); +} + +void SAL_CALL ImportDocumentHandler::ignorableWhitespace(const OUString & aWhitespaces) +{ + m_xDelegatee->ignorableWhitespace(aWhitespaces); +} + +void SAL_CALL ImportDocumentHandler::processingInstruction(const OUString & aTarget, const OUString & aData) +{ + m_xDelegatee->processingInstruction(aTarget,aData); +} + +void SAL_CALL ImportDocumentHandler::setDocumentLocator(const uno::Reference< xml::sax::XLocator > & xLocator) +{ + m_xDelegatee->setDocumentLocator(xLocator); +} +void SAL_CALL ImportDocumentHandler::initialize( const uno::Sequence< uno::Any >& _aArguments ) +{ + ::osl::MutexGuard aGuard(m_aMutex); + comphelper::SequenceAsHashMap aArgs(_aArguments); + m_xDocumentHandler = aArgs.getUnpackedValueOrDefault("DocumentHandler",m_xDocumentHandler); + m_xModel = aArgs.getUnpackedValueOrDefault("Model",m_xModel); + + OSL_ENSURE(m_xDocumentHandler.is(), "No document handler available!"); + if (!m_xDocumentHandler.is() || !m_xModel.is()) + throw uno::Exception("no delegatee and no model", nullptr); + + m_xDelegatee.set(new SvXMLLegacyToFastDocHandler(dynamic_cast<SvXMLImport*>(m_xDocumentHandler.get()))); + + m_xDatabaseDataProvider.set(m_xModel->getDataProvider(),uno::UNO_QUERY); + if ( !m_xDatabaseDataProvider.is() ) + { + // tdf#117162 reportbuilder needs the DataProvider to exist to progress further + setDataProvider(m_xModel, OUString()); + m_xDatabaseDataProvider.set(m_xModel->getDataProvider(), uno::UNO_QUERY_THROW); + } + + m_aArguments = m_xDatabaseDataProvider->detectArguments(nullptr); + + uno::Reference< reflection::XProxyFactory > xProxyFactory = reflection::ProxyFactory::create( m_xContext ); + m_xProxy = xProxyFactory->createProxy(m_xDelegatee); + ::comphelper::query_aggregation(m_xProxy,m_xDelegatee); + m_xTypeProvider.set(m_xDelegatee,uno::UNO_QUERY); + m_xServiceInfo.set(m_xDelegatee,uno::UNO_QUERY); + + // set ourself as delegator + m_xProxy->setDelegator( *this ); + + m_pReportElemTokenMap = OXMLHelper::GetReportElemTokenMap(); +} + +uno::Any SAL_CALL ImportDocumentHandler::queryInterface( const uno::Type& _rType ) +{ + uno::Any aReturn = ImportDocumentHandler_BASE::queryInterface(_rType); + return aReturn.hasValue() ? aReturn : (m_xProxy.is() ? m_xProxy->queryAggregation(_rType) : aReturn); +} + +uno::Sequence< uno::Type > SAL_CALL ImportDocumentHandler::getTypes( ) +{ + if ( m_xTypeProvider.is() ) + return ::comphelper::concatSequences( + ImportDocumentHandler_BASE::getTypes(), + m_xTypeProvider->getTypes() + ); + return ImportDocumentHandler_BASE::getTypes(); +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlImportDocumentHandler.hxx b/reportdesign/source/filter/xml/xmlImportDocumentHandler.hxx new file mode 100644 index 000000000..aadea441c --- /dev/null +++ b/reportdesign/source/filter/xml/xmlImportDocumentHandler.hxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMPORTDOCUMENTHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMPORTDOCUMENTHANDLER_HXX + +#include <sal/config.h> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/xml/sax/XFastDocumentHandler.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <comphelper/uno3.hxx> +#include <xmloff/xmlimp.hxx> +#include <memory> + +class SvXMLTokenMap; +namespace rptxml +{ +typedef ::cppu::WeakAggImplHelper3< css::xml::sax::XDocumentHandler + , css::lang::XInitialization + , css::lang::XServiceInfo> ImportDocumentHandler_BASE; + +class ImportDocumentHandler : public ImportDocumentHandler_BASE +{ +public: + explicit ImportDocumentHandler(css::uno::Reference< css::uno::XComponentContext > const & context); + +private: + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override; + + DECLARE_XTYPEPROVIDER( ) + + // css::xml::sax::XDocumentHandler: + virtual void SAL_CALL startDocument() override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL startElement(const OUString & aName, const css::uno::Reference< css::xml::sax::XAttributeList > & xAttribs) override; + virtual void SAL_CALL endElement(const OUString & aName) override; + virtual void SAL_CALL characters(const OUString & aChars) override; + virtual void SAL_CALL ignorableWhitespace(const OUString & aWhitespaces) override; + virtual void SAL_CALL processingInstruction(const OUString & aTarget, const OUString & aData) override; + virtual void SAL_CALL setDocumentLocator(const css::uno::Reference< css::xml::sax::XLocator > & xLocator) override; + + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + +private: + ImportDocumentHandler(ImportDocumentHandler const &) = delete; + void operator =(ImportDocumentHandler const &) = delete; + + virtual ~ImportDocumentHandler() override; + + ::osl::Mutex m_aMutex; + bool m_bImportedChart; + ::std::vector< OUString> m_aMasterFields; + ::std::vector< OUString> m_aDetailFields; + css::uno::Sequence< css::beans::PropertyValue > m_aArguments; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference<css::xml::sax::XFastDocumentHandler> m_xDocumentHandler; + css::uno::Reference< css::xml::sax::XDocumentHandler > m_xDelegatee; + css::uno::Reference< css::uno::XAggregation > m_xProxy; + css::uno::Reference< css::lang::XTypeProvider > m_xTypeProvider; + css::uno::Reference< css::lang::XServiceInfo > m_xServiceInfo; + css::uno::Reference< css::chart2::XChartDocument > m_xModel; + css::uno::Reference< css::chart2::data::XDatabaseDataProvider > m_xDatabaseDataProvider; + + ::std::unique_ptr<SvXMLTokenMap> m_pReportElemTokenMap; +}; + +} // namespace rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLIMPORTDOCUMENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlMasterFields.cxx b/reportdesign/source/filter/xml/xmlMasterFields.cxx new file mode 100644 index 000000000..2dfd0ac4d --- /dev/null +++ b/reportdesign/source/filter/xml/xmlMasterFields.cxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlMasterFields.hxx" +#include "xmlReportElementBase.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" + + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + +OXMLMasterFields::OXMLMasterFields( ORptFilter& rImport, + const Reference< XFastAttributeList > & _xAttrList + ,IMasterDetailFieds* _pReport + ) : + SvXMLImportContext( rImport ) +,m_pReport(_pReport) +{ + OUString sMasterField,sDetailField; + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + OUString sValue = aIter.toString(); + + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_MASTER): + sMasterField = sValue; + break; + case XML_ELEMENT(REPORT, XML_DETAIL): + sDetailField = sValue; + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + if ( sDetailField.isEmpty() ) + sDetailField = sMasterField; + if ( !sMasterField.isEmpty() ) + m_pReport->addMasterDetailPair(::std::pair< OUString,OUString >(sMasterField,sDetailField)); +} + + +OXMLMasterFields::~OXMLMasterFields() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLMasterFields::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_MASTER_DETAIL_FIELD): + { + GetImport().GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLMasterFields(static_cast<ORptFilter&>(GetImport()),xAttrList ,m_pReport); + } + break; + default: + break; + } + + return xContext; +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlMasterFields.hxx b/reportdesign/source/filter/xml/xmlMasterFields.hxx new file mode 100644 index 000000000..e8e212827 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlMasterFields.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLMASTERFIELDS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLMASTERFIELDS_HXX + +#include <xmloff/xmlictxt.hxx> +namespace rptxml +{ + class ORptFilter; + class IMasterDetailFieds; + class OXMLMasterFields : public SvXMLImportContext + { + IMasterDetailFieds* m_pReport; + OXMLMasterFields(const OXMLMasterFields&) = delete; + void operator =(const OXMLMasterFields&) = delete; + public: + + OXMLMasterFields( ORptFilter& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,IMasterDetailFieds* _pReport); + virtual ~OXMLMasterFields() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + }; + +} // namespace rptxml + + +#endif // RPT_XMLMasterFields_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlPropertyHandler.cxx b/reportdesign/source/filter/xml/xmlPropertyHandler.cxx new file mode 100644 index 000000000..3279629fa --- /dev/null +++ b/reportdesign/source/filter/xml/xmlPropertyHandler.cxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "xmlPropertyHandler.hxx" +#include <xmloff/txtimp.hxx> + +namespace rptxml +{ +using namespace ::com::sun::star; +using namespace xmloff; +using namespace ::com::sun::star::uno; + +OXMLRptPropHdlFactory::OXMLRptPropHdlFactory() {} + +OXMLRptPropHdlFactory::~OXMLRptPropHdlFactory() {} + +} // rptxml + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlPropertyHandler.hxx b/reportdesign/source/filter/xml/xmlPropertyHandler.hxx new file mode 100644 index 000000000..5ca92d9c1 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlPropertyHandler.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLPROPERTYHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLPROPERTYHANDLER_HXX + +#include <xmloff/prhdlfac.hxx> + +namespace rptxml +{ + class OXMLRptPropHdlFactory : public XMLPropertyHandlerFactory + { + private: + OXMLRptPropHdlFactory(const OXMLRptPropHdlFactory&) = delete; + void operator =(const OXMLRptPropHdlFactory&) = delete; + public: + OXMLRptPropHdlFactory(); + virtual ~OXMLRptPropHdlFactory() override; + }; + +}// rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLPROPERTYHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReport.cxx b/reportdesign/source/filter/xml/xmlReport.cxx new file mode 100644 index 000000000..29f7315fe --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReport.cxx @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlReport.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlHelper.hxx" +#include "xmlGroup.hxx" +#include "xmlSection.hxx" +#include "xmlEnums.hxx" +#include "xmlFunction.hxx" +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> +#include <com/sun/star/sdb/CommandType.hpp> +#include "xmlMasterFields.hxx" + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace uno; + using namespace xml::sax; + + +OXMLReport::OXMLReport( ORptFilter& rImport, + const Reference< css::xml::sax::XFastAttributeList > & _xAttrList + ,const uno::Reference< report::XReportDefinition >& _xComponent) : + OXMLReportElementBase( rImport, _xComponent,nullptr) + ,m_xReportDefinition(_xComponent) +{ + OSL_ENSURE(m_xReportDefinition.is(),"No Report definition!"); + + impl_initRuntimeDefaults(); + + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_COMMAND_TYPE): + { + sal_Int32 nRet = sdb::CommandType::COMMAND; + const SvXMLEnumMapEntry<sal_Int32>* aXML_EnumMap = OXMLHelper::GetCommandTypeOptions(); + bool bConvertOk = SvXMLUnitConverter::convertEnum( nRet, aIter.toView(), aXML_EnumMap ); + SAL_WARN_IF(!bConvertOk, "reportdesign", "convertEnum failed"); + m_xReportDefinition->setCommandType(nRet); + } + break; + case XML_ELEMENT(REPORT, XML_COMMAND): + m_xReportDefinition->setCommand(aIter.toString()); + break; + case XML_ELEMENT(REPORT, XML_FILTER): + m_xReportDefinition->setFilter(aIter.toString()); + break; + case XML_ELEMENT(REPORT, XML_CAPTION): + case XML_ELEMENT(OFFICE, XML_CAPTION): + m_xReportDefinition->setCaption(aIter.toString()); + break; + case XML_ELEMENT(REPORT, XML_ESCAPE_PROCESSING): + m_xReportDefinition->setEscapeProcessing(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(OFFICE, XML_MIMETYPE): + m_xReportDefinition->setMimeType(aIter.toString()); + break; + case XML_ELEMENT(DRAW, XML_NAME): + m_xReportDefinition->setName(aIter.toString()); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the report definition props"); + } +} + + +OXMLReport::~OXMLReport() +{ +} + + +void OXMLReport::impl_initRuntimeDefaults() const +{ + OSL_PRECOND( m_xReportDefinition.is(), "OXMLReport::impl_initRuntimeDefaults: no component!" ); + if ( !m_xReportDefinition.is() ) + return; + + try + { + m_xReportDefinition->setCommandType( sdb::CommandType::COMMAND ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLReport::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext = OXMLReportElementBase::createFastChildContext(nElement,xAttrList); + if (xContext) + return xContext; + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_FUNCTION): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLFunction( m_rImport,xAttrList,m_xReportDefinition,true); + } + break; + case XML_ELEMENT(REPORT, XML_MASTER_DETAIL_FIELDS): + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLMasterFields(m_rImport,xAttrList ,this); + break; + case XML_ELEMENT(REPORT, XML_REPORT_HEADER): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xReportDefinition->setReportHeaderOn(true); + xContext = new OXMLSection( m_rImport,xAttrList, m_xReportDefinition->getReportHeader()); + } + break; + case XML_ELEMENT(REPORT, XML_PAGE_HEADER): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xReportDefinition->setPageHeaderOn(true); + xContext = new OXMLSection( m_rImport,xAttrList, m_xReportDefinition->getPageHeader()); + } + break; + case XML_ELEMENT(REPORT, XML_GROUP): + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLGroup( m_rImport,xAttrList); + break; + case XML_ELEMENT(REPORT, XML_DETAIL): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLSection( m_rImport,xAttrList, m_xReportDefinition->getDetail()); + } + break; + case XML_ELEMENT(REPORT, XML_PAGE_FOOTER): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xReportDefinition->setPageFooterOn(true); + xContext = new OXMLSection( m_rImport,xAttrList, m_xReportDefinition->getPageFooter(),false); + } + break; + case XML_ELEMENT(REPORT, XML_REPORT_FOOTER): + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + m_xReportDefinition->setReportFooterOn(true); + xContext = new OXMLSection( m_rImport, xAttrList, m_xReportDefinition->getReportFooter()); + } + break; + default: + break; + } + + return xContext; +} + +void OXMLReport::endFastElement(sal_Int32) +{ + Reference< XFunctions > xFunctions = m_xReportDefinition->getFunctions(); + const ORptFilter::TGroupFunctionMap& aFunctions = m_rImport.getFunctions(); + for (const auto& rEntry : aFunctions) + xFunctions->insertByIndex(xFunctions->getCount(),uno::Any(rEntry.second)); + + if ( !m_aMasterFields.empty() ) + m_xReportDefinition->setMasterFields(Sequence< OUString>(&*m_aMasterFields.begin(),m_aMasterFields.size())); + if ( !m_aDetailFields.empty() ) + m_xReportDefinition->setDetailFields(Sequence< OUString>(&*m_aDetailFields.begin(),m_aDetailFields.size())); +} + +void OXMLReport::addMasterDetailPair(const ::std::pair< OUString,OUString >& _aPair) +{ + m_aMasterFields.push_back(_aPair.first); + m_aDetailFields.push_back(_aPair.second); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReport.hxx b/reportdesign/source/filter/xml/xmlReport.hxx new file mode 100644 index 000000000..eda2c0462 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReport.hxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORT_HXX + +#include "xmlReportElementBase.hxx" +#include <vector> + +namespace rptxml +{ + class ORptFilter; + class OXMLReport final : public OXMLReportElementBase, public IMasterDetailFieds + { + css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition; + ::std::vector< OUString> m_aMasterFields; + ::std::vector< OUString> m_aDetailFields; + OXMLReport(const OXMLReport&) = delete; + void operator =(const OXMLReport&) = delete; + public: + + OXMLReport( ORptFilter& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XReportDefinition >& _xComponent); + virtual ~OXMLReport() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + virtual void addMasterDetailPair(const ::std::pair< OUString,OUString >& _aPair) override; + + private: + /** initializes our object's properties whose runtime (API) default is different from the file + format default. + */ + void impl_initRuntimeDefaults() const; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReportElement.cxx b/reportdesign/source/filter/xml/xmlReportElement.cxx new file mode 100644 index 000000000..89025ae22 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReportElement.cxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlReportElement.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include "xmlComponent.hxx" +#include "xmlCondPrtExpr.hxx" +#include "xmlFormatCondition.hxx" +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace report; + using namespace uno; + using namespace xml::sax; + +OXMLReportElement::OXMLReportElement( ORptFilter& rImport, + const Reference< XFastAttributeList > & _xAttrList + ,const Reference< XReportControlModel > & _xComponent) : + SvXMLImportContext( rImport ) +,m_xComponent(_xComponent) +{ + + OSL_ENSURE(m_xComponent.is(),"Component is NULL!"); + + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_PRINT_WHEN_GROUP_CHANGE): + m_xComponent->setPrintWhenGroupChange(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_PRINT_REPEATED_VALUES): + m_xComponent->setPrintRepeatedValues(IsXMLToken(aIter, XML_TRUE)); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the report definition props"); + } +} + + +OXMLReportElement::~OXMLReportElement() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLReportElement::createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_REPORT_COMPONENT): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLComponent( rImport,xAttrList,m_xComponent); + break; + case XML_ELEMENT(REPORT, XML_CONDITIONAL_PRINT_EXPRESSION): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLCondPrtExpr( rImport,xAttrList,m_xComponent); + break; + case XML_ELEMENT(REPORT, XML_FORMAT_CONDITION): + { + uno::Reference< report::XFormatCondition > xNewCond = m_xComponent->createFormatCondition(); + m_xComponent->insertByIndex(m_xComponent->getCount(),uno::Any(xNewCond)); + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLFormatCondition( rImport,xAttrList,xNewCond); + } + break; + default: + break; + } + + return xContext; +} + +ORptFilter& OXMLReportElement::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReportElement.hxx b/reportdesign/source/filter/xml/xmlReportElement.hxx new file mode 100644 index 000000000..5f64dbe73 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReportElement.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENT_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XReportControlModel.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLReportElement : public SvXMLImportContext + { + css::uno::Reference< css::report::XReportControlModel > m_xComponent; + ORptFilter& GetOwnImport(); + OXMLReportElement(const OXMLReportElement&) = delete; + void operator =(const OXMLReportElement&) = delete; + public: + + OXMLReportElement( ORptFilter& rImport, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XReportControlModel >& _xComponent); + virtual ~OXMLReportElement() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReportElementBase.cxx b/reportdesign/source/filter/xml/xmlReportElementBase.cxx new file mode 100644 index 000000000..ffcb8b7b6 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReportElementBase.cxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <xmloff/ProgressBarHelper.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmltoken.hxx> +#include "xmlReportElementBase.hxx" +#include "xmlfilter.hxx" +#include "xmlControlProperty.hxx" +#include "xmlReportElement.hxx" +#include "xmlEnums.hxx" +#include "xmlTable.hxx" +#include <tools/diagnose_ex.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + +OXMLReportElementBase::OXMLReportElementBase( ORptFilter& rImport + ,const Reference< XReportComponent > & _xComponent + ,OXMLTable* _pContainer) : + SvXMLImportContext( rImport ) +,m_rImport(rImport) +,m_pContainer(_pContainer) +,m_xReportComponent(_xComponent) +{ +} + + +OXMLReportElementBase::~OXMLReportElementBase() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLReportElementBase::createFastChildContext( + sal_Int32 nElement, + const Reference< XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_REPORT_ELEMENT): + { + uno::Reference<report::XReportControlModel> xReportModel(m_xReportComponent,uno::UNO_QUERY); + if ( xReportModel.is() ) + { + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLReportElement( m_rImport,xAttrList,xReportModel); + } + } + break; + case XML_ELEMENT(FORM, XML_PROPERTIES): + m_rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLControlProperty( m_rImport,xAttrList,m_xReportComponent); + break; + default: + break; + } + + return xContext; +} + +void OXMLReportElementBase::endFastElement(sal_Int32 ) +{ + try + { + if ( m_pContainer && m_pContainer->getSection().is() && m_xReportComponent.is() ) + m_pContainer->getSection()->add(m_xReportComponent); + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while inserting a new control!"); + } +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlReportElementBase.hxx b/reportdesign/source/filter/xml/xmlReportElementBase.hxx new file mode 100644 index 000000000..c37e17c50 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlReportElementBase.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENTBASE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENTBASE_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XReportComponent.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLTable; + + class SAL_NO_VTABLE IMasterDetailFieds + { + public: + virtual void addMasterDetailPair(const ::std::pair< OUString,OUString >& _aPair) = 0; + + protected: + ~IMasterDetailFieds() {} + }; + + class OXMLReportElementBase : public SvXMLImportContext + { + OXMLReportElementBase(const OXMLReportElementBase&) = delete; + void operator =(const OXMLReportElementBase&) = delete; + protected: + ORptFilter& m_rImport; + OXMLTable* m_pContainer; + css::uno::Reference< css::report::XReportComponent > m_xReportComponent; + + public: + + OXMLReportElementBase( ORptFilter& rImport + ,const css::uno::Reference< css::report::XReportComponent >& _xComponent + ,OXMLTable* _pContainer); + virtual ~OXMLReportElementBase() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLREPORTELEMENTBASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlSection.cxx b/reportdesign/source/filter/xml/xmlSection.cxx new file mode 100644 index 000000000..957c3a2ca --- /dev/null +++ b/reportdesign/source/filter/xml/xmlSection.cxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlSection.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmluconv.hxx> +#include "xmlHelper.hxx" +#include <com/sun/star/report/ReportPrintOption.hpp> +#include "xmlTable.hxx" +#include <tools/diagnose_ex.h> + + +namespace rptxml +{ + using namespace ::xmloff; + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + + static sal_Int16 lcl_getReportPrintOption(std::string_view _sValue) + { + sal_Int16 nRet = report::ReportPrintOption::ALL_PAGES; + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetReportPrintOptions(); + (void)SvXMLUnitConverter::convertEnum( nRet, _sValue, aXML_EnumMap ); + return nRet; + } + + +OXMLSection::OXMLSection( ORptFilter& rImport, + const uno::Reference< xml::sax::XFastAttributeList > & _xAttrList + ,const uno::Reference< report::XSection >& _xSection + ,bool _bPageHeader) +:SvXMLImportContext( rImport ) +,m_xSection(_xSection) +{ + + if (!m_xSection.is()) + return; + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_PAGE_PRINT_OPTION): + if ( _bPageHeader ) + m_xSection->getReportDefinition()->setPageHeaderOption(lcl_getReportPrintOption(aIter.toView())); + else + m_xSection->getReportDefinition()->setPageFooterOption(lcl_getReportPrintOption(aIter.toView())); + break; + case XML_ELEMENT(REPORT, XML_REPEAT_SECTION): + m_xSection->setRepeatSection(IsXMLToken(aIter, XML_TRUE)); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the section props"); + } +} + +OXMLSection::~OXMLSection() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLSection::createFastChildContext( + sal_Int32 nElement, + const Reference< XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(TABLE, XML_TABLE): + xContext = new OXMLTable( rImport, xAttrList, m_xSection); + break; + default: + break; + } + + return xContext; +} + +ORptFilter& OXMLSection::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlSection.hxx b/reportdesign/source/filter/xml/xmlSection.hxx new file mode 100644 index 000000000..c1e25cd83 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlSection.hxx @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSECTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSECTION_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XSection.hpp> + +namespace rptxml +{ + class ORptFilter; + class OXMLSection : public SvXMLImportContext + { + private: + css::uno::Reference< css::report::XSection > m_xSection; + ORptFilter& GetOwnImport(); + + OXMLSection(const OXMLSection&) = delete; + void operator =(const OXMLSection&) = delete; + public: + + OXMLSection( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XSection >& _xSection + ,bool _bPageHeader = true); + virtual ~OXMLSection() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlStyleImport.cxx b/reportdesign/source/filter/xml/xmlStyleImport.cxx new file mode 100644 index 000000000..595bd5506 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlStyleImport.cxx @@ -0,0 +1,393 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlStyleImport.hxx" +#include <xmloff/maptype.hxx> +#include <xmloff/namespacemap.hxx> +#include <xmloff/xmlimppr.hxx> +#include <xmloff/txtimppr.hxx> +#include <xmloff/families.hxx> +#include <xmloff/xmlnumfi.hxx> +#include <xmloff/xmltoken.hxx> +#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <xmloff/xmluconv.hxx> +#include <xmloff/XMLGraphicsDefaultStyle.hxx> +#include "xmlfilter.hxx" +#include "xmlHelper.hxx" +#include <osl/diagnose.h> + +namespace rptxml +{ + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::style; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace xmloff::token; + +namespace { + +class OSpecialHandleXMLImportPropertyMapper : public SvXMLImportPropertyMapper +{ +public: + OSpecialHandleXMLImportPropertyMapper(const rtl::Reference< XMLPropertySetMapper >& rMapper,SvXMLImport& _rImport) : SvXMLImportPropertyMapper(rMapper ,_rImport) + { + } + /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */ + virtual bool handleSpecialItem( + XMLPropertyState& /*rProperty*/, + ::std::vector< XMLPropertyState >& /*rProperties*/, + const OUString& /*rValue*/, + const SvXMLUnitConverter& /*rUnitConverter*/, + const SvXMLNamespaceMap& /*rNamespaceMap*/ ) const override + { + // nothing to do here + return true; + } +}; + +} + +OControlStyleContext::OControlStyleContext( ORptFilter& rImport, + SvXMLStylesContext& rStyles, XmlStyleFamily nFamily ) : + XMLPropStyleContext( rImport, rStyles, nFamily, false/*bDefaultStyle*/ ), + pStyles(&rStyles), + m_nNumberFormat(-1), + m_rImport(rImport) +{ + +} + + +OControlStyleContext::~OControlStyleContext() +{ + +} + + +void OControlStyleContext::FillPropertySet(const Reference< XPropertySet > & rPropSet ) +{ + if ( !IsDefaultStyle() ) + { + if ( GetFamily() == XmlStyleFamily::TABLE_CELL ) + { + if ((m_nNumberFormat == -1) && !m_sDataStyleName.isEmpty()) + { + SvXMLNumFormatContext* pStyle = const_cast< SvXMLNumFormatContext*>(dynamic_cast<const SvXMLNumFormatContext*>(pStyles->FindStyleChildContext( + XmlStyleFamily::DATA_STYLE, m_sDataStyleName))); + if ( !pStyle ) + { + OReportStylesContext* pMyStyles = dynamic_cast< OReportStylesContext *>(m_rImport.GetAutoStyles()); + if ( pMyStyles ) + pStyle = const_cast<SvXMLNumFormatContext*>(dynamic_cast< const SvXMLNumFormatContext *>(pMyStyles-> + FindStyleChildContext(XmlStyleFamily::DATA_STYLE, m_sDataStyleName, true))); + else { + OSL_FAIL("not possible to get style"); + } + } + if ( pStyle ) + { + m_nNumberFormat = pStyle->GetKey(); + AddProperty(CTF_RPT_NUMBERFORMAT, uno::Any(m_nNumberFormat)); + } + } + } + } + XMLPropStyleContext::FillPropertySet(rPropSet); +} + +void OControlStyleContext::SetDefaults() +{ +} + + +void OControlStyleContext::AddProperty(const sal_Int16 nContextID, const uno::Any& rValue) +{ + sal_Int32 nIndex(static_cast<OReportStylesContext *>(pStyles)->GetIndex(nContextID)); + OSL_ENSURE(nIndex != -1, "Property not found in Map"); + XMLPropertyState aPropState(nIndex, rValue); + GetProperties().push_back(aPropState); // has to be inserted in a sort order later +} + +void OControlStyleContext::SetAttribute( sal_Int32 nElement, + const OUString& rValue ) +{ + switch(nElement & TOKEN_MASK) + { + case XML_DATA_STYLE_NAME: + m_sDataStyleName = rValue; + break; + case XML_MASTER_PAGE_NAME: + break; + default: + XMLPropStyleContext::SetAttribute( nElement, rValue ); + } +} + + +OReportStylesContext::OReportStylesContext( ORptFilter& rImport, + const bool bTempAutoStyles ) : + SvXMLStylesContext( rImport ), + m_rImport(rImport), + m_nNumberFormatIndex(-1), + bAutoStyles(bTempAutoStyles) +{ + +} + + +OReportStylesContext::~OReportStylesContext() +{ + +} + + +void OReportStylesContext::endFastElement(sal_Int32 ) +{ + if (bAutoStyles) + GetImport().GetTextImport()->SetAutoStyles( this ); + else + GetImport().GetStyles()->CopyStylesToDoc(true); +} + + +rtl::Reference < SvXMLImportPropertyMapper > + OReportStylesContext::GetImportPropertyMapper( + XmlStyleFamily nFamily ) const +{ + rtl::Reference < SvXMLImportPropertyMapper > xMapper(SvXMLStylesContext::GetImportPropertyMapper(nFamily)); + + if (!xMapper.is()) + { + ORptFilter& rImport = GetOwnImport(); + switch( nFamily ) + { + case XmlStyleFamily::TABLE_CELL: + { + if( !m_xCellImpPropMapper.is() ) + { + m_xCellImpPropMapper = + new XMLTextImportPropertyMapper/*OSpecialHandleXMLImportPropertyMapper*/( rImport.GetCellStylesPropertySetMapper(), m_rImport ); + + m_xCellImpPropMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(m_rImport)); + } + xMapper = m_xCellImpPropMapper; + } + break; + case XmlStyleFamily::TABLE_COLUMN: + { + if( !m_xColumnImpPropMapper.is() ) + m_xColumnImpPropMapper = + new SvXMLImportPropertyMapper( rImport.GetColumnStylesPropertySetMapper(), m_rImport ); + + xMapper = m_xColumnImpPropMapper; + } + break; + case XmlStyleFamily::TABLE_ROW: + { + if( !m_xRowImpPropMapper.is() ) + m_xRowImpPropMapper =new OSpecialHandleXMLImportPropertyMapper( rImport.GetRowStylesPropertySetMapper(), m_rImport ); + xMapper = m_xRowImpPropMapper; + } + break; + case XmlStyleFamily::TABLE_TABLE: + { + if( !m_xTableImpPropMapper.is() ) + { + rtl::Reference < XMLPropertyHandlerFactory> xFac = new ::xmloff::OControlPropertyHandlerFactory(); + m_xTableImpPropMapper = new SvXMLImportPropertyMapper( new XMLPropertySetMapper(OXMLHelper::GetTableStyleProps(), xFac, false), m_rImport ); + } + xMapper = m_xTableImpPropMapper; + } + break; + default: + break; + } + } + + return xMapper; +} + +SvXMLStyleContext *OReportStylesContext::CreateDefaultStyleStyleChildContext( + XmlStyleFamily nFamily, sal_Int32 /*nElement*/, + const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/ ) +{ + switch( nFamily ) + { + case XmlStyleFamily::SD_GRAPHICS_ID: + // There are no writer specific defaults for graphic styles! + return new XMLGraphicsDefaultStyle( GetImport(), *this ); + default: + return nullptr; + } +} + +SvXMLStyleContext *OReportStylesContext::CreateStyleStyleChildContext( + XmlStyleFamily nFamily, sal_Int32 nElement, + const Reference< xml::sax::XFastAttributeList > & xAttrList ) +{ + SvXMLStyleContext *pStyle = SvXMLStylesContext::CreateStyleStyleChildContext( nFamily, nElement, + xAttrList ); + if (!pStyle) + { + switch( nFamily ) + { + case XmlStyleFamily::TABLE_TABLE: + case XmlStyleFamily::TABLE_COLUMN: + case XmlStyleFamily::TABLE_ROW: + case XmlStyleFamily::TABLE_CELL: + pStyle = new OControlStyleContext( GetOwnImport(), *this, nFamily ); + break; + default: + OSL_FAIL("OReportStylesContext::CreateStyleStyleChildContext: Unknown style family. Please check."); + break; + } + } + + return pStyle; +} + +Reference < XNameContainer > + OReportStylesContext::GetStylesContainer( XmlStyleFamily nFamily ) const +{ + Reference < XNameContainer > xStyles(SvXMLStylesContext::GetStylesContainer(nFamily)); + if (!xStyles.is()) + { + OUString sName; + switch( nFamily ) + { + case XmlStyleFamily::TABLE_TABLE: + { + if( m_xTableStyles.is() ) + xStyles.set(m_xTableStyles); + else + sName = "TableStyles"; + } + break; + case XmlStyleFamily::TABLE_CELL: + { + if( m_xCellStyles.is() ) + xStyles.set(m_xCellStyles); + else + sName = "CellStyles"; + } + break; + case XmlStyleFamily::TABLE_COLUMN: + { + if( m_xColumnStyles.is() ) + xStyles.set(m_xColumnStyles); + else + sName = "ColumnStyles"; + } + break; + case XmlStyleFamily::TABLE_ROW: + { + if( m_xRowStyles.is() ) + xStyles.set(m_xRowStyles); + else + sName = "RowStyles"; + } + break; + case XmlStyleFamily::SD_GRAPHICS_ID: + xStyles = const_cast<SvXMLImport *>(&GetImport())->GetTextImport()->GetFrameStyles(); + break; + default: + OSL_FAIL("OReportStylesContext::CreateStyleStyleChildContext: Unknown style family. Please check."); + break; + } + if( !xStyles.is() && !sName.isEmpty() && GetOwnImport().GetModel().is() ) + { + Reference< XStyleFamiliesSupplier > xFamiliesSupp( + GetOwnImport().GetModel(), UNO_QUERY ); + if (xFamiliesSupp.is()) + { + Reference< XNameAccess > xFamilies(xFamiliesSupp->getStyleFamilies()); + + xStyles.set(xFamilies->getByName( sName ), uno::UNO_QUERY); + switch( nFamily ) + { + case XmlStyleFamily::TABLE_TABLE: + m_xTableStyles.set(xStyles); + break; + case XmlStyleFamily::TABLE_CELL: + m_xCellStyles.set(xStyles); + break; + case XmlStyleFamily::TABLE_COLUMN: + m_xColumnStyles.set(xStyles); + break; + case XmlStyleFamily::TABLE_ROW: + m_xRowStyles.set(xStyles); + break; + default: + break; + } + } + } + } + + return xStyles; +} + + +OUString OReportStylesContext::GetServiceName( XmlStyleFamily nFamily ) const +{ + OUString sServiceName = SvXMLStylesContext::GetServiceName(nFamily); + if (sServiceName.isEmpty()) + { + switch( nFamily ) + { + case XmlStyleFamily::TABLE_TABLE: + sServiceName = XML_STYLE_FAMILY_TABLE_TABLE_STYLES_NAME; + break; + case XmlStyleFamily::TABLE_COLUMN: + sServiceName = XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME; + break; + case XmlStyleFamily::TABLE_ROW: + sServiceName = XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME; + break; + case XmlStyleFamily::TABLE_CELL: + sServiceName = XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME; + break; + default: + break; + } + } + return sServiceName; +} + + +sal_Int32 OReportStylesContext::GetIndex(const sal_Int16 nContextID) +{ + if ( nContextID == CTF_RPT_NUMBERFORMAT ) + { + if (m_nNumberFormatIndex == -1) + m_nNumberFormatIndex = + GetImportPropertyMapper(XmlStyleFamily::TABLE_CELL)->getPropertySetMapper()->FindEntryIndex(nContextID); + return m_nNumberFormatIndex; + } + return -1; +} + + +} // rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlStyleImport.hxx b/reportdesign/source/filter/xml/xmlStyleImport.hxx new file mode 100644 index 000000000..b51108fd5 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlStyleImport.hxx @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSTYLEIMPORT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSTYLEIMPORT_HXX + +#include <rtl/ustring.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/xmlimppr.hxx> + +namespace rptxml +{ + class ORptFilter; + + class OControlStyleContext : public XMLPropStyleContext + { + OUString m_sDataStyleName; + SvXMLStylesContext* pStyles; + // std::vector<ScXMLMapContent> aMaps; + sal_Int32 m_nNumberFormat; + ORptFilter& m_rImport; + + OControlStyleContext(const OControlStyleContext&) = delete; + void operator =(const OControlStyleContext&) = delete; + protected: + + virtual void SetAttribute( sal_Int32 nElement, + const OUString& rValue ) override; + + public: + + OControlStyleContext( ORptFilter& rImport, + SvXMLStylesContext& rStyles, XmlStyleFamily nFamily ); + + virtual ~OControlStyleContext() override; + + + virtual void FillPropertySet(const css::uno::Reference< + css::beans::XPropertySet > & rPropSet ) override; + + virtual void SetDefaults() override; + + void AddProperty(sal_Int16 nContextID, const css::uno::Any& aValue); + }; + + class OReportStylesContext : public SvXMLStylesContext + { + ORptFilter& m_rImport; + sal_Int32 m_nNumberFormatIndex; + bool bAutoStyles : 1; + + //mutable rtl::Reference < SvXMLImportPropertyMapper > m_xControlImpPropMapper; + mutable rtl::Reference < SvXMLImportPropertyMapper > m_xCellImpPropMapper; + mutable rtl::Reference < SvXMLImportPropertyMapper > m_xColumnImpPropMapper; + mutable rtl::Reference < SvXMLImportPropertyMapper > m_xRowImpPropMapper; + mutable rtl::Reference < SvXMLImportPropertyMapper > m_xTableImpPropMapper; + + mutable css::uno::Reference< css::container::XNameContainer > m_xCellStyles; + mutable css::uno::Reference< css::container::XNameContainer > m_xColumnStyles; + mutable css::uno::Reference< css::container::XNameContainer > m_xRowStyles; + mutable css::uno::Reference< css::container::XNameContainer > m_xTableStyles; + + ORptFilter& GetOwnImport() const { return m_rImport;} + + OReportStylesContext(const OReportStylesContext&) = delete; + void operator =(const OReportStylesContext&) = delete; + protected: + + // Create a style context. + using SvXMLStylesContext::CreateStyleStyleChildContext; + virtual SvXMLStyleContext *CreateStyleStyleChildContext( + XmlStyleFamily nFamily, + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override; + + using SvXMLStylesContext::CreateDefaultStyleStyleChildContext; + virtual SvXMLStyleContext *CreateDefaultStyleStyleChildContext( + XmlStyleFamily nFamily, sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override; + + public: + + + OReportStylesContext( ORptFilter& rImport, + const bool bAutoStyles ); + virtual ~OReportStylesContext() override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + virtual rtl::Reference < SvXMLImportPropertyMapper > GetImportPropertyMapper( + XmlStyleFamily nFamily ) const override; + virtual css::uno::Reference< css::container::XNameContainer > + GetStylesContainer( XmlStyleFamily nFamily ) const override; + virtual OUString GetServiceName( XmlStyleFamily nFamily ) const override; + + sal_Int32 GetIndex(const sal_Int16 nContextID); + }; + +} // rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSTYLEIMPORT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlSubDocument.cxx b/reportdesign/source/filter/xml/xmlSubDocument.cxx new file mode 100644 index 000000000..4a5f9fd5c --- /dev/null +++ b/reportdesign/source/filter/xml/xmlSubDocument.cxx @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlSubDocument.hxx" +#include "xmlCell.hxx" +#include "xmlfilter.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include "xmlEnums.hxx" +#include "xmlMasterFields.hxx" +#include "xmlTable.hxx" +#include <comphelper/property.hxx> +#include <com/sun/star/report/XReportControlModel.hpp> +#include <sal/log.hxx> +#include <osl/diagnose.h> + +namespace rptxml +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::report; + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::xml::sax; + +OXMLSubDocument::OXMLSubDocument( ORptFilter& rImport + ,const Reference< XReportComponent > & _xComponent + ,OXMLTable* _pContainer + ,OXMLCell* _pCellParent) : + OXMLReportElementBase( rImport,_xComponent,_pContainer) +,m_xFake(_xComponent) +,m_pCellParent(_pCellParent) +,m_nCurrentCount(0) +,m_bContainsShape(false) +{ + +} + +OXMLSubDocument::~OXMLSubDocument() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLSubDocument::createFastChildContext( + sal_Int32 nElement, + const Reference< XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext = OXMLReportElementBase::createFastChildContext(nElement,xAttrList); + if (xContext) + return xContext; + + switch( nElement ) + { + case XML_ELEMENT(REPORT, XML_MASTER_DETAIL_FIELDS): + { + GetImport().GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLMasterFields(static_cast<ORptFilter&>(GetImport()),xAttrList ,this); + } + break; + // FIXME: is it *intentional* that this is supported? + // ORptExport::exportContainer() can export this but the import + // used to be rather accidental previously + case XML_ELEMENT(OFFICE, XML_BODY): + xContext = new RptXMLDocumentBodyContext(GetImport()); + break; + + case XML_ELEMENT(DRAW, XML_FRAME): + { + if ( !m_bContainsShape ) + m_nCurrentCount = m_pContainer->getSection()->getCount(); + uno::Reference< drawing::XShapes > xShapes = m_pContainer->getSection(); + xContext = XMLShapeImportHelper::CreateGroupChildContext(GetImport(),nElement,xAttrList,xShapes); + m_bContainsShape = true; + if (m_pCellParent) + { + // #i94115 say to the parent Cell it contains shapes + m_pCellParent->setContainsShape(true); + } + } + break; + default: + SAL_WARN("reportdesign", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement)); + break; + } + + return xContext; +} + +void OXMLSubDocument::endFastElement(sal_Int32 ) +{ + if ( !m_bContainsShape ) + return; + + m_xReportComponent.set(m_pContainer->getSection()->getByIndex(m_nCurrentCount),uno::UNO_QUERY); + if ( !m_xReportComponent.is() ) + return; + + if ( !m_aMasterFields.empty() ) + m_xReportComponent->setMasterFields(Sequence< OUString>(&*m_aMasterFields.begin(),m_aMasterFields.size())); + if ( !m_aDetailFields.empty() ) + m_xReportComponent->setDetailFields(Sequence< OUString>(&*m_aDetailFields.begin(),m_aDetailFields.size())); + + m_xReportComponent->setName(m_xFake->getName()); + m_xReportComponent->setPrintRepeatedValues(m_xFake->getPrintRepeatedValues()); + uno::Reference< report::XReportControlModel > xFakeModel(m_xFake,uno::UNO_QUERY); + uno::Reference< report::XReportControlModel > xComponentModel(m_xReportComponent,uno::UNO_QUERY); + if ( !(xComponentModel.is() && xFakeModel.is()) ) + return; + + xComponentModel->setPrintWhenGroupChange(xFakeModel->getPrintWhenGroupChange()); + const sal_Int32 nCount = xFakeModel->getCount(); + try + { + for (sal_Int32 i = 0; i < nCount ; ++i) + { + uno::Reference< report::XFormatCondition > xCond(xFakeModel->getByIndex(i),uno::UNO_QUERY); + uno::Reference< report::XFormatCondition > xNewCond = xComponentModel->createFormatCondition(); + ::comphelper::copyProperties(xCond, xNewCond); + xComponentModel->insertByIndex(xComponentModel->getCount(),uno::Any(xNewCond)); + } + } + catch(uno::Exception&) + { + OSL_FAIL("Can not access format condition!"); + } +} + +void OXMLSubDocument::addMasterDetailPair(const ::std::pair< OUString,OUString >& _aPair) +{ + m_aMasterFields.push_back(_aPair.first); + m_aDetailFields.push_back(_aPair.second); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlSubDocument.hxx b/reportdesign/source/filter/xml/xmlSubDocument.hxx new file mode 100644 index 000000000..f4cbf9848 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlSubDocument.hxx @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSUBDOCUMENT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLSUBDOCUMENT_HXX + +#include "xmlReportElementBase.hxx" +#include <com/sun/star/report/XReportComponent.hpp> +#include <vector> + +namespace rptxml +{ + class ORptFilter; + class OXMLCell; + class OXMLSubDocument : public OXMLReportElementBase, public IMasterDetailFieds + { + css::uno::Reference< css::report::XReportComponent> m_xFake; + ::std::vector< OUString> m_aMasterFields; + ::std::vector< OUString> m_aDetailFields; + OXMLCell* m_pCellParent; + sal_Int32 m_nCurrentCount; + bool m_bContainsShape; + + OXMLSubDocument(const OXMLSubDocument&) = delete; + void operator =(const OXMLSubDocument&) = delete; + + public: + + OXMLSubDocument( ORptFilter& rImport + ,const css::uno::Reference< css::report::XReportComponent >& _xComponent + ,OXMLTable* _pContainer + ,OXMLCell* _pCellParent); + virtual ~OXMLSubDocument() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + virtual void addMasterDetailPair(const ::std::pair< OUString,OUString >& _aPair) override; + }; + +} // namespace rptxml + + +#endif // RPT_XMLSubDocument_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlTable.cxx b/reportdesign/source/filter/xml/xmlTable.cxx new file mode 100644 index 000000000..34075b46d --- /dev/null +++ b/reportdesign/source/filter/xml/xmlTable.cxx @@ -0,0 +1,289 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "xmlTable.hxx" +#include "xmlfilter.hxx" +#include <o3tl/safeint.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmlstyle.hxx> +#include <xmloff/prstylei.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include <RptDef.hxx> +#include "xmlHelper.hxx" +#include "xmlEnums.hxx" +#include "xmlColumn.hxx" +#include <com/sun/star/report/ForceNewPage.hpp> +#include "xmlCondPrtExpr.hxx" +#include <strings.hxx> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> + +#include <numeric> + +#define MIN_WIDTH 80 +#define MIN_HEIGHT 20 + +namespace rptxml +{ + using namespace ::xmloff; + using namespace ::com::sun::star; + using ::com::sun::star::uno::Reference; + using namespace ::com::sun::star::xml::sax; + + static sal_Int16 lcl_getForceNewPageOption(std::string_view _sValue) + { + sal_Int16 nRet = report::ForceNewPage::NONE; + const SvXMLEnumMapEntry<sal_Int16>* aXML_EnumMap = OXMLHelper::GetForceNewPageOptions(); + (void)SvXMLUnitConverter::convertEnum( nRet,_sValue,aXML_EnumMap ); + return nRet; + } + +OXMLTable::OXMLTable( ORptFilter& rImport + ,const Reference< XFastAttributeList > & _xAttrList + ,const uno::Reference< report::XSection >& _xSection + ) +:SvXMLImportContext( rImport ) +,m_xSection(_xSection) +,m_nColSpan(1) +,m_nRowSpan(0) +,m_nRowIndex(0) +,m_nColumnIndex(0) +{ + + if (!m_xSection.is()) + return; + try + { + for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList )) + { + switch( aIter.getToken() ) + { + case XML_ELEMENT(REPORT, XML_VISIBLE): + m_xSection->setVisible(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(REPORT, XML_FORCE_NEW_PAGE): + m_xSection->setForceNewPage(lcl_getForceNewPageOption(aIter.toView())); + break; + case XML_ELEMENT(REPORT, XML_FORCE_NEW_COLUMN): + m_xSection->setNewRowOrCol(lcl_getForceNewPageOption(aIter.toView())); + break; + case XML_ELEMENT(REPORT, XML_KEEP_TOGETHER): + m_xSection->setKeepTogether(IsXMLToken(aIter, XML_TRUE)); + break; + case XML_ELEMENT(TABLE, XML_NAME): + m_xSection->setName(aIter.toString()); + break; + case XML_ELEMENT(TABLE, XML_STYLE_NAME): + m_sStyleName = aIter.toString(); + break; + default: + XMLOFF_WARN_UNKNOWN("reportdesign", aIter); + break; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the section props"); + } +} + +OXMLTable::~OXMLTable() +{ +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLTable::createFastChildContext( + sal_Int32 nElement, + const Reference< XFastAttributeList > & xAttrList ) +{ + css::uno::Reference< css::xml::sax::XFastContextHandler > xContext; + ORptFilter& rImport = GetOwnImport(); + + switch( nElement ) + { + case XML_ELEMENT(TABLE, XML_TABLE_COLUMNS): + case XML_ELEMENT(TABLE, XML_TABLE_ROWS): + xContext = new OXMLRowColumn( rImport,xAttrList ,this); + break; + case XML_ELEMENT(TABLE, XML_TABLE_ROW): + incrementRowIndex(); + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLRowColumn( rImport,xAttrList,this); + break; + case XML_ELEMENT(TABLE, XML_TABLE_COLUMN): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + xContext = new OXMLRowColumn( rImport,xAttrList,this); + break; + case XML_ELEMENT(REPORT, XML_CONDITIONAL_PRINT_EXPRESSION): + xContext = new OXMLCondPrtExpr( rImport,xAttrList,m_xSection); + break; + default: + break; + } + + return xContext; +} + +ORptFilter& OXMLTable::GetOwnImport() +{ + return static_cast<ORptFilter&>(GetImport()); +} + +void OXMLTable::endFastElement(sal_Int32 ) +{ + try + { + if ( m_xSection.is() ) + { + if ( !m_sStyleName.isEmpty() ) + { + const SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles(); + if ( pAutoStyles ) + { + XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext *>(pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_TABLE,m_sStyleName))); + if ( pAutoStyle ) + { + pAutoStyle->FillPropertySet(m_xSection); + } + } + } + // set height + sal_Int32 nHeight = std::accumulate(m_aHeight.begin(), m_aHeight.end(), sal_Int32(0), + [](const sal_Int32& rSum, const sal_Int32& rHeight) { return rSum + rHeight; }); + m_xSection->setHeight( nHeight ); + // set positions, widths, and heights + sal_Int32 nLeftMargin = rptui::getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_LEFTMARGIN); + sal_Int32 nPosY = 0; + ::std::vector< ::std::vector<TCell> >::iterator aRowIter = m_aGrid.begin(); + ::std::vector< ::std::vector<TCell> >::const_iterator aRowEnd = m_aGrid.end(); + for (sal_Int32 i = 0; aRowIter != aRowEnd; ++aRowIter,++i) + { + sal_Int32 nPosX = nLeftMargin; + ::std::vector<TCell>::iterator aColIter = (*aRowIter).begin(); + ::std::vector<TCell>::const_iterator aColEnd = (*aRowIter).end(); + for (sal_Int32 j = 0; aColIter != aColEnd; ++aColIter,++j) + { + TCell& rCell = *aColIter; + for (const auto& rxElement : rCell.xElements) + { + uno::Reference<report::XShape> xShape(rxElement,uno::UNO_QUERY); + if ( xShape.is() ) + { + xShape->setPositionX(xShape->getPositionX() + nLeftMargin); + } + else + { + sal_Int32 nWidth = rCell.nWidth; + sal_Int32 nColSpan = rCell.nColSpan; + if ( nColSpan > 1 ) + { + ::std::vector<TCell>::const_iterator aWidthIter = aColIter + 1; + while ( nColSpan > 1 ) + { + nWidth += (aWidthIter++)->nWidth; + --nColSpan; + } + } + nHeight = rCell.nHeight; + sal_Int32 nRowSpan = rCell.nRowSpan; + if ( nRowSpan > 1 ) + { + ::std::vector< ::std::vector<TCell> >::const_iterator aHeightIter = aRowIter + 1; + while( nRowSpan > 1) + { + nHeight += (*aHeightIter)[j].nHeight; + ++aHeightIter; + --nRowSpan; + } + } + Reference<XFixedLine> xFixedLine(rxElement,uno::UNO_QUERY); + if ( xFixedLine.is() ) + { + if ( xFixedLine->getOrientation() == 1 ) // vertical + { + OSL_ENSURE(o3tl::make_unsigned(j+1) < m_aWidth.size(),"Illegal pos of col iter. There should be an empty cell for the next line part."); + nWidth += m_aWidth[j+1]; + if ( nWidth < MIN_WIDTH ) + nWidth = MIN_WIDTH; + } + else if ( nHeight < MIN_HEIGHT ) + nHeight = MIN_HEIGHT; + } + try + { + rxElement->setSize(awt::Size(nWidth,nHeight)); + rxElement->setPosition(awt::Point(nPosX,nPosY)); + rxElement->setAutoGrow(rCell.bAutoHeight); + } + catch(const beans::PropertyVetoException &) + { + OSL_FAIL("Could not set the correct position or size!"); + } + } + } + nPosX += m_aWidth[j]; + } + nPosY += m_aHeight[i]; + } + } + } + catch(Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OXMLTable::EndElement"); + } +} + +void OXMLTable::addCell(const Reference<XReportComponent>& _xElement) +{ + uno::Reference<report::XShape> xShape(_xElement,uno::UNO_QUERY); + OSL_ENSURE(o3tl::make_unsigned(m_nRowIndex-1 ) < m_aGrid.size() && o3tl::make_unsigned( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size(), + "OXMLTable::addCell: Invalid column and row index"); + if ( o3tl::make_unsigned(m_nRowIndex-1 ) < m_aGrid.size() && o3tl::make_unsigned( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size() ) + { + TCell& rCell = m_aGrid[m_nRowIndex-1][m_nColumnIndex-1]; + if ( _xElement.is() ) + rCell.xElements.push_back( _xElement ); + if ( !xShape.is() ) + { + rCell.nWidth = m_aWidth[m_nColumnIndex-1]; + rCell.nHeight = m_aHeight[m_nRowIndex-1]; + rCell.bAutoHeight = m_aAutoHeight[m_nRowIndex-1]; + rCell.nColSpan = m_nColSpan; + rCell.nRowSpan = m_nRowSpan; + } + } + + if ( !xShape.is() ) + m_nColSpan = m_nRowSpan = 1; +} + +void OXMLTable::incrementRowIndex() +{ + ++m_nRowIndex; + m_nColumnIndex = 0; + m_aGrid.push_back(::std::vector<TCell>(m_aWidth.size())); +} + +} // namespace rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlTable.hxx b/reportdesign/source/filter/xml/xmlTable.hxx new file mode 100644 index 000000000..508ad5087 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlTable.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLTABLE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLTABLE_HXX + +#include <xmloff/xmlictxt.hxx> +#include <com/sun/star/report/XSection.hpp> +#include <vector> + +namespace rptxml +{ + class ORptFilter; + class OXMLTable : public SvXMLImportContext + { + public: + struct TCell + { + sal_Int32 nWidth; + sal_Int32 nHeight; + sal_Int32 nColSpan; + sal_Int32 nRowSpan; + bool bAutoHeight; + ::std::vector< css::uno::Reference< css::report::XReportComponent> > xElements; + TCell() : nWidth(0),nHeight(0),nColSpan(1),nRowSpan(1),bAutoHeight(false){} + }; + private: + ::std::vector< ::std::vector<TCell> > m_aGrid; + ::std::vector<sal_Int32> m_aHeight; + ::std::vector<bool> m_aAutoHeight; + ::std::vector<sal_Int32> m_aWidth; + css::uno::Reference< css::report::XSection > m_xSection; + OUString m_sStyleName; + sal_Int32 m_nColSpan; + sal_Int32 m_nRowSpan; + sal_Int32 m_nRowIndex; + sal_Int32 m_nColumnIndex; + ORptFilter& GetOwnImport(); + + OXMLTable(const OXMLTable&) = delete; + void operator =(const OXMLTable&) = delete; + public: + + OXMLTable( ORptFilter& rImport + ,const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList + ,const css::uno::Reference< css::report::XSection >& _xSection + ); + virtual ~OXMLTable() override; + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; + + void addHeight(sal_Int32 _nHeight) { m_aHeight.push_back(_nHeight); } + void addAutoHeight(bool _bAutoHeight) { m_aAutoHeight.push_back(_bAutoHeight); } + void addWidth(sal_Int32 _nWidth) { m_aWidth.push_back( _nWidth ); } + + void setColumnSpanned(sal_Int32 _nColSpan) { m_nColSpan = _nColSpan; } + void setRowSpanned( sal_Int32 _nRowSpan) { m_nRowSpan = _nRowSpan; } + + void incrementRowIndex(); + void incrementColumnIndex() { ++m_nColumnIndex; } + + void addCell(const css::uno::Reference< css::report::XReportComponent>& _xElement); + + const css::uno::Reference< css::report::XSection >& getSection() const { return m_xSection; } + }; + +} // namespace rptxml + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLTABLE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlfilter.cxx b/reportdesign/source/filter/xml/xmlfilter.cxx new file mode 100644 index 000000000..166c8c435 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlfilter.cxx @@ -0,0 +1,764 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> +#include <sal/log.hxx> + +#include <com/sun/star/packages/WrongPasswordException.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> +#include <com/sun/star/embed/ElementModes.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <com/sun/star/document/XGraphicStorageHandler.hpp> +#include <com/sun/star/document/XEmbeddedObjectResolver.hpp> +#include "xmlfilter.hxx" +#include "xmlReport.hxx" +#include <vcl/errinf.hxx> +#include "xmlHelper.hxx" +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <connectivity/dbtools.hxx> +#include <xmloff/xmlnamespace.hxx> +#include <xmloff/xmltoken.hxx> +#include <xmloff/txtimp.hxx> +#include <xmloff/namespacemap.hxx> +#include <xmloff/XMLFontStylesContext.hxx> +#include <com/sun/star/xml/sax/InputSource.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <comphelper/genericpropertyset.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <unotools/mediadescriptor.hxx> +#include <xmloff/ProgressBarHelper.hxx> +#include <xmloff/XMLTextMasterStylesContext.hxx> +#include <sfx2/docfile.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <xmloff/DocumentSettingsContext.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlmetai.hxx> +#include <tools/diagnose_ex.h> +#include <svtools/sfxecode.hxx> +#include "xmlEnums.hxx" +#include "xmlStyleImport.hxx" +#include <strings.hxx> +#include "xmlPropertyHandler.hxx" +#include <ReportDefinition.hxx> + +namespace rptxml +{ +using namespace ::com::sun::star::uno; +using ::com::sun::star::uno::Reference; +using namespace ::com::sun::star; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::report; +using namespace ::com::sun::star::xml::sax; +using namespace xmloff; +using namespace ::com::sun::star::util; + +namespace { + +class RptMLMasterStylesContext_Impl: + public XMLTextMasterStylesContext +{ + ORptFilter& GetImport() { return static_cast<ORptFilter&>(XMLTextMasterStylesContext::GetImport()); } + +public: + + + RptMLMasterStylesContext_Impl( ORptFilter& rImport ); + + RptMLMasterStylesContext_Impl(const RptMLMasterStylesContext_Impl&) = delete; + RptMLMasterStylesContext_Impl& operator=(const RptMLMasterStylesContext_Impl&) = delete; + virtual void SAL_CALL endFastElement(sal_Int32 nElement) override; +}; + +} + +RptMLMasterStylesContext_Impl::RptMLMasterStylesContext_Impl( ORptFilter& rImport ) : + XMLTextMasterStylesContext( rImport ) +{ +} + +void RptMLMasterStylesContext_Impl::endFastElement(sal_Int32 ) +{ + FinishStyles( true ); + GetImport().FinishStyles(); +} + + /// read a component (file + filter version) +static ErrCode ReadThroughComponent( + const uno::Reference<XInputStream>& xInputStream, + const uno::Reference<XComponent>& xModelComponent, + const uno::Reference<XComponentContext> & rContext, + const uno::Reference<XFastParser>& rFastParser ) +{ + OSL_ENSURE(xInputStream.is(), "input stream missing"); + OSL_ENSURE(xModelComponent.is(), "document missing"); + OSL_ENSURE(rContext.is(), "factory missing"); + + // prepare Parser InputSource + InputSource aParserInput; + aParserInput.aInputStream = xInputStream; + + // get filter + SAL_WARN_IF( !rFastParser.is(), "reportdesign", "Can't instantiate filter component." ); + if( !rFastParser.is() ) + return ErrCode(1); + + // connect model and filter + uno::Reference < XImporter > xImporter( rFastParser, UNO_QUERY ); + xImporter->setTargetDocument( xModelComponent ); + + // finally, parser the stream + try + { + rFastParser->parseStream( aParserInput ); + } + catch (const SAXParseException&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + return ErrCode(1); + } + catch (const SAXException&) + { + return ErrCode(1); + } + catch (const packages::zip::ZipIOException&) + { + return ERRCODE_IO_BROKENPACKAGE; + } + catch (const IOException&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + return ErrCode(1); + } + catch (const Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + return ErrCode(1); + } + + // success! + return ERRCODE_NONE; +} + +/// read a component (storage version) +static ErrCode ReadThroughComponent( + const uno::Reference< embed::XStorage >& xStorage, + const uno::Reference<XComponent>& xModelComponent, + const char* pStreamName, + const uno::Reference<XComponentContext> & rxContext, + const Reference<document::XGraphicStorageHandler> & rxGraphicStorageHandler, + const Reference<document::XEmbeddedObjectResolver>& _xEmbeddedObjectResolver, + const OUString& _sFilterName + ,const uno::Reference<beans::XPropertySet>& _xProp) +{ + OSL_ENSURE( xStorage.is(), "Need storage!"); + OSL_ENSURE(nullptr != pStreamName, "Please, please, give me a name!"); + + if ( !xStorage ) + // TODO/LATER: better error handling + return ErrCode(1); + + uno::Reference< io::XStream > xDocStream; + + try + { + // open stream (and set parser input) + OUString sStreamName = OUString::createFromAscii(pStreamName); + if ( !xStorage->hasByName( sStreamName ) || !xStorage->isStreamElement( sStreamName ) ) + { + // stream name not found! return immediately with OK signal + return ERRCODE_NONE; + } + + // get input stream + xDocStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ ); + } + catch (const packages::WrongPasswordException&) + { + return ERRCODE_SFX_WRONGPASSWORD; + } + catch (const uno::Exception&) + { + return ErrCode(1); // TODO/LATER: error handling + } + + sal_Int32 nArgs = 0; + if (rxGraphicStorageHandler.is()) + nArgs++; + if( _xEmbeddedObjectResolver.is()) + nArgs++; + if ( _xProp.is() ) + nArgs++; + + uno::Sequence< uno::Any > aFilterCompArgs( nArgs ); + auto aFilterCompArgsRange = asNonConstRange(aFilterCompArgs); + + nArgs = 0; + if (rxGraphicStorageHandler.is()) + aFilterCompArgsRange[nArgs++] <<= rxGraphicStorageHandler; + if( _xEmbeddedObjectResolver.is()) + aFilterCompArgsRange[ nArgs++ ] <<= _xEmbeddedObjectResolver; + if ( _xProp.is() ) + aFilterCompArgsRange[ nArgs++ ] <<= _xProp; + + // the underlying SvXMLImport implements XFastParser, XImporter, XFastDocumentHandler + Reference< XFastParser > xFastParser( + rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(_sFilterName, aFilterCompArgs, rxContext), + uno::UNO_QUERY_THROW ); + uno::Reference< XInputStream > xInputStream = xDocStream->getInputStream(); + // read from the stream + return ReadThroughComponent( xInputStream + ,xModelComponent + ,rxContext + ,xFastParser ); +} + + +/** Imports only settings + * \ingroup reportdesign_source_filter_xml + * + */ +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ORptImportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptFilter(context, + SERVICE_SETTINGSIMPORTER, + SvXMLImportFlags::SETTINGS )); +} + +/** Imports only content + * \ingroup reportdesign_source_filter_xml + * + */ +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_XMLOasisContentImporter_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptFilter(context, + SERVICE_CONTENTIMPORTER, + SvXMLImportFlags::AUTOSTYLES | SvXMLImportFlags::CONTENT | SvXMLImportFlags::SCRIPTS | SvXMLImportFlags::FONTDECLS )); +} + +/** Imports only styles + * \ingroup reportdesign_source_filter_xml + * + */ +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ORptStylesImportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptFilter(context, + SERVICE_STYLESIMPORTER, + SvXMLImportFlags::STYLES | SvXMLImportFlags::MASTERSTYLES | SvXMLImportFlags::AUTOSTYLES | + SvXMLImportFlags::FONTDECLS )); +} + +/** Imports only meta data + * \ingroup reportdesign_source_filter_xml + * + */ +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ORptMetaImportHelper_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptFilter(context, + SERVICE_METAIMPORTER, + SvXMLImportFlags::META )); +} + + +ORptFilter::ORptFilter( const uno::Reference< XComponentContext >& _rxContext, OUString const & rImplementationName, SvXMLImportFlags nImportFlags ) + :SvXMLImport(_rxContext, rImplementationName, nImportFlags) +{ + GetMM100UnitConverter().SetCoreMeasureUnit(util::MeasureUnit::MM_100TH); + GetMM100UnitConverter().SetXMLMeasureUnit(util::MeasureUnit::CM); + GetNamespaceMap().Add( "_report", + GetXMLToken(XML_N_RPT), + XML_NAMESPACE_REPORT ); + + GetNamespaceMap().Add( "__report", + GetXMLToken(XML_N_RPT_OASIS), + XML_NAMESPACE_REPORT ); + + m_xPropHdlFactory = new OXMLRptPropHdlFactory; + m_xCellStylesPropertySetMapper = OXMLHelper::GetCellStylePropertyMap(true, false); + m_xColumnStylesPropertySetMapper = new XMLPropertySetMapper(OXMLHelper::GetColumnStyleProps(), m_xPropHdlFactory, false); + m_xRowStylesPropertySetMapper = new XMLPropertySetMapper(OXMLHelper::GetRowStyleProps(), m_xPropHdlFactory, false); +} + + +ORptFilter::~ORptFilter() noexcept +{ +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_OReportFilter_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new ORptFilter(context, + "com.sun.star.comp.report.OReportFilter", + SvXMLImportFlags::ALL )); +} + +sal_Bool SAL_CALL ORptFilter::filter( const Sequence< PropertyValue >& rDescriptor ) +{ + vcl::Window* pFocusWindow = Application::GetFocusWindow(); + bool bRet = false; + + if( pFocusWindow ) + pFocusWindow->EnterWait(); + + if ( GetModel().is() ) + bRet = implImport( rDescriptor ); + + if ( pFocusWindow ) + pFocusWindow->LeaveWait(); + + return bRet; +} + +bool ORptFilter::implImport( const Sequence< PropertyValue >& rDescriptor ) +{ + OUString sFileName; + uno::Reference< embed::XStorage > xStorage; + uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier; + + for(const PropertyValue& rProp : rDescriptor) + { + if ( rProp.Name == "FileName" ) + rProp.Value >>= sFileName; + else if ( rProp.Name == "Storage" ) + rProp.Value >>= xStorage; + else if ( rProp.Name == "ComponentData" ) + { + Sequence< PropertyValue > aComponent; + rProp.Value >>= aComponent; + const PropertyValue* pComponentIter = aComponent.getConstArray(); + const PropertyValue* pComponentEnd = pComponentIter + aComponent.getLength(); + pComponentIter = std::find_if(pComponentIter, pComponentEnd, + [](const PropertyValue& rComponent) { return rComponent.Name == "ActiveConnection"; }); + if (pComponentIter != pComponentEnd) + { + uno::Reference<sdbc::XConnection> xCon(pComponentIter->Value, uno::UNO_QUERY); + xNumberFormatsSupplier = ::dbtools::getNumberFormats(xCon); + } + } + } + + if ( !sFileName.isEmpty() ) + { + tools::SvRef<SfxMedium> pMedium = new SfxMedium( + sFileName, ( StreamMode::READ | StreamMode::NOCREATE ) ); + + if( pMedium.is() ) + { + try + { + xStorage = pMedium->GetStorage(); + } + catch (const Exception&) + { + } + } + } + bool bRet = xStorage.is(); + if ( bRet ) + { + m_xReportDefinition.set(GetModel(),UNO_QUERY_THROW); + +#if OSL_DEBUG_LEVEL > 1 + uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY ); + uno::Sequence< OUString> aSeq = xAccess->getElementNames(); + const OUString* pDebugIter = aSeq.getConstArray(); + const OUString* pDebugEnd = pDebugIter + aSeq.getLength(); + for(;pDebugIter != pDebugEnd;++pDebugIter) + { + (void)*pDebugIter; + } +#endif + + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler; + uno::Reference<document::XEmbeddedObjectResolver> xEmbeddedObjectResolver; + uno::Reference< uno::XComponentContext > xContext = GetComponentContext(); + + uno::Sequence<uno::Any> aArgs{ uno::Any(xStorage) }; + xGraphicStorageHandler.set( + xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.Svx.GraphicImportHelper", aArgs, xContext), + uno::UNO_QUERY); + + uno::Reference< lang::XMultiServiceFactory > xReportServiceFactory( m_xReportDefinition, uno::UNO_QUERY); + aArgs.getArray()[0] <<= beans::NamedValue("Storage", uno::Any(xStorage)); + xEmbeddedObjectResolver.set( xReportServiceFactory->createInstanceWithArguments("com.sun.star.document.ImportEmbeddedObjectResolver",aArgs) , uno::UNO_QUERY); + + static constexpr OUStringLiteral s_sOld = u"OldFormat"; + static comphelper::PropertyMapEntry const pMap[] = + { + { OUString("OldFormat") , 1, cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::BOUND, 0 }, + { OUString("StreamName"), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("PrivateData"),0, cppu::UnoType<XInterface>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("BaseURI"), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + { OUString("StreamRelPath"), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0 }, + }; + utl::MediaDescriptor aDescriptor(rDescriptor); + uno::Reference<beans::XPropertySet> xProp = comphelper::GenericPropertySet_CreateInstance(new comphelper::PropertySetInfo(pMap)); + const OUString sVal( aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTBASEURL, OUString()) ); + assert(!sVal.isEmpty()); // needed for relative URLs + xProp->setPropertyValue("BaseURI", uno::Any(sVal)); + const OUString sHierarchicalDocumentName( aDescriptor.getUnpackedValueOrDefault("HierarchicalDocumentName",OUString()) ); + xProp->setPropertyValue("StreamRelPath", uno::Any(sHierarchicalDocumentName)); + + uno::Reference<XComponent> xModel = GetModel(); + static constexpr OUStringLiteral s_sMeta = u"meta.xml"; + static constexpr OUStringLiteral s_sStreamName = u"StreamName"; + xProp->setPropertyValue(s_sStreamName, uno::Any(OUString(s_sMeta))); + ErrCode nRet = ReadThroughComponent( xStorage + ,xModel + ,"meta.xml" + ,GetComponentContext() + ,xGraphicStorageHandler + ,xEmbeddedObjectResolver + ,SERVICE_METAIMPORTER + ,xProp + ); + + + try + { + xProp->setPropertyValue(s_sOld,uno::Any(!(xStorage->hasByName(s_sMeta) || xStorage->isStreamElement( s_sMeta )))); + } + catch (const uno::Exception&) + { + xProp->setPropertyValue(s_sOld,uno::Any(true)); + } + + if ( nRet == ERRCODE_NONE ) + { + xProp->setPropertyValue(s_sStreamName, uno::Any(OUString("settings.xml"))); + nRet = ReadThroughComponent( xStorage + ,xModel + ,"settings.xml" + ,GetComponentContext() + ,xGraphicStorageHandler + ,xEmbeddedObjectResolver + ,SERVICE_SETTINGSIMPORTER + ,xProp + ); + } + if ( nRet == ERRCODE_NONE ) + { + xProp->setPropertyValue(s_sStreamName, uno::Any(OUString("styles.xml"))); + nRet = ReadThroughComponent(xStorage + ,xModel + ,"styles.xml" + ,GetComponentContext() + ,xGraphicStorageHandler + ,xEmbeddedObjectResolver + ,SERVICE_STYLESIMPORTER + ,xProp); + } + + if ( nRet == ERRCODE_NONE ) + { + xProp->setPropertyValue(s_sStreamName, uno::Any(OUString("content.xml"))); + nRet = ReadThroughComponent( xStorage + ,xModel + ,"content.xml" + ,GetComponentContext() + ,xGraphicStorageHandler + ,xEmbeddedObjectResolver + ,SERVICE_CONTENTIMPORTER + ,xProp + ); + } + + + bRet = nRet == ERRCODE_NONE; + + if ( bRet ) + { + m_xReportDefinition->setModified(false); + } + else + { + if( nRet == ERRCODE_IO_BROKENPACKAGE && xStorage.is() ) + ; // TODO/LATER: no way to transport the error outside from the filter! + else + { + // TODO/LATER: this is completely wrong! Filter code should never call ErrorHandler directly! But for now this is the only way! + ErrorHandler::HandleError( nRet ); + if( nRet.IsWarning() ) + bRet = true; + } + } + } + + return bRet; +} + +namespace { + +class RptXMLDocumentSettingsContext : public SvXMLImportContext +{ +public: + RptXMLDocumentSettingsContext(SvXMLImport & rImport) + : SvXMLImportContext(rImport) + { + } + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override + { + if (nElement == XML_ELEMENT(OFFICE, XML_SETTINGS)) + { + return new XMLDocumentSettingsContext(GetImport()); + } + return nullptr; + } +}; + +class RptXMLDocumentStylesContext : public SvXMLImportContext +{ +public: + RptXMLDocumentStylesContext(SvXMLImport & rImport) + : SvXMLImportContext(rImport) + { + } + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override + { + ORptFilter & rImport(static_cast<ORptFilter&>(GetImport())); + switch (nElement) + { + case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + return rImport.CreateFontDeclsContext(); + case XML_ELEMENT(OFFICE, XML_MASTER_STYLES): + { + SvXMLStylesContext* pStyleContext = new RptMLMasterStylesContext_Impl(rImport); + rImport.SetMasterStyles(pStyleContext); + return pStyleContext; + } + case XML_ELEMENT(OFFICE, XML_STYLES): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + return rImport.CreateStylesContext(false); + case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES): + // don't use the autostyles from the styles-document for the progress + return rImport.CreateStylesContext(true); + } + return nullptr; + } +}; + +} + +css::uno::Reference< css::xml::sax::XFastContextHandler > RptXMLDocumentBodyContext::createFastChildContext( + sal_Int32 nElement, + const uno::Reference<xml::sax::XFastAttributeList> & xAttrList) +{ + ORptFilter & rImport(static_cast<ORptFilter&>(GetImport())); + if (nElement == XML_ELEMENT(OFFICE, XML_REPORT) || nElement == XML_ELEMENT(OOO, XML_REPORT)) + { + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + const SvXMLStylesContext* pAutoStyles = rImport.GetAutoStyles(); + if (pAutoStyles) + { + XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast<const XMLPropStyleContext *>(pAutoStyles->FindStyleChildContext(XmlStyleFamily::PAGE_MASTER, "pm1"))); + if (pAutoStyle) + { + pAutoStyle->FillPropertySet(rImport.getReportDefinition()); + } + } + return new OXMLReport(rImport, xAttrList, rImport.getReportDefinition()); + } + return nullptr; +} + +namespace { + +class RptXMLDocumentContentContext : public SvXMLImportContext +{ +public: + RptXMLDocumentContentContext(SvXMLImport & rImport) + : SvXMLImportContext(rImport) + { + } + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override + { + ORptFilter & rImport(static_cast<ORptFilter&>(GetImport())); + switch (nElement) + { + case XML_ELEMENT(OFFICE, XML_BODY): + return new RptXMLDocumentBodyContext(rImport); + case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + return rImport.CreateFontDeclsContext(); + case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES): + rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + return rImport.CreateStylesContext(true); + } + return nullptr; + } +}; + +} + +SvXMLImportContext *ORptFilter::CreateFastContext( sal_Int32 nElement, + const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ ) +{ + SvXMLImportContext *pContext = nullptr; + + switch (nElement) + { + case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ): + GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + pContext = CreateMetaContext( nElement ); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ): + pContext = new RptXMLDocumentContentContext(*this); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ): + pContext = new RptXMLDocumentStylesContext(*this); + break; + case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ): + GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); + pContext = new RptXMLDocumentSettingsContext(*this); + break; + } + return pContext; +} + +SvXMLImportContext* ORptFilter::CreateStylesContext( bool bIsAutoStyle ) +{ + SvXMLImportContext* pContext = bIsAutoStyle ? GetAutoStyles() : GetStyles(); + if ( !pContext ) + { + pContext = new OReportStylesContext(*this, bIsAutoStyle); + if (bIsAutoStyle) + SetAutoStyles(static_cast<SvXMLStylesContext*>(pContext)); + else + SetStyles(static_cast<SvXMLStylesContext*>(pContext)); + } + return pContext; +} + +SvXMLImportContext *ORptFilter::CreateFontDeclsContext() +{ + XMLFontStylesContext *pFSContext = + new XMLFontStylesContext( *this, osl_getThreadTextEncoding() ); + SetFontDecls( pFSContext ); + return pFSContext; +} + +XMLShapeImportHelper* ORptFilter::CreateShapeImport() +{ + return new XMLShapeImportHelper( *this,GetModel() ); +} + +void ORptFilter::FinishStyles() +{ + if( GetStyles() ) + GetStyles()->FinishStyles( true ); +} + +const OUString& ORptFilter::convertFormula(const OUString& _sFormula) +{ + return _sFormula; +} + +void SAL_CALL ORptFilter::startDocument() +{ + m_xReportDefinition.set(GetModel(),UNO_QUERY_THROW); + m_pReportModel = reportdesign::OReportDefinition::getSdrModel(m_xReportDefinition); + OSL_ENSURE(m_pReportModel,"Report model is NULL!"); + + SvXMLImport::startDocument(); +} + +void ORptFilter::endDocument() +{ + OSL_ENSURE( GetModel().is(), "model missing; maybe startDocument wasn't called?" ); + if( !GetModel().is() ) + return; + + // this method will modify the document directly -> lock SolarMutex + SolarMutexGuard aGuard; + // Clear the shape import to sort the shapes (and not in the + // destructor that might be called after the import has finished + // for Java filters. + if( HasShapeImport() ) + ClearShapeImport(); + + // delegate to parent: takes care of error handling + SvXMLImport::endDocument(); +} + +void ORptFilter::removeFunction(const OUString& _sFunctionName) +{ + m_aFunctions.erase(_sFunctionName); +} + +void ORptFilter::insertFunction(const css::uno::Reference< css::report::XFunction > & _xFunction) +{ + m_aFunctions.emplace(_xFunction->getName(),_xFunction); +} + +SvXMLImportContext* ORptFilter::CreateMetaContext(const sal_Int32 /*nElement*/) +{ + SvXMLImportContext* pContext = nullptr; + + if ( getImportFlags() & SvXMLImportFlags::META ) + { + uno::Reference<document::XDocumentPropertiesSupplier> xDPS(GetModel(), uno::UNO_QUERY_THROW); + pContext = new SvXMLMetaDocumentContext(*this, xDPS->getDocumentProperties()); + } + return pContext; +} + +bool ORptFilter::isOldFormat() const +{ + bool bOldFormat = true; + uno::Reference<beans::XPropertySet> xProp = getImportInfo(); + if ( xProp.is() ) + { + static constexpr OUStringLiteral s_sOld = u"OldFormat"; + if ( xProp->getPropertySetInfo()->hasPropertyByName(s_sOld)) + { + xProp->getPropertyValue(s_sOld) >>= bOldFormat; + } + } + return bOldFormat; +} + + +}// rptxml + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/filter/xml/xmlfilter.hxx b/reportdesign/source/filter/xml/xmlfilter.hxx new file mode 100644 index 000000000..0a101c635 --- /dev/null +++ b/reportdesign/source/filter/xml/xmlfilter.hxx @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFILTER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFILTER_HXX + +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <xmloff/xmlimp.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <map> +#include <memory> +#include <xmloff/prhdlfac.hxx> +#include <xmloff/xmlprmap.hxx> + +namespace rptui +{ +class OReportModel; +} +namespace rptxml +{ +using namespace ::xmloff::token; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::report; +using namespace ::com::sun::star::xml::sax; + + +class ORptFilter : public SvXMLImport +{ +public: + typedef std::map< OUString, Sequence<PropertyValue> > TPropertyNameMap; + typedef std::map< OUString, Reference<XFunction> > TGroupFunctionMap; +private: + + TGroupFunctionMap m_aFunctions; + + rtl::Reference < XMLPropertyHandlerFactory > m_xPropHdlFactory; + rtl::Reference < XMLPropertySetMapper > m_xCellStylesPropertySetMapper; + rtl::Reference < XMLPropertySetMapper > m_xColumnStylesPropertySetMapper; + rtl::Reference < XMLPropertySetMapper > m_xRowStylesPropertySetMapper; + + Reference<XReportDefinition> m_xReportDefinition; + std::shared_ptr<rptui::OReportModel> m_pReportModel; + + /// @throws RuntimeException + bool implImport( const Sequence< PropertyValue >& rDescriptor ); + +public: + using SvXMLImport::SetMasterStyles; + SvXMLImportContext* CreateStylesContext( bool bIsAutoStyle ); + SvXMLImportContext* CreateMetaContext(const sal_Int32 nElement); + SvXMLImportContext* CreateFontDeclsContext(); +protected: + // SvXMLImport + virtual SvXMLImportContext *CreateFastContext( sal_Int32 nElement, + const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override; + + virtual XMLShapeImportHelper* CreateShapeImport() override; + + virtual ~ORptFilter() noexcept override; +public: + + ORptFilter( const Reference< XComponentContext >& _rxContext, OUString const & rImplementationName, SvXMLImportFlags nImportFlags ); + + // XFilter + virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& rDescriptor ) override; + + const Reference<XReportDefinition>& getReportDefinition() const { + return m_xReportDefinition; + } + void FinishStyles(); + + virtual void SAL_CALL startDocument() override; + virtual void SAL_CALL endDocument() override; + + const rtl::Reference< XMLPropertySetMapper >& GetCellStylesPropertySetMapper() const { + return m_xCellStylesPropertySetMapper; + } + const rtl::Reference< XMLPropertySetMapper >& GetColumnStylesPropertySetMapper() const { + return m_xColumnStylesPropertySetMapper; + } + const rtl::Reference< XMLPropertySetMapper >& GetRowStylesPropertySetMapper() const { + return m_xRowStylesPropertySetMapper; + } + static const OUString& convertFormula(const OUString& _sFormula); + /** inserts a new function + * + * \param _xFunction + */ + void insertFunction(const css::uno::Reference< css::report::XFunction > & _xFunction); + void removeFunction(const OUString& _sFunctionName); + const TGroupFunctionMap& getFunctions() const { + return m_aFunctions; + } + + bool isOldFormat() const; +}; + + +class RptXMLDocumentBodyContext : public SvXMLImportContext +{ +public: + RptXMLDocumentBodyContext(SvXMLImport & rImport) + : SvXMLImportContext(rImport) + { + } + + virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( + sal_Int32 /*nElement*/, const css::uno::Reference< css::xml::sax::XFastAttributeList >& /*xAttrList*/ ) override; +}; + +} // rptxml + +#endif // INCLUDED_REPORTDESIGN_SOURCE_FILTER_XML_XMLFILTER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/inc/GroupProperties.hxx b/reportdesign/source/inc/GroupProperties.hxx new file mode 100644 index 000000000..873a08038 --- /dev/null +++ b/reportdesign/source/inc/GroupProperties.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_INC_GROUPPROPERTIES_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_INC_GROUPPROPERTIES_HXX + +#include <rtl/ustring.hxx> + +namespace rptshared +{ + /** struct for the group properties + */ + struct GroupProperties + { + sal_Int32 m_nGroupInterval; + OUString m_sExpression; + sal_Int16 m_nGroupOn; + sal_Int16 m_nKeepTogether; + bool m_eSortAscending; + bool m_bStartNewColumn; + bool m_bResetPageNumber; + + GroupProperties() + :m_nGroupInterval(1) + ,m_nGroupOn(0) + ,m_nKeepTogether(0) + ,m_eSortAscending(true) + ,m_bStartNewColumn(false) + ,m_bResetPageNumber(false) + {} + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_INC_GROUPPROPERTIES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/AddField.cxx b/reportdesign/source/ui/dlg/AddField.cxx new file mode 100644 index 000000000..6bf3cd1f0 --- /dev/null +++ b/reportdesign/source/ui/dlg/AddField.cxx @@ -0,0 +1,352 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <AddField.hxx> +#include <UITools.hxx> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/XDocumentDataSource.hpp> + +#include <vcl/svapp.hxx> + +#include <tools/diagnose_ex.h> + +#include <connectivity/dbtools.hxx> +#include <core_resource.hxx> +#include <helpids.h> +#include <strings.hrc> +#include <strings.hxx> + +#include <comphelper/sequence.hxx> + +namespace rptui +{ + +using namespace ::com::sun::star; +using namespace sdbc; +using namespace sdb; +using namespace uno; +using namespace datatransfer; +using namespace beans; +using namespace lang; +using namespace container; +using namespace ::svx; + +IMPL_LINK(OAddFieldWindow, DragBeginHdl, bool&, rUnsetDragIcon, bool) +{ + rUnsetDragIcon = false; + if (m_xListBox->get_selected_index() == -1) + { + // no drag without a field + return true; + } + + m_xHelper->setDescriptors(getSelectedFieldDescriptors()); + return false; +} + +OAddFieldWindow::OAddFieldWindow(weld::Window* pParent, const uno::Reference< beans::XPropertySet >& xRowSet) + : GenericDialogController(pParent, "modules/dbreport/ui/floatingfield.ui", "FloatingField") + , ::comphelper::OPropertyChangeListener(m_aMutex) + , ::comphelper::OContainerListener(m_aMutex) + , m_xRowSet(xRowSet) + , m_xActions(m_xBuilder->weld_toolbar("toolbox")) + , m_xListBox(m_xBuilder->weld_tree_view("treeview")) + , m_xHelpText(m_xBuilder->weld_label("helptext")) + , m_nCommandType(0) + , m_bEscapeProcessing(false) +{ + m_xListBox->set_help_id(HID_RPT_FIELD_SEL); + m_xListBox->set_selection_mode(SelectionMode::Multiple); + m_xHelper.set(new svx::OMultiColumnTransferable); + rtl::Reference<TransferDataContainer> xHelper(m_xHelper); + m_xListBox->enable_drag_source(xHelper, DND_ACTION_COPYMOVE | DND_ACTION_LINK); + m_xListBox->connect_drag_begin(LINK(this, OAddFieldWindow, DragBeginHdl)); + + m_xDialog->connect_container_focus_changed(LINK(this, OAddFieldWindow, FocusChangeHdl)); + + m_xDialog->set_help_id(HID_RPT_FIELD_SEL_WIN); + + m_xActions->connect_clicked(LINK(this, OAddFieldWindow, OnSortAction)); + m_xActions->set_item_active("up", true); + m_xListBox->make_sorted(); + m_xActions->set_item_sensitive("insert", false); + + m_xListBox->connect_row_activated(LINK( this, OAddFieldWindow, OnDoubleClickHdl ) ); + m_xListBox->connect_changed(LINK( this, OAddFieldWindow, OnSelectHdl ) ); + m_xListBox->set_size_request(m_xListBox->get_approximate_digit_width() * 45, m_xListBox->get_height_rows(8)); + + if (!m_xRowSet.is()) + return; + + try + { + // be notified when the settings of report definition change + m_pChangeListener = new ::comphelper::OPropertyChangeMultiplexer( this, m_xRowSet ); + m_pChangeListener->addProperty( PROPERTY_COMMAND ); + m_pChangeListener->addProperty( PROPERTY_COMMANDTYPE ); + m_pChangeListener->addProperty( PROPERTY_ESCAPEPROCESSING ); + m_pChangeListener->addProperty( PROPERTY_FILTER ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +OAddFieldWindow::~OAddFieldWindow() +{ + m_aListBoxData.clear(); + if (m_pChangeListener.is()) + m_pChangeListener->dispose(); + if ( m_pContainerListener.is() ) + m_pContainerListener->dispose(); +} + +IMPL_LINK_NOARG(OAddFieldWindow, FocusChangeHdl, weld::Container&, void) +{ + if (m_xDialog->has_toplevel_focus()) + m_xListBox->grab_focus(); +} + +uno::Sequence< beans::PropertyValue > OAddFieldWindow::getSelectedFieldDescriptors() +{ + std::vector<beans::PropertyValue> aArgs; + + m_xListBox->selected_foreach([this, &aArgs](weld::TreeIter& rEntry){ + // build a descriptor for the currently selected field + svx::ODataAccessDescriptor aDescriptor; + fillDescriptor(rEntry, aDescriptor); + aArgs.push_back(beans::PropertyValue()); + aArgs.back().Value <<= aDescriptor.createPropertyValueSequence(); + + return false; + }); + + return comphelper::containerToSequence(aArgs); +} + +void OAddFieldWindow::_propertyChanged( const beans::PropertyChangeEvent& _evt ) +{ + OSL_ENSURE( _evt.Source == m_xRowSet, "OAddFieldWindow::_propertyChanged: where did this come from?" ); + Update(); +} + +void OAddFieldWindow::addToList(const uno::Sequence< OUString >& rEntries) +{ + for (const OUString& rEntry : rEntries) + { + m_aListBoxData.emplace_back(new ColumnInfo(rEntry)); + OUString sId(weld::toId(m_aListBoxData.back().get())); + m_xListBox->append(sId, rEntry); + } +} + +void OAddFieldWindow::addToList(const uno::Reference< container::XNameAccess>& i_xColumns) +{ + const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames(); + for ( const OUString& rEntry : aEntries ) + { + uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),UNO_QUERY_THROW); + OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + m_aListBoxData.emplace_back(new ColumnInfo(rEntry, sLabel)); + OUString sId(weld::toId(m_aListBoxData.back().get())); + if ( !sLabel.isEmpty() ) + m_xListBox->append(sId, sLabel); + else + m_xListBox->append(sId, rEntry); + } +} + +void OAddFieldWindow::Update() +{ + SolarMutexGuard aSolarGuard; + + if ( m_pContainerListener.is() ) + m_pContainerListener->dispose(); + m_pContainerListener = nullptr; + m_xColumns.clear(); + + try + { + // ListBox loeschen + m_xListBox->clear(); + m_aListBoxData.clear(); + const OString aIds[] = { "up", "down" }; + for (size_t j = 0; j< std::size(aIds); ++j) + m_xActions->set_item_sensitive(aIds[j], false); + + OUString aTitle(RptResId(RID_STR_FIELDSELECTION)); + m_xDialog->set_title(aTitle); + if ( m_xRowSet.is() ) + { + OUString sCommand( m_aCommandName ); + sal_Int32 nCommandType( m_nCommandType ); + bool bEscapeProcessing( m_bEscapeProcessing ); + OUString sFilter( m_sFilter ); + + OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand ); + OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nCommandType ); + OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_ESCAPEPROCESSING ) >>= bEscapeProcessing ); + OSL_VERIFY( m_xRowSet->getPropertyValue( PROPERTY_FILTER ) >>= sFilter ); + + m_aCommandName = sCommand; + m_nCommandType = nCommandType; + m_bEscapeProcessing = bEscapeProcessing; + m_sFilter = sFilter; + + // add the columns to the list + uno::Reference< sdbc::XConnection> xCon = getConnection(); + if ( xCon.is() && !m_aCommandName.isEmpty() ) + m_xColumns = dbtools::getFieldsByCommandDescriptor( xCon, GetCommandType(), GetCommand(), m_xHoldAlive ); + if ( m_xColumns.is() ) + { + addToList(m_xColumns); + uno::Reference< container::XContainer> xContainer(m_xColumns,uno::UNO_QUERY); + if ( xContainer.is() ) + m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer); + } + + // add the parameter columns to the list + uno::Reference< css::sdbc::XRowSet > xRowSet(m_xRowSet,uno::UNO_QUERY); + Sequence< OUString > aParamNames( getParameterNames( xRowSet ) ); + addToList(aParamNames); + + // set title + aTitle += " " + m_aCommandName; + m_xDialog->set_title(aTitle); + if ( !m_aCommandName.isEmpty() ) + { + for (size_t i = 0; i < std::size(aIds); ++i) + m_xActions->set_item_sensitive(aIds[i], true); + } + OnSelectHdl(*m_xListBox); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +uno::Reference< sdbc::XConnection> OAddFieldWindow::getConnection() const +{ + return uno::Reference< sdbc::XConnection>(m_xRowSet->getPropertyValue( PROPERTY_ACTIVECONNECTION ),uno::UNO_QUERY); +} + +void OAddFieldWindow::fillDescriptor(const weld::TreeIter& rSelected, svx::ODataAccessDescriptor& rDescriptor) +{ + if (!m_xColumns.is()) + return; + + uno::Reference<container::XChild> xChild(getConnection(),uno::UNO_QUERY); + if ( xChild.is( ) ) + { + uno::Reference<sdb::XDocumentDataSource> xDocument( xChild->getParent(), uno::UNO_QUERY ); + if ( xDocument.is() ) + { + uno::Reference<frame::XModel> xModel(xDocument->getDatabaseDocument(),uno::UNO_QUERY); + if ( xModel.is() ) + rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] <<= xModel->getURL(); + } + } + + rDescriptor[ svx::DataAccessDescriptorProperty::Command ] <<= GetCommand(); + rDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] <<= GetCommandType(); + rDescriptor[ svx::DataAccessDescriptorProperty::EscapeProcessing ] <<= m_bEscapeProcessing; + rDescriptor[ svx::DataAccessDescriptorProperty::Connection ] <<= getConnection(); + + ColumnInfo* pInfo = weld::fromId<ColumnInfo*>(m_xListBox->get_id(rSelected)); + rDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] <<= pInfo->sColumnName; + if ( m_xColumns->hasByName( pInfo->sColumnName ) ) + rDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ] = m_xColumns->getByName(pInfo->sColumnName); +} + +void OAddFieldWindow::_elementInserted( const container::ContainerEvent& _rEvent ) +{ + OUString sName; + if ( !((_rEvent.Accessor >>= sName) && m_xColumns->hasByName(sName)) ) + return; + + uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(sName),UNO_QUERY_THROW); + OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + m_aListBoxData.emplace_back(new ColumnInfo(sName, sLabel)); + OUString sId(weld::toId(m_aListBoxData.back().get())); + if (!sLabel.isEmpty()) + m_xListBox->append(sId, sLabel); + else + m_xListBox->append(sId, sName); +} + +void OAddFieldWindow::_elementRemoved( const container::ContainerEvent& /*_rEvent*/ ) +{ + m_xListBox->clear(); + m_aListBoxData.clear(); + if ( m_xColumns.is() ) + addToList(m_xColumns); +} + +void OAddFieldWindow::_elementReplaced( const container::ContainerEvent& /*_rEvent*/ ) +{ +} + +IMPL_LINK_NOARG( OAddFieldWindow, OnSelectHdl, weld::TreeView&, void ) +{ + m_xActions->set_item_sensitive("insert", m_xListBox->get_selected_index() != -1); +} + +IMPL_LINK_NOARG( OAddFieldWindow, OnDoubleClickHdl, weld::TreeView&, bool ) +{ + m_aCreateLink.Call(*this); + return true; +} + +IMPL_LINK(OAddFieldWindow, OnSortAction, const OString&, rCurItem, void) +{ + if (rCurItem == "insert") + { + OnDoubleClickHdl(*m_xListBox); + return; + } + + const OString aIds[] = { "up", "down" }; + + if (rCurItem == "delete") + { + for (size_t j = 0; j< std::size(aIds); ++j) + m_xActions->set_item_active(aIds[j], false); + + m_xListBox->make_unsorted(); + Update(); + return; + } + + for (size_t j = 0; j< std::size(aIds); ++j) + m_xActions->set_item_active(aIds[j], rCurItem == aIds[j]); + + m_xListBox->make_sorted(); + if (m_xActions->get_item_active("down")) + m_xListBox->set_sort_order(false); +} + +} // namespace rptui + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/CondFormat.cxx b/reportdesign/source/ui/dlg/CondFormat.cxx new file mode 100644 index 000000000..5c593c3a0 --- /dev/null +++ b/reportdesign/source/ui/dlg/CondFormat.cxx @@ -0,0 +1,449 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <CondFormat.hxx> + +#include <strings.hxx> +#include <strings.hrc> +#include <core_resource.hxx> +#include <ReportController.hxx> +#include "Condition.hxx" + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <o3tl/safeint.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <tools/diagnose_ex.h> + +#include <comphelper/property.hxx> +#include <comphelper/propertyvalue.hxx> + +#include <algorithm> +#include <UndoActions.hxx> + + +namespace rptui +{ + + + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::beans::PropertyValue; + using ::com::sun::star::uno::Any; + + using namespace ::com::sun::star::report; + + void ConditionalFormattingDialog::impl_setPrefHeight(bool bFirst) + { + if (!m_bConstructed && !bFirst) + return; + + //allow dialog to resize itself + size_t nCount = impl_getConditionCount(); + if (!nCount) + return; + + auto nHeight = m_aConditions[0]->get_preferred_size().Height(); + size_t nVisibleConditions = ::std::min(nCount, MAX_CONDITIONS); + nHeight *= nVisibleConditions; + nHeight += 2; + if (nHeight != m_xScrollWindow->get_size_request().Height()) + { + m_xScrollWindow->set_size_request(-1, nHeight); + if (!bFirst) + m_xDialog->resize_to_request(); + } + } + + ConditionalFormattingDialog::ConditionalFormattingDialog( + weld::Window* _pParent, const Reference< XReportControlModel >& _rxFormatConditions, ::rptui::OReportController& _rController) + : GenericDialogController(_pParent, "modules/dbreport/ui/condformatdialog.ui", "CondFormat") + , m_rController(_rController) + , m_xFormatConditions(_rxFormatConditions) + , m_bConstructed(false) + , m_xScrollWindow(m_xBuilder->weld_scrolled_window("scrolledwindow")) + , m_xConditionPlayground(m_xBuilder->weld_box("condPlaygroundDrawingarea")) + { + OSL_ENSURE( m_xFormatConditions.is(), "ConditionalFormattingDialog::ConditionalFormattingDialog: ReportControlModel is NULL -> Prepare for GPF!" ); + + m_xCopy.set( m_xFormatConditions->createClone(), UNO_QUERY_THROW ); + + m_xScrollWindow->connect_vadjustment_changed(LINK(this, ConditionalFormattingDialog, OnScroll)); + + impl_initializeConditions(); + + impl_setPrefHeight(true); + + m_bConstructed = true; + } + + ConditionalFormattingDialog::~ConditionalFormattingDialog() + { + } + + void ConditionalFormattingDialog::impl_updateConditionIndicies() + { + sal_Int32 nIndex = 0; + for (const auto& rxCondition : m_aConditions) + { + rxCondition->setConditionIndex( nIndex, impl_getConditionCount() ); + m_xConditionPlayground->reorder_child(rxCondition->get_widget(), nIndex); + ++nIndex; + } + } + + void ConditionalFormattingDialog::impl_conditionCountChanged() + { + if ( m_aConditions.empty() ) + impl_addCondition_nothrow( 0 ); + + impl_setPrefHeight(false); + + impl_updateConditionIndicies(); + impl_layoutAll(); + } + + void ConditionalFormattingDialog::addCondition( size_t _nAddAfterIndex ) + { + OSL_PRECOND( _nAddAfterIndex < impl_getConditionCount(), "ConditionalFormattingDialog::addCondition: illegal condition index!" ); + impl_addCondition_nothrow( _nAddAfterIndex + 1 ); + } + + + void ConditionalFormattingDialog::deleteCondition( size_t _nCondIndex ) + { + impl_deleteCondition_nothrow( _nCondIndex ); + } + + + void ConditionalFormattingDialog::impl_addCondition_nothrow( size_t _nNewCondIndex ) + { + try + { + if ( _nNewCondIndex > o3tl::make_unsigned(m_xCopy->getCount()) ) + throw IllegalArgumentException(); + + Reference< XFormatCondition > xCond = m_xCopy->createFormatCondition(); + ::comphelper::copyProperties(m_xCopy, xCond); + m_xCopy->insertByIndex( _nNewCondIndex, Any( xCond ) ); + auto xCon = std::make_unique<Condition>(m_xConditionPlayground.get(), m_xDialog.get(), *this, m_rController); + xCon->setCondition(xCond); + m_xConditionPlayground->reorder_child(xCon->get_widget(), _nNewCondIndex); + m_aConditions.insert(m_aConditions.begin() + _nNewCondIndex, std::move(xCon)); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + impl_conditionCountChanged(); + + impl_ensureConditionVisible( _nNewCondIndex ); + } + + void ConditionalFormattingDialog::impl_focusCondition( size_t _nCondIndex ) + { + OSL_PRECOND( _nCondIndex < impl_getConditionCount(), + "ConditionalFormattingDialog::impl_focusCondition: illegal index!" ); + + impl_ensureConditionVisible( _nCondIndex ); + m_aConditions[ _nCondIndex ]->grab_focus(); + } + + void ConditionalFormattingDialog::impl_deleteCondition_nothrow( size_t _nCondIndex ) + { + OSL_PRECOND( _nCondIndex < impl_getConditionCount(), + "ConditionalFormattingDialog::impl_deleteCondition_nothrow: illegal index!" ); + + bool bLastCondition = ( impl_getConditionCount() == 1 ); + + bool bSetNewFocus = false; + size_t nNewFocusIndex( _nCondIndex ); + try + { + if ( !bLastCondition ) + m_xCopy->removeByIndex( _nCondIndex ); + + Conditions::iterator pos = m_aConditions.begin() + _nCondIndex; + if ( bLastCondition ) + { + Reference< XFormatCondition > xFormatCondition( m_xCopy->getByIndex( 0 ), UNO_QUERY_THROW ); + xFormatCondition->setFormula( OUString() ); + (*pos)->setCondition( xFormatCondition ); + } + else + { + bSetNewFocus = (*pos)->has_focus(); + + auto xMovedCondition = std::move(*pos); + m_aConditions.erase(pos); + m_xConditionPlayground->move(xMovedCondition->get_widget(), nullptr); + } + + if ( bSetNewFocus ) + { + if ( nNewFocusIndex >= impl_getConditionCount() ) + nNewFocusIndex = impl_getConditionCount() - 1; + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + impl_conditionCountChanged(); + if ( bSetNewFocus ) + impl_focusCondition( nNewFocusIndex ); + } + + + void ConditionalFormattingDialog::impl_moveCondition_nothrow( size_t _nCondIndex, bool _bMoveUp ) + { + size_t nOldConditionIndex( _nCondIndex ); + size_t nNewConditionIndex( _bMoveUp ? _nCondIndex - 1 : _nCondIndex + 1 ); + + // do this in two steps, so we don't become inconsistent if any of the UNO actions fails + Any aMovedCondition; + std::unique_ptr<Condition> xMovedCondition; + try + { + aMovedCondition = m_xCopy->getByIndex( static_cast<sal_Int32>(nOldConditionIndex) ); + m_xCopy->removeByIndex( static_cast<sal_Int32>(nOldConditionIndex) ); + + Conditions::iterator aRemovePos( m_aConditions.begin() + nOldConditionIndex ); + xMovedCondition = std::move(*aRemovePos); + m_aConditions.erase( aRemovePos ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + return; + } + + try + { + m_xCopy->insertByIndex( static_cast<sal_Int32>(nNewConditionIndex), aMovedCondition ); + m_aConditions.insert(m_aConditions.begin() + nNewConditionIndex, std::move(xMovedCondition)); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + // at least the two swapped conditions need to know their new index + impl_updateConditionIndicies(); + + // ensure the moved condition is visible + impl_ensureConditionVisible( nNewConditionIndex ); + } + + IMPL_LINK_NOARG(ConditionalFormattingDialog, OnScroll, weld::ScrolledWindow&, void) + { + size_t nFirstCondIndex( impl_getFirstVisibleConditionIndex() ); + size_t nFocusCondIndex = impl_getFocusedConditionIndex( nFirstCondIndex ); + + if ( nFocusCondIndex < nFirstCondIndex ) + impl_focusCondition( nFirstCondIndex ); + else if ( nFocusCondIndex >= nFirstCondIndex + MAX_CONDITIONS ) + impl_focusCondition( nFirstCondIndex + MAX_CONDITIONS - 1 ); + } + + void ConditionalFormattingDialog::impl_layoutAll() + { + // scrollbar visibility + if ( m_aConditions.size() <= MAX_CONDITIONS ) + // normalize the position, so it can, in all situations, be used as top index + m_xScrollWindow->vadjustment_set_value(0); + } + + void ConditionalFormattingDialog::impl_initializeConditions() + { + try + { + sal_Int32 nCount = m_xCopy->getCount(); + for ( sal_Int32 i = 0; i < nCount ; ++i ) + { + auto xCon = std::make_unique<Condition>(m_xConditionPlayground.get(), m_xDialog.get(), *this, m_rController); + Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY ); + m_xConditionPlayground->reorder_child(xCon->get_widget(), i); + xCon->setCondition(xCond); + xCon->updateToolbar(xCond); + m_aConditions.push_back(std::move(xCon)); + } + } + catch(Exception&) + { + OSL_FAIL("Can not access format condition!"); + } + + impl_conditionCountChanged(); + } + + void ConditionalFormattingDialog::applyCommand(size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor) + { + OSL_PRECOND( _nCommandId, "ConditionalFormattingDialog::applyCommand: illegal command id!" ); + try + { + Reference< XReportControlFormat > xReportControlFormat( m_xCopy->getByIndex( _nCondIndex ), UNO_QUERY_THROW ); + + Sequence< PropertyValue > aArgs{ + comphelper::makePropertyValue(REPORTCONTROLFORMAT, xReportControlFormat), + comphelper::makePropertyValue(CURRENT_WINDOW, m_xDialog->GetXWindow()), + comphelper::makePropertyValue(PROPERTY_FONTCOLOR, rColor) + }; + + // we use this way to create undo actions + m_rController.executeUnChecked(_nCommandId,aArgs); + m_aConditions[ _nCondIndex ]->updateToolbar(xReportControlFormat); + } + catch( Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + + void ConditionalFormattingDialog::moveConditionUp( size_t _nCondIndex ) + { + OSL_PRECOND( _nCondIndex > 0, "ConditionalFormattingDialog::moveConditionUp: cannot move up the first condition!" ); + if ( _nCondIndex > 0 ) + impl_moveCondition_nothrow( _nCondIndex, true ); + } + + + void ConditionalFormattingDialog::moveConditionDown( size_t _nCondIndex ) + { + OSL_PRECOND( _nCondIndex < impl_getConditionCount(), "ConditionalFormattingDialog::moveConditionDown: cannot move down the last condition!" ); + if ( _nCondIndex < impl_getConditionCount() ) + impl_moveCondition_nothrow( _nCondIndex, false ); + } + + OUString ConditionalFormattingDialog::getDataField() const + { + OUString sDataField; + try + { + sDataField = m_xFormatConditions->getDataField(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + return sDataField; + } + + short ConditionalFormattingDialog::run() + { + short nRet = GenericDialogController::run(); + if (nRet == RET_OK) + { + const OUString sUndoAction( RptResId( RID_STR_UNDO_CONDITIONAL_FORMATTING ) ); + const UndoContext aUndoContext( m_rController.getUndoManager(), sUndoAction ); + try + { + sal_Int32 j(0), i(0); + for ( Conditions::const_iterator cond = m_aConditions.begin(); + cond != m_aConditions.end(); + ++cond, ++i + ) + { + Reference< XFormatCondition > xCond( m_xCopy->getByIndex(i), UNO_QUERY_THROW ); + (*cond)->fillFormatCondition( xCond ); + + if ( (*cond)->isEmpty() ) + continue; + + Reference< XFormatCondition > xNewCond; + bool bAppend = j >= m_xFormatConditions->getCount(); + if ( bAppend ) + { + xNewCond = m_xFormatConditions->createFormatCondition(); + m_xFormatConditions->insertByIndex( i, Any( xNewCond ) ); + } + else + xNewCond.set( m_xFormatConditions->getByIndex(j), UNO_QUERY ); + ++j; + + ::comphelper::copyProperties(xCond, xNewCond); + } + + for ( sal_Int32 k = m_xFormatConditions->getCount()-1; k >= j; --k ) + m_xFormatConditions->removeByIndex(k); + + ::comphelper::copyProperties( m_xCopy, m_xFormatConditions ); + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + nRet = RET_NO; + } + } + return nRet; + } + + size_t ConditionalFormattingDialog::impl_getFirstVisibleConditionIndex() const + { + auto nHeight = m_aConditions[0]->get_preferred_size().Height(); + return m_xScrollWindow->vadjustment_get_value() / nHeight; + } + + size_t ConditionalFormattingDialog::impl_getLastVisibleConditionIndex() const + { + return ::std::min( impl_getFirstVisibleConditionIndex() + MAX_CONDITIONS, impl_getConditionCount() ) - 1; + } + + size_t ConditionalFormattingDialog::impl_getFocusedConditionIndex( sal_Int32 _nFallBackIfNone ) const + { + auto cond = std::find_if(m_aConditions.begin(), m_aConditions.end(), + [](const std::unique_ptr<Condition>& rxCondition) { return rxCondition->has_focus(); }); + if (cond != m_aConditions.end()) + return static_cast<size_t>(std::distance(m_aConditions.begin(), cond)); + return _nFallBackIfNone; + } + + void ConditionalFormattingDialog::impl_scrollTo( size_t nTopCondIndex ) + { + OSL_PRECOND( nTopCondIndex + MAX_CONDITIONS <= impl_getConditionCount(), + "ConditionalFormattingDialog::impl_scrollTo: illegal index!" ); + + auto nHeight = m_aConditions[0]->get_preferred_size().Height(); + m_xScrollWindow->vadjustment_set_value(nTopCondIndex * nHeight); + OnScroll(*m_xScrollWindow); + } + + void ConditionalFormattingDialog::impl_ensureConditionVisible( size_t _nCondIndex ) + { + OSL_PRECOND( _nCondIndex < impl_getConditionCount(), + "ConditionalFormattingDialog::impl_ensureConditionVisible: illegal index!" ); + + if ( _nCondIndex < impl_getFirstVisibleConditionIndex() ) + impl_scrollTo( _nCondIndex ); + else if ( _nCondIndex > impl_getLastVisibleConditionIndex() ) + impl_scrollTo( _nCondIndex - MAX_CONDITIONS + 1 ); + } + + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/Condition.cxx b/reportdesign/source/ui/dlg/Condition.cxx new file mode 100644 index 000000000..392b9d5e8 --- /dev/null +++ b/reportdesign/source/ui/dlg/Condition.cxx @@ -0,0 +1,379 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "Condition.hxx" +#include <UITools.hxx> +#include <CondFormat.hxx> +#include <core_resource.hxx> +#include <strings.hrc> +#include <ReportController.hxx> +#include <reportformula.hxx> + +#include <svx/PaletteManager.hxx> +#include <svx/svxids.hrc> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +#include <tools/diagnose_ex.h> + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; + +ConditionField::ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit, + std::unique_ptr<weld::Button> xFormula) + : m_pParent(pParent) + , m_xSubEdit(std::move(xSubEdit)) + , m_xFormula(std::move(xFormula)) +{ + m_xFormula->set_label("..."); + m_xFormula->connect_clicked( LINK( this, ConditionField, OnFormula ) ); +} + +IMPL_LINK_NOARG(ConditionField, OnFormula, weld::Button&, void) +{ + OUString sFormula(m_xSubEdit->get_text()); + const sal_Int32 nLen = sFormula.getLength(); + if ( nLen ) + { + ReportFormula aFormula( sFormula ); + sFormula = aFormula.getCompleteFormula(); + } + uno::Reference< awt::XWindow> xInspectorWindow = m_pParent->GetXWindow(); + uno::Reference< beans::XPropertySet> xProp(m_pParent->getController().getRowSet(),uno::UNO_QUERY); + if ( rptui::openDialogFormula_nothrow( sFormula, m_pParent->getController().getContext(),xInspectorWindow,xProp ) ) + { + ReportFormula aFormula( sFormula ); + m_xSubEdit->set_text(aFormula.getUndecoratedContent()); + } +} + +ConditionColorWrapper::ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId) + : mpControl(pControl) + , mnSlotId(nSlotId) +{ +} + +void ConditionColorWrapper::operator()( + [[maybe_unused]] const OUString& /*rCommand*/, const svx::NamedThemedColor& rNamedColor) +{ + mpControl->ApplyCommand(mnSlotId, rNamedColor.ToNamedColor()); +} + +// = Condition +Condition::Condition(weld::Container* pParent, weld::Window* pDialog, IConditionalFormatAction& _rAction, ::rptui::OReportController& _rController) + : m_xPaletteManager(std::make_shared<PaletteManager>()) + , m_aBackColorWrapper(this, SID_BACKGROUND_COLOR) + , m_aForeColorWrapper(this, SID_ATTR_CHAR_COLOR2) + , m_rController(_rController) + , m_rAction(_rAction) + , m_nCondIndex(0) + , m_pDialog(pDialog) + , m_xBuilder(Application::CreateBuilder(pParent, "modules/dbreport/ui/conditionwin.ui")) + , m_xContainer(m_xBuilder->weld_container("ConditionWin")) + , m_xHeader(m_xBuilder->weld_label("headerLabel")) + , m_xConditionType(m_xBuilder->weld_combo_box("typeCombobox")) + , m_xOperationList(m_xBuilder->weld_combo_box("opCombobox")) + , m_xOperandGlue(m_xBuilder->weld_label("andLabel")) + , m_xActions(m_xBuilder->weld_toolbar("formatToolbox")) + , m_xPreview(new weld::CustomWeld(*m_xBuilder, "previewDrawingarea", m_aPreview)) + , m_xMoveUp(m_xBuilder->weld_button("upButton")) + , m_xMoveDown(m_xBuilder->weld_button("downButton")) + , m_xAddCondition(m_xBuilder->weld_button("addButton")) + , m_xRemoveCondition(m_xBuilder->weld_button("removeButton")) +{ + m_xCondLHS.reset(new ConditionField(this, m_xBuilder->weld_entry("lhsEntry"), m_xBuilder->weld_button("lhsButton"))); + m_xCondRHS.reset(new ConditionField(this, m_xBuilder->weld_entry("rhsEntry"), m_xBuilder->weld_button("rhsButton"))); + + m_xCondLHS->grab_focus(); + + m_xConditionType->connect_changed( LINK( this, Condition, OnTypeSelected ) ); + + m_xOperationList->connect_changed( LINK( this, Condition, OnOperationSelected ) ); + + m_xActions->connect_clicked(LINK(this, Condition, OnFormatAction)); + + m_xMoveUp->connect_clicked( LINK( this, Condition, OnConditionAction ) ); + m_xMoveDown->connect_clicked( LINK( this, Condition, OnConditionAction ) ); + m_xAddCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) ); + m_xRemoveCondition->connect_clicked( LINK( this, Condition, OnConditionAction ) ); + + m_xConditionType->set_active(0); + m_xOperationList->set_active(0); + + SetBackgroundDropdownClick(); + SetForegroundDropdownClick(); + + m_xContainer->show(); + + ConditionalExpressionFactory::getKnownConditionalExpressions( m_aConditionalExpressions ); +} + +sal_uInt16 Condition::mapToolbarItemToSlotId(std::string_view rItemId) +{ + if (rItemId == "bold") + return SID_ATTR_CHAR_WEIGHT; + if (rItemId == "italic") + return SID_ATTR_CHAR_POSTURE; + if (rItemId == "underline") + return SID_ATTR_CHAR_UNDERLINE; + if (rItemId == "background") + return SID_BACKGROUND_COLOR; + if (rItemId == "foreground") + return SID_ATTR_CHAR_COLOR2; + if (rItemId == "fontdialog") + return SID_CHAR_DLG; + return 0; +} + +Condition::~Condition() +{ +} + +void Condition::SetBackgroundDropdownClick() +{ + m_xBackColorFloat.reset(new ColorWindow( + OUString() /*m_aCommandURL*/, + m_xPaletteManager, + m_aColorStatus, + SID_BACKGROUND_COLOR, + nullptr, + MenuOrToolMenuButton(m_xActions.get(), "background"), + [this]{ return m_pDialog; }, + m_aBackColorWrapper)); + + m_xActions->set_item_popover("background", m_xBackColorFloat->getTopLevel()); +} + +void Condition::SetForegroundDropdownClick() +{ + m_xForeColorFloat.reset(new ColorWindow( + OUString() /*m_aCommandURL*/, + m_xPaletteManager, + m_aColorStatus, + SID_ATTR_CHAR_COLOR2, + nullptr, + MenuOrToolMenuButton(m_xActions.get(), "foreground"), + [this]{ return m_pDialog; }, + m_aForeColorWrapper)); + + m_xActions->set_item_popover("foreground", m_xForeColorFloat->getTopLevel()); +} + + +IMPL_LINK(Condition, OnFormatAction, const OString&, rIdent, void) +{ + ApplyCommand(mapToolbarItemToSlotId(rIdent), + NamedColor(COL_AUTO, "#" + COL_AUTO.AsRGBHexString())); +} + +IMPL_LINK(Condition, OnConditionAction, weld::Button&, rClickedButton, void) +{ + if ( &rClickedButton == m_xMoveUp.get() ) + m_rAction.moveConditionUp( getConditionIndex() ); + else if ( &rClickedButton == m_xMoveDown.get() ) + m_rAction.moveConditionDown( getConditionIndex() ); + else if ( &rClickedButton == m_xAddCondition.get() ) + m_rAction.addCondition( getConditionIndex() ); + else if ( &rClickedButton == m_xRemoveCondition.get() ) + m_rAction.deleteCondition( getConditionIndex() ); +} + +void Condition::ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor ) +{ + m_rAction.applyCommand( m_nCondIndex, _nCommandId, rNamedColor.first ); +} + +IMPL_LINK_NOARG( Condition, OnTypeSelected, weld::ComboBox&, void ) +{ + impl_layoutOperands(); +} + +IMPL_LINK_NOARG( Condition, OnOperationSelected, weld::ComboBox&, void ) +{ + impl_layoutOperands(); +} + +void Condition::impl_layoutOperands() +{ + const ConditionType eType( impl_getCurrentConditionType() ); + const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() ); + + const bool bIsExpression = ( eType == eExpression ); + const bool bHaveRHS = + ( ( eType == eFieldValueComparison ) + && ( ( eOperation == eBetween ) + || ( eOperation == eNotBetween ) + ) + ); + + // the "condition type" list box + m_xOperationList->set_visible( !bIsExpression ); + m_xOperandGlue->set_visible( bHaveRHS ); + m_xCondRHS->set_visible( bHaveRHS ); +} + +void Condition::impl_setCondition( const OUString& _rConditionFormula ) +{ + // determine the condition's type and comparison operation + ConditionType eType( eFieldValueComparison ); + ComparisonOperation eOperation( eBetween ); + + // LHS and RHS, matched below + OUString sLHS, sRHS; + + if ( !_rConditionFormula.isEmpty() ) + { + // the unprefixed expression which forms the condition + ReportFormula aFormula( _rConditionFormula ); + OSL_ENSURE( aFormula.getType() == ReportFormula::Expression, "Condition::setCondition: illegal formula!" ); + OUString sExpression; + if ( aFormula.getType() == ReportFormula::Expression ) + sExpression = aFormula.getExpression(); + // as fallback, if the below matching does not succeed, assume + // the whole expression is the LHS + eType = eExpression; + sLHS = sExpression; + + // the data field (or expression) to which our control is bound + const ReportFormula aFieldContentFormula( m_rAction.getDataField() ); + const OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() ); + + // check whether one of the Field Value Expression Factories recognizes the expression + for (const auto& [rOperation, rxConditionalExpression] : m_aConditionalExpressions) + { + if ( rxConditionalExpression->matchExpression( sExpression, sUnprefixedFieldContent, sLHS, sRHS ) ) + { + eType = eFieldValueComparison; + eOperation = rOperation; + break; + } + } + } + + // update UI + m_xConditionType->set_active(static_cast<sal_uInt16>(eType)); + m_xOperationList->set_active(static_cast<sal_uInt16>(eOperation)); + m_xCondLHS->set_text( sLHS ); + m_xCondRHS->set_text( sRHS ); + + // re-layout + impl_layoutOperands(); +} + + +void Condition::setCondition( const uno::Reference< report::XFormatCondition >& _rxCondition ) +{ + OSL_PRECOND( _rxCondition.is(), "Condition::setCondition: empty condition object!" ); + if ( !_rxCondition.is() ) + return; + + OUString sConditionFormula; + try + { + if ( _rxCondition.is() ) + sConditionFormula = _rxCondition->getFormula(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + impl_setCondition( sConditionFormula ); + updateToolbar( _rxCondition ); +} + + +void Condition::updateToolbar(const uno::Reference< report::XReportControlFormat >& _xReportControlFormat) +{ + OString aItems[] = { "bold", "italic", "underline", "fontdialog" }; + + OSL_ENSURE(_xReportControlFormat.is(),"XReportControlFormat is NULL!"); + if ( !_xReportControlFormat.is() ) + return; + + for (size_t j = 0; j < SAL_N_ELEMENTS(aItems); ++j) + { + m_xActions->set_item_active(aItems[j], OReportController::isFormatCommandEnabled(mapToolbarItemToSlotId(aItems[j]), + _xReportControlFormat)); + } + + try + { + vcl::Font aBaseFont( Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont() ); + SvxFont aFont( VCLUnoHelper::CreateFont( _xReportControlFormat->getFontDescriptor(), aBaseFont ) ); + aFont.SetFontHeight(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip)); + aFont.SetEmphasisMark( static_cast< FontEmphasisMark >( _xReportControlFormat->getControlTextEmphasis() ) ); + aFont.SetRelief( static_cast< FontRelief >( _xReportControlFormat->getCharRelief() ) ); + aFont.SetColor( Color(ColorTransparency, _xReportControlFormat->getCharColor()) ); + m_aPreview.SetFont( aFont, aFont, aFont ); + m_aPreview.SetTextLineColor( Color( ColorTransparency, _xReportControlFormat->getCharUnderlineColor() ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void Condition::fillFormatCondition(const uno::Reference< report::XFormatCondition >& _xCondition) +{ + const ConditionType eType( impl_getCurrentConditionType() ); + const ComparisonOperation eOperation( impl_getCurrentComparisonOperation() ); + + const OUString sLHS( m_xCondLHS->get_text() ); + const OUString sRHS( m_xCondRHS->get_text() ); + + OUString sUndecoratedFormula( sLHS ); + + if ( eType == eFieldValueComparison ) + { + ReportFormula aFieldContentFormula( m_rAction.getDataField() ); + OUString sUnprefixedFieldContent( aFieldContentFormula.getBracketedFieldOrExpression() ); + + PConditionalExpression pFactory( m_aConditionalExpressions[ eOperation ] ); + sUndecoratedFormula = pFactory->assembleExpression( sUnprefixedFieldContent, sLHS, sRHS ); + } + + ReportFormula aFormula( ReportFormula::Expression, sUndecoratedFormula ); + _xCondition->setFormula( aFormula.getCompleteFormula() ); +} + +void Condition::setConditionIndex( size_t _nCondIndex, size_t _nCondCount ) +{ + m_nCondIndex = _nCondIndex; + OUString sHeader( RptResId( STR_NUMBERED_CONDITION ) ); + sHeader = sHeader.replaceFirst( "$number$", OUString::number( _nCondIndex + 1) ); + m_xHeader->set_label( sHeader ); + + m_xMoveUp->set_sensitive(_nCondIndex > 0); + OSL_PRECOND( _nCondCount > 0, "Condition::setConditionIndex: having no conditions at all is nonsense!" ); + m_xMoveDown->set_sensitive(_nCondIndex < _nCondCount - 1); +} + +bool Condition::isEmpty() const +{ + return m_xCondLHS->get_text().isEmpty(); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/Condition.hxx b/reportdesign/source/ui/dlg/Condition.hxx new file mode 100644 index 000000000..2e25d343d --- /dev/null +++ b/reportdesign/source/ui/dlg/Condition.hxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX + +#include <conditionalexpression.hxx> + +#include <com/sun/star/report/XFormatCondition.hpp> + +#include <svx/colorwindow.hxx> +#include <svx/fntctrl.hxx> + +#include <vcl/customweld.hxx> +#include <vcl/weld.hxx> + +#include <memory> + +namespace rptui +{ + class OColorPopup; + class OReportController; + class IConditionalFormatAction; + class Condition; + + class ConditionField + { + Condition* m_pParent; + std::unique_ptr<weld::Entry> m_xSubEdit; + std::unique_ptr<weld::Button> m_xFormula; + + DECL_LINK(OnFormula, weld::Button&, void); + public: + ConditionField(Condition* pParent, std::unique_ptr<weld::Entry> xSubEdit, std::unique_ptr<weld::Button> xFormula); + void grab_focus() { m_xSubEdit->grab_focus(); } + void set_visible(bool bShow) { m_xSubEdit->set_visible(bShow); m_xFormula->set_visible(bShow); } + void set_text(const OUString& rText) { m_xSubEdit->set_text(rText); } + OUString get_text() const { return m_xSubEdit->get_text(); } + }; + + class ConditionColorWrapper + { + public: + ConditionColorWrapper(Condition* pControl, sal_uInt16 nSlotId); + void operator()(const OUString& rCommand, const svx::NamedThemedColor& rColor); + // ColorSelectFunction signature + private: + Condition* mpControl; + sal_uInt16 mnSlotId; + }; + + //= Condition + + class Condition + { + std::shared_ptr<PaletteManager> m_xPaletteManager; + ColorStatus m_aColorStatus; + ConditionColorWrapper m_aBackColorWrapper; + ConditionColorWrapper m_aForeColorWrapper; + + ::rptui::OReportController& m_rController; + IConditionalFormatAction& m_rAction; + + size_t m_nCondIndex; + + ConditionalExpressions m_aConditionalExpressions; + + SvxFontPrevWindow m_aPreview; + weld::Window* m_pDialog; + std::unique_ptr<weld::Builder> m_xBuilder; + std::unique_ptr<weld::Container> m_xContainer; + std::unique_ptr<weld::Label> m_xHeader; + std::unique_ptr<weld::ComboBox> m_xConditionType; + std::unique_ptr<weld::ComboBox> m_xOperationList; + std::unique_ptr<ConditionField> m_xCondLHS; + std::unique_ptr<weld::Label> m_xOperandGlue; + std::unique_ptr<ConditionField> m_xCondRHS; + std::unique_ptr<weld::Toolbar> m_xActions; + std::unique_ptr<weld::CustomWeld> m_xPreview; + std::unique_ptr<weld::Button> m_xMoveUp; + std::unique_ptr<weld::Button> m_xMoveDown; + std::unique_ptr<weld::Button> m_xAddCondition; + std::unique_ptr<weld::Button> m_xRemoveCondition; + std::unique_ptr<ColorWindow> m_xBackColorFloat; + std::unique_ptr<ColorWindow> m_xForeColorFloat; + + void SetBackgroundDropdownClick(); + void SetForegroundDropdownClick(); + + DECL_LINK( OnFormatAction, const OString&, void ); + DECL_LINK( OnConditionAction, weld::Button&, void ); + + public: + Condition(weld::Container* pParent, weld::Window* pDialog, IConditionalFormatAction& rAction, ::rptui::OReportController& rController); + ~Condition(); + + /** sets the props at the control + @param _xCondition the source + */ + void setCondition(const css::uno::Reference< css::report::XFormatCondition >& _xCondition); + + /** fills from the control + _xCondition the destination + */ + void fillFormatCondition(const css::uno::Reference< css::report::XFormatCondition >& _xCondition); + + /** updates the toolbar + _xCondition the destination + */ + void updateToolbar(const css::uno::Reference< css::report::XReportControlFormat >& _xCondition); + + /// tells the condition its new index within the dialog's condition array + void setConditionIndex( size_t _nCondIndex, size_t _nCondCount ); + + /// returns the condition's index within the dialog's condition array + size_t getConditionIndex() const { return m_nCondIndex; } + + /** determines whether the condition is actually empty + */ + bool isEmpty() const; + + /** forward to the parent class + */ + void ApplyCommand( sal_uInt16 _nCommandId, const NamedColor& rNamedColor ); + + ::rptui::OReportController& getController() const { return m_rController; } + + static sal_uInt16 mapToolbarItemToSlotId(std::string_view rItemId); + + css::uno::Reference<css::awt::XWindow> GetXWindow() const { return m_pDialog->GetXWindow(); } + + void grab_focus() { m_xContainer->grab_focus(); } + bool has_focus() const { return m_xContainer->has_focus(); } + Size get_preferred_size() const { return m_xContainer->get_preferred_size(); } + weld::Widget* get_widget() const { return m_xContainer.get(); } + + private: + void impl_layoutOperands(); + + inline ConditionType + impl_getCurrentConditionType() const; + + inline ComparisonOperation + impl_getCurrentComparisonOperation() const; + + void impl_setCondition( const OUString& _rConditionFormula ); + + private: + DECL_LINK( OnTypeSelected, weld::ComboBox&, void ); + DECL_LINK( OnOperationSelected, weld::ComboBox&, void ); + }; + + inline ConditionType Condition::impl_getCurrentConditionType() const + { + return sal::static_int_cast<ConditionType>(m_xConditionType->get_active()); + } + + inline ComparisonOperation Condition::impl_getCurrentComparisonOperation() const + { + return sal::static_int_cast<ComparisonOperation>(m_xOperationList->get_active()); + } + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_CONDITION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/DateTime.cxx b/reportdesign/source/ui/dlg/DateTime.cxx new file mode 100644 index 000000000..01cc62d1e --- /dev/null +++ b/reportdesign/source/ui/dlg/DateTime.cxx @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <DateTime.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <rptui_slotid.hrc> +#include <connectivity/dbconversion.hxx> +#include <unotools/syslocale.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <vcl/svapp.hxx> +#include <strings.hxx> +#include <ReportController.hxx> +#include <com/sun/star/util/NumberFormat.hpp> +#include <com/sun/star/util/XNumberFormatPreviewer.hpp> +#include <algorithm> + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace ::comphelper; + + + +ODateTimeDialog::ODateTimeDialog(weld::Window* _pParent, const uno::Reference< report::XSection >& _xHoldAlive, + OReportController* _pController) + : GenericDialogController(_pParent, "modules/dbreport/ui/datetimedialog.ui", "DateTimeDialog") + + , m_pController(_pController) + , m_xHoldAlive(_xHoldAlive) + , m_xDate(m_xBuilder->weld_check_button("date")) + , m_xFTDateFormat(m_xBuilder->weld_label("datelistbox_label")) + , m_xDateListBox(m_xBuilder->weld_combo_box("datelistbox")) + , m_xTime(m_xBuilder->weld_check_button("time")) + , m_xFTTimeFormat(m_xBuilder->weld_label("timelistbox_label")) + , m_xTimeListBox(m_xBuilder->weld_combo_box("timelistbox")) + , m_xPB_OK(m_xBuilder->weld_button("ok")) +{ + try + { + SvtSysLocale aSysLocale; + m_nLocale = aSysLocale.GetLanguageTag().getLocale(); + // Fill listbox with all well known date types + InsertEntry(util::NumberFormat::DATE); + InsertEntry(util::NumberFormat::TIME); + } + catch (const uno::Exception&) + { + } + + m_xDateListBox->set_active(0); + m_xTimeListBox->set_active(0); + + weld::CheckButton* aCheckBoxes[] = { m_xDate.get(), m_xTime.get() }; + for (weld::CheckButton* pCheckBox : aCheckBoxes) + pCheckBox->connect_toggled(LINK(this,ODateTimeDialog,CBClickHdl)); + CBClickHdl(*m_xTime); +} + +void ODateTimeDialog::InsertEntry(sal_Int16 _nNumberFormatId) +{ + const bool bTime = util::NumberFormat::TIME == _nNumberFormatId; + weld::ComboBox* pListBox = m_xDateListBox.get(); + if (bTime) + pListBox = m_xTimeListBox.get(); + + const uno::Reference< util::XNumberFormatter> xNumberFormatter = m_pController->getReportNumberFormatter(); + const uno::Reference< util::XNumberFormats> xFormats = xNumberFormatter->getNumberFormatsSupplier()->getNumberFormats(); + const uno::Sequence<sal_Int32> aFormatKeys = xFormats->queryKeys(_nNumberFormatId,m_nLocale,true); + for (const sal_Int32 nFormatKey : aFormatKeys) + { + pListBox->append(OUString::number(nFormatKey), getFormatStringByKey(nFormatKey,xFormats,bTime)); + } +} + +short ODateTimeDialog::run() +{ + short nRet = GenericDialogController::run(); + if (nRet == RET_OK && (m_xDate->get_active() || m_xTime->get_active())) + { + try + { + sal_Int32 nLength = 0; + uno::Sequence<beans::PropertyValue> aValues( 6 ); + auto pValues = aValues.getArray(); + pValues[nLength].Name = PROPERTY_SECTION; + pValues[nLength++].Value <<= m_xHoldAlive; + + pValues[nLength].Name = PROPERTY_TIME_STATE; + pValues[nLength++].Value <<= m_xTime->get_active(); + + pValues[nLength].Name = PROPERTY_DATE_STATE; + pValues[nLength++].Value <<= m_xDate->get_active(); + + pValues[nLength].Name = PROPERTY_FORMATKEYDATE; + pValues[nLength++].Value <<= getFormatKey(true); + + pValues[nLength].Name = PROPERTY_FORMATKEYTIME; + pValues[nLength++].Value <<= getFormatKey(false); + + OutputDevice* pDefDev = Application::GetDefaultDevice(); + sal_Int32 nWidth = 0; + if ( m_xDate->get_active() ) + { + OUString sDateFormat = m_xDateListBox->get_active_text(); + nWidth = OutputDevice::LogicToLogic(pDefDev->PixelToLogic(Size(pDefDev->GetCtrlTextWidth(sDateFormat),0)).Width(), + pDefDev->GetMapMode().GetMapUnit(),MapUnit::Map100thMM); + } + if ( m_xTime->get_active() ) + { + OUString sDateFormat = m_xTimeListBox->get_active_text(); + nWidth = ::std::max<sal_Int32>(OutputDevice::LogicToLogic(pDefDev->PixelToLogic(Size(pDefDev->GetCtrlTextWidth(sDateFormat),0)).Width(), + pDefDev->GetMapMode().GetMapUnit(),MapUnit::Map100thMM),nWidth); + } + + if ( nWidth > 4000 ) + { + pValues[nLength].Name = PROPERTY_WIDTH; + pValues[nLength++].Value <<= nWidth; + } + + m_pController->executeChecked(SID_DATETIME,aValues); + } + catch (const uno::Exception&) + { + nRet = RET_NO; + } + } + return nRet; +} + +OUString ODateTimeDialog::getFormatStringByKey(::sal_Int32 _nNumberFormatKey,const uno::Reference< util::XNumberFormats>& _xFormats,bool _bTime) +{ + uno::Reference< beans::XPropertySet> xFormSet = _xFormats->getByKey(_nNumberFormatKey); + OSL_ENSURE(xFormSet.is(),"XPropertySet is null!"); + OUString sFormat; + xFormSet->getPropertyValue("FormatString") >>= sFormat; + + double nValue = 0; + if ( _bTime ) + { + tools::Time aCurrentTime( tools::Time::SYSTEM ); + nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(aCurrentTime.GetTime())); + } + else + { + Date aCurrentDate( Date::SYSTEM ); + static css::util::Date STANDARD_DB_DATE(30,12,1899); + nValue = ::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(aCurrentDate.GetDate()),STANDARD_DB_DATE); + } + + uno::Reference< util::XNumberFormatPreviewer> xPreviewer(m_pController->getReportNumberFormatter(),uno::UNO_QUERY); + OSL_ENSURE(xPreviewer.is(),"XNumberFormatPreviewer is null!"); + return xPreviewer->convertNumberToPreviewString(sFormat,nValue,m_nLocale,true); +} + +IMPL_LINK_NOARG(ODateTimeDialog, CBClickHdl, weld::Toggleable&, void) +{ + const bool bDate = m_xDate->get_active(); + m_xFTDateFormat->set_sensitive(bDate); + m_xDateListBox->set_sensitive(bDate); + + const bool bTime = m_xTime->get_active(); + m_xFTTimeFormat->set_sensitive(bTime); + m_xTimeListBox->set_sensitive(bTime); + + if (!bDate && !bTime) + { + m_xPB_OK->set_sensitive(false); + } + else + { + m_xPB_OK->set_sensitive(true); + } +} + +sal_Int32 ODateTimeDialog::getFormatKey(bool _bDate) const +{ + sal_Int32 nFormatKey; + if ( _bDate ) + { + nFormatKey = m_xDateListBox->get_active_id().toInt32(); + } + else + { + nFormatKey = m_xTimeListBox->get_active_id().toInt32(); + } + return nFormatKey; +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/Formula.cxx b/reportdesign/source/ui/dlg/Formula.cxx new file mode 100644 index 000000000..f2b95e0df --- /dev/null +++ b/reportdesign/source/ui/dlg/Formula.cxx @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <unotools/viewoptions.hxx> +#include <formula/formdata.hxx> +#include <formula/funcutl.hxx> +#include <formula/tokenarray.hxx> +#include <formula/FormulaCompiler.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <memory> + +#include <Formula.hxx> +#include <AddField.hxx> +#include <helpids.h> + + +namespace rptui +{ + using namespace formula; + using namespace ::com::sun::star; + + +// initialization / shared functions for the dialog + + +FormulaDialog::FormulaDialog(weld::Window* pParent + , const uno::Reference<lang::XMultiServiceFactory>& _xServiceFactory + , const std::shared_ptr< IFunctionManager >& _pFunctionMgr + , const OUString& _sFormula + , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet + , svl::SharedStringPool& rStrPool ) + : FormulaModalDialog( pParent, _pFunctionMgr.get(),this) + ,m_aFunctionManager(_pFunctionMgr) + ,m_xFormulaData(new FormEditData()) + ,m_xRowSet(_xRowSet) + ,m_pEdit(nullptr) + ,m_sFormula("=") + ,m_nStart(0) + ,m_nEnd(1) + ,mrStringPool(rStrPool) +{ + if ( !_sFormula.isEmpty() ) + { + if ( _sFormula[0] != '=' ) + m_sFormula += _sFormula; + else + m_sFormula = _sFormula; + } + m_xParser.set(_xServiceFactory->createInstance("org.libreoffice.report.pentaho.SOFormulaParser"),uno::UNO_QUERY); + if ( m_xParser.is() ) + m_xOpCodeMapper = m_xParser->getFormulaOpCodeMapper(); + fill(); +} + +void FormulaDialog::notifyChange() +{ +} + +void FormulaDialog::fill() +{ + SetMeText(m_sFormula); + Update(m_sFormula); + CheckMatrix(m_sFormula); + Update(); +} + +FormulaDialog::~FormulaDialog() +{ + if ( m_xAddField ) + { + SvtViewOptions aDlgOpt( EViewType::Window, HID_RPT_FIELD_SEL_WIN ); + aDlgOpt.SetWindowState(OStringToOUString(m_xAddField->getDialog()->get_window_state(WindowStateMask::X | WindowStateMask::Y | WindowStateMask::State | WindowStateMask::Minimized), RTL_TEXTENCODING_ASCII_US)); + + if (m_xAddField->getDialog()->get_visible()) + m_xAddField->response(RET_CANCEL); + + m_xAddField.reset(); + } + + StoreFormEditData(m_xFormulaData.get()); + m_pEdit = nullptr; +} + +// functions for right side + +bool FormulaDialog::calculateValue( const OUString& rStrExp, OUString& rStrResult, bool /*bMatrixFormula*/ ) +{ + rStrResult = rStrExp; + return false; +} + +std::shared_ptr<formula::FormulaCompiler> FormulaDialog::getCompiler() const +{ + return nullptr; +} + +std::unique_ptr<formula::FormulaCompiler> FormulaDialog::createCompiler( formula::FormulaTokenArray& rArray ) const +{ + return std::unique_ptr<formula::FormulaCompiler>(new FormulaCompiler(rArray)); +} + +void FormulaDialog::doClose(bool _bOk) +{ + response(_bOk ? RET_OK : RET_CANCEL); +} + +void FormulaDialog::insertEntryToLRUList(const IFunctionDescription* /*_pDesc*/) +{ +} +void FormulaDialog::showReference(const OUString& /*_sFormula*/) +{ +} +void FormulaDialog::dispatch(bool /*_bOK*/, bool /*_bMatrixChecked*/) +{ +} +void FormulaDialog::setDispatcherLock( bool /*bLock*/ ) +{ +} +void FormulaDialog::deleteFormData() +{ +} +void FormulaDialog::clear() +{ +} +void FormulaDialog::switchBack() +{ +} +FormEditData* FormulaDialog::getFormEditData() const +{ + return m_xFormulaData.get(); +} +void FormulaDialog::setCurrentFormula(const OUString& _sReplacement) +{ + const sal_Int32 nOldLen = m_nEnd - m_nStart; + const sal_Int32 nNewLen = _sReplacement.getLength(); + if (nOldLen) + m_sFormula = m_sFormula.replaceAt( m_nStart, nOldLen, u"" ); + if (nNewLen) + m_sFormula = m_sFormula.replaceAt( m_nStart, 0, _sReplacement ); + m_nEnd = m_nStart + nNewLen; +} +void FormulaDialog::setSelection(sal_Int32 _nStart, sal_Int32 _nEnd) +{ + if ( _nStart <= _nEnd ) + { + m_nStart = _nStart; + m_nEnd = _nEnd; + } + else + { + m_nEnd = _nStart; + m_nStart = _nEnd; + } +} +void FormulaDialog::getSelection(sal_Int32& _nStart, sal_Int32& _nEnd) const +{ + _nStart = m_nStart; + _nEnd = m_nEnd; +} +OUString FormulaDialog::getCurrentFormula() const +{ + return m_sFormula; +} +IFunctionManager* FormulaDialog::getFunctionManager() +{ + return m_aFunctionManager.get(); +} + +void FormulaDialog::ShowReference(const OUString& /*_sRef*/) +{ +} + +void FormulaDialog::HideReference( bool /*bDoneRefMode*/) +{ +} + +void FormulaDialog::ReleaseFocus( RefEdit* /*pEdit*/) +{ +} + +void FormulaDialog::ToggleCollapsed( RefEdit* _pEdit, RefButton* _pButton) +{ + ::std::pair<RefButton*,RefEdit*> aPair = RefInputStartBefore( _pEdit, _pButton ); + m_pEdit = aPair.second; + if ( m_pEdit ) + m_pEdit->GetWidget()->hide(); + if ( aPair.first ) + aPair.first->GetWidget()->hide(); + + if (!m_xAddField) + { + m_xAddField = std::make_shared<OAddFieldWindow>(m_xDialog.get(), m_xRowSet); + m_xAddField->SetCreateHdl(LINK( this, FormulaDialog, OnClickHdl ) ); + SvtViewOptions aDlgOpt( EViewType::Window, HID_RPT_FIELD_SEL_WIN ); + if ( aDlgOpt.Exists() ) + { + m_xAddField->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US)); + + } + + m_xAddField->Update(); + } + RefInputStartAfter(); + + if (!m_xAddField->getDialog()->get_visible()) + weld::DialogController::runAsync(m_xAddField, [this](sal_Int32 /*nResult*/) { m_xAddField.reset(); }); +} + +IMPL_LINK( FormulaDialog, OnClickHdl, OAddFieldWindow& ,_rAddFieldDlg, void) +{ + const uno::Sequence< beans::PropertyValue > aArgs = _rAddFieldDlg.getSelectedFieldDescriptors(); + // we use this way to create undo actions + if ( m_pEdit && aArgs.getLength() == 1) + { + uno::Sequence< beans::PropertyValue > aValue; + aArgs[0].Value >>= aValue; + svx::ODataAccessDescriptor aDescriptor(aValue); + OUString sName; + aDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] >>= sName; + if ( !sName.isEmpty() ) + { + sName = "[" + sName + "]"; + m_pEdit->SetText(sName); + } + } + m_pEdit = nullptr; + if (_rAddFieldDlg.getDialog()->get_visible()) + _rAddFieldDlg.response(RET_CANCEL); + RefInputDoneAfter(); +} + +uno::Reference< sheet::XFormulaParser> FormulaDialog::getFormulaParser() const +{ + return m_xParser; +} + +uno::Reference< sheet::XFormulaOpCodeMapper> FormulaDialog::getFormulaOpCodeMapper() const +{ + return m_xOpCodeMapper; +} + +table::CellAddress FormulaDialog::getReferencePosition() const +{ + return table::CellAddress(); +} + +::std::unique_ptr<formula::FormulaTokenArray> FormulaDialog::convertToTokenArray(const uno::Sequence< sheet::FormulaToken >& _aTokenList) +{ + ::std::unique_ptr<formula::FormulaTokenArray> pArray(new FormulaTokenArray()); + pArray->Fill(_aTokenList, mrStringPool, nullptr); + return pArray; +} + +} // rptui + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/GroupExchange.cxx b/reportdesign/source/ui/dlg/GroupExchange.cxx new file mode 100644 index 000000000..7b749c3f4 --- /dev/null +++ b/reportdesign/source/ui/dlg/GroupExchange.cxx @@ -0,0 +1,68 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include "GroupExchange.hxx" +#include <sot/formats.hxx> +#include <osl/diagnose.h> + +namespace rptui +{ + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; + + SotClipboardFormatId OGroupExchange::getReportGroupId() + { + static SotClipboardFormatId s_nReportFormat = static_cast<SotClipboardFormatId>(-1); + if ( static_cast<SotClipboardFormatId>(-1) == s_nReportFormat ) + { + s_nReportFormat = SotExchange::RegisterFormatName("application/x-openoffice;windows_formatname=\"reportdesign.GroupFormat\""); + OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nReportFormat, "Bad exchange id!"); + } + return s_nReportFormat; + } + OGroupExchange::OGroupExchange(const uno::Sequence< uno::Any >& _aGroupRow) + : m_aGroupRow(_aGroupRow) + { + } + + void OGroupExchange::AddSupportedFormats() + { + if ( m_aGroupRow.hasElements() ) + { + AddFormat(OGroupExchange::getReportGroupId()); + } + } + + bool OGroupExchange::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ ) + { + SotClipboardFormatId nFormat = SotExchange::GetFormat(rFlavor); + if(nFormat == OGroupExchange::getReportGroupId() ) + { + return SetAny(uno::Any(m_aGroupRow)); + } + return false; + } + + void OGroupExchange::ObjectReleased() + { + m_aGroupRow.realloc(0); + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/GroupExchange.hxx b/reportdesign/source/ui/dlg/GroupExchange.hxx new file mode 100644 index 000000000..6154e75ae --- /dev/null +++ b/reportdesign/source/ui/dlg/GroupExchange.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX + +#include <vcl/transfer.hxx> + +namespace rptui +{ + /** clipboard class for group rows in the groups and sorting dialog + */ + class OGroupExchange : public TransferableHelper + { + css::uno::Sequence< css::uno::Any> m_aGroupRow; + public: + explicit OGroupExchange(const css::uno::Sequence< css::uno::Any>& _aGroupRow); + + static SotClipboardFormatId getReportGroupId(); + protected: + virtual void AddSupportedFormats() override; + virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override; + virtual void ObjectReleased() override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_DLG_GROUPEXCHANGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/GroupsSorting.cxx b/reportdesign/source/ui/dlg/GroupsSorting.cxx new file mode 100644 index 000000000..e0599d83a --- /dev/null +++ b/reportdesign/source/ui/dlg/GroupsSorting.cxx @@ -0,0 +1,1181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <GroupsSorting.hxx> +#include <svtools/editbrowsebox.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/report/GroupOn.hpp> +#include <com/sun/star/sdbc/DataType.hpp> + +#include <strings.hrc> +#include <rptui_slotid.hrc> +#include <core_resource.hxx> +#include <helpids.h> +#include "GroupExchange.hxx" +#include <UITools.hxx> +#include <UndoActions.hxx> +#include <strings.hxx> +#include <ReportController.hxx> +#include <ColumnInfo.hxx> + +#include <comphelper/propertyvalue.hxx> +#include <cppuhelper/implbase.hxx> +#include <vcl/commandevent.hxx> +#include <vcl/svapp.hxx> +#include <tools/diagnose_ex.h> + +#include <algorithm> + +#define HANDLE_ID 0 +#define FIELD_EXPRESSION 1 +#define GROUPS_START_LEN 5 +#define NO_GROUP -1 + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace svt; +using namespace ::comphelper; + + static void lcl_addToList_throw( weld::ComboBox& _rListBox, ::std::vector<ColumnInfo>& o_aColumnList,const uno::Reference< container::XNameAccess>& i_xColumns ) + { + const uno::Sequence< OUString > aEntries = i_xColumns->getElementNames(); + for ( const OUString& rEntry : aEntries ) + { + uno::Reference< beans::XPropertySet> xColumn(i_xColumns->getByName(rEntry),uno::UNO_QUERY_THROW); + OUString sLabel; + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + o_aColumnList.emplace_back(rEntry,sLabel ); + if ( !sLabel.isEmpty() ) + _rListBox.append_text( sLabel ); + else + _rListBox.append_text( rEntry ); + } + } + +/** + * Separated out from OFieldExpressionControl to prevent collision of ref-counted base classes + */ +class OFieldExpressionControl; + +namespace { + +class OFieldExpressionControlContainerListener : public ::cppu::WeakImplHelper< container::XContainerListener > +{ + VclPtr<OFieldExpressionControl> mpParent; +public: + explicit OFieldExpressionControlContainerListener(OFieldExpressionControl* pParent) : mpParent(pParent) {} + + // XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + // XContainerListener + virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& rEvent) override; + virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& rEvent) override; + virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& rEvent) override; +}; + +} + +class OFieldExpressionControl : public ::svt::EditBrowseBox +{ + ::osl::Mutex m_aMutex; + ::std::vector<sal_Int32> m_aGroupPositions; + ::std::vector<ColumnInfo> m_aColumnInfo; + VclPtr< ::svt::ComboBoxControl> m_pComboCell; + sal_Int32 m_nDataPos; + sal_Int32 m_nCurrentPos; + ImplSVEvent * m_nDeleteEvent; + OGroupsSortingDialog* m_pParent; + bool m_bIgnoreEvent; + rtl::Reference<OFieldExpressionControlContainerListener> aContainerListener; + +public: + OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent); + virtual ~OFieldExpressionControl() override; + virtual void dispose() override; + + // XContainerListener + /// @throws css::uno::RuntimeException + void elementInserted(const css::container::ContainerEvent& rEvent); + /// @throws css::uno::RuntimeException + void elementRemoved(const css::container::ContainerEvent& rEvent); + + virtual Size GetOptimalSize() const override; + + void fillColumns(const uno::Reference< container::XNameAccess>& _xColumns); + void lateInit(); + bool IsDeleteAllowed( ) const; + void DeleteRows(); + + sal_Int32 getGroupPosition(sal_Int32 _nRow) const { return _nRow != BROWSER_ENDOFSELECTION ? m_aGroupPositions[_nRow] : sal_Int32(NO_GROUP); } + + /** returns the sequence with the selected groups + */ + uno::Sequence<uno::Any> fillSelectedGroups(); + + /** move groups given by _aGroups + */ + void moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect = true); + + virtual bool CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol) override; + using ::svt::EditBrowseBox::GetRowCount; +protected: + virtual bool IsTabAllowed(bool bForward) const override; + + virtual void InitController( ::svt::CellControllerRef& rController, sal_Int32 nRow, sal_uInt16 nCol ) override; + virtual ::svt::CellController* GetController( sal_Int32 nRow, sal_uInt16 nCol ) override; + virtual void PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColId ) const override; + virtual bool SeekRow( sal_Int32 nRow ) override; + virtual bool SaveModified() override; + virtual OUString GetCellText( sal_Int32 nRow, sal_uInt16 nColId ) const override; + virtual RowStatus GetRowStatus(sal_Int32 nRow) const override; + + virtual void KeyInput(const KeyEvent& rEvt) override; + virtual void Command( const CommandEvent& rEvt ) override; + + // D&D + virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override; + virtual sal_Int8 AcceptDrop( const BrowserAcceptDropEvent& rEvt ) override; + virtual sal_Int8 ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) override; + + using BrowseBox::AcceptDrop; + using BrowseBox::ExecuteDrop; + +private: + + DECL_LINK( CBChangeHdl, weld::ComboBox&, void); + +public: + DECL_LINK( DelayedDelete, void*, void ); + +}; + + +void OFieldExpressionControlContainerListener::disposing(const css::lang::EventObject& ) +{} + +void OFieldExpressionControlContainerListener::elementInserted(const css::container::ContainerEvent& rEvent) +{ mpParent->elementInserted(rEvent); } + +void OFieldExpressionControlContainerListener::elementReplaced(const css::container::ContainerEvent& ) +{} + +void OFieldExpressionControlContainerListener::elementRemoved(const css::container::ContainerEvent& rEvent) +{ mpParent->elementRemoved(rEvent); } + +OFieldExpressionControl::OFieldExpressionControl(OGroupsSortingDialog* pParentDialog, const css::uno::Reference<css::awt::XWindow> &rParent) + :EditBrowseBox( VCLUnoHelper::GetWindow(rParent), EditBrowseBoxFlags::NONE, WB_TABSTOP, + BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::AUTOSIZE_LASTCOL | + BrowserMode::KEEPHIGHLIGHT | BrowserMode::HLINES | BrowserMode::VLINES) + ,m_aGroupPositions(GROUPS_START_LEN,-1) + ,m_pComboCell(nullptr) + ,m_nDataPos(-1) + ,m_nCurrentPos(-1) + ,m_nDeleteEvent(nullptr) + ,m_pParent(pParentDialog) + ,m_bIgnoreEvent(false) + ,aContainerListener(new OFieldExpressionControlContainerListener(this)) +{ + SetBorderStyle(WindowBorderStyle::MONO); +} + +OFieldExpressionControl::~OFieldExpressionControl() +{ + disposeOnce(); +} + +void OFieldExpressionControl::dispose() +{ + uno::Reference< report::XGroups > xGroups = m_pParent->getGroups(); + xGroups->removeContainerListener(aContainerListener); + + // delete events from queue + if( m_nDeleteEvent ) + Application::RemoveUserEvent( m_nDeleteEvent ); + + m_pComboCell.disposeAndClear(); + m_pParent = nullptr; + ::svt::EditBrowseBox::dispose(); +} + +uno::Sequence<uno::Any> OFieldExpressionControl::fillSelectedGroups() +{ + uno::Sequence<uno::Any> aList; + ::std::vector<uno::Any> vClipboardList; + vClipboardList.reserve(GetSelectRowCount()); + + uno::Reference<report::XGroups> xGroups = m_pParent->getGroups(); + sal_Int32 nCount = xGroups->getCount(); + if ( nCount >= 1 ) + { + for( tools::Long nIndex=FirstSelectedRow(); nIndex != SFX_ENDOFSELECTION; nIndex=NextSelectedRow() ) + { + try + { + if ( m_aGroupPositions[nIndex] != NO_GROUP ) + { + uno::Reference< report::XGroup> xOrgGroup(xGroups->getByIndex(m_aGroupPositions[nIndex]),uno::UNO_QUERY); + /*uno::Reference< report::XGroup> xCopy = xGroups->createGroup(); + ::comphelper::copyProperties(xOrgGroup.get(),xCopy.get());*/ + vClipboardList.push_back( uno::Any(xOrgGroup) ); + } + } + catch(uno::Exception&) + { + OSL_FAIL("Can not access group!"); + } + } + if ( !vClipboardList.empty() ) + aList = uno::Sequence< uno::Any >(vClipboardList.data(), vClipboardList.size()); + } + return aList; +} + +void OFieldExpressionControl::StartDrag( sal_Int8 /*_nAction*/ , const Point& /*_rPosPixel*/ ) +{ + if ( m_pParent && !m_pParent->isReadOnly( ) ) + { + uno::Sequence<uno::Any> aClipboardList = fillSelectedGroups(); + + if( aClipboardList.hasElements() ) + { + rtl::Reference<OGroupExchange> pData = new OGroupExchange(aClipboardList); + pData->StartDrag(this, DND_ACTION_MOVE ); + } + } +} + +sal_Int8 OFieldExpressionControl::AcceptDrop( const BrowserAcceptDropEvent& rEvt ) +{ + sal_Int8 nAction = DND_ACTION_NONE; + if ( IsEditing() ) + { + weld::ComboBox& rComboBox = m_pComboCell->get_widget(); + sal_Int32 nPos = rComboBox.get_active(); + if (nPos != -1 || !rComboBox.get_active_text().isEmpty()) + SaveModified(); + DeactivateCell(); + } + if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) && m_pParent->getGroups()->getCount() > 1 && rEvt.GetWindow() == &GetDataWindow() ) + { + nAction = DND_ACTION_MOVE; + } + return nAction; +} + +sal_Int8 OFieldExpressionControl::ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) +{ + sal_Int8 nAction = DND_ACTION_NONE; + if ( IsDropFormatSupported( OGroupExchange::getReportGroupId() ) ) + { + sal_Int32 nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), false); + SetNoSelection(); + + TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable ); + uno::Any aDrop = aDropped.GetAny(OGroupExchange::getReportGroupId(), OUString()); + uno::Sequence< uno::Any > aGroups; + aDrop >>= aGroups; + if ( aGroups.hasElements() ) + { + moveGroups(aGroups,nRow); + nAction = DND_ACTION_MOVE; + } + } + return nAction; +} + +void OFieldExpressionControl::moveGroups(const uno::Sequence<uno::Any>& _aGroups,sal_Int32 _nRow,bool _bSelect) +{ + if ( !_aGroups.hasElements() ) + return; + + m_bIgnoreEvent = true; + { + sal_Int32 nRow = _nRow; + const OUString sUndoAction(RptResId(RID_STR_UNDO_MOVE_GROUP)); + const UndoContext aUndoContext( m_pParent->m_pController->getUndoManager(), sUndoAction ); + + uno::Reference< report::XGroups> xGroups = m_pParent->getGroups(); + for(const uno::Any& rGroup : _aGroups) + { + uno::Reference< report::XGroup> xGroup(rGroup,uno::UNO_QUERY); + if ( xGroup.is() ) + { + uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue( + PROPERTY_GROUP, xGroup) }; + // we use this way to create undo actions + m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs); + aArgs.realloc(2); + auto pArgs = aArgs.getArray(); + if ( nRow > xGroups->getCount() ) + nRow = xGroups->getCount(); + if ( _bSelect ) + SelectRow(nRow); + pArgs[1].Name = PROPERTY_POSITIONY; + pArgs[1].Value <<= nRow; + m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs); + ++nRow; + } + } + } + m_bIgnoreEvent = false; + Invalidate(); +} + +void OFieldExpressionControl::fillColumns(const uno::Reference< container::XNameAccess>& _xColumns) +{ + weld::ComboBox& rComboBox = m_pComboCell->get_widget(); + rComboBox.clear(); + if ( _xColumns.is() ) + lcl_addToList_throw(rComboBox, m_aColumnInfo, _xColumns); +} + +void OFieldExpressionControl::lateInit() +{ + uno::Reference< report::XGroups > xGroups = m_pParent->getGroups(); + sal_Int32 nGroupsCount = xGroups->getCount(); + m_aGroupPositions.resize(::std::max<sal_Int32>(nGroupsCount,sal_Int32(GROUPS_START_LEN)),NO_GROUP); + ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin(); + for (sal_Int32 i = 0; i < nGroupsCount; ++i,++aIter) + *aIter = i; + + if ( ColCount() == 0 ) + { + vcl::Font aFont( GetDataWindow().GetFont() ); + aFont.SetWeight( WEIGHT_NORMAL ); + GetDataWindow().SetFont( aFont ); + + // Set font of the headline to light + aFont = GetFont(); + aFont.SetWeight( WEIGHT_LIGHT ); + SetFont(aFont); + + InsertHandleColumn(static_cast<sal_uInt16>(GetTextWidth(OUString('0')) * 4)/*, sal_True */); + InsertDataColumn( FIELD_EXPRESSION, RptResId(STR_RPT_EXPRESSION), 100); + + m_pComboCell = VclPtr<ComboBoxControl>::Create( &GetDataWindow() ); + weld::ComboBox& rComboBox = m_pComboCell->get_widget(); + rComboBox.connect_changed(LINK(this,OFieldExpressionControl,CBChangeHdl)); + m_pComboCell->SetHelpId(HID_RPT_FIELDEXPRESSION); + + m_pComboCell->SetFocusInHdl(LINK(m_pParent, OGroupsSortingDialog, OnControlFocusGot)); + + + // set browse mode + BrowserMode nMode(BrowserMode::COLUMNSELECTION | BrowserMode::MULTISELECTION | BrowserMode::KEEPHIGHLIGHT | + BrowserMode::HLINES | BrowserMode::VLINES | BrowserMode::AUTOSIZE_LASTCOL | BrowserMode::AUTO_VSCROLL | BrowserMode::AUTO_HSCROLL); + if( m_pParent->isReadOnly() ) + nMode |= BrowserMode::HIDECURSOR; + SetMode(nMode); + xGroups->addContainerListener(aContainerListener); + } + else + // not the first call + RowRemoved(0, GetRowCount()); + + RowInserted(0, m_aGroupPositions.size()); +} + +IMPL_LINK_NOARG( OFieldExpressionControl, CBChangeHdl, weld::ComboBox&, void ) +{ + SaveModified(); +} + +bool OFieldExpressionControl::IsTabAllowed(bool /*bForward*/) const +{ + return false; +} + +bool OFieldExpressionControl::SaveModified() +{ + sal_Int32 nRow = GetCurRow(); + if ( nRow == BROWSER_ENDOFSELECTION ) + return true; + + try + { + bool bAppend = false; + uno::Reference< report::XGroup> xGroup; + if ( m_aGroupPositions[nRow] == NO_GROUP ) + { + bAppend = true; + OUString sUndoAction(RptResId(RID_STR_UNDO_APPEND_GROUP)); + m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) ); + xGroup = m_pParent->getGroups()->createGroup(); + xGroup->setHeaderOn(true); + + // find position where to insert the new group + sal_Int32 nGroupPos = 0; + ::std::vector<sal_Int32>::iterator aIter = m_aGroupPositions.begin(); + ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.begin() + nRow; + for(;aIter != aEnd;++aIter) + if ( *aIter != NO_GROUP ) + nGroupPos = *aIter + 1; + uno::Sequence< beans::PropertyValue > aArgs{ + comphelper::makePropertyValue(PROPERTY_GROUP, xGroup), + comphelper::makePropertyValue(PROPERTY_POSITIONY, nGroupPos) + }; + m_bIgnoreEvent = true; + m_pParent->m_pController->executeChecked(SID_GROUP_APPEND,aArgs); + m_bIgnoreEvent = false; + OSL_ENSURE(*aIter == NO_GROUP ,"Illegal iterator!"); + *aIter++ = nGroupPos; + + aEnd = m_aGroupPositions.end(); + for(;aIter != aEnd;++aIter) + if ( *aIter != NO_GROUP ) + ++*aIter; + } + else + xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]); + if ( xGroup.is() ) + { + weld::ComboBox& rComboBox = m_pComboCell->get_widget(); + sal_Int32 nPos = rComboBox.get_active(); + OUString sExpression; + if (nPos == -1) + sExpression = rComboBox.get_active_text(); + else + { + sExpression = m_aColumnInfo[nPos].sColumnName; + } + xGroup->setExpression( sExpression ); + + ::rptui::adjustSectionName(xGroup,nPos); + + if ( bAppend ) + m_pParent->m_pController->getUndoManager().LeaveListAction(); + } + + if (Controller().is()) + Controller()->SaveValue(); + if ( GetRowCount() == m_pParent->getGroups()->getCount() ) + { + RowInserted( GetRowCount()-1); + m_aGroupPositions.push_back(NO_GROUP); + } + + GoToRow(nRow); + m_pParent->DisplayData(nRow); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OFieldExpressionControl::SaveModified"); + } + + return true; +} + +OUString OFieldExpressionControl::GetCellText( sal_Int32 nRow, sal_uInt16 /*nColId*/ ) const +{ + OUString sText; + if ( nRow != BROWSER_ENDOFSELECTION && m_aGroupPositions[nRow] != NO_GROUP ) + { + try + { + uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]); + OUString sExpression = xGroup->getExpression(); + + auto aIter = std::find_if(m_aColumnInfo.begin(), m_aColumnInfo.end(), + [&sExpression](const ColumnInfo& rColumnInfo) { return rColumnInfo.sColumnName == sExpression; }); + if (aIter != m_aColumnInfo.end() && !aIter->sLabel.isEmpty()) + sExpression = aIter->sLabel; + sText = sExpression; + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting expression value from the group"); + } + } + return sText; +} + +void OFieldExpressionControl::InitController( CellControllerRef& /*rController*/, sal_Int32 nRow, sal_uInt16 nColumnId ) +{ + weld::ComboBox& rComboBox = m_pComboCell->get_widget(); + rComboBox.set_entry_text(GetCellText(nRow, nColumnId)); +} + +bool OFieldExpressionControl::CursorMoving(sal_Int32 nNewRow, sal_uInt16 nNewCol) +{ + + if (!EditBrowseBox::CursorMoving(nNewRow, nNewCol)) + return false; + m_nDataPos = nNewRow; + tools::Long nOldDataPos = GetCurRow(); + InvalidateStatusCell( m_nDataPos ); + InvalidateStatusCell( nOldDataPos ); + + m_pParent->SaveData( nOldDataPos ); + m_pParent->DisplayData( m_nDataPos ); + return true; +} + +CellController* OFieldExpressionControl::GetController( sal_Int32 /*nRow*/, sal_uInt16 /*nColumnId*/ ) +{ + ComboBoxCellController* pCellController = new ComboBoxCellController( m_pComboCell ); + pCellController->GetComboBox().set_entry_editable(m_pParent->m_pController->isEditable()); + return pCellController; +} + +bool OFieldExpressionControl::SeekRow( sal_Int32 _nRow ) +{ + // the basis class needs the call, because that's how the class knows which line will be painted + EditBrowseBox::SeekRow(_nRow); + m_nCurrentPos = _nRow; + return true; +} + +void OFieldExpressionControl::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId ) const +{ + OUString aText =GetCellText( m_nCurrentPos, nColumnId ); + + Point aPos( rRect.TopLeft() ); + Size aTextSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight() ); + + if( aPos.X() < rRect.Left() || aPos.X() + aTextSize.Width() > rRect.Right() || + aPos.Y() < rRect.Top() || aPos.Y() + aTextSize.Height() > rRect.Bottom() ) + rDev.SetClipRegion(vcl::Region(rRect)); + + rDev.DrawText( aPos, aText ); + + if( rDev.IsClipRegion() ) + rDev.SetClipRegion(); +} + +EditBrowseBox::RowStatus OFieldExpressionControl::GetRowStatus(sal_Int32 nRow) const +{ + if (nRow >= 0 && nRow == m_nDataPos) + return EditBrowseBox::CURRENT; + if ( nRow != BROWSER_ENDOFSELECTION && nRow < static_cast<tools::Long>(m_aGroupPositions.size()) && m_aGroupPositions[nRow] != NO_GROUP ) + { + try + { + uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(m_aGroupPositions[nRow]); + return (xGroup->getHeaderOn() || xGroup->getFooterOn())? EditBrowseBox::HEADERFOOTER : EditBrowseBox::CLEAN; + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while try to get a group!"); + } + } + return EditBrowseBox::CLEAN; +} + +// XContainerListener + +void OFieldExpressionControl::elementInserted(const container::ContainerEvent& evt) +{ + if ( m_bIgnoreEvent ) + return; + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + sal_Int32 nGroupPos = 0; + if ( !(evt.Accessor >>= nGroupPos) ) + return; + + if ( nGroupPos >= GetRowCount() ) + { + sal_Int32 nAddedRows = nGroupPos - GetRowCount(); + RowInserted(nAddedRows); + for (sal_Int32 i = 0; i < nAddedRows; ++i) + m_aGroupPositions.push_back(NO_GROUP); + m_aGroupPositions[nGroupPos] = nGroupPos; + } + else + { + ::std::vector<sal_Int32>::iterator aFind = m_aGroupPositions.begin()+ nGroupPos; + if ( aFind == m_aGroupPositions.end() ) + aFind = ::std::find(m_aGroupPositions.begin(),m_aGroupPositions.end(),NO_GROUP); + + if ( aFind != m_aGroupPositions.end() ) + { + if ( *aFind != NO_GROUP ) + aFind = m_aGroupPositions.insert(aFind,nGroupPos); + else + *aFind = nGroupPos; + + ::std::vector<sal_Int32>::const_iterator aEnd = m_aGroupPositions.end(); + for(++aFind;aFind != aEnd;++aFind) + if ( *aFind != NO_GROUP ) + ++*aFind; + } + } + Invalidate(); +} + +void OFieldExpressionControl::elementRemoved(const container::ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_bIgnoreEvent ) + return; + + sal_Int32 nGroupPos = 0; + if ( !(evt.Accessor >>= nGroupPos) ) + return; + + std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end(); + std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos); + if (aFind != aEnd) + { + *aFind = NO_GROUP; + for(++aFind;aFind != aEnd;++aFind) + if ( *aFind != NO_GROUP ) + --*aFind; + Invalidate(); + } +} + +bool OFieldExpressionControl::IsDeleteAllowed( ) const +{ + return !m_pParent->isReadOnly() && GetSelectRowCount() > 0; +} + +void OFieldExpressionControl::KeyInput( const KeyEvent& rEvt ) +{ + if (IsDeleteAllowed()) + { + if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows + !rEvt.GetKeyCode().IsShift() && + !rEvt.GetKeyCode().IsMod1()) + { + DeleteRows(); + return; + } + } + EditBrowseBox::KeyInput(rEvt); +} + +void OFieldExpressionControl::Command(const CommandEvent& rEvt) +{ + switch (rEvt.GetCommand()) + { + case CommandEventId::ContextMenu: + { + if (!rEvt.IsMouseEvent()) + { + EditBrowseBox::Command(rEvt); + return; + } + + sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X())); + + if ( nColId == HANDLE_ID ) + { + bool bEnable = false; + tools::Long nIndex = FirstSelectedRow(); + while( nIndex != SFX_ENDOFSELECTION && !bEnable ) + { + if ( m_aGroupPositions[nIndex] != NO_GROUP ) + bEnable = true; + nIndex = NextSelectedRow(); + } + + ::tools::Rectangle aRect(rEvt.GetMousePosPixel(), Size(1, 1)); + weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect); + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/dbreport/ui/groupsortmenu.ui")); + std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu")); + xContextMenu->set_sensitive("delete", IsDeleteAllowed() && bEnable); + if (!xContextMenu->popup_at_rect(pPopupParent, aRect).isEmpty()) + { + if( m_nDeleteEvent ) + Application::RemoveUserEvent( m_nDeleteEvent ); + m_nDeleteEvent = Application::PostUserEvent( LINK(this, OFieldExpressionControl, DelayedDelete), nullptr, true ); + } + } + [[fallthrough]]; + } + default: + EditBrowseBox::Command(rEvt); + } + +} + +void OFieldExpressionControl::DeleteRows() +{ + + bool bIsEditing = IsEditing(); + if (bIsEditing) + { + DeactivateCell(); + } + tools::Long nIndex = FirstSelectedRow(); + if (nIndex == SFX_ENDOFSELECTION) + { + nIndex = GetCurRow(); + } + bool bFirstTime = true; + + tools::Long nOldDataPos = nIndex; + m_bIgnoreEvent = true; + while( nIndex >= 0 ) + { + if ( m_aGroupPositions[nIndex] != NO_GROUP ) + { + if ( bFirstTime ) + { + bFirstTime = false; + OUString sUndoAction(RptResId(RID_STR_UNDO_REMOVE_SELECTION)); + m_pParent->m_pController->getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) ); + } + + sal_Int32 nGroupPos = m_aGroupPositions[nIndex]; + uno::Reference< report::XGroup> xGroup = m_pParent->getGroup(nGroupPos); + uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue( + PROPERTY_GROUP, xGroup) }; + // we use this way to create undo actions + m_pParent->m_pController->executeChecked(SID_GROUP_REMOVE,aArgs); + + std::vector<sal_Int32>::iterator aEnd = m_aGroupPositions.end(); + std::vector<sal_Int32>::iterator aFind = std::find(m_aGroupPositions.begin(), aEnd, nGroupPos); + if (aFind != aEnd) + { + *aFind = NO_GROUP; + for(++aFind;aFind != aEnd;++aFind) + if ( *aFind != NO_GROUP ) + --*aFind; + } + } + nIndex = NextSelectedRow(); + } + + if ( !bFirstTime ) + m_pParent->m_pController->getUndoManager().LeaveListAction(); + + m_nDataPos = GetCurRow(); + InvalidateStatusCell( nOldDataPos ); + InvalidateStatusCell( m_nDataPos ); + ActivateCell(); + m_pParent->DisplayData( m_nDataPos ); + m_bIgnoreEvent = false; + Invalidate(); +} + +IMPL_LINK_NOARG( OFieldExpressionControl, DelayedDelete, void*, void ) +{ + m_nDeleteEvent = nullptr; + DeleteRows(); +} + +Size OFieldExpressionControl::GetOptimalSize() const +{ + return LogicToPixel(Size(106, 75), MapMode(MapUnit::MapAppFont)); +} + +OGroupsSortingDialog::OGroupsSortingDialog(weld::Window* pParent, bool bReadOnly, + OReportController* pController) + : GenericDialogController(pParent, "modules/dbreport/ui/floatingsort.ui", "FloatingSort") + , OPropertyChangeListener(m_aMutex) + , m_pController(pController) + , m_xGroups(m_pController->getReportDefinition()->getGroups()) + , m_bReadOnly(bReadOnly) + , m_xToolBox(m_xBuilder->weld_toolbar("toolbox")) + , m_xProperties(m_xBuilder->weld_widget("properties")) + , m_xOrderLst(m_xBuilder->weld_combo_box("sorting")) + , m_xHeaderLst(m_xBuilder->weld_combo_box("header")) + , m_xFooterLst(m_xBuilder->weld_combo_box("footer")) + , m_xGroupOnLst(m_xBuilder->weld_combo_box("group")) + , m_xGroupIntervalEd(m_xBuilder->weld_spin_button("interval")) + , m_xKeepTogetherLst(m_xBuilder->weld_combo_box("keep")) + , m_xHelpWindow(m_xBuilder->weld_label("helptext")) + , m_xBox(m_xBuilder->weld_container("box")) + , m_xTableCtrlParent(m_xBox->CreateChildFrame()) + , m_xFieldExpression(VclPtr<OFieldExpressionControl>::Create(this, m_xTableCtrlParent)) +{ + m_xHelpWindow->set_size_request(-1, m_xHelpWindow->get_text_height() * 4); + m_xFieldExpression->set_hexpand(true); + m_xFieldExpression->set_vexpand(true); + + weld::Widget* pControlsLst[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(), + m_xKeepTogetherLst.get(), m_xOrderLst.get(), m_xGroupIntervalEd.get() }; + for (weld::Widget* i : pControlsLst) + { + i->connect_focus_in(LINK(this, OGroupsSortingDialog, OnWidgetFocusGot)); + i->show(); + } + + m_xGroupIntervalEd->connect_focus_out(LINK(this, OGroupsSortingDialog, OnWidgetFocusLost)); + + for (size_t i = 0; i < SAL_N_ELEMENTS(pControlsLst) - 1; ++i) + dynamic_cast<weld::ComboBox&>(*pControlsLst[i]).connect_changed(LINK(this,OGroupsSortingDialog,LBChangeHdl)); + + m_pReportListener = new OPropertyChangeMultiplexer(this, m_pController->getReportDefinition()); + m_pReportListener->addProperty(PROPERTY_COMMAND); + m_pReportListener->addProperty(PROPERTY_COMMANDTYPE); + + m_xFieldExpression->lateInit(); + fillColumns(); + Size aPrefSize = m_xFieldExpression->GetOptimalSize(); + m_xBox->set_size_request(aPrefSize.Width(), aPrefSize.Height()); + m_xFieldExpression->Show(); + + m_xToolBox->connect_clicked(LINK(this, OGroupsSortingDialog, OnFormatAction)); + + checkButtons(0); +} + +OGroupsSortingDialog::~OGroupsSortingDialog() +{ + m_pReportListener->dispose(); + if ( m_pCurrentGroupListener.is() ) + m_pCurrentGroupListener->dispose(); + m_xFieldExpression.disposeAndClear(); + m_xTableCtrlParent->dispose(); + m_xTableCtrlParent.clear(); +} + +void OGroupsSortingDialog::UpdateData( ) +{ + m_xFieldExpression->Invalidate(); + sal_Int32 nCurRow = m_xFieldExpression->GetCurRow(); + m_xFieldExpression->DeactivateCell(); + m_xFieldExpression->ActivateCell(nCurRow, m_xFieldExpression->GetCurColumnId()); + DisplayData(nCurRow); +} + +void OGroupsSortingDialog::DisplayData( sal_Int32 _nRow ) +{ + const sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow); + const bool bEmpty = nGroupPos == NO_GROUP; + m_xProperties->set_sensitive(!bEmpty); + + checkButtons(_nRow); + + if ( m_pCurrentGroupListener.is() ) + m_pCurrentGroupListener->dispose(); + m_pCurrentGroupListener = nullptr; + if (!bEmpty) + { + uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos); + + m_pCurrentGroupListener = new OPropertyChangeMultiplexer(this, xGroup); + m_pCurrentGroupListener->addProperty(PROPERTY_HEADERON); + m_pCurrentGroupListener->addProperty(PROPERTY_FOOTERON); + + displayGroup(xGroup); + } +} + +void OGroupsSortingDialog::SaveData( sal_Int32 _nRow) +{ + sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow); + if ( nGroupPos == NO_GROUP ) + return; + + uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos); + if (m_xHeaderLst->get_value_changed_from_saved()) + xGroup->setHeaderOn( m_xHeaderLst->get_active() == 0 ); + if (m_xFooterLst->get_value_changed_from_saved()) + xGroup->setFooterOn( m_xFooterLst->get_active() == 0 ); + if (m_xKeepTogetherLst->get_value_changed_from_saved()) + xGroup->setKeepTogether( m_xKeepTogetherLst->get_active() ); + if (m_xGroupOnLst->get_value_changed_from_saved()) + { + auto nGroupOn = m_xGroupOnLst->get_active_id().toInt32(); + xGroup->setGroupOn( nGroupOn ); + } + if (m_xGroupIntervalEd->get_value_changed_from_saved()) + { + xGroup->setGroupInterval(m_xGroupIntervalEd->get_value()); + m_xGroupIntervalEd->save_value(); + } + if ( m_xOrderLst->get_value_changed_from_saved() ) + xGroup->setSortAscending( m_xOrderLst->get_active() == 0 ); + + weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(), + m_xKeepTogetherLst.get(), m_xOrderLst.get() }; + for (weld::ComboBox* pControl : pControls) + pControl->save_value(); +} + +sal_Int32 OGroupsSortingDialog::getColumnDataType(const OUString& _sColumnName) +{ + sal_Int32 nDataType = sdbc::DataType::VARCHAR; + try + { + if ( !m_xColumns.is() ) + fillColumns(); + if ( m_xColumns.is() && m_xColumns->hasByName(_sColumnName) ) + { + uno::Reference< beans::XPropertySet> xColumn(m_xColumns->getByName(_sColumnName),uno::UNO_QUERY); + if ( xColumn.is() ) + xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType; + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while getting the type of a column"); + } + + return nDataType; +} + +IMPL_LINK_NOARG(OGroupsSortingDialog, OnControlFocusGot, LinkParamNone*, void ) +{ + m_xHelpWindow->set_label(RptResId(STR_RPT_HELP_FIELD)); +} + +IMPL_LINK(OGroupsSortingDialog, OnWidgetFocusGot, weld::Widget&, rControl, void ) +{ + const std::pair<weld::Widget*, TranslateId> pControls[] = { + { m_xHeaderLst.get(), STR_RPT_HELP_HEADER }, + { m_xFooterLst.get(), STR_RPT_HELP_FOOTER }, + { m_xGroupOnLst.get(), STR_RPT_HELP_GROUPON }, + { m_xGroupIntervalEd.get(), STR_RPT_HELP_INTERVAL }, + { m_xKeepTogetherLst.get(), STR_RPT_HELP_KEEP }, + { m_xOrderLst.get(), STR_RPT_HELP_SORT } + }; + for (size_t i = 0; i < SAL_N_ELEMENTS(pControls); ++i) + { + if (&rControl == pControls[i].first) + { + weld::ComboBox* pListBox = dynamic_cast<weld::ComboBox*>( &rControl ); + if ( pListBox ) + pListBox->save_value(); + weld::SpinButton* pNumericField = dynamic_cast<weld::SpinButton*>(&rControl); + if ( pNumericField ) + pNumericField->save_value(); + //shows the text given by the id in the multiline edit + m_xHelpWindow->set_label(RptResId(pControls[i].second)); + break; + } + } +} + +IMPL_LINK_NOARG(OGroupsSortingDialog, OnWidgetFocusLost, weld::Widget&, void) +{ + if (m_xFieldExpression) + { + if (m_xGroupIntervalEd->get_value_changed_from_saved()) + SaveData(m_xFieldExpression->GetCurRow()); + } +} + +IMPL_LINK(OGroupsSortingDialog, OnFormatAction, const OString&, rCommand, void) +{ + if ( !m_xFieldExpression ) + return; + + tools::Long nIndex = m_xFieldExpression->GetCurrRow(); + sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nIndex); + uno::Sequence<uno::Any> aClipboardList; + if ( nIndex >= 0 && nGroupPos != NO_GROUP ) + { + aClipboardList = { m_xGroups->getByIndex(nGroupPos) }; + } + if (rCommand == "up") + { + --nIndex; + } + if (rCommand == "down") + { + ++nIndex; + } + if (rCommand == "delete") + { + Application::PostUserEvent(LINK(m_xFieldExpression, OFieldExpressionControl, DelayedDelete)); + } + else + { + if ( nIndex >= 0 && aClipboardList.hasElements() ) + { + m_xFieldExpression->SetNoSelection(); + m_xFieldExpression->moveGroups(aClipboardList,nIndex,false); + m_xFieldExpression->DeactivateCell(); + m_xFieldExpression->GoToRow(nIndex); + m_xFieldExpression->ActivateCell(nIndex, m_xFieldExpression->GetCurColumnId()); + DisplayData(nIndex); + } + } +} + +IMPL_LINK( OGroupsSortingDialog, LBChangeHdl, weld::ComboBox&, rListBox, void ) +{ + if ( !rListBox.get_value_changed_from_saved() ) + return; + + sal_Int32 nRow = m_xFieldExpression->GetCurRow(); + sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(nRow); + if (&rListBox != m_xHeaderLst.get() && &rListBox != m_xFooterLst.get()) + { + if ( rListBox.get_value_changed_from_saved() ) + SaveData(nRow); + if ( &rListBox == m_xGroupOnLst.get() ) + m_xGroupIntervalEd->set_sensitive(rListBox.get_active() != 0); + } + else if ( nGroupPos != NO_GROUP ) + { + uno::Reference< report::XGroup> xGroup = getGroup(nGroupPos); + const OUString aHeaderFooterOnName(( m_xHeaderLst.get() == &rListBox ) + ? std::u16string_view(PROPERTY_HEADERON) + : std::u16string_view(PROPERTY_FOOTERON)); + uno::Sequence< beans::PropertyValue > aArgs{ + comphelper::makePropertyValue(aHeaderFooterOnName, rListBox.get_active() == 0), + comphelper::makePropertyValue(PROPERTY_GROUP, xGroup) + }; + m_pController->executeChecked(m_xHeaderLst.get() == &rListBox ? SID_GROUPHEADER : SID_GROUPFOOTER, aArgs); + m_xFieldExpression->InvalidateHandleColumn(); + } +} + +void OGroupsSortingDialog::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) +{ + uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY); + if ( xGroup.is() ) + displayGroup(xGroup); + else + fillColumns(); +} + +void OGroupsSortingDialog::fillColumns() +{ + m_xColumns = m_pController->getColumns(); + m_xFieldExpression->fillColumns(m_xColumns); +} + +void OGroupsSortingDialog::displayGroup(const uno::Reference<report::XGroup>& _xGroup) +{ + m_xHeaderLst->set_active(_xGroup->getHeaderOn() ? 0 : 1 ); + m_xFooterLst->set_active(_xGroup->getFooterOn() ? 0 : 1 ); + sal_Int32 nDataType = getColumnDataType(_xGroup->getExpression()); + + // first clear whole group on list + while (m_xGroupOnLst->get_count() > 1 ) + { + m_xGroupOnLst->remove(1); + } + + switch(nDataType) + { + case sdbc::DataType::LONGVARCHAR: + case sdbc::DataType::VARCHAR: + case sdbc::DataType::CHAR: + m_xGroupOnLst->append(OUString::number(report::GroupOn::PREFIX_CHARACTERS), RptResId(STR_RPT_PREFIXCHARS)); + break; + case sdbc::DataType::DATE: + case sdbc::DataType::TIME: + case sdbc::DataType::TIMESTAMP: + { + const TranslateId aIds[] = { STR_RPT_YEAR, STR_RPT_QUARTER,STR_RPT_MONTH,STR_RPT_WEEK,STR_RPT_DAY,STR_RPT_HOUR,STR_RPT_MINUTE }; + for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i) + { + m_xGroupOnLst->append(OUString::number(i+2), RptResId(aIds[i])); + } + } + break; + default: + m_xGroupOnLst->append(OUString::number(report::GroupOn::INTERVAL), RptResId(STR_RPT_INTERVAL)); + break; + } + sal_Int32 nPos = 0; + switch(_xGroup->getGroupOn()) + { + case report::GroupOn::DEFAULT: + nPos = 0; + break; + case report::GroupOn::PREFIX_CHARACTERS: + nPos = 1; + break; + case report::GroupOn::YEAR: + nPos = 1; + break; + case report::GroupOn::QUARTAL: + nPos = 2; + break; + case report::GroupOn::MONTH: + nPos = 3; + break; + case report::GroupOn::WEEK: + nPos = 4; + break; + case report::GroupOn::DAY: + nPos = 5; + break; + case report::GroupOn::HOUR: + nPos = 6; + break; + case report::GroupOn::MINUTE: + nPos = 7; + break; + case report::GroupOn::INTERVAL: + nPos = 1; + break; + default: + nPos = 0; + } + m_xGroupOnLst->set_active(nPos); + m_xGroupIntervalEd->set_value(_xGroup->getGroupInterval()); + m_xGroupIntervalEd->save_value(); + m_xGroupIntervalEd->set_sensitive( nPos != 0 ); + m_xKeepTogetherLst->set_active(_xGroup->getKeepTogether()); + m_xOrderLst->set_active(_xGroup->getSortAscending() ? 0 : 1); + + weld::ComboBox* pControls[] = { m_xHeaderLst.get(), m_xFooterLst.get(), m_xGroupOnLst.get(), + m_xKeepTogetherLst.get(), m_xOrderLst.get() }; + for (weld::ComboBox* pControl : pControls) + pControl->save_value(); + + bool bReadOnly = !m_pController->isEditable(); + for (weld::ComboBox* pControl : pControls) + pControl->set_sensitive(!bReadOnly); + m_xGroupIntervalEd->set_editable(!bReadOnly); +} + +void OGroupsSortingDialog::checkButtons(sal_Int32 _nRow) +{ + sal_Int32 nGroupCount = m_xGroups->getCount(); + sal_Int32 nRowCount = m_xFieldExpression->GetRowCount(); + bool bEnabled = nGroupCount > 1; + + if (bEnabled && _nRow > 0 ) + { + m_xToolBox->set_item_sensitive("up", true); + } + else + { + m_xToolBox->set_item_sensitive("up", false); + } + if (bEnabled && _nRow < (nRowCount - 1) ) + { + m_xToolBox->set_item_sensitive("down", true); + } + else + { + m_xToolBox->set_item_sensitive("down", false); + } + + sal_Int32 nGroupPos = m_xFieldExpression->getGroupPosition(_nRow); + if ( nGroupPos != NO_GROUP ) + { + bool bEnableDelete = nGroupCount > 0; + m_xToolBox->set_item_sensitive("delete", bEnableDelete); + } + else + { + m_xToolBox->set_item_sensitive("delete", false); + } +} + +} // rptui + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/Navigator.cxx b/reportdesign/source/ui/dlg/Navigator.cxx new file mode 100644 index 000000000..e05c2a54b --- /dev/null +++ b/reportdesign/source/ui/dlg/Navigator.cxx @@ -0,0 +1,836 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <Navigator.hxx> + +#include <strings.hxx> +#include <bitmaps.hlst> +#include <ReportController.hxx> +#include <UITools.hxx> +#include <reportformula.hxx> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/report/XFixedText.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <com/sun/star/report/XFormattedField.hpp> +#include <com/sun/star/report/XImageControl.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <helpids.h> +#include <strings.hrc> +#include <rptui_slotid.hrc> +#include <comphelper/propmultiplex.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/containermultiplexer.hxx> +#include <cppuhelper/basemutex.hxx> +#include <comphelper/SelectionMultiplex.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <vcl/commandevent.hxx> +#include <ReportVisitor.hxx> +#include <core_resource.hxx> +#include <rtl/ref.hxx> +#include <svx/svxids.hrc> + +#include <memory> +#include <string_view> + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace utl; +using namespace ::comphelper; + +static OUString lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement) +{ + OUString sId; + uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY); + if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() ) + sId = RID_SVXBMP_FM_FIXEDTEXT; + else if ( xFixedLine.is() ) + sId = xFixedLine->getOrientation() ? OUString(RID_SVXBMP_INSERT_VFIXEDLINE) : OUString(RID_SVXBMP_INSERT_HFIXEDLINE); + else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() ) + sId = RID_SVXBMP_FM_EDIT; + else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() ) + sId = RID_SVXBMP_FM_IMAGECONTROL; + else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() ) + sId = RID_SVXBMP_DRAWTBX_CS_BASIC; + return sId; +} + +static OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement) +{ + OSL_ENSURE(_xElement.is(),"Found report element which is NULL!"); + OUString sTempName; + _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName; + OUStringBuffer sName(sTempName); + uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY); + uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY); + if ( xFixedText.is() ) + { + sName.append(" : "); + sName.append(xFixedText->getLabel()); + } + else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) ) + { + ReportFormula aFormula( xReportModel->getDataField() ); + if ( aFormula.isValid() ) + { + sName.append(" : "); + sName.append( aFormula.getUndecoratedContent() ); + } + } + return sName.makeStringAndClear(); +} + +namespace { + +class NavigatorTree : public ::cppu::BaseMutex + , public reportdesign::ITraverseReport + , public comphelper::OSelectionChangeListener + , public ::comphelper::OPropertyChangeListener +{ + class UserData; + friend class UserData; + class UserData : public ::cppu::BaseMutex + ,public ::comphelper::OPropertyChangeListener + ,public ::comphelper::OContainerListener + { + uno::Reference< uno::XInterface > m_xContent; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pListener; + ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener; + NavigatorTree* m_pTree; + public: + UserData(NavigatorTree* pTree, const uno::Reference<uno::XInterface>& xContent); + virtual ~UserData() override; + + const uno::Reference< uno::XInterface >& getContent() const { return m_xContent; } + void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; } + + protected: + // OPropertyChangeListener + virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override; + + // OContainerListener + virtual void _elementInserted( const container::ContainerEvent& _rEvent ) override; + virtual void _elementRemoved( const container::ContainerEvent& Event ) override; + virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) override; + virtual void _disposing(const lang::EventObject& _rSource) override; + }; + + std::unique_ptr<weld::TreeView> m_xTreeView; + OReportController& m_rController; + std::unique_ptr<weld::TreeIter> m_xMasterReport; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; + ::rtl::Reference< comphelper::OSelectionChangeMultiplexer> m_pSelectionListener; + + void insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition, const UserData* pData, weld::TreeIter& rRet); + + void traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition = -1); + void traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent); + +protected: + // OSelectionChangeListener + virtual void _disposing(const lang::EventObject& _rSource) override; + + // OPropertyChangeListener + virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override; + + // OContainerListener Helper + void _elementInserted( const container::ContainerEvent& _rEvent ); + void _elementRemoved( const container::ContainerEvent& Event ); + void _elementReplaced( const container::ContainerEvent& _rEvent ); + +public: + NavigatorTree(std::unique_ptr<weld::TreeView>, OReportController& rController); + virtual ~NavigatorTree() override; + + DECL_LINK(OnEntrySelDesel, weld::TreeView&, void); + DECL_LINK(CommandHdl, const CommandEvent&, bool); + + virtual void _selectionChanged( const lang::EventObject& aEvent ) override; + + // ITraverseReport + virtual void traverseReport(const uno::Reference< report::XReportDefinition>& xReport) override; + virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions) override; + virtual void traverseReportHeader(const uno::Reference< report::XSection>& xSection) override; + virtual void traverseReportFooter(const uno::Reference< report::XSection>& xSection) override; + virtual void traversePageHeader(const uno::Reference< report::XSection>& xSection) override; + virtual void traversePageFooter(const uno::Reference< report::XSection>& xSection) override; + + virtual void traverseGroups(const uno::Reference< report::XGroups>& xGroups) override; + virtual void traverseGroup(const uno::Reference< report::XGroup>& xGroup) override; + virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions) override; + virtual void traverseGroupHeader(const uno::Reference< report::XSection>& xSection) override; + virtual void traverseGroupFooter(const uno::Reference< report::XSection>& xSection) override; + + virtual void traverseDetail(const uno::Reference< report::XSection>& xSection) override; + + bool find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rIter); + void removeEntry(const weld::TreeIter& rEntry, bool bRemove = true); + + void grab_focus() { m_xTreeView->grab_focus(); } + + void set_text(const weld::TreeIter& rIter, const OUString& rStr) + { + m_xTreeView->set_text(rIter, rStr); + } + + void expand_row(const weld::TreeIter& rIter) + { + m_xTreeView->expand_row(rIter); + } + + std::unique_ptr<weld::TreeIter> make_iterator() const + { + return m_xTreeView->make_iterator(); + } + + int iter_n_children(const weld::TreeIter& rIter) const + { + return m_xTreeView->iter_n_children(rIter); + } +}; + +} + +NavigatorTree::NavigatorTree(std::unique_ptr<weld::TreeView> xTreeView, OReportController& rController) + : OPropertyChangeListener(m_aMutex) + , m_xTreeView(std::move(xTreeView)) + , m_rController(rController) +{ + m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 25, m_xTreeView->get_height_rows(18)); + + m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition()); + m_pReportListener->addProperty(PROPERTY_PAGEHEADERON); + m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON); + m_pReportListener->addProperty(PROPERTY_REPORTHEADERON); + m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON); + + m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController); + + m_xTreeView->set_help_id(HID_REPORT_NAVIGATOR_TREE); + + m_xTreeView->set_selection_mode(SelectionMode::Multiple); + + m_xTreeView->connect_changed(LINK(this, NavigatorTree, OnEntrySelDesel)); + m_xTreeView->connect_popup_menu(LINK(this, NavigatorTree, CommandHdl)); +} + +NavigatorTree::~NavigatorTree() +{ + m_xTreeView->all_foreach([this](weld::TreeIter& rIter) { + UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter)); + delete pData; + return false; + }); + m_pSelectionListener->dispose(); + m_pReportListener->dispose(); +} + +namespace +{ + sal_uInt16 mapIdent(std::string_view rIdent) + { + if (rIdent == "sorting") + return SID_SORTINGANDGROUPING; + else if (rIdent == "page") + return SID_PAGEHEADERFOOTER; + else if (rIdent == "report") + return SID_REPORTHEADERFOOTER; + else if (rIdent == "function") + return SID_RPT_NEW_FUNCTION; + else if (rIdent == "properties") + return SID_SHOW_PROPERTYBROWSER; + else if (rIdent == "delete") + return SID_DELETE; + return 0; + } +} + +IMPL_LINK(NavigatorTree, CommandHdl, const CommandEvent&, rEvt, bool) +{ + bool bHandled = false; + switch( rEvt.GetCommand()) + { + case CommandEventId::ContextMenu: + { + UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_selected_id()); + if (!pData) + break; + + uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY); + uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY); + uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY); + bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() || + uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is()); + + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), "modules/dbreport/ui/navigatormenu.ui")); + std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu")); + + const OString aIds[] = { "sorting", "page", "report", "function", "properties", "delete" }; + for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i) + { + sal_uInt16 nSId = mapIdent(aIds[i]); + + if (aIds[i] == "page" || aIds[i] == "report" || aIds[i] == "properties") + xContextMenu->set_active(aIds[i], m_rController.isCommandChecked(nSId)); + bool bEnabled = m_rController.isCommandEnabled(nSId); + if (nSId == SID_RPT_NEW_FUNCTION) + xContextMenu->set_sensitive(aIds[i], m_rController.isEditable() && (xSupplier.is() || xFunctions.is())); + // special condition, check for function and group + else if (nSId == SID_DELETE) + xContextMenu->set_sensitive(aIds[i], bDeleteAllowed); + else + xContextMenu->set_sensitive(aIds[i], bEnabled); + } + + // the point that was clicked on + ::Point aWhere(rEvt.GetMousePosPixel()); + OString sCurItemIdent = xContextMenu->popup_at_rect(m_xTreeView.get(), tools::Rectangle(aWhere, Size(1,1))); + if (!sCurItemIdent.isEmpty()) + { + sal_uInt16 nId = mapIdent(sCurItemIdent); + uno::Sequence< beans::PropertyValue> aArgs; + if ( nId == SID_RPT_NEW_FUNCTION ) + { + aArgs.realloc(1); + aArgs.getArray()[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions()); + } + else if ( nId == SID_DELETE ) + { + if ( xGroup.is() ) + nId = SID_GROUP_REMOVE; + aArgs = { comphelper::makePropertyValue(PROPERTY_GROUP, pData->getContent()) }; + } + m_rController.executeUnChecked(nId,aArgs); + } + + bHandled = true; + } + break; + default: break; + } + + return bHandled; +} + +IMPL_LINK_NOARG(NavigatorTree, OnEntrySelDesel, weld::TreeView&, void) +{ + if ( !m_pSelectionListener->locked() ) + { + m_pSelectionListener->lock(); + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + bool bEntry = m_xTreeView->get_cursor(xEntry.get()); + uno::Any aSelection; + if (bEntry && m_xTreeView->is_selected(*xEntry)) + aSelection <<= weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry))->getContent(); + m_rController.select(aSelection); + m_pSelectionListener->unlock(); + } +} + +void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent ) +{ + m_pSelectionListener->lock(); + uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY); + uno::Any aSec = xSelectionSupplier->getSelection(); + uno::Sequence< uno::Reference< report::XReportComponent > > aSelection; + aSec >>= aSelection; + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + if ( !aSelection.hasElements() ) + { + uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY); + bool bEntry = find(xSelection, *xEntry); + if (bEntry && !m_xTreeView->is_selected(*xEntry)) + { + m_xTreeView->select(*xEntry); + m_xTreeView->set_cursor(*xEntry); + } + else if (!bEntry) + m_xTreeView->unselect_all(); + } + else + { + for (const uno::Reference<report::XReportComponent>& rElem : std::as_const(aSelection)) + { + bool bEntry = find(rElem, *xEntry); + if (bEntry && !m_xTreeView->is_selected(*xEntry)) + { + m_xTreeView->select(*xEntry); + m_xTreeView->set_cursor(*xEntry); + } + } + } + m_pSelectionListener->unlock(); +} + +void NavigatorTree::insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId, + int nPosition, const UserData* pData, weld::TreeIter& rRet) +{ + OUString sId = pData ? weld::toId(pData) : OUString(); + m_xTreeView->insert(pParent, nPosition, &rName, &sId, nullptr, nullptr, false, &rRet); + if (!rImageId.isEmpty()) + m_xTreeView->set_image(rRet, rImageId); +} + +void NavigatorTree::traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition) +{ + std::unique_ptr<weld::TreeIter> xSectionIter = m_xTreeView->make_iterator(); + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(xSection->getName(), pParent, rImageId, nPosition, new UserData(this, xSection), *xSectionIter); + const sal_Int32 nCount = xSection->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference< report::XReportComponent> xElement(xSection->getByIndex(i), uno::UNO_QUERY_THROW); + insertEntry(lcl_getName(xElement), xSectionIter.get(), lcl_getImageId(xElement), -1, new UserData(this, xElement), *xScratch); + uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY); + if ( xSubReport.is() ) + { + bool bMasterReport = find(xSection->getReportDefinition(), *xScratch); + if (!bMasterReport) + m_xMasterReport.reset(); + else + m_xMasterReport = m_xTreeView->make_iterator(xScratch.get()); + reportdesign::OReportVisitor aSubVisitor(this); + aSubVisitor.start(xSubReport); + } + } +} + +void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent) +{ + std::unique_ptr<weld::TreeIter> xFunctionIter = m_xTreeView->make_iterator(); + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(RptResId(RID_STR_FUNCTIONS), pParent, RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this, xFunctions), *xFunctionIter); + const sal_Int32 nCount = xFunctions->getCount(); + for (sal_Int32 i = 0; i< nCount; ++i) + { + uno::Reference< report::XFunction> xElement(xFunctions->getByIndex(i),uno::UNO_QUERY); + insertEntry(xElement->getName(), xFunctionIter.get(), RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this,xElement), *xScratch); + } +} + +bool NavigatorTree::find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rRet) +{ + bool bRet = false; + if (xContent.is()) + { + m_xTreeView->all_foreach([this, &xContent, &bRet, &rRet](weld::TreeIter& rIter) { + UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter)); + if (pData->getContent() == xContent) + { + m_xTreeView->copy_iterator(rIter, rRet); + bRet = true; + return true; + } + return false; + }); + } + return bRet; +} + +// ITraverseReport + +void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& xReport) +{ + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(xReport->getName(), m_xMasterReport.get(), RID_SVXBMP_SELECT_REPORT,-1, new UserData(this, xReport), *xScratch); +} + +void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xFunctions->getParent(), *xReport); + if (!bReport) + xReport.reset(); + traverseFunctions(xFunctions, xReport.get()); +} + +void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getReportDefinition(), *xReport); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER); +} + +void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getReportDefinition(), *xReport); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER); +} + +void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getReportDefinition(), *xReport); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER); +} + +void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getReportDefinition(), *xReport); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER); +} + +void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& xGroups) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xGroups->getReportDefinition(), *xReport); + if (!bReport) + xReport.reset(); + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(RptResId(RID_STR_GROUPS), xReport.get(), RID_SVXBMP_SORTINGANDGROUPING, -1, new UserData(this, xGroups), *xScratch); +} + +void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& xGroup) +{ + uno::Reference< report::XGroups> xGroups(xGroup->getParent(),uno::UNO_QUERY); + std::unique_ptr<weld::TreeIter> xGroupsIter = m_xTreeView->make_iterator(); + bool bGroups = find(xGroups, *xGroupsIter); + OSL_ENSURE(bGroups, "No Groups inserted so far. Why!"); + if (!bGroups) + xGroupsIter.reset(); + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(xGroup->getExpression(), xGroupsIter.get(), RID_SVXBMP_GROUP, rptui::getPositionInIndexAccess(xGroups,xGroup), new UserData(this,xGroup), *xScratch); +} + +void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xFunctions->getParent(), *xReport); + if (!bReport) + xReport.reset(); + traverseFunctions(xFunctions, xReport.get()); +} + +void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getGroup(), *xReport); + OSL_ENSURE(bReport, "No group found"); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPHEADER, 1); +} + +void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& xSection) +{ + std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator(); + bool bReport = find(xSection->getGroup(), *xReport); + OSL_ENSURE(bReport, "No group found"); + if (!bReport) + xReport.reset(); + traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPFOOTER); +} + +void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& xSection) +{ + uno::Reference< report::XReportDefinition> xReport = xSection->getReportDefinition(); + std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator(); + bool bParent = find(xReport, *xParent); + if (!bParent) + xParent.reset(); + traverseSection(xSection, xParent.get(), RID_SVXBMP_ICON_DETAIL); +} + +void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) +{ + uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY); + if ( !xReport.is() ) + return; + + bool bEnabled = false; + _rEvent.NewValue >>= bEnabled; + if ( !bEnabled ) + return; + + std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator(); + bool bParent = find(xReport, *xParent); + if (!bParent) + xParent.reset(); + if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON ) + { + sal_uLong nPos = xReport->getReportHeaderOn() ? 2 : 1; + traverseSection(xReport->getReportHeader(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos); + } + else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON ) + { + traverseSection(xReport->getPageHeader(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER,1); + } + else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON ) + traverseSection(xReport->getPageFooter(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER); + else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON ) + { + int nPos = -1; + if (xReport->getPageFooterOn() && xParent) + nPos = m_xTreeView->iter_n_children(*xParent) - 1; + traverseSection(xReport->getReportFooter(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos); + } +} + +void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent ) +{ + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + bool bEntry = find(_rEvent.Source, *xEntry); + if (!bEntry) + xEntry.reset(); + uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW); + OUString sName; + uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo(); + if ( xInfo.is() ) + { + if ( xInfo->hasPropertyByName(PROPERTY_NAME) ) + xProp->getPropertyValue(PROPERTY_NAME) >>= sName; + else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) ) + xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName; + } + uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY); + if ( xGroup.is() ) + { + reportdesign::OReportVisitor aSubVisitor(this); + aSubVisitor.start(xGroup); + } + else + { + uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY); + if ( xProp.is() ) + sName = lcl_getName(xProp); + std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator(); + insertEntry(sName, xEntry.get(), (!xElement.is() ? OUString(RID_SVXBMP_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)), + -1, new UserData(this,xProp), *xScratch); + } + if (bEntry && !m_xTreeView->get_row_expanded(*xEntry)) + m_xTreeView->expand_row(*xEntry); +} + +void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent ) +{ + uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY); + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + bool bEntry = find(xProp, *xEntry); + OSL_ENSURE(bEntry,"NavigatorTree::_elementRemoved: No Entry found!"); + + if (bEntry) + { + removeEntry(*xEntry); + } +} + +void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent ) +{ + uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY); + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + bool bEntry = find(xProp, *xEntry); + if (bEntry) + { + UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry)); + xProp.set(_rEvent.Element,uno::UNO_QUERY); + pData->setContent(xProp); + OUString sName; + xProp->getPropertyValue(PROPERTY_NAME) >>= sName; + m_xTreeView->set_text(*xEntry, sName); + } +} + +void NavigatorTree::_disposing(const lang::EventObject& _rSource) +{ + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + if (find(_rSource.Source, *xEntry)) + removeEntry(*xEntry); +} + +void NavigatorTree::removeEntry(const weld::TreeIter& rEntry, bool bRemove) +{ + std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rEntry); + bool bChild = m_xTreeView->iter_children(*xChild); + while (bChild) + { + removeEntry(*xChild, false); + bChild = m_xTreeView->iter_next_sibling(*xChild); + } + delete weld::fromId<UserData*>(m_xTreeView->get_id(rEntry)); + if (bRemove) + m_xTreeView->remove(rEntry); +} + +NavigatorTree::UserData::UserData(NavigatorTree* pTree,const uno::Reference<uno::XInterface>& xContent) + : OPropertyChangeListener(m_aMutex) + , OContainerListener(m_aMutex) + , m_xContent(xContent) + , m_pTree(pTree) +{ + uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY); + if ( xProp.is() ) + { + uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo(); + if ( xInfo.is() ) + { + m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp); + if ( xInfo->hasPropertyByName(PROPERTY_NAME) ) + m_pListener->addProperty(PROPERTY_NAME); + else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) ) + m_pListener->addProperty(PROPERTY_EXPRESSION); + if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) ) + m_pListener->addProperty(PROPERTY_DATAFIELD); + if ( xInfo->hasPropertyByName(PROPERTY_LABEL) ) + m_pListener->addProperty(PROPERTY_LABEL); + if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) ) + m_pListener->addProperty(PROPERTY_HEADERON); + if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) ) + m_pListener->addProperty(PROPERTY_FOOTERON); + } + } + uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY); + if ( xContainer.is() ) + { + m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer); + } +} + +NavigatorTree::UserData::~UserData() +{ + if ( m_pContainerListener.is() ) + m_pContainerListener->dispose(); + if ( m_pListener.is() ) + m_pListener->dispose(); +} + +// OPropertyChangeListener +void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) +{ + std::unique_ptr<weld::TreeIter> xEntry = m_pTree->make_iterator(); + bool bEntry = m_pTree->find(_rEvent.Source, *xEntry); + OSL_ENSURE(bEntry,"No entry could be found! Why not!"); + if (!bEntry) + return; + const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName); + try + { + if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName ) + { + sal_Int32 nPos = 1; + uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY); + ::std::function<bool(OGroupHelper *)> pIsOn = ::std::mem_fn(&OGroupHelper::getHeaderOn); + ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader); + if ( bFooterOn ) + { + pIsOn = ::std::mem_fn(&OGroupHelper::getFooterOn); + pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter); + nPos = m_pTree->iter_n_children(*xEntry) - 1; + } + + OGroupHelper aGroupHelper(xGroup); + if ( pIsOn(&aGroupHelper) ) + { + if ( bFooterOn ) + ++nPos; + m_pTree->traverseSection(pMemFunSection(&aGroupHelper),xEntry.get(),bFooterOn ? OUString(RID_SVXBMP_GROUPFOOTER) : OUString(RID_SVXBMP_GROUPHEADER),nPos); + } + } + else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName) + { + OUString sNewName; + _rEvent.NewValue >>= sNewName; + m_pTree->set_text(*xEntry, sNewName); + } + else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName ) + { + uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY); + m_pTree->set_text(*xEntry, lcl_getName(xProp)); + } + } + catch(const uno::Exception &) + {} +} + +void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent ) +{ + m_pTree->_elementInserted( _rEvent ); +} + +void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent ) +{ + m_pTree->_elementRemoved( _rEvent ); +} + +void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent ) +{ + m_pTree->_elementReplaced( _rEvent ); +} + +void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource) +{ + m_pTree->_disposing( _rSource ); +} + +class ONavigatorImpl +{ +public: + ONavigatorImpl(OReportController& rController, weld::Builder& rBuilder); + ONavigatorImpl(const ONavigatorImpl&) = delete; + ONavigatorImpl& operator=(const ONavigatorImpl&) = delete; + + uno::Reference< report::XReportDefinition> m_xReport; + std::unique_ptr<NavigatorTree> m_xNavigatorTree; +}; + +ONavigatorImpl::ONavigatorImpl(OReportController& rController, weld::Builder& rBuilder) + : m_xReport(rController.getReportDefinition()) + , m_xNavigatorTree(std::make_unique<NavigatorTree>(rBuilder.weld_tree_view("treeview"), rController)) +{ + reportdesign::OReportVisitor aVisitor(m_xNavigatorTree.get()); + aVisitor.start(m_xReport); + std::unique_ptr<weld::TreeIter> xScratch = m_xNavigatorTree->make_iterator(); + if (m_xNavigatorTree->find(m_xReport, *xScratch)) + m_xNavigatorTree->expand_row(*xScratch); + lang::EventObject aEvent(rController); + m_xNavigatorTree->_selectionChanged(aEvent); +} + +ONavigator::ONavigator(weld::Window* pParent, OReportController& rController) + : GenericDialogController(pParent, "modules/dbreport/ui/floatingnavigator.ui", "FloatingNavigator") +{ + m_pImpl.reset(new ONavigatorImpl(rController, *m_xBuilder)); + m_pImpl->m_xNavigatorTree->grab_focus(); + + m_xDialog->connect_container_focus_changed(LINK(this, ONavigator, FocusChangeHdl)); +} + +ONavigator::~ONavigator() +{ +} + +IMPL_LINK_NOARG(ONavigator, FocusChangeHdl, weld::Container&, void) +{ + if (m_xDialog->has_toplevel_focus()) + m_pImpl->m_xNavigatorTree->grab_focus(); +} + +} // rptui + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/PageNumber.cxx b/reportdesign/source/ui/dlg/PageNumber.cxx new file mode 100644 index 000000000..2d18077ab --- /dev/null +++ b/reportdesign/source/ui/dlg/PageNumber.cxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <PageNumber.hxx> +#include <rptui_slotid.hrc> +#include <RptDef.hxx> + +#include <strings.hxx> +#include <ReportController.hxx> +#include <comphelper/propertysequence.hxx> + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace ::comphelper; + + + +OPageNumberDialog::OPageNumberDialog(weld::Window* pParent, + const uno::Reference< report::XReportDefinition >& _xHoldAlive, + OReportController* _pController) + : GenericDialogController(pParent, "modules/dbreport/ui/pagenumberdialog.ui", "PageNumberDialog") + , m_pController(_pController) + , m_xHoldAlive(_xHoldAlive) + , m_xPageN(m_xBuilder->weld_radio_button("pagen")) + , m_xPageNofM(m_xBuilder->weld_radio_button("pagenofm")) + , m_xTopPage(m_xBuilder->weld_radio_button("toppage")) + , m_xBottomPage(m_xBuilder->weld_radio_button("bottompage")) + , m_xAlignmentLst(m_xBuilder->weld_combo_box("alignment")) + , m_xShowNumberOnFirstPage(m_xBuilder->weld_check_button("shownumberonfirstpage")) +{ + m_xShowNumberOnFirstPage->hide(); +} + +OPageNumberDialog::~OPageNumberDialog() +{ +} + +short OPageNumberDialog::run() +{ + short nRet = GenericDialogController::run(); + if (nRet == RET_OK) + { + try + { + sal_Int32 nControlMaxSize = 3000; + sal_Int32 nPosX = 0; + sal_Int32 nPos2X = 0; + awt::Size aRptSize = getStyleProperty<awt::Size>(m_xHoldAlive,PROPERTY_PAPERSIZE); + switch (m_xAlignmentLst->get_active()) + { + case 0: // left + nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN); + break; + case 1: // middle + nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN) + (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN) - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize) / 2; + break; + case 2: // right + nPosX = (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize); + break; + case 3: // inner + case 4: // outer + nPosX = getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_LEFTMARGIN); + nPos2X = (aRptSize.Width - getStyleProperty<sal_Int32>(m_xHoldAlive,PROPERTY_RIGHTMARGIN) - nControlMaxSize); + break; + default: + break; + } + if (m_xAlignmentLst->get_active() > 2) + nPosX = nPos2X; + + uno::Sequence<beans::PropertyValue> aValues( comphelper::InitPropertySequence({ + { PROPERTY_POSITION, uno::Any(awt::Point(nPosX,0)) }, + { PROPERTY_PAGEHEADERON, uno::Any(m_xTopPage->get_active()) }, + { PROPERTY_STATE, uno::Any(m_xPageNofM->get_active()) } + })); + + m_pController->executeChecked(SID_INSERT_FLD_PGNUMBER,aValues); + } + catch(uno::Exception&) + { + } + } + return nRet; +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/dlg/dlgpage.cxx b/reportdesign/source/ui/dlg/dlgpage.cxx new file mode 100644 index 000000000..c4fb41c46 --- /dev/null +++ b/reportdesign/source/ui/dlg/dlgpage.cxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <svx/dialogs.hrc> +#include <sfx2/sfxdlg.hxx> +#include <dlgpage.hxx> +#include <svl/cjkoptions.hxx> +#include <osl/diagnose.h> + +namespace rptui +{ +/************************************************************************* +|* +|* constructor of the tab dialogs: Add the page to the dialog +|* +\************************************************************************/ + +ORptPageDialog::ORptPageDialog(weld::Window* pParent, const SfxItemSet* pAttr, const OUString &rDialog) + : SfxTabDialogController(pParent, "modules/dbreport/ui/" + + rDialog.toAsciiLowerCase() + ".ui", rDialog.toUtf8(), pAttr) +{ + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + if (rDialog == "BackgroundDialog") + { + AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr ); + } + else if (rDialog == "PageDialog") + { + AddTabPage("page", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PAGE ), nullptr ); + AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr ); + } + else if (rDialog == "CharDialog") + { + AddTabPage("font", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), nullptr ); + AddTabPage("fonteffects", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), nullptr ); + AddTabPage("position", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_POSITION ), nullptr ); + AddTabPage("asianlayout", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_TWOLINES ), nullptr ); + AddTabPage("background", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr ); + AddTabPage("alignment", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGNMENT ), nullptr ); + } + else + OSL_FAIL("Unknown page id"); + + if ( !SvtCJKOptions::IsDoubleLinesEnabled() ) + RemoveTabPage("asianlayout"); +} + +void ORptPageDialog::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + if (rId == "background") + { + rPage.PageCreated(aSet); + } +} + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/AddField.hxx b/reportdesign/source/ui/inc/AddField.hxx new file mode 100644 index 000000000..5a388d49a --- /dev/null +++ b/reportdesign/source/ui/inc/AddField.hxx @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <comphelper/propmultiplex.hxx> +#include <comphelper/containermultiplexer.hxx> + +#include <svx/dataaccessdescriptor.hxx> +#include <svx/dbaexchange.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <vcl/weld.hxx> + +#include <rtl/ref.hxx> + +#include "ColumnInfo.hxx" + +namespace rptui +{ + +class OAddFieldWindow; + +class OAddFieldWindow : public weld::GenericDialogController + , public ::cppu::BaseMutex + , public ::comphelper::OPropertyChangeListener + , public ::comphelper::OContainerListener +{ + css::uno::Reference< css::lang::XComponent> m_xHoldAlive; + css::uno::Reference< css::container::XNameAccess> m_xColumns; + css::uno::Reference< css::beans::XPropertySet > m_xRowSet; + + std::unique_ptr<weld::Toolbar> m_xActions; + std::unique_ptr<weld::TreeView> m_xListBox; + std::unique_ptr<weld::Label> m_xHelpText; + + Link<OAddFieldWindow&,void> m_aCreateLink; + OUString m_aCommandName; + OUString m_sFilter; + sal_Int32 m_nCommandType; + bool m_bEscapeProcessing; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pChangeListener; + ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener; + ::rtl::Reference< svx::OMultiColumnTransferable > m_xHelper; + + std::vector<std::unique_ptr<ColumnInfo>> m_aListBoxData; + + DECL_LINK( OnDoubleClickHdl, weld::TreeView&, bool ); + DECL_LINK( OnSelectHdl, weld::TreeView&, void ); + DECL_LINK( DragBeginHdl, bool&, bool ); + DECL_LINK( OnSortAction, const OString&, void ); + DECL_LINK( FocusChangeHdl, weld::Container&, void ); + + void addToList(const css::uno::Sequence<OUString>& rEntries); + void addToList(const css::uno::Reference<css::container::XNameAccess>& i_xColumns); + + OAddFieldWindow(const OAddFieldWindow&) = delete; + void operator =(const OAddFieldWindow&) = delete; +public: + OAddFieldWindow(weld::Window* pParent, + const css::uno::Reference< css::beans::XPropertySet >& xRowSet); + + virtual ~OAddFieldWindow() override; + + const OUString& GetCommand() const { return m_aCommandName; } + sal_Int32 GetCommandType() const { return m_nCommandType; } + void SetCreateHdl(const Link<OAddFieldWindow&,void>& _aCreateLink) { m_aCreateLink = _aCreateLink; } + + css::uno::Reference< css::sdbc::XConnection> getConnection() const; + + css::uno::Sequence< css::beans::PropertyValue > getSelectedFieldDescriptors(); + + /// Updates the current field list + void Update(); + + /** fills the descriptor with the column name, column object, command and command type + * + * \param rSelected the currently selected + * \param rDescriptor the descriptor will be filled + */ + void fillDescriptor(const weld::TreeIter& rSelected, svx::ODataAccessDescriptor& rDescriptor); + +private: + // FmXChangeListener + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& evt) override; + // OContainerListener + virtual void _elementInserted( const css::container::ContainerEvent& _rEvent ) override; + virtual void _elementRemoved( const css::container::ContainerEvent& _rEvent ) override; + virtual void _elementReplaced( const css::container::ContainerEvent& _rEvent ) override; +}; + +} // rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ADDFIELD_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ColorChanger.hxx b/reportdesign/source/ui/inc/ColorChanger.hxx new file mode 100644 index 000000000..34a336b01 --- /dev/null +++ b/reportdesign/source/ui/inc/ColorChanger.hxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX + +#include <vcl/outdev.hxx> + +namespace rptui +{ + + //= ColorChanger + + class ColorChanger final + { + VclPtr<OutputDevice> m_pDev; + + public: + ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor ) + :m_pDev( _pDev ) + { + m_pDev->Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR ); + m_pDev->SetLineColor( _rNewLineColor ); + m_pDev->SetFillColor( _rNewFillColor ); + } + + ~ColorChanger() + { + m_pDev->Pop(); + } + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORCHANGER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ColorListener.hxx b/reportdesign/source/ui/inc/ColorListener.hxx new file mode 100644 index 000000000..0f8a89aca --- /dev/null +++ b/reportdesign/source/ui/inc/ColorListener.hxx @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX + +#include <vcl/window.hxx> +#include <svtools/colorcfg.hxx> +#include <svtools/extcolorcfg.hxx> +#include <tools/link.hxx> + +namespace rptui +{ + class OColorListener : public vcl::Window, public SfxListener + { + OColorListener(const OColorListener&) = delete; + void operator =(const OColorListener&) = delete; + protected: + Link<OColorListener&,void> m_aCollapsedLink; + svtools::ColorConfig m_aColorConfig; + svtools::ExtendedColorConfig m_aExtendedColorConfig; + OUString m_sColorEntry; + Color m_nColor; + Color m_nTextBoundaries; + bool m_bCollapsed; + bool m_bMarked; + + virtual void ImplInitSettings() = 0; + protected: + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + public: + OColorListener(vcl::Window* _pParent,const OUString& _sColorEntry); + virtual ~OColorListener() override; + virtual void dispose() override; + + // SfxListener + virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override; + + /** set the marker as marked or not marked + @param _bMark set the new state of the marker + */ + void setMarked(bool _bMark); + + /** returns if the section is marked + */ + bool isMarked() const { return m_bMarked; } + + void setCollapsedHdl(const Link<OColorListener&,void>& _aLink ){ m_aCollapsedLink = _aLink; } + bool isCollapsed() const { return m_bCollapsed; } + + /** collapse or expand + * + * \param _bCollapsed + */ + virtual void setCollapsed(bool _bCollapsed); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLORLISTENER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ColumnInfo.hxx b/reportdesign/source/ui/inc/ColumnInfo.hxx new file mode 100644 index 000000000..65062f9dc --- /dev/null +++ b/reportdesign/source/ui/inc/ColumnInfo.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX + +#include <rtl/ustring.hxx> + +namespace rptui +{ + struct ColumnInfo + { + OUString sColumnName; + OUString sLabel; + ColumnInfo(const OUString& i_sColumnName,const OUString& i_sLabel) + : sColumnName(i_sColumnName) + , sLabel(i_sLabel) + { + } + ColumnInfo(const OUString& i_sColumnName) + : sColumnName(i_sColumnName) + { + } + }; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_COLUMNINFO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/CondFormat.hxx b/reportdesign/source/ui/inc/CondFormat.hxx new file mode 100644 index 000000000..9b648be10 --- /dev/null +++ b/reportdesign/source/ui/inc/CondFormat.hxx @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX + +#include <com/sun/star/report/XReportControlModel.hpp> +#include <vcl/weld.hxx> +#include <vector> + +namespace rptui +{ + + + constexpr size_t MAX_CONDITIONS = 3; + + class OReportController; + class Condition; + + + //= IConditionalFormatAction + + class SAL_NO_VTABLE IConditionalFormatAction + { + public: + virtual void addCondition( size_t _nAddAfterIndex ) = 0; + virtual void deleteCondition( size_t _nCondIndex ) = 0; + virtual void applyCommand( size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor ) = 0; + virtual void moveConditionUp( size_t _nCondIndex ) = 0; + virtual void moveConditionDown( size_t _nCondIndex ) = 0; + virtual OUString getDataField() const = 0; + + protected: + ~IConditionalFormatAction() {} + }; + + /************************************************************************* + |* + |* Conditional formatting dialog + |* + \************************************************************************/ + class ConditionalFormattingDialog : public weld::GenericDialogController + , public IConditionalFormatAction + { + typedef ::std::vector< std::unique_ptr<Condition> > Conditions; + + ::rptui::OReportController& m_rController; + css::uno::Reference< css::report::XReportControlModel > + m_xFormatConditions; + css::uno::Reference< css::report::XReportControlModel > + m_xCopy; + + bool m_bConstructed; + + std::unique_ptr<weld::ScrolledWindow> m_xScrollWindow; + std::unique_ptr<weld::Box> m_xConditionPlayground; + Conditions m_aConditions; + + public: + ConditionalFormattingDialog( + weld::Window* pParent, + const css::uno::Reference< css::report::XReportControlModel>& _xHoldAlive, + ::rptui::OReportController& _rController + ); + virtual ~ConditionalFormattingDialog() override; + // Dialog overridables + virtual short run() override; + + // IConditionalFormatAction overridables + virtual void addCondition( size_t _nAddAfterIndex ) override; + virtual void deleteCondition( size_t _nCondIndex ) override; + virtual void applyCommand( size_t _nCondIndex, sal_uInt16 _nCommandId, const ::Color& rColor ) override; + virtual void moveConditionUp( size_t _nCondIndex ) override; + virtual void moveConditionDown( size_t _nCondIndex ) override; + virtual OUString getDataField() const override; + + private: + DECL_LINK(OnScroll, weld::ScrolledWindow&, void); + + private: + /// returns the current number of conditions + size_t impl_getConditionCount() const { return m_aConditions.size(); } + + /** adds a condition + @param _nNewCondIndex + the index of the to-be-inserted condition + */ + void impl_addCondition_nothrow( size_t _nNewCondIndex ); + + /// deletes the condition with the given index + void impl_deleteCondition_nothrow( size_t _nCondIndex ); + + /// moves the condition with the given index one position + void impl_moveCondition_nothrow( size_t _nCondIndex, bool _bMoveUp ); + + /// does the dialog layouting + void impl_layoutAll(); + + /// called when the number of conditions has changed in any way + void impl_conditionCountChanged(); + + /// initializes the conditions from m_xCopy + void impl_initializeConditions(); + + /// tells all our Condition instances their new index + void impl_updateConditionIndicies(); + + /// returns the number of the condition which has the (child path) focus + size_t impl_getFocusedConditionIndex( sal_Int32 _nFallBackIfNone ) const; + + /// returns the index of the first visible condition + size_t impl_getFirstVisibleConditionIndex() const; + + /// returns the index of the last visible condition + size_t impl_getLastVisibleConditionIndex() const; + + /// focuses the condition with the given index, making it visible if necessary + void impl_focusCondition( size_t _nCondIndex ); + + /// scrolls the condition with the given index to the top position + void impl_scrollTo( size_t _nTopCondIndex ); + + /// ensures the condition with the given index is visible + void impl_ensureConditionVisible( size_t _nCondIndex ); + + /// set the preferred height of the action_area + void impl_setPrefHeight(bool bFirst); + }; + + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_CONDFORMAT_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/DataProviderHandler.hxx b/reportdesign/source/ui/inc/DataProviderHandler.hxx new file mode 100644 index 000000000..05dd693a9 --- /dev/null +++ b/reportdesign/source/ui/inc/DataProviderHandler.hxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX + +#include <sal/config.h> + +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/inspection/XPropertyHandler.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> +#include <com/sun/star/chart2/data/XDatabaseDataProvider.hpp> +#include <com/sun/star/report/XReportComponent.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + + +namespace rptui +{ + + + class OPropertyInfoService; + + typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler + , css::lang::XServiceInfo> DataProviderHandler_Base; + + class DataProviderHandler: + private ::cppu::BaseMutex, + public DataProviderHandler_Base + { + public: + explicit DataProviderHandler(css::uno::Reference< css::uno::XComponentContext > const & context); + private: + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // css::lang::XComponent: + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override; + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override; + + // css::inspection::XPropertyHandler: + virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override; + virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override; + virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override; + virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override; + virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override; + virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override; + virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override; + virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override; + virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override; + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override; + virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override; + virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override; + virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override; + virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override; + + protected: + virtual ~DataProviderHandler() override {} + private: + DataProviderHandler(DataProviderHandler const &) = delete; + void operator =(DataProviderHandler const &) = delete; + + + bool impl_dialogLinkedFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const; + bool impl_dialogChartType_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const; + void impl_updateChartTitle_throw(const css::uno::Any& _aValue); + + // override WeakComponentImplHelperBase::disposing() + // This function is called upon disposing the component, + // if your component needs special work when it becomes + // disposed, do it here. + virtual void SAL_CALL disposing() override; + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee + css::uno::Reference< css::chart2::data::XDatabaseDataProvider> m_xDataProvider; /// inspectee + css::uno::Reference< css::uno::XInterface > m_xFormComponent; /// inspectee + css::uno::Reference< css::report::XReportComponent > m_xReportComponent; /// inspectee + css::uno::Reference< css::chart2::XChartDocument> m_xChartModel; + css::uno::Reference< css::beans::XPropertyChangeListener > m_xMasterDetails; + /// type converter, needed on various occasions + css::uno::Reference< css::script::XTypeConverter > m_xTypeConverter; + }; + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATAPROVIDERHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/DateTime.hxx b/reportdesign/source/ui/inc/DateTime.hxx new file mode 100644 index 000000000..df9fbfe87 --- /dev/null +++ b/reportdesign/source/ui/inc/DateTime.hxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX + +#include <vcl/weld.hxx> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/util/XNumberFormats.hpp> +#include <com/sun/star/lang/Locale.hpp> + +namespace rptui +{ +class OReportController; +/************************************************************************* +|* +|* Groups and Sorting dialog +|* +\************************************************************************/ +class ODateTimeDialog : public weld::GenericDialogController +{ + ::rptui::OReportController* m_pController; + css::uno::Reference< css::report::XSection> + m_xHoldAlive; + css::lang::Locale m_nLocale; + + std::unique_ptr<weld::CheckButton> m_xDate; + std::unique_ptr<weld::Label> m_xFTDateFormat; + std::unique_ptr<weld::ComboBox> m_xDateListBox; + std::unique_ptr<weld::CheckButton> m_xTime; + std::unique_ptr<weld::Label> m_xFTTimeFormat; + std::unique_ptr<weld::ComboBox> m_xTimeListBox; + std::unique_ptr<weld::Button> m_xPB_OK; + + /** returns the format string + * + * \param _nNumberFormatKey the number format key + * \param _xFormats + * \param _bTime + * \return + */ + OUString getFormatStringByKey(::sal_Int32 _nNumberFormatKey,const css::uno::Reference< css::util::XNumberFormats>& _xFormats,bool _bTime); + + /** returns the number format key + @param _nNumberFormatIndex the number format index @see css::i18n::NumberFormatIndex + */ + sal_Int32 getFormatKey(bool _bDate) const; + + DECL_LINK(CBClickHdl, weld::Toggleable&, void); + ODateTimeDialog(const ODateTimeDialog&) = delete; + void operator =(const ODateTimeDialog&) = delete; + + // fill methods + void InsertEntry(sal_Int16 _nNumberFormatId); +public: + ODateTimeDialog(weld::Window* pParent, + const css::uno::Reference< css::report::XSection>& _xHoldAlive, + ::rptui::OReportController* _pController); + virtual short run() override; +}; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DATETIME_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/DefaultInspection.hxx b/reportdesign/source/ui/inc/DefaultInspection.hxx new file mode 100644 index 000000000..3f32725c5 --- /dev/null +++ b/reportdesign/source/ui/inc/DefaultInspection.hxx @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX + +#include <com/sun/star/inspection/XObjectInspectorModel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <cppuhelper/implbase3.hxx> + + +namespace rptui +{ + + class OPropertyInfoService; + + //= DefaultComponentInspectorModel + + typedef ::cppu::WeakAggImplHelper3 < css::inspection::XObjectInspectorModel + , css::lang::XServiceInfo + , css::lang::XInitialization + > DefaultComponentInspectorModel_Base; + class DefaultComponentInspectorModel final : public DefaultComponentInspectorModel_Base + { + private: + ::osl::Mutex m_aMutex; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::inspection::XObjectInspectorModel > m_xComponent; /// delegatee + bool m_bConstructed; + bool m_bHasHelpSection; + bool m_bIsReadOnly; + sal_Int32 m_nMinHelpTextLines; + sal_Int32 m_nMaxHelpTextLines; + + DefaultComponentInspectorModel(const DefaultComponentInspectorModel&) = delete; + DefaultComponentInspectorModel& operator=(const DefaultComponentInspectorModel&) = delete; + + virtual ~DefaultComponentInspectorModel() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // XObjectInspectorModel + virtual css::uno::Sequence< css::uno::Any > SAL_CALL getHandlerFactories() override; + virtual sal_Bool SAL_CALL getHasHelpSection() override; + virtual ::sal_Int32 SAL_CALL getMinHelpTextLines() override; + virtual ::sal_Int32 SAL_CALL getMaxHelpTextLines() override; + virtual sal_Bool SAL_CALL getIsReadOnly() override; + virtual void SAL_CALL setIsReadOnly( sal_Bool _isreadonly ) override; + + virtual css::uno::Sequence< css::inspection::PropertyCategoryDescriptor > SAL_CALL describeCategories( ) override; + virtual ::sal_Int32 SAL_CALL getPropertyOrderIndex( const OUString& PropertyName ) override; + + // XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + // Service constructors + void createWithHelpSection( sal_Int32 _nMinHelpTextLines, sal_Int32 _nMaxHelpTextLines ); + + public: + DefaultComponentInspectorModel( const css::uno::Reference< css::uno::XComponentContext >& _rxContext); + }; + + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DEFAULTINSPECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/DesignView.hxx b/reportdesign/source/ui/inc/DesignView.hxx new file mode 100644 index 000000000..def0495c1 --- /dev/null +++ b/reportdesign/source/ui/inc/DesignView.hxx @@ -0,0 +1,257 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX + +#include <dbaccess/dataview.hxx> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/report/XReportComponent.hpp> +#include <tools/link.hxx> +#include <tools/gen.hxx> +#include <vcl/timer.hxx> +#include <vcl/idle.hxx> +#include <svl/SfxBroadcaster.hxx> +#include "ReportDefines.hxx" +#include <vcl/splitwin.hxx> +#include "MarkedSection.hxx" +#include "ScrollHelper.hxx" + +class KeyEvent; +class MouseEvent; +class Timer; +namespace vcl { class Window; } + +namespace rptui +{ + class OSectionView; + class OReportController; + class PropBrw; + class OAddFieldWindow; + class ONavigator; + + + class ODesignView : public dbaui::ODataView, public SfxBroadcaster, public IMarkedSection + { + private: + VclPtr<SplitWindow> m_aSplitWin; + + css::uno::Reference< css::uno::XInterface> m_xReportComponent; + OReportController& m_rReportController; + VclPtr<OScrollWindowHelper> m_aScrollWindow; + VclPtr<vcl::Window> m_pTaskPane; + VclPtr<PropBrw> m_pPropWin; + std::shared_ptr<OAddFieldWindow> m_xAddField; + OSectionView* m_pCurrentView; + std::shared_ptr<ONavigator> m_xReportExplorer; + Idle m_aMarkIdle; + DlgEdMode m_eMode; + SdrObjKind m_eActObj; + Size m_aGridSizeCoarse; + Size m_aGridSizeFine; + bool m_bDeleted; + + + DECL_LINK(MarkTimeout, Timer *, void); + DECL_LINK( SplitHdl, SplitWindow*, void ); + + void ImplInitSettings(); + + ODesignView(ODesignView const &) = delete; + void operator =(ODesignView const &) = delete; + protected: + // return the Rectangle where I can paint myself + virtual void resizeDocumentView(tools::Rectangle& rRect) override; + // return the Rectangle where I can paint myself + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + + public: + ODesignView(vcl::Window* pParent, + const css::uno::Reference< css::uno::XComponentContext >&, + OReportController& _rController); + virtual ~ODesignView() override; + virtual void dispose() override; + + // Window overrides + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual bool PreNotify( NotifyEvent& rNEvt ) override; + virtual void GetFocus() override; + + virtual void initialize() override; + + OReportController& getController() const { return m_rReportController; } + + void SetMode( DlgEdMode m_eMode ); + void SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType = OUString()); + SdrObjKind GetInsertObj() const { return m_eActObj;} + OUString const & GetInsertObjString() const; + DlgEdMode GetMode() const { return m_eMode; } + + /** cuts the current selection in this section + */ + void Cut(); + + /** copies the current selection in this section + */ + void Copy(); + + /** returns if paste is allowed + * + * \return <TRUE/> if paste is allowed + */ + bool IsPasteAllowed() const; + + /** paste a new control in this section + */ + void Paste(); + + /** Deletes the current selection in this section + * + */ + void Delete(); + + /** align all marked objects in all sections + */ + void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection); + + /** All objects will be marked. + */ + void SelectAll(const SdrObjKind _nObjectType); + + /// checks if a selection exists + bool HasSelection() const; + + void UpdatePropertyBrowserDelayed(OSectionView& _rView); + + sal_uInt16 getSectionCount() const; + + /** removes the section at the given position. + * + * \param _nPosition Zero based. + */ + void removeSection(sal_uInt16 _nPosition); + + /** adds a new section at position _nPosition. + If the section is <NULL/> nothing happens. + If the position is grater than the current elements, the section will be appended. + */ + void addSection(const css::uno::Reference< css::report::XSection >& _xSection + ,const OUString& _sColorEntry + ,sal_uInt16 _nPosition = USHRT_MAX); + + const Size& getGridSizeCoarse() const { return m_aGridSizeCoarse; } + const Size& getGridSizeFine() const { return m_aGridSizeFine; } + void setGridSnap(bool bOn); + void setDragStripes(bool bOn); + /** turns the grid on or off + * + * \param _bGridVisible + */ + void toggleGrid(bool _bGridVisible); + + void togglePropertyBrowser(bool _bToggleOn); + + bool isAddFieldVisible() const; + void toggleAddField(); + + bool isReportExplorerVisible() const; + void toggleReportExplorer(); + + /** shows or hides the ruler. + */ + void showRuler(bool _bShow); + + /** unmark all objects on the views. + */ + void unmarkAllObjects(); + + /** triggers the property browser with the section + @param _xReportComponent the report component + */ + void showProperties( const css::uno::Reference< css::uno::XInterface>& _xReportComponent); + css::uno::Any getCurrentlyShownProperty() const; + + /** returns the current section or the detail section if no section was selected previously + */ + css::uno::Reference< css::report::XSection > getCurrentSection() const; + + /** returns the current control report model or <NULL/> + */ + css::uno::Reference< css::report::XReportComponent > getCurrentControlModel() const; + + // IMarkedSection + OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override; + OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const; + virtual void markSection(const sal_uInt16 _nPos) override; + + /** fills the positions of all collapsed sections. + * + * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections. + */ + void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const; + + /** collapse all sections given by their position + * + * \param _aCollapsedSections The position of the sections which should be collapsed. + */ + void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections); + + OUString getCurrentPage() const; + void setCurrentPage(const OUString& _sLastActivePage); + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** set the section as marked or not marked + @param _pSectionView the section where to set the marked flag + @param _bMark the marked flag + */ + void setMarked(const css::uno::Reference< css::report::XSection>& _xSection,bool _bMark); + void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape,bool _bMark); + + /** returns if the view handles the event by itself + * + * \return <FALSE/> is the event is not handled by the view otherwise <TRUE/> + */ + bool isHandleEvent() const; + + sal_uInt32 getMarkedObjectCount() const; + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + + /** fills the vector with all selected control models + /param _rSelection The vector will be filled and will not be cleared before. + */ + void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const; + + /** calculates the zoom factor. + @param _eType which kind of zoom is needed + */ + sal_uInt16 getZoomFactor(SvxZoomType _eType) const; + }; + +} //rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DESIGNVIEW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/EndMarker.hxx b/reportdesign/source/ui/inc/EndMarker.hxx new file mode 100644 index 000000000..a48eb8106 --- /dev/null +++ b/reportdesign/source/ui/inc/EndMarker.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX + +#include "ColorListener.hxx" + +namespace rptui +{ + /** \class OEndMarker + * \brief Defines the right side of a graphical section. + */ + class OEndMarker : public OColorListener + { + OEndMarker(OEndMarker const &) = delete; + void operator =(OEndMarker const &) = delete; + protected: + virtual void ImplInitSettings() override; + public: + OEndMarker(vcl::Window* _pParent,const OUString& _sColorEntry); + virtual ~OEndMarker() override; + + // windows + virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override; + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_ENDMARKER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/FixedTextColor.hxx b/reportdesign/source/ui/inc/FixedTextColor.hxx new file mode 100644 index 000000000..fa76a52df --- /dev/null +++ b/reportdesign/source/ui/inc/FixedTextColor.hxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FIXEDTEXTCOLOR_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FIXEDTEXTCOLOR_HXX + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/report/XFixedText.hpp> +#include <tools/color.hxx> + +#include "IReportControllerObserver.hxx" + +namespace rptui +{ + class OReportController; + + class FixedTextColor : public IReportControllerObserver + { + const OReportController& m_rReportController; + + /// @throws css::uno::RuntimeException + css::uno::Reference< css::awt::XVclWindowPeer > getVclWindowPeer(const css::uno::Reference< css::report::XFixedText >& _xComponent); + /// @throws css::uno::RuntimeException + css::uno::Reference< css::awt::XControl > getXControl(const css::uno::Reference< css::report::XFixedText >& _xFixedText); + + static void setPropertyTextColor(const css::uno::Reference< css::awt::XVclWindowPeer >& _xVclWindowPeer, Color _nFormatKey); + + public: + FixedTextColor(const OReportController & _aObserver); + virtual ~FixedTextColor() override; + + void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) override; + void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override; + void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override; + + }; + +} // namespace rptui + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx new file mode 100644 index 000000000..455dfd396 --- /dev/null +++ b/reportdesign/source/ui/inc/FormattedFieldBeautifier.hxx @@ -0,0 +1,61 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMATTEDFIELDBEAUTIFIER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMATTEDFIELDBEAUTIFIER_HXX + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> +#include <com/sun/star/report/XReportComponent.hpp> +#include <tools/color.hxx> + +#include "IReportControllerObserver.hxx" + +namespace rptui +{ + class OReportController; + + class FormattedFieldBeautifier : public IReportControllerObserver + { + const OReportController& m_rReportController; + Color m_nTextColor; + + /// @throws css::uno::RuntimeException + css::uno::Reference< css::awt::XVclWindowPeer > getVclWindowPeer(const css::uno::Reference< css::report::XReportComponent >& _xComponent); + + void setPlaceholderText( const css::uno::Reference< css::uno::XInterface >& _rxComponent ); + void setPlaceholderText( const css::uno::Reference< css::awt::XVclWindowPeer >& _xVclWindowPeer, const OUString& _rText ); + + Color getTextColor(); + + public: + FormattedFieldBeautifier(const OReportController & _aObserver); + virtual ~FormattedFieldBeautifier() override; + + void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) override; + void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override; + void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) override; + }; + +} // namespace rptui + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/Formula.hxx b/reportdesign/source/ui/inc/Formula.hxx new file mode 100644 index 000000000..8ec93075b --- /dev/null +++ b/reportdesign/source/ui/inc/Formula.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX + +#include <formula/formula.hxx> +#include <formula/IControlReferenceHandler.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/report/meta/XFormulaParser.hpp> +#include <memory> + +namespace com::sun::star::lang { + class XMultiServiceFactory; +} + +namespace svl { + +class SharedStringPool; + +} + +namespace rptui +{ + +class OAddFieldWindow; + + +class FormulaDialog : public formula::FormulaModalDialog, + public formula::IControlReferenceHandler +{ + std::shared_ptr<formula::IFunctionManager> m_aFunctionManager; + std::unique_ptr<formula::FormEditData> m_xFormulaData; + std::shared_ptr<OAddFieldWindow> m_xAddField; + css::uno::Reference < css::beans::XPropertySet > m_xRowSet; + css::uno::Reference< css::report::meta::XFormulaParser> m_xParser; + css::uno::Reference< css::sheet::XFormulaOpCodeMapper> m_xOpCodeMapper; + formula::RefEdit* m_pEdit; + OUString m_sFormula; + sal_Int32 m_nStart; + sal_Int32 m_nEnd; + + svl::SharedStringPool& mrStringPool; + + DECL_LINK( OnClickHdl, OAddFieldWindow&, void ); +public: + FormulaDialog( weld::Window* pParent + , const css::uno::Reference< css::lang::XMultiServiceFactory>& _xServiceFactory + , const std::shared_ptr< formula::IFunctionManager >& _pFunctionMgr + , const OUString& _sFormula + , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet + , svl::SharedStringPool& rStrPool ); + + virtual ~FormulaDialog() override; + + // IFormulaEditorHelper + virtual void notifyChange() override; + virtual void fill() override; + virtual bool calculateValue(const OUString& _sExpression, OUString& _rResult, bool bMatrixFormula) override; + virtual std::shared_ptr<formula::FormulaCompiler> getCompiler() const override; + virtual std::unique_ptr<formula::FormulaCompiler> createCompiler( formula::FormulaTokenArray& rArray ) const override; + virtual void doClose(bool _bOk) override; + virtual void insertEntryToLRUList(const formula::IFunctionDescription* pDesc) override; + virtual void showReference(const OUString& _sFormula) override; + virtual void dispatch(bool _bOK, bool _bMatrixChecked) override; + virtual void setDispatcherLock( bool bLock ) override; + virtual void deleteFormData() override; + virtual void clear() override; + virtual void switchBack() override; + virtual formula::FormEditData* getFormEditData() const override; + virtual void setCurrentFormula(const OUString& _sReplacement) override; + virtual void setSelection(sal_Int32 _nStart, sal_Int32 _nEnd) override; + virtual void getSelection(sal_Int32& _nStart, sal_Int32& _nEnd) const override; + virtual OUString getCurrentFormula() const override; + + virtual formula::IFunctionManager* getFunctionManager() override; + virtual css::uno::Reference< css::sheet::XFormulaParser> getFormulaParser() const override; + virtual css::uno::Reference< css::sheet::XFormulaOpCodeMapper> getFormulaOpCodeMapper() const override; + virtual css::table::CellAddress getReferencePosition() const override; + + virtual ::std::unique_ptr<formula::FormulaTokenArray> convertToTokenArray(const css::uno::Sequence< css::sheet::FormulaToken >& _aTokenList) override; + + // IControlReferenceHandler + virtual void ShowReference(const OUString& _sRef) override; + virtual void HideReference( bool bDoneRefMode = true ) override; + virtual void ReleaseFocus( formula::RefEdit* pEdit ) override; + virtual void ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton ) override; +}; + + +} // rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FORMULA_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/FunctionHelper.hxx b/reportdesign/source/ui/inc/FunctionHelper.hxx new file mode 100644 index 000000000..8eea9632b --- /dev/null +++ b/reportdesign/source/ui/inc/FunctionHelper.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX + +#include <formula/IFunctionDescription.hxx> +#include <com/sun/star/report/meta/XFunctionManager.hpp> +#include <com/sun/star/report/meta/XFunctionCategory.hpp> +#include <com/sun/star/report/meta/XFunctionDescription.hpp> +#include <map> +#include <memory> +#include <vector> + +namespace rptui +{ + +class FunctionCategory; +class FunctionDescription; + +class FunctionManager : public formula::IFunctionManager +{ + typedef std::map< OUString, std::shared_ptr< FunctionDescription > > TFunctionsMap; + typedef std::map< OUString, std::shared_ptr< FunctionCategory > > TCategoriesMap; + css::uno::Reference< css::report::meta::XFunctionManager> m_xMgr; + mutable TCategoriesMap m_aCategories; + mutable ::std::vector< TCategoriesMap::iterator > m_aCategoryIndex; + mutable TFunctionsMap m_aFunctions; +public: + FunctionManager(const css::uno::Reference< css::report::meta::XFunctionManager>& _xMgr); + virtual ~FunctionManager(); + virtual sal_uInt32 getCount() const override; + virtual const formula::IFunctionCategory* getCategory(sal_uInt32 nPos) const override; + virtual void fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const override; + virtual sal_Unicode getSingleToken(const EToken _eToken) const override; + + std::shared_ptr< FunctionDescription > get(const css::uno::Reference< css::report::meta::XFunctionDescription>& _xFunctionDescription) const; +}; + +class FunctionDescription : public formula::IFunctionDescription +{ + css::uno::Sequence< css::sheet::FunctionArgument > m_aParameter; + css::uno::Reference< css::report::meta::XFunctionDescription> m_xFunctionDescription; + const formula::IFunctionCategory* m_pFunctionCategory; +public: + FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory,const css::uno::Reference< css::report::meta::XFunctionDescription>& _xFunctionDescription); + virtual ~FunctionDescription(){} + + virtual OUString getFunctionName() const override ; + virtual const formula::IFunctionCategory* getCategory() const override ; + virtual OUString getDescription() const override ; + virtual sal_Int32 getSuppressedArgumentCount() const override ; + virtual OUString getFormula(const ::std::vector< OUString >& _aArguments) const override ; + virtual void fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const override ; + virtual void initArgumentInfo() const override; + virtual OUString getSignature() const override ; + virtual OString getHelpId() const override ; + virtual bool isHidden() const override; + virtual sal_uInt32 getParameterCount() const override ; + virtual sal_uInt32 getVarArgsStart() const override; + virtual sal_uInt32 getVarArgsLimit() const override; + virtual OUString getParameterName(sal_uInt32 _nPos) const override ; + virtual OUString getParameterDescription(sal_uInt32 _nPos) const override ; + virtual bool isParameterOptional(sal_uInt32 _nPos) const override ; +}; + +class FunctionCategory : public formula::IFunctionCategory +{ + mutable ::std::vector< std::shared_ptr< FunctionDescription > > m_aFunctions; + css::uno::Reference< css::report::meta::XFunctionCategory> m_xCategory; + sal_uInt32 m_nFunctionCount; + sal_uInt32 m_nNumber; + const FunctionManager* m_pFunctionManager; +public: + FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const css::uno::Reference< css::report::meta::XFunctionCategory>& _xCategory); + virtual ~FunctionCategory() {} + + virtual sal_uInt32 getCount() const override; + virtual const formula::IFunctionDescription* getFunction(sal_uInt32 _nPos) const override; + virtual sal_uInt32 getNumber() const override; + virtual OUString getName() const override; +}; + +} // rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_FUNCTIONHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/GeometryHandler.hxx b/reportdesign/source/ui/inc/GeometryHandler.hxx new file mode 100644 index 000000000..13d08414c --- /dev/null +++ b/reportdesign/source/ui/inc/GeometryHandler.hxx @@ -0,0 +1,307 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GEOMETRYHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GEOMETRYHANDLER_HXX + +#include <sal/config.h> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/inspection/XPropertyHandler.hpp> +#include <com/sun/star/script/XTypeConverter.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/report/XFunctionsSupplier.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <unotools/resmgr.hxx> +#include <map> +#include <memory> +#include <string_view> + +#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/stl_types.hxx> + + +namespace rptui +{ + + + struct DefaultFunction + { + css::beans::Optional< OUString> m_sInitialFormula; + OUString m_sName; + OUString m_sSearchString; + OUString m_sFormula; + bool m_bPreEvaluated; + + const OUString& getName() const { return m_sName; } + } ; + + class OPropertyInfoService; + typedef ::std::pair< css::uno::Reference< css::report::XFunction>, css::uno::Reference< css::report::XFunctionsSupplier> > TFunctionPair; + typedef ::std::multimap< OUString,TFunctionPair, ::comphelper::UStringMixLess > TFunctions; + typedef ::comphelper::OInterfaceContainerHelper3< css::beans::XPropertyChangeListener > PropertyChangeListeners; + typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler + , css::beans::XPropertyChangeListener + , css::lang::XServiceInfo> GeometryHandler_Base; + + class GeometryHandler: + private ::cppu::BaseMutex, + public GeometryHandler_Base + { + /** sets the counter function at the data field. + * If the counter function doesn't exist it will be created. + */ + void impl_setCounterFunction_throw(); + + /** executes a dialog for choosing a filter criterion for a database report + @param _out_rSelectedClause + the filter or order clause as chosen by the user + @precond + we're really inspecting a database form (well, a RowSet at least) + @return + <TRUE/> if and only if the user successfully chose a clause + */ + bool impl_dialogFilter_nothrow( OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const; + + /** returns the data field type depending on the data field of the report control + * + * \param _sDataField if the data field is not empty it will be used as data field, otherwise the data field will be used. + * \return the data field type + */ + sal_uInt32 impl_getDataFieldType_throw(const OUString& _sDataField = OUString()) const; + + css::uno::Any getConstantValue(bool bToControlValue,const TranslateId* pResId,const css::uno::Any& _aValue,const OUString& _sConstantName,const OUString & PropertyName ); + css::beans::Property getProperty(const OUString & PropertyName); + static void implCreateListLikeControl( + const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory + ,css::inspection::LineDescriptor & out_Descriptor + ,const TranslateId* pResId + ,bool _bReadOnlyControl + ,bool _bTrueIfListBoxFalseIfComboBox + ); + static void implCreateListLikeControl( + const css::uno::Reference< css::inspection::XPropertyControlFactory >& _rxControlFactory + ,css::inspection::LineDescriptor & out_Descriptor + ,const ::std::vector< OUString>& _aEntries + ,bool _bReadOnlyControl + ,bool _bTrueIfListBoxFalseIfComboBox + ); + void checkPosAndSize( const css::awt::Point& _aNewPos, + const css::awt::Size& _aSize); + + OUString impl_convertToFormula( const css::uno::Any& _rControlValue ); + + void impl_initFieldList_nothrow( css::uno::Sequence< OUString >& _rFieldNames ) const; + + /** Creates the function defined by the function template + * + * \param _sFunctionName the function name + * \param _sDataField the data field + * \param _aFunction the function template + */ + void impl_createFunction(const OUString& _sFunctionName,std::u16string_view _sDataField,const DefaultFunction& _aFunction); + + /** check whether the given function name is a counter function. + * + * \param _sQuotedFunctionName the quoted function name to check + * \param Out_sScope the scope of the function + * \return When true it is a counter functions otherwise false. + */ + bool impl_isCounterFunction_throw(const OUString& _sQuotedFunctionName,OUString& Out_sScope) const; + + /** clear the own properties like function and scope and send a notification + * + * \param _aGuard + * \param _sOldFunctionName + * \param _sOldScope + * \param _nOldDataFieldType + */ + void resetOwnProperties(::osl::ResettableMutexGuard& _aGuard,const OUString& _sOldFunctionName,const OUString& _sOldScope,const sal_uInt32 _nOldDataFieldType); + + /** checks whether the name is a field or a parameter + * + * \param _sName the name to check + * \return true when it is a field or parameter otherwise false + */ + bool impl_isDataField(const OUString& _sName) const; + + /**return all formula in a semicolon separated list + * + * \param _rList the localized function names + */ + void impl_fillFormulaList_nothrow(::std::vector< OUString >& _out_rList) const; + + /** return all group names in a semicolon separated list starting with the group where this control is contained in. + * + * \param _rList fills the list with all scope names. + */ + void impl_fillScopeList_nothrow(::std::vector< OUString >& _out_rList) const; + + /** return all supported output formats of the report definition + * + * \param _rList fills the list with all mime types + */ + void impl_fillMimeTypes_nothrow(::std::vector< OUString >& _out_rList) const; + + /** return the one supported output formats of the report definition + * + * \param _sMimetype the mimetype + */ + OUString impl_ConvertMimeTypeToUI_nothrow(const OUString& _sMimetype) const; + + /** return the MimeType for the given UI Name + * + * \param _sUIName the doc ui name + */ + OUString impl_ConvertUIToMimeType_nothrow(const OUString& _sUIName) const; + + /** get the functions supplier for the set scope, default is the surrounding group. + * + * \param _rsNamePostfix the name postfix which can be used when the scope as name part is needed + * \return the function supplier + */ + css::uno::Reference< css::report::XFunctionsSupplier> fillScope_throw(OUString& _rsNamePostfix); + + /** checks if the given function is a default function we know. + * + * \param _sQuotedFunction the quoted function name + * \param Out_rDataField the data field which is used in the function + * \param _xFunctionsSupplier the function supplier to search or empty if not used + * \param _bSet If set to sal_True than the m_sDefaultFunction and m_sScope vars will be set if successful. + * \return sal_True with known otherwise sal_False + */ + bool isDefaultFunction(const OUString& _sQuotedFunction + ,OUString& Out_rDataField + ,const css::uno::Reference< css::report::XFunctionsSupplier>& _xFunctionsSupplier = css::uno::Reference< css::report::XFunctionsSupplier>() + ,bool _bSet = false) const; + + /** checks if the given function is a default function we know. + * + * \param _xFunction + * \param _rDataField + * \param _rsDefaultFunctionName + * \return + */ + bool impl_isDefaultFunction_nothrow( const css::uno::Reference< css::report::XFunction>& _xFunction + ,OUString& _rDataField + ,OUString& _rsDefaultFunctionName) const; + + /** fills the member m_aDefaultFunctions + * + */ + void loadDefaultFunctions(); + + /** creates a default function of the _sFunction for the data field _sDataField + * The new function will only be created if it didn't exist. + * + * \param _aGuard Will be cleared, when a new function was created. + * \param _sFunction The name of the function. + * \param _sDataField The name of the data field. + */ + void createDefaultFunction(::osl::ResettableMutexGuard& _aGuard ,const OUString& _sFunction,std::u16string_view _sDataField); + + void removeFunction(); + + class OBlocker + { + bool& m_bIn; + public: + OBlocker(bool& _bIn) : m_bIn(_bIn){ m_bIn = true; } + ~OBlocker() { m_bIn = false; } + }; + + + // XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + // XPropertyChangeListener + virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override; + + public: + explicit GeometryHandler(css::uno::Reference< css::uno::XComponentContext > const & context); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // css::lang::XComponent: + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override; + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override; + + // css::inspection::XPropertyHandler: + virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override; + virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override; + virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override; + virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override; + virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override; + virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override; + virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override; + virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override; + virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override; + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override; + virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override; + virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override; + virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override; + virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override; + + protected: + virtual ~GeometryHandler() override; + private: + GeometryHandler(GeometryHandler const &) = delete; + void operator =(GeometryHandler const &) = delete; + + // override WeakComponentImplHelperBase::disposing() + // This function is called upon disposing the component, + // if your component needs special work when it becomes + // disposed, do it here. + virtual void SAL_CALL disposing() override; + + PropertyChangeListeners m_aPropertyListeners; + css::uno::Sequence< OUString > m_aFieldNames; + css::uno::Sequence< OUString > m_aParamNames; + TFunctions m_aFunctionNames; + ::std::vector< DefaultFunction > m_aDefaultFunctions; + DefaultFunction m_aCounterFunction; + css::uno::Reference< css::uno::XComponentContext > m_xContext; + mutable css::uno::Reference< css::report::XFunction> m_xFunction; + css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee + css::uno::Reference< css::beans::XPropertySet > m_xReportComponent; /// inspectee + mutable css::uno::Reference< css::sdbc::XRowSet > m_xRowSet; + /// type converter, needed on various occasions + css::uno::Reference< css::script::XTypeConverter > m_xTypeConverter; + mutable OUString m_sDefaultFunction; + mutable OUString m_sScope; + sal_uInt32 m_nDataFieldType; + mutable bool m_bNewFunction; + bool m_bIn; + }; + +} // namespace rptui + + +#endif // RPT_GeometryHandler_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/GroupsSorting.hxx b/reportdesign/source/ui/inc/GroupsSorting.hxx new file mode 100644 index 000000000..0418ee1d9 --- /dev/null +++ b/reportdesign/source/ui/inc/GroupsSorting.hxx @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX + +#include <com/sun/star/report/XGroups.hpp> +#include <com/sun/star/report/XGroup.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <comphelper/propmultiplex.hxx> +#include <cppuhelper/basemutex.hxx> +#include <rtl/ref.hxx> +#include <vcl/weld.hxx> +#include <osl/diagnose.h> + +namespace comphelper +{ + class OPropertyChangeMultiplexer; +} +namespace rptui +{ +class OFieldExpressionControl; +class OReportController; +/************************************************************************* +|* +|* Groups and Sorting dialog +|* +\************************************************************************/ + +class OGroupsSortingDialog : public weld::GenericDialogController + , public ::cppu::BaseMutex + , public ::comphelper::OPropertyChangeListener +{ + friend class OFieldExpressionControl; + + ::rptui::OReportController* m_pController; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pCurrentGroupListener; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; + css::uno::Reference< css::report::XGroups> m_xGroups; + css::uno::Reference< css::container::XNameAccess > m_xColumns; + bool m_bReadOnly; + + std::unique_ptr<weld::Toolbar> m_xToolBox; + std::unique_ptr<weld::Widget> m_xProperties; + std::unique_ptr<weld::ComboBox> m_xOrderLst; + std::unique_ptr<weld::ComboBox> m_xHeaderLst; + std::unique_ptr<weld::ComboBox> m_xFooterLst; + std::unique_ptr<weld::ComboBox> m_xGroupOnLst; + std::unique_ptr<weld::SpinButton> m_xGroupIntervalEd; + std::unique_ptr<weld::ComboBox> m_xKeepTogetherLst; + std::unique_ptr<weld::Label> m_xHelpWindow; + std::unique_ptr<weld::Container> m_xBox; + css::uno::Reference<css::awt::XWindow> m_xTableCtrlParent; + VclPtr<OFieldExpressionControl> m_xFieldExpression; + +private: + DECL_LINK( OnWidgetFocusLost, weld::Widget&, void ); + DECL_LINK( OnWidgetFocusGot, weld::Widget&, void ); + + DECL_LINK( OnControlFocusGot, LinkParamNone*, void ); + + DECL_LINK( LBChangeHdl, weld::ComboBox&, void ); + DECL_LINK( OnFormatAction, const OString&, void ); + + /** returns the groups + @return the groups which now have to check which one changes + */ + css::uno::Reference< css::report::XGroups>& getGroups() { return m_xGroups; } + + css::uno::Reference< css::report::XGroup> getGroup(sal_Int32 _nPos) + { + OSL_ENSURE(_nPos >= 0 && _nPos < m_xGroups->getCount(),"Invalid count!"); + return css::uno::Reference< css::report::XGroup>(m_xGroups->getByIndex(_nPos),css::uno::UNO_QUERY); + } + + /** updates the listboxes with the new group properties + @param _nRow the new group pos + */ + void DisplayData( sal_Int32 _nRow ); + + /** saves the values from the listboxes into the group at position _nRow + @param _nRow the group pos to store in + */ + void SaveData( sal_Int32 _nRow ); + + /** returns <TRUE/> when the dialog should be read only + */ + bool isReadOnly( ) const { return m_bReadOnly;} + + /** returns the data type for the given column name + @param _sColumnName + */ + sal_Int32 getColumnDataType(const OUString& _sColumnName); + + /** display the group props + @param _xGroup the group to display + */ + void displayGroup(const css::uno::Reference< css::report::XGroup>& _xGroup); + + /** enables or disables the up and down button + @param _nRow the row which will be active + */ + void checkButtons(sal_Int32 _nRow); + + /** clears the m_xColumns member and reset the fields + * + */ + void fillColumns(); + OGroupsSortingDialog(OGroupsSortingDialog const &) = delete; + void operator =(OGroupsSortingDialog const &) = delete; +protected: + // OPropertyChangeListener + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override; +public: + OGroupsSortingDialog(weld::Window* pParent, + bool _bReadOnly, + ::rptui::OReportController* _pController); + virtual ~OGroupsSortingDialog() override; + + /* updates the current view + */ + void UpdateData( ); +}; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_GROUPSSORTING_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/IReportControllerObserver.hxx b/reportdesign/source/ui/inc/IReportControllerObserver.hxx new file mode 100644 index 000000000..3d9f7e75c --- /dev/null +++ b/reportdesign/source/ui/inc/IReportControllerObserver.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_IREPORTCONTROLLEROBSERVER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_IREPORTCONTROLLEROBSERVER_HXX + +#include <com/sun/star/beans/PropertyChangeEvent.hpp> + +namespace rptui +{ + /* abstract */ class IReportControllerObserver + { + protected: + // IReportControllerObserver(){} + virtual ~IReportControllerObserver() {} + + public: + + virtual void notifyPropertyChange( const css::beans::PropertyChangeEvent& _rEvent ) = 0; + virtual void notifyElementInserted( const css::uno::Reference< css::uno::XInterface >& _rxElement ) = 0; + virtual void handle( const css::uno::Reference< css::uno::XInterface >& _rxElement ) = 0; + }; + +} // namespace rptui + +#endif + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/MarkedSection.hxx b/reportdesign/source/ui/inc/MarkedSection.hxx new file mode 100644 index 000000000..2d97645c4 --- /dev/null +++ b/reportdesign/source/ui/inc/MarkedSection.hxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX + +#include <sal/types.h> + +namespace rptui +{ + class OSectionWindow; + + enum NearSectionAccess + { + CURRENT = 0, + PREVIOUS = -1, + POST = 1 + }; + + class IMarkedSection + { + public: + /** returns the section which is currently marked. + */ + virtual OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const =0; + + /** mark the section on the given position . + * + * \param _nPos the position is zero based. + */ + virtual void markSection(const sal_uInt16 _nPos) = 0; + + protected: + ~IMarkedSection() {} + }; + +} // rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_MARKEDSECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/Navigator.hxx b/reportdesign/source/ui/inc/Navigator.hxx new file mode 100644 index 000000000..eed3e529c --- /dev/null +++ b/reportdesign/source/ui/inc/Navigator.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX + +#include <vcl/weld.hxx> +#include <memory> +namespace rptui +{ + class OReportController; + class ONavigatorImpl; + class ONavigator : public weld::GenericDialogController + { + ::std::unique_ptr<ONavigatorImpl> m_pImpl; + ONavigator(const ONavigator&) = delete; + void operator =(const ONavigator&) = delete; + + DECL_LINK(FocusChangeHdl, weld::Container&, void); + + public: + ONavigator(weld::Window* pParent, OReportController& rController); + ~ONavigator(); + }; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_NAVIGATOR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/PageNumber.hxx b/reportdesign/source/ui/inc/PageNumber.hxx new file mode 100644 index 000000000..eefa10c8b --- /dev/null +++ b/reportdesign/source/ui/inc/PageNumber.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX + +#include <vcl/weld.hxx> +#include <com/sun/star/report/XReportDefinition.hpp> + +namespace rptui +{ +class OReportController; +/************************************************************************* +|* +|* Groups and Sorting dialog +|* +\************************************************************************/ +class OPageNumberDialog : public weld::GenericDialogController +{ + ::rptui::OReportController* m_pController; + css::uno::Reference< css::report::XReportDefinition> + m_xHoldAlive; + std::unique_ptr<weld::RadioButton> m_xPageN; + std::unique_ptr<weld::RadioButton> m_xPageNofM; + std::unique_ptr<weld::RadioButton> m_xTopPage; + std::unique_ptr<weld::RadioButton> m_xBottomPage; + std::unique_ptr<weld::ComboBox> m_xAlignmentLst; + std::unique_ptr<weld::CheckButton> m_xShowNumberOnFirstPage; + + OPageNumberDialog(const OPageNumberDialog&) = delete; + void operator =(const OPageNumberDialog&) = delete; +public: + OPageNumberDialog(weld::Window* pParent, + const css::uno::Reference< css::report::XReportDefinition>& _xHoldAlive, + ::rptui::OReportController* _pController); + virtual ~OPageNumberDialog() override; + virtual short run() override; +}; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PAGENUMBER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportComponentHandler.hxx b/reportdesign/source/ui/inc/ReportComponentHandler.hxx new file mode 100644 index 000000000..fdf4ad0e6 --- /dev/null +++ b/reportdesign/source/ui/inc/ReportComponentHandler.hxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX + +#include <sal/config.h> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <cppuhelper/compbase.hxx> +#include <cppuhelper/basemutex.hxx> +#include <com/sun/star/inspection/XPropertyHandler.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + + +namespace rptui +{ + + + class OPropertyInfoService; + + typedef ::cppu::WeakComponentImplHelper< css::inspection::XPropertyHandler + , css::lang::XServiceInfo> ReportComponentHandler_Base; + + class ReportComponentHandler: + private ::cppu::BaseMutex, + public ReportComponentHandler_Base + { + public: + explicit ReportComponentHandler(css::uno::Reference< css::uno::XComponentContext > const & context); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + + // css::lang::XComponent: + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > & xListener) override; + virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > & aListener) override; + + // css::inspection::XPropertyHandler: + virtual void SAL_CALL inspect(const css::uno::Reference< css::uno::XInterface > & Component) override; + virtual css::uno::Any SAL_CALL getPropertyValue(const OUString & PropertyName) override; + virtual void SAL_CALL setPropertyValue(const OUString & PropertyName, const css::uno::Any & Value) override; + virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString & PropertyName) override; + virtual css::inspection::LineDescriptor SAL_CALL describePropertyLine(const OUString& PropertyName, const css::uno::Reference< css::inspection::XPropertyControlFactory >& ControlFactory ) override; + virtual css::uno::Any SAL_CALL convertToPropertyValue(const OUString & PropertyName, const css::uno::Any & ControlValue) override; + virtual css::uno::Any SAL_CALL convertToControlValue(const OUString & PropertyName, const css::uno::Any & PropertyValue, const css::uno::Type & ControlValueType) override; + virtual void SAL_CALL addPropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & Listener) override; + virtual void SAL_CALL removePropertyChangeListener(const css::uno::Reference< css::beans::XPropertyChangeListener > & _rxListener) override; + virtual css::uno::Sequence< css::beans::Property > SAL_CALL getSupportedProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupersededProperties() override; + virtual css::uno::Sequence< OUString > SAL_CALL getActuatingProperties() override; + virtual sal_Bool SAL_CALL isComposable(const OUString & PropertyName) override; + virtual css::inspection::InteractiveSelectionResult SAL_CALL onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, css::uno::Any & out_Data, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI) override; + virtual void SAL_CALL actuatingPropertyChanged(const OUString & ActuatingPropertyName, const css::uno::Any & NewValue, const css::uno::Any & OldValue, const css::uno::Reference< css::inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) override; + virtual sal_Bool SAL_CALL suspend(sal_Bool Suspend) override; + + protected: + virtual ~ReportComponentHandler() override {} + private: + ReportComponentHandler(ReportComponentHandler const &) = delete; + void operator =(ReportComponentHandler const &) = delete; + + + // override WeakComponentImplHelperBase::disposing() + // This function is called upon disposing the component, + // if your component needs special work when it becomes + // disposed, do it here. + virtual void SAL_CALL disposing() override; + + css::uno::Reference< css::uno::XComponentContext > m_xContext; + css::uno::Reference< css::inspection::XPropertyHandler > m_xFormComponentHandler; /// delegatee + css::uno::Reference< css::uno::XInterface > m_xFormComponent; /// inspectee + }; + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCOMPONENTHANDLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportController.hxx b/reportdesign/source/ui/inc/ReportController.hxx new file mode 100644 index 000000000..726ac8012 --- /dev/null +++ b/reportdesign/source/ui/inc/ReportController.hxx @@ -0,0 +1,450 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX + +#include "DesignView.hxx" +#include "ReportControllerObserver.hxx" +#include <RptDef.hxx> + +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/embed/XVisualObject.hpp> +#include <com/sun/star/frame/XDesktop2.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/report/XReportEngine.hpp> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/util/XModeSelector.hpp> +#include <com/sun/star/util/XNumberFormatter.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> + +#include <comphelper/proparrhlp.hxx> +#include <comphelper/propertystatecontainer.hxx> +#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase5.hxx> +#include <comphelper/interfacecontainer3.hxx> +#include <dbaccess/dbsubcomponentcontroller.hxx> +#include <svl/lstner.hxx> +#include <vcl/transfer.hxx> +#include <sfx2/zoomitem.hxx> + +#include <functional> +#include <memory> + +class TransferableClipboardListener; +class VclWindowEvent; +class SfxUndoManager; +namespace rptui +{ + class OGroupsSortingDialog; + class OReportModel; + class OSectionView; + class OAddFieldWindow; + class OSectionWindow; + + typedef ::dbaui::DBSubComponentController OReportController_BASE; + typedef ::cppu::ImplHelper5 < css::container::XContainerListener + , css::beans::XPropertyChangeListener + , css::view::XSelectionSupplier + , css::util::XModeSelector + , css::embed::XVisualObject + > OReportController_Listener; + + class OReportController : public OReportController_BASE + ,public OReportController_Listener + ,public SfxListener + ,public ::comphelper::OPropertyStateContainer + ,public ::comphelper::OPropertyArrayUsageHelper < OReportController_BASE > + { + private: + ::comphelper::OInterfaceContainerHelper3<css::view::XSelectionChangeListener> + m_aSelectionListeners; + css::uno::Sequence< css::beans::PropertyValue> + m_aCollapsedSections; + TransferableDataHelper m_aSystemClipboard; // content of the clipboard + rtl::Reference<TransferableClipboardListener> + m_pClipboardNotifier; /// notifier for changes in the clipboard + std::shared_ptr<OGroupsSortingDialog> m_xGroupsFloater; + + rtl::Reference<OXReportControllerObserver> m_pReportControllerObserver; + + ODesignView* getDesignView() const { return static_cast< ODesignView* >( getView() ); } + + css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition; + css::uno::Reference< css::report::XReportEngine > m_xReportEngine; + css::uno::Reference< css::frame::XDesktop2 > m_xFrameLoader; + css::uno::Reference< css::sdbc::XRowSet > m_xRowSet; + css::uno::Reference< css::beans::XPropertyChangeListener > m_xRowSetMediator; + css::uno::Reference< css::util::XNumberFormatter > m_xFormatter; // a number formatter working with the report's NumberFormatsSupplier + mutable css::uno::Reference< css::lang::XComponent > m_xHoldAlive; + mutable css::uno::Reference< css::container::XNameAccess > m_xColumns; + css::awt::Size m_aVisualAreaSize; + + std::shared_ptr<rptui::OReportModel> + m_aReportModel; + OUString m_sName; /// name for the report definition + OUString m_sLastActivePage; /// last active property browser page + OUString m_sMode; /// the current mode of the controller + sal_Int32 m_nSplitPos; /// the position of the splitter + sal_Int32 m_nPageNum; /// the page number from the restoreView call + sal_Int32 m_nSelectionCount; + ::sal_Int64 m_nAspect; + sal_Int16 m_nZoomValue; + SvxZoomType m_eZoomType; + bool m_bShowRuler; + bool m_bGridVisible; + bool m_bGridUse; + bool m_bShowProperties; + bool m_bHelplinesMove; + bool m_bChartEnabled; + bool m_bChartEnabledAsked; + bool m_bInGeneratePreview; + + /** creates a formatted field in the given section with the given formula as data field + * + * \param _aArgs + * \param _xSection the section where to create the formatted field + * \param _sFunction the function which will be set at the data field. + */ + void createControl(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs,const css::uno::Reference< css::report::XSection>& _xSection,const OUString& _sFunction ,SdrObjKind _nObjectId = SdrObjKind::ReportDesignFormattedField); + /** switch the report header/footer sectionon off with undo or without depending on the given id. + * + * \param _nId Can either be SID_REPORTHEADER_WITHOUT_UNDO or SID_REPORTFOOTER_WITHOUT_UNDO or SID_REPORTHEADERFOOTER. + */ + void switchReportSection(const sal_Int16 _nId); + + /** switch the report header/footer sectionon off with undo or without depending on the given id. + * + * \param _nId Can either be SID_PAGEHEADER_WITHOUT_UNDO or SID_PAGEFOOTER_WITHOUT_UNDO or SID_PAGEHEADERFOOTER. + */ + void switchPageSection(const sal_Int16 _nId); + + /** append a new group or remove it with undo. + * + * \param _bAppend + * \param _aArgs The args which contains an element named PROPERTY_GROUP of type report::XGroup. + */ + void modifyGroup(const bool _bAppend, const css::uno::Sequence< css::beans::PropertyValue >& _aArgs); + + /** creates a group section. + * + * \param _bUndo true when undo action should be created + * \param _bHeader true when it is a header otherwise it is a footer + * \param _aArgs The args which contains an element named PROPERTY_GROUP of type report::XGroup. + */ + void createGroupSection(const bool _bUndo,const bool _bHeader,const css::uno::Sequence< css::beans::PropertyValue >&_aArgs); + + /** add or remove me as listener at the report definition + * + * \param _bAdd + */ + void listen(const bool _bAdd); + + /** opens the common page dialog + */ + void openPageDialog(const css::uno::Reference< css::report::XSection>& _xSection); + + /** opens or hides the sorting and grouping dialog + */ + void openSortingAndGroupingDialog(); + + /** opens the zoom dialog + */ + void openZoomDialog(); + + /** returns the position of the group inside the groups collection + */ + sal_Int32 getGroupPosition(const css::uno::Reference< css::report::XGroup >& _xGroup); + + /** calls propertyChanged when the header or footer is really turned on. + @param _rEvent the group + @param _bShow when <TRUE/> the header and footer will be shown otherwise not + */ + void notifyGroupSections(const css::container::ContainerEvent& _rEvent + ,bool _bShow); + + /** change the sections for a group + @param _sPropName the header or footer + @param _xGroup the group + @param _nGroupPos the position of the group inside the groups collection or the previous index when it was removed + @param _bShow when <TRUE/> the header and footer will be shown otherwise not + */ + void groupChange( const css::uno::Reference< css::report::XGroup>& _xGroup + ,std::u16string_view _sPropName + ,sal_Int32 _nGroupPos + ,bool _bShow); + + void executeMethodWithUndo(TranslateId pUndoStrId,const ::std::function<void(ODesignView *)>& _pMemfun); + void alignControlsWithUndo(TranslateId pUndoStrId, ControlModification _nControlModification, bool _bAlignAtSection = false); + + css::uno::Reference< css::frame::XFrame > getXFrame(); + + /** shrink a section + @param pUndoStrId the string id of the string which is shown in undo menu + @param _nShrinkId ID of what you would like to shrink. + */ + static void shrinkSectionBottom(const css::uno::Reference< css::report::XSection >& _xSection); + static void shrinkSectionTop(const css::uno::Reference< css::report::XSection >& _xSection); + + public: + void shrinkSection(TranslateId pUndoStrId, const css::uno::Reference< css::report::XSection >& _xSection, sal_Int32 _nShrinkId); + + /** opens the file open dialog to allow the user to select an image which will be + * bound to a newly created image button. + */ + void insertGraphic(); + + /** creates a new function in the given value context + * + * \param _aValue contains a XNameContainer + */ + void createNewFunction(const css::uno::Any& _aValue); + + /** inserts a label - field pair into the current selected section + * + * \param aArgs + */ + void addPairControls(const css::uno::Sequence< css::beans::PropertyValue >& aArgs); + + /** inserts a label - field combination to show the page number and/or page count + * + * \param _aArgs + */ + void createPageNumber(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs); + + /** creates a formatted field with TODAY() function and if set also a NOW() function + * + * \param _aArgs + */ + void createDateTime(const css::uno::Sequence< css::beans::PropertyValue >& _aArgs); + + /** gets the current section (SdrView) + * + * \return the currently selected section or <NULL/> if no one is selected + */ + OSectionView* getCurrentSectionView() const; + + /**change the ZOrder of a current select object. + * + * \param _nId The command ID about what to do. + */ + void changeZOrder(sal_Int32 _nId); + + /** marks the next or previous section, when the first/last section was already selected then the report will be selected. + * + * \param _bNext + */ + void markSection(const bool _bNext); + + /** collapse or expand the currently selected section. + * + * \param _bCollapse collapse if sal_True otherwise expand + */ + void collapseSection(const bool _bCollapse); + + /** fills the member that chart is enabled or not + * + */ + void checkChartEnabled(); + + /** set the zoom factor at the design view + */ + void impl_zoom_nothrow(); + + virtual void impl_onModifyChanged() override; + + virtual void onLoadedMenu( const css::uno::Reference< css::frame::XLayoutManager >& _xLayoutManager ) override; + virtual void impl_initialize( ) override; + bool isUiVisible() const; + + /** creates a new default control for the currently set type when the modifier KEY_MOD1 was pressed + * \param _aArgs must contain a propertyvalue with name "KeyModifier" and value KEY_MOD1 when control should be created. + */ + void createDefaultControl(const css::uno::Sequence< css::beans::PropertyValue>& _aArgs); + + /** fills the state for the feature request. + @param _sProperty the property which should be filled in the value + @param _rState the state to fill + */ + void impl_fillState_nothrow(const OUString& _sProperty,dbaui::FeatureState& _rState) const; + void impl_fillCustomShapeState_nothrow(const char* _pCustomShapeType,dbaui::FeatureState& _rState) const; + + /** set the property at all selected controls. + @return <TRUE/> when the selection is not empty + */ + bool impl_setPropertyAtControls_throw(TranslateId pUndoResId + ,const OUString& _sProperty + ,const css::uno::Any& _aValue + ,const css::uno::Sequence< css::beans::PropertyValue >& _aArgs); + + void OnInvalidateClipboard(); + DECL_LINK( OnClipboardChanged, TransferableDataHelper*, void ); + DECL_LINK( OnExecuteReport, void*, void ); + // all the features which should be handled by this class + virtual void describeSupportedFeatures() override; + // state of a feature. 'feature' may be the handle of a css::util::URL somebody requested a dispatch interface for OR a toolbar slot. + virtual dbaui::FeatureState GetState(sal_uInt16 nId) const override; + // execute a feature + virtual void Execute(sal_uInt16 nId, const css::uno::Sequence< css::beans::PropertyValue>& aArgs) override; + + virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, css::uno::Any& _rDefault ) const override; + virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const css::uno::Any& rValue) override; + + private: + virtual ~OReportController() override; + + public: + explicit OReportController(css::uno::Reference< css::uno::XComponentContext > const & the_context); + OReportController(const OReportController&) = delete; + OReportController& operator=(const OReportController&) = delete; + + DECL_LINK( OnCreateHdl, OAddFieldWindow&, void); + + DECLARE_XINTERFACE( ) + DECLARE_XTYPEPROVIDER( ) + + // SfxListener + virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override; + + /** returns <TRUE/> when the command is enabled + @param _nCommand the command id + @param _xControlFormat the report control format + */ + static bool isFormatCommandEnabled(sal_uInt16 _nCommand + ,const css::uno::Reference< css::report::XReportControlFormat>& _xControlFormat); + + virtual bool Construct(vcl::Window* pParent) override; + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override; + + // css::frame::XController + virtual sal_Bool SAL_CALL suspend(sal_Bool bSuspend) override; + + // css::lang::XComponent + virtual void SAL_CALL disposing() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString> SAL_CALL getSupportedServiceNames() override; + + // css::container::XContainerListener + virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& Event) override; + virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& Event) override; + virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& Event) override; + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override; + + // XSelectionSupplier + virtual sal_Bool SAL_CALL select( const css::uno::Any& xSelection ) override; + virtual css::uno::Any SAL_CALL getSelection( ) override; + virtual void SAL_CALL addSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override; + virtual void SAL_CALL removeSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override; + + // css::frame::XController + virtual sal_Bool SAL_CALL attachModel(const css::uno::Reference< css::frame::XModel > & xModel) override; + virtual css::uno::Any SAL_CALL getViewData() override; + virtual void SAL_CALL restoreViewData(const css::uno::Any& Data) override; + + /** gives access to the report definition + * \return the report definition object, may be <NULL/> + */ + const css::uno::Reference< css::report::XReportDefinition>& getReportDefinition() const { return m_xReportDefinition; } + + // css::frame::XController + virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel() override; + + // XTitle + virtual OUString SAL_CALL getTitle( ) override; + + // XModeSelector + virtual void SAL_CALL setMode( const OUString& aMode ) override ; + virtual OUString SAL_CALL getMode( ) override ; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedModes( ) override ; + virtual sal_Bool SAL_CALL supportsMode( const OUString& aMode ) override ; + + // XVisualObject + virtual void SAL_CALL setVisualAreaSize( ::sal_Int64 nAspect, const css::awt::Size& aSize ) override; + virtual css::awt::Size SAL_CALL getVisualAreaSize( ::sal_Int64 nAspect ) override; + virtual css::embed::VisualRepresentation SAL_CALL getPreferredVisualRepresentation( ::sal_Int64 nAspect ) override; + virtual ::sal_Int32 SAL_CALL getMapUnit( ::sal_Int64 nAspect ) override; + + + /** returns the current position of the splitter + * + * \return + */ + sal_Int32 getSplitPos() const { return m_nSplitPos;} + void setSplitPos(sal_Int32 _nSplitPos) { m_nSplitPos = _nSplitPos;} + + /** creates a new report from the report definition. + * + * \return The model or <NULL/> if the model could not be created. + */ + css::uno::Reference< css::frame::XModel> executeReport(); + + /** returns the RowSet which reflects the current settings of the report definition + + The caller is allowed to hold a reference to the RowSet - it is kept alive as long + as the controller lives, and it's settings will follow the report definition's settings. + */ + css::uno::Reference< css::sdbc::XRowSet > const & getRowSet(); + + /** returns the number formatter + */ + const css::uno::Reference< css::util::XNumberFormatter >& getReportNumberFormatter() const { return m_xFormatter;} + + /** return the SdrModel of the real model + * + * \return + */ + const std::shared_ptr<rptui::OReportModel>& getSdrModel() const { return m_aReportModel;} + + const css::uno::Reference< css::uno::XComponentContext >& getContext() const { return m_xContext; } + sal_Int16 getZoomValue() const { return m_nZoomValue; } + void resetZoomType() { m_eZoomType = SvxZoomType::PERCENT; } + + // css::beans::XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override + { + return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); + } + // comphelper::OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const override; + + // cppu::OPropertySetHelper + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + + OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const; + + css::uno::Reference< css::container::XNameAccess > const & getColumns() const; + OUString getColumnLabel_throw(const OUString& i_sColumnName) const; + + SfxUndoManager& getUndoManager() const; + void clearUndoManager() const; + void addUndoAction( std::unique_ptr<SfxUndoAction> i_pAction ); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportControllerObserver.hxx b/reportdesign/source/ui/inc/ReportControllerObserver.hxx new file mode 100644 index 000000000..d77fb3f2e --- /dev/null +++ b/reportdesign/source/ui/inc/ReportControllerObserver.hxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX + +#include <com/sun/star/beans/XPropertyChangeListener.hpp> +#include <com/sun/star/beans/PropertyChangeEvent.hpp> +#include <cppuhelper/implbase.hxx> + +#include <memory> + +#include <tools/link.hxx> + +#include "FormattedFieldBeautifier.hxx" +#include "FixedTextColor.hxx" + +class VclSimpleEvent; + +namespace rptui +{ + class OReportController; + class OXReportControllerObserverImpl; + + + class OXReportControllerObserver + : public ::cppu::WeakImplHelper< css::beans::XPropertyChangeListener + , css::container::XContainerListener + , css::util::XModifyListener + > + { + + const ::std::unique_ptr<OXReportControllerObserverImpl> m_pImpl; + + FormattedFieldBeautifier m_aFormattedFieldBeautifier; + FixedTextColor m_aFixedTextColor; + + // do not allow copy + OXReportControllerObserver(const OXReportControllerObserver&) = delete; + OXReportControllerObserver& operator=(const OXReportControllerObserver&) = delete; + virtual ~OXReportControllerObserver() override; // UNO Object must have private destructor! + public: + OXReportControllerObserver(const OReportController& _rController); + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override; + + // XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; + + // XContainerListener + virtual void SAL_CALL elementInserted(const css::container::ContainerEvent& rEvent) override; + virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent& rEvent) override; + virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent& rEvent) override; + + // XModifyListener + virtual void SAL_CALL modified( const css::lang::EventObject& aEvent ) override; + + + void AddElement(const css::uno::Reference< css::uno::XInterface>& Element); + void RemoveElement(const css::uno::Reference< css::uno::XInterface>& Element); + + void AddSection( const css::uno::Reference< css::report::XSection>& _xSection); + void RemoveSection( const css::uno::Reference< css::report::XSection>& _xSection ); + + /** + Create an object ob OUndoEnvLock locks the undo possibility + As long as in the OUndoEnvLock scope, no undo is possible for manipulated object. + */ + class OEnvLock + { + OXReportControllerObserver& m_rObserver; + public: + OEnvLock(OXReportControllerObserver& _rObserver): m_rObserver(_rObserver){m_rObserver.Lock();} + ~OEnvLock(){ m_rObserver.UnLock(); } + }; + + void Lock(); + void UnLock(); + + void Clear(); + private: + + void switchListening( const css::uno::Reference< css::container::XIndexAccess >& _rxContainer, bool _bStartListening ); + void switchListening( const css::uno::Reference< css::uno::XInterface >& _rxObject, bool _bStartListening ); + + DECL_LINK(SettingsChanged, VclSimpleEvent&, void ); + }; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTCONTROLLEROBSERVER_HXX + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportDefines.hxx b/reportdesign/source/ui/inc/ReportDefines.hxx new file mode 100644 index 000000000..c56e20841 --- /dev/null +++ b/reportdesign/source/ui/inc/ReportDefines.hxx @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX + +namespace rptui +{ + enum class DlgEdMode { Insert, Select }; + +#define REPORT_STARTMARKER_WIDTH 120 +#define REPORT_ENDMARKER_WIDTH 10 +#define REPORT_EXTRA_SPACE 10 + +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTDEFINES_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportSection.hxx b/reportdesign/source/ui/inc/ReportSection.hxx new file mode 100644 index 000000000..03bb57199 --- /dev/null +++ b/reportdesign/source/ui/inc/ReportSection.hxx @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX + +#include <vcl/window.hxx> +#include <RptPage.hxx> +#include <com/sun/star/beans/NamedValue.hpp> +#include <comphelper/propmultiplex.hxx> +#include <cppuhelper/basemutex.hxx> +#include "ReportDefines.hxx" +#include "dlgedfunc.hxx" +#include <vcl/transfer.hxx> +#include <rtl/ref.hxx> +#include <memory> + +namespace rptui +{ + class OReportModel; + class OReportPage; + class OSectionView; + class OSectionWindow; + + class OReportSection : public vcl::Window + , public ::cppu::BaseMutex + , public ::comphelper::OPropertyChangeListener + , public DropTargetHelper + { + OReportPage* m_pPage; + OSectionView* m_pView; + VclPtr<OSectionWindow> m_pParent; + ::std::unique_ptr<DlgEdFunc> m_pFunc; + std::shared_ptr<OReportModel> m_pModel; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pMulti; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; + css::uno::Reference< css::report::XSection > m_xSection; + sal_Int32 m_nPaintEntranceCount; + + DlgEdMode m_eMode; + + /** fills the section with all control from the report section + */ + void fill(); + /** checks all objects if they fit in the new paper width. + */ + void impl_adjustObjectSizePosition(sal_Int32 i_nPaperWidth,sal_Int32 i_nLeftMargin,sal_Int32 i_nRightMargin); + + OReportSection(OReportSection const &) = delete; + void operator =(OReportSection const &) = delete; + protected: + // DropTargetHelper overridables + virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt ) override; + virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt ) override; + + // window overrides + virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override; + virtual void MouseMove( const MouseEvent& rMEvt ) override; + virtual void Command( const CommandEvent& rCEvt ) override; + + // OPropertyChangeListener + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override; + public: + OReportSection(OSectionWindow* _pParent,const css::uno::Reference< css::report::XSection >& _xSection); + virtual ~OReportSection() override; + virtual void dispose() override; + + // window overrides + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) override; + + /** copies the current selection in this section + @param _rAllreadyCopiedObjects This is an out/in put param which contains all already copied objects. + */ + void Copy(css::uno::Sequence< css::beans::NamedValue >& _rAllreadyCopiedObjects); + + void Copy(css::uno::Sequence< css::beans::NamedValue >& _rAllreadyCopiedObjects,bool _bEraseAnddNoClone); + + /** paste a new control in this section + @param _aAllreadyCopiedObjects objects to paste into the section. Only objects are pasted where the name is equal to the section name. + @param _bForce If set to <TRUE/> than the objects will be copied into this section. The name is not compared in this case. + */ + void Paste(const css::uno::Sequence< css::beans::NamedValue >& _aAllreadyCopiedObjects,bool _bForce = false); + + /** Deletes the current selection in this section + * + */ + void Delete(); + + /** All objects will be marked. + */ + void SelectAll(const SdrObjKind _nObjectType); + + /** makes the grid visible + * + * \param _bVisible when <TRUE/> the grid is made visible + */ + void SetGridVisible(bool _bVisible); + + OSectionWindow* getSectionWindow() const { return m_pParent; } + OSectionView& getSectionView() const { return *m_pView; } + OReportPage* getPage() const { return m_pPage; } + const css::uno::Reference< css::report::XSection >& getSection() const { return m_xSection; } + + void SetMode( DlgEdMode m_eMode ); + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** returns the current control report model or <NULL/> + */ + css::uno::Reference< css::report::XReportComponent > getCurrentControlModel() const; + + /** fills the vector with all selected control models + /param _rSelection The vector will be filled and will not be cleared before. + */ + void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const; + + /** creates a default object (custom shape) + * + * @param _sType + */ + void createDefault(const OUString& _sType); + + /** creates a new default custom shape + * + * \param _sType + * \param _pObj + */ + static void createDefault(const OUString& _sType,SdrObject* _pObj); + void stopScrollTimer(); + + /** deactivate the current active ole object if any + */ + void deactivateOle(); + + /** returns true when an ole object is currently active + */ + bool isUiActive() const; + }; + +} //rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTSECTION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ReportWindow.hxx b/reportdesign/source/ui/inc/ReportWindow.hxx new file mode 100644 index 000000000..7e1716384 --- /dev/null +++ b/reportdesign/source/ui/inc/ReportWindow.hxx @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX + +#include <com/sun/star/report/XSection.hpp> +#include "ReportDefines.hxx" +#include <o3tl/deleter.hxx> +#include <svtools/ruler.hxx> +#include <sfx2/zoomitem.hxx> + +#include <memory> +#include <vector> +#include <comphelper/propmultiplex.hxx> + +#include "MarkedSection.hxx" +#include "ViewsWindow.hxx" + +namespace rptui +{ + class ODesignView; + class OScrollWindowHelper; + class OSectionView; + class DlgEdFactory; + + class OReportWindow : public vcl::Window + , public IMarkedSection + , public ::cppu::BaseMutex + , public ::comphelper::OPropertyChangeListener + { + VclPtr<Ruler> m_aHRuler; + VclPtr<ODesignView> m_pView; + VclPtr<OScrollWindowHelper> m_pParent; + VclPtr<OViewsWindow> m_aViewsWindow; + rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener; + std::unique_ptr<DlgEdFactory, o3tl::default_delete<DlgEdFactory>> m_pObjFac; + + void ImplInitSettings(); + + sal_Int32 GetTotalHeight() const; + sal_Int32 impl_getRealPixelWidth() const; + + OReportWindow(OReportWindow const &) = delete; + void operator =(OReportWindow const &) = delete; + protected: + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + // OPropertyChangeListener + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override; + public: + OReportWindow(OScrollWindowHelper* _pParent,ODesignView* _pView); + virtual ~OReportWindow() override; + virtual void dispose() override; + + // Window overrides + virtual void Resize() override; + + ODesignView* getReportView() const { return m_pView; } + OScrollWindowHelper* getScrollWindow() const { return m_pParent; } + + void SetMode( DlgEdMode m_eMode ); + void SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType); + OUString const & GetInsertObjString() const; + void setGridSnap(bool bOn); + void setDragStripes(bool bOn); + + /** copies the current selection in this section + */ + void Copy(); + + /** returns if paste is allowed + * + * \return <TRUE/> if paste is allowed + */ + bool IsPasteAllowed() const; + + /** paste a new control in this section + */ + void Paste(); + + /** Deletes the current selection in this section + * + */ + void Delete(); + + /** All objects will be marked. + */ + void SelectAll(const SdrObjKind _nObjectType); + + /** returns <TRUE/> when an object is marked + */ + bool HasSelection() const; + + Point getThumbPos() const; + + /** removes the section at the given position. + * + * \param _nPosition Zero based. + */ + void removeSection(sal_uInt16 _nPosition); + + /** adds a new section at position _nPosition. + If the section is <NULL/> nothing happens. + If the position is grater than the current elements, the section will be appended. + */ + void addSection(const css::uno::Reference< css::report::XSection >& _xSection + ,const OUString& _sColorEntry + ,sal_uInt16 _nPosition); + + sal_uInt16 getSectionCount() const; + + /** turns the grid on or off + * + * \param _bVisible + */ + void toggleGrid(bool _bVisible); + + + /** shows the ruler + */ + void showRuler(bool _bShow); + + sal_Int32 getRulerHeight() const { return m_aHRuler->GetSizePixel().Height(); } + + /** returns the total width of the first section + */ + sal_Int32 GetTotalWidth() const; + + /** calculate the max width of the markers + * The end marker will not be used for calculation. + * + * \return the max width + */ + sal_Int32 getMaxMarkerWidth() const; + + void ScrollChildren(const Point& _aThumbPos); + + void notifySizeChanged(); + + /** unmark all objects on the views without the given one. + */ + void unmarkAllObjects(); + + /** triggers the property browser with the report component or section + @param _xReportComponent + */ + void showProperties( const css::uno::Reference< css::report::XSection>& _xReportComponent); + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** the section as marked or not marked + @param _pSectionView the section where to set the marked flag + @param _bMark the marked flag + */ + void setMarked(OSectionView const * _pSectionView, bool _bMark); + void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark); + void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark); + + // IMarkedSection + OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override; + OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const; + virtual void markSection(const sal_uInt16 _nPos) override; + + + /** fills the positions of all collapsed sections. + * + * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections. + */ + void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const; + + /** collapse all sections given by their position + * + * \param _aCollapsedSections The position of the sections which should be collapsed. + */ + void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections); + + /** align all marked objects in all sections + */ + void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection); + + sal_uInt32 getMarkedObjectCount() const; + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + + /** fills the vector with all selected control models + /param _rSelection The vector will be filled and will not be cleared before. + */ + void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const; + + /** calculates the zoom factor. + @param _eType which kind of zoom is needed + */ + sal_uInt16 getZoomFactor(SvxZoomType _eType) const; + }; + +} //rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_REPORTWINDOW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/RptUndo.hxx b/reportdesign/source/ui/inc/RptUndo.hxx new file mode 100644 index 000000000..cef45a59d --- /dev/null +++ b/reportdesign/source/ui/inc/RptUndo.hxx @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX + +#include <RptModel.hxx> +#include <UndoActions.hxx> +#include <functional> + +namespace com::sun::star { + namespace drawing { + class XShape; + } +} + +namespace rptui +{ + /** \class OSectionUndo + * Undo class for section add and remove. + */ + class OSectionUndo : public OCommentUndoAction + { + OSectionUndo(const OSectionUndo&) = delete; + void operator =(const OSectionUndo&) = delete; + protected: + ::std::vector< css::uno::Reference< css::drawing::XShape> > + m_aControls; + ::std::vector< ::std::pair< OUString ,css::uno::Any> > + m_aValues; + Action m_eAction; + sal_uInt16 m_nSlot; + bool m_bInserted; + + virtual void implReInsert( ) = 0; + virtual void implReRemove( ) = 0; + + void collectControls(const css::uno::Reference< css::report::XSection >& _xSection); + public: + OSectionUndo( OReportModel& rMod + ,sal_uInt16 _nSlot + ,Action _eAction + ,TranslateId pCommentID); + virtual ~OSectionUndo() override; + + virtual void Undo() override; + virtual void Redo() override; + }; + + /** Undo action for the group header, footer, page header, footer + */ + class OReportSectionUndo : public OSectionUndo + { + OReportHelper m_aReportHelper; + ::std::function<css::uno::Reference< css::report::XSection >(OReportHelper *)> m_pMemberFunction; + + void implReInsert( ) override; + void implReRemove( ) override; + OReportSectionUndo(const OReportSectionUndo&) = delete; + void operator =(const OReportSectionUndo&) = delete; + public: + //OReportSectionUndo( const css::uno::Reference< css::report::XSection >& _xSection + OReportSectionUndo( OReportModel& rMod + ,sal_uInt16 _nSlot + ,::std::function<css::uno::Reference< css::report::XSection >(OReportHelper *)> _pMemberFunction + ,const css::uno::Reference< css::report::XReportDefinition >& _xReport + ,Action _eAction); + virtual ~OReportSectionUndo() override; + }; + + /** Undo action for the group header, footer + */ + class OGroupSectionUndo : public OSectionUndo + { + OGroupHelper m_aGroupHelper; + ::std::function<css::uno::Reference< css::report::XSection >(OGroupHelper *)> m_pMemberFunction; + + mutable OUString m_sName; + + void implReInsert( ) override; + void implReRemove( ) override; + OGroupSectionUndo(const OGroupSectionUndo&) = delete; + void operator =(const OGroupSectionUndo&) = delete; + public: + //OGroupSectionUndo( const css::uno::Reference< css::report::XSection >& _xSection + OGroupSectionUndo( OReportModel& rMod + ,sal_uInt16 _nSlot + ,::std::function<css::uno::Reference< css::report::XSection >(OGroupHelper *)> _pMemberFunction + ,const css::uno::Reference< css::report::XGroup >& _xGroup + ,Action _eAction + ,TranslateId pCommentID); + + virtual OUString GetComment() const override; + }; + + /** /class OGroupUndo + * \brief Undo action for removing a group object. + */ + class OGroupUndo : public OCommentUndoAction + { + css::uno::Reference< css::report::XGroup> m_xGroup; ///<! the group for the undo redo action + css::uno::Reference< css::report::XReportDefinition > m_xReportDefinition; ///<! the parent report definition + Action m_eAction; ///<! the current action + sal_Int32 m_nLastPosition; ///<! the last position of the group + + void implReInsert( ); + void implReRemove( ); + public: + OGroupUndo(OReportModel& rMod + ,TranslateId pCommentID + ,Action _eAction + ,const css::uno::Reference< css::report::XGroup>& _xGroup + ,const css::uno::Reference< css::report::XReportDefinition >& _xReportDefinition); + virtual void Undo() override; + virtual void Redo() override; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_RPTUNDO_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ScrollHelper.hxx b/reportdesign/source/ui/inc/ScrollHelper.hxx new file mode 100644 index 000000000..076943ff7 --- /dev/null +++ b/reportdesign/source/ui/inc/ScrollHelper.hxx @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX + +#include <vcl/scrbar.hxx> +#include <com/sun/star/report/XSection.hpp> +#include <comphelper/propmultiplex.hxx> +#include "ReportDefines.hxx" +#include <cppuhelper/basemutex.hxx> +#include <rtl/ref.hxx> +#include "MarkedSection.hxx" +#include "ReportWindow.hxx" + +namespace rptui +{ + class ODesignView; + class OReportWindow; + class OSectionView; + + /** This class defines the scrollable area of the report design. It includes + the h-ruler and the sections, and end marker. Not the start marker. + */ + typedef vcl::Window OScrollWindowHelper_BASE; + class OScrollWindowHelper : public ::cppu::BaseMutex + , public OScrollWindowHelper_BASE/*TabPage*/ + , public ::comphelper::OPropertyChangeListener + , public IMarkedSection + { + private: + VclPtr<ScrollBar> m_aHScroll; + VclPtr<ScrollBar> m_aVScroll; + VclPtr<ScrollBarBox> m_aCornerWin; // window in the bottom right corner + Size m_aTotalPixelSize; + VclPtr<ODesignView> m_pParent; + VclPtr<OReportWindow> m_aReportWindow; + ::rtl::Reference<comphelper::OPropertyChangeMultiplexer > + m_pReportDefinitionMultiPlexer; // listener for property changes + + DECL_LINK( ScrollHdl, ScrollBar*, void); + Size ResizeScrollBars(); + void ImplInitSettings(); + void impl_initScrollBar( ScrollBar& _rScrollBar ) const; + + OScrollWindowHelper(OScrollWindowHelper const &) = delete; + void operator =(OScrollWindowHelper const &) = delete; + protected: + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + // window + virtual void Resize() override; + virtual bool EventNotify( NotifyEvent& rNEvt ) override; + // OPropertyChangeListener + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override; + public: + OScrollWindowHelper( ODesignView* _pReportDesignView); + virtual ~OScrollWindowHelper() override; + virtual void dispose() override; + + /** late ctor + */ + void initialize(); + + Point getThumbPos() const { return Point(m_aHScroll->GetThumbPos(),m_aVScroll->GetThumbPos())/*m_aScrollOffset*/; } + void setTotalSize(sal_Int32 _nWidth, sal_Int32 _nHeight); + const Size& getTotalSize() const { return m_aTotalPixelSize; } + ScrollBar& GetHScroll() { return *m_aHScroll; } + ScrollBar& GetVScroll() { return *m_aVScroll; } + + // forwards + void SetMode( DlgEdMode _eMode ); + void SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType); + OUString const & GetInsertObjString() const; + void setGridSnap(bool bOn); + void setDragStripes(bool bOn); + /** copies the current selection in this section + */ + void Copy(); + + /** returns if paste is allowed + * + * \return <TRUE/> if paste is allowed + */ + bool IsPasteAllowed() const; + + /** paste a new control in this section + */ + void Paste(); + + /** Deletes the current selection in this section + * + */ + void Delete(); + + /** All objects will be marked. + */ + void SelectAll(const SdrObjKind _nObjectType); + + /** returns <TRUE/> when an object is marked + */ + bool HasSelection() const; + + /** removes the section at the given position. + * + * \param _nPosition Zero based. + */ + void removeSection(sal_uInt16 _nPosition); + + /** adds a new section at position _nPosition. + If the section is <NULL/> nothing happens. + If the position is grater than the current elements, the section will be appended. + */ + void addSection(const css::uno::Reference< css::report::XSection >& _xSection + ,const OUString& _sColorEntry + ,sal_uInt16 _nPosition); + + sal_uInt16 getSectionCount() const; + + /** turns the grid on or off + * + * \param _bVisible + */ + void toggleGrid(bool _bVisible); + + /** unmark all objects on the views. + */ + void unmarkAllObjects(); + + /** shows or hides the ruler. + */ + void showRuler(bool _bShow); + + /** calculate the max width of the markers + * + * The end marker will not be used for calculation. + * \return the max width + */ + sal_Int32 getMaxMarkerWidth() const; + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** the section as marked or not marked + @param _pSectionView the section where to set the marked flag + @param _bMark the marked flag + */ + void setMarked(OSectionView const * _pSectionView, bool _bMark); + void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark); + void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark); + + // IMarkedSection + OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override; + OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const; + virtual void markSection(const sal_uInt16 _nPos) override; + + + /** fills the positions of all collapsed sections. + * + * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections. + */ + void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const; + + /** collapse all sections given by their position + * + * \param _aCollapsedSections The position of the sections which should be collapsed. + */ + void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections); + + /** align all marked objects in all sections + */ + void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection); + + sal_uInt32 getMarkedObjectCount() const; + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + + /** fills the vector with all selected control models + /param _rSelection The vector will be filled and will not be cleared before. + */ + void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const; + + /** calculates the zoom factor. + @param _eType which kind of zoom is needed + */ + sal_uInt16 getZoomFactor(SvxZoomType _eType) const; + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SCROLLHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/SectionView.hxx b/reportdesign/source/ui/inc/SectionView.hxx new file mode 100644 index 000000000..df3cbc7b0 --- /dev/null +++ b/reportdesign/source/ui/inc/SectionView.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX + + +#include <svx/svdview.hxx> +namespace rptui +{ +class OReportWindow; +class OReportSection; + + +// OSectionView + + +class OSectionView : public SdrView +{ +private: + VclPtr<OReportWindow> m_pReportWindow; + VclPtr<OReportSection> m_pSectionWindow; + + void ObjectRemovedInAliveMode( const SdrObject* pObject ); + OSectionView(const OSectionView&) = delete; + void operator =(const OSectionView&) = delete; +public: + + OSectionView( + SdrModel& rSdrModel, + OReportSection* _pSectionWindow, + OReportWindow* pEditor); + + virtual ~OSectionView() override; + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; + virtual void MarkListHasChanged() override; + virtual void MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin ) override; + + OReportSection* getReportSection() const { return m_pSectionWindow; } + + // switch the marked objects to the given layer. + void SetMarkedToLayer( SdrLayerID nLayerNo ); + + // return true when only shapes are marked, otherwise false. + bool OnlyShapesMarked() const; + + /* returns the common layer id of the marked objects, otherwise -1 will be returned. + */ + SdrLayerID GetLayerIdOfMarkedObjects() const; + + // returns true if objects at Drag & Drop is resize not move + bool IsDragResize() const; +}; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONVIEW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/SectionWindow.hxx b/reportdesign/source/ui/inc/SectionWindow.hxx new file mode 100644 index 000000000..1e727c2e5 --- /dev/null +++ b/reportdesign/source/ui/inc/SectionWindow.hxx @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX + +#include <com/sun/star/report/XSection.hpp> +#include <vcl/window.hxx> +#include <vcl/split.hxx> +#include <comphelper/propmultiplex.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <UndoActions.hxx> +#include "StartMarker.hxx" +#include "EndMarker.hxx" +#include "ReportSection.hxx" + +namespace comphelper +{ + class OPropertyChangeMultiplexer; +} +namespace rptui +{ + class OViewsWindow; + class OSectionWindow : public vcl::Window + , public ::cppu::BaseMutex + , public ::comphelper::OPropertyChangeListener + { + VclPtr<OViewsWindow> m_pParent; + VclPtr<OStartMarker> m_aStartMarker; + VclPtr<OReportSection> m_aReportSection; + VclPtr<Splitter> m_aSplitter; + VclPtr<OEndMarker> m_aEndMarker; + + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pSectionMulti; + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pGroupMulti; + + OSectionWindow(OSectionWindow const &) = delete; + void operator =(OSectionWindow const &) = delete; + + /** set the title of the group header or footer + * + * \param _xGroup + * \param _nResId + * \param _pGetSection + * \param _pIsSectionOn + * @return sal_True when title was set otherwise FALSE + */ + bool setGroupSectionTitle( + const css::uno::Reference<css::report::XGroup>& _xGroup, TranslateId pResId, + const ::std::function<css::uno::Reference<css::report::XSection>(OGroupHelper*)>& + _pGetSection, + const ::std::function<bool(OGroupHelper*)>& _pIsSectionOn); + + /** set the title of the (report/page) header or footer + * + * \param _xGroup + * \param _nResId + * \param _pGetSection + * \param _pIsSectionOn + * @return sal_True when title was set otherwise FALSE + */ + bool setReportSectionTitle( + const css::uno::Reference<css::report::XReportDefinition>& _xReport, TranslateId pResId, + const ::std::function<css::uno::Reference<css::report::XSection>(OReportHelper*)>& + _pGetSection, + const ::std::function<bool(OReportHelper*)>& _pIsSectionOn); + void ImplInitSettings(); + + DECL_LINK(Collapsed, OColorListener&, void); + DECL_LINK(StartSplitHdl, Splitter*, void); + DECL_LINK(SplitHdl, Splitter*, void); + DECL_LINK(EndSplitHdl, Splitter*, void); + + + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + // Window overrides + virtual void Resize() override; + + protected: + virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) override; + public: + OSectionWindow( OViewsWindow* _pParent + ,const css::uno::Reference< css::report::XSection >& _xSection + ,const OUString& _sColorEntry); + virtual ~OSectionWindow() override; + virtual void dispose() override; + + OStartMarker& getStartMarker() { return *m_aStartMarker; } + OReportSection& getReportSection() { return *m_aReportSection; } + OEndMarker& getEndMarker() { return *m_aEndMarker; } + OViewsWindow* getViewsWindow() { return m_pParent; } + + void setCollapsed(bool _bCollapsed); + + /** triggers the property browser with the section + @param _pStartMarker + */ + void showProperties(); + + /** set the marker as marked or not marked + @param _bMark set the new state of the marker + */ + void setMarked(bool _bMark); + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + + void scrollChildren(tools::Long _nThumbPosX); + }; + +} // rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_SECTIONWINDOW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/StartMarker.hxx b/reportdesign/source/ui/inc/StartMarker.hxx new file mode 100644 index 000000000..630630faa --- /dev/null +++ b/reportdesign/source/ui/inc/StartMarker.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX + +#include <osl/interlck.h> +#include <svtools/ruler.hxx> +#include "ColorListener.hxx" +#include <vcl/image.hxx> + +namespace rptui +{ + class OSectionWindow; + class OStartMarker : public OColorListener + { + + VclPtr<Ruler> m_aVRuler; + OUString m_aText; + tools::Rectangle m_aTextRect; + Image m_aImage; + tools::Rectangle m_aImageRect; + VclPtr<OSectionWindow> m_pParent; + static Image* s_pDefCollapsed; + static Image* s_pDefExpanded; + static oslInterlockedCount s_nImageRefCount; /// When 0 all static images will be destroyed + + bool m_bShowRuler; + + void changeImage(); + void initDefaultNodeImages(); + + virtual void ImplInitSettings() override; + virtual void ApplySettings(vcl::RenderContext& rRenderContext) override; + + OStartMarker(OStartMarker const &) = delete; + void operator =(OStartMarker const &) = delete; + public: + OStartMarker(OSectionWindow* _pParent,const OUString& _sColorEntry); + virtual ~OStartMarker() override; + virtual void dispose() override; + + // SfxListener + virtual void Notify(SfxBroadcaster & rBc, SfxHint const & rHint) override; + // Window overrides + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; + virtual void MouseButtonUp(const MouseEvent& rMEvt) override; + virtual void Resize() override; + virtual void RequestHelp(const HelpEvent& rHEvt) override; + + void setTitle(const OUString& _sTitle); + sal_Int32 getMinHeight() const; + + /** shows or hides the ruler. + */ + void showRuler(bool _bShow); + + virtual void setCollapsed(bool _bCollapsed) override; + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + }; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STARTMARKER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/UITools.hxx b/reportdesign/source/ui/inc/UITools.hxx new file mode 100644 index 000000000..13aafb14f --- /dev/null +++ b/reportdesign/source/ui/inc/UITools.hxx @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX + +#include <com/sun/star/report/XGroup.hpp> +#include <com/sun/star/report/XReportControlFormat.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include "ReportSection.hxx" +#include <rtl/ref.hxx> +#include <vcl/taskpanelist.hxx> +#include <comphelper/stl_types.hxx> + +class SdrPage; +class SdrObject; +class SdrUnoObj; +class SdrView; +namespace tools { class Rectangle; } +namespace comphelper +{ + class OPropertyChangeMultiplexer; + class OPropertyChangeListener; +} +namespace rptui +{ + /** returns the position of the object inside the index container + @param _xReportDefinition the report definition to get the groups + @param _xGroup the group to search + @return returns the position of the group in the list, otherwise -1 + */ + template<typename T> sal_Int32 getPositionInIndexAccess( + const css::uno::Reference< css::container::XIndexAccess >& _xCollection + ,const css::uno::Reference< T >& _xSearch) + { + sal_Int32 nCount = _xCollection->getCount(); + sal_Int32 i = (nCount == 0) ? -1 : 0; + for (;i<nCount ; ++i) + { + css::uno::Reference< T > xObject(_xCollection->getByIndex(i),css::uno::UNO_QUERY); + if ( xObject == _xSearch ) + break; + } + return i; + } + + /** set the name of the header and footer of the group by the expression appended by the localized name of the section + @param _xGroup the group where the header/footer name is set by the expression of the group + */ + void adjustSectionName(const css::uno::Reference< css::report::XGroup >& _xGroup,sal_Int32 _nPos); + + /** add a listener for the properties size, left margin, right margin to the page style + * + * \param _xReportDefinition + * \param _pListener + * \return + */ + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> addStyleListener( const css::uno::Reference< css::report::XReportDefinition >& _xReportDefinition + ,::comphelper::OPropertyChangeListener* _pListener); + + /** opens the common character font dialog + */ + bool openCharDialog( + const css::uno::Reference< css::report::XReportControlFormat>& _xReportControlFormat, + const css::uno::Reference< css::awt::XWindow>& _xWindow, + css::uno::Sequence< css::beans::NamedValue >& _out_rNewValues + ); + + /** opens the area dialog for shapes + */ + bool openAreaDialog( + const css::uno::Reference< css::report::XShape >& _xShape + ,const css::uno::Reference< css::awt::XWindow>& _xWindow + ); + + /** opens the formula dialog + @param _out_rFormula + the formula chosen by the user + @precond + we're really inspecting a database report (well, a RowSet at least) + @return + <TRUE/> if and only if the user successfully chose a clause + */ + bool openDialogFormula_nothrow( OUString& _in_out_rFormula + , const css::uno::Reference< css::uno::XComponentContext >& _xContext + , const css::uno::Reference< css::awt::XWindow>& _xWindow + , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet + ); + + /** applies the character settings previously obtained via openCharDialog + */ + void applyCharacterSettings( + const css::uno::Reference< css::report::XReportControlFormat >& _rxReportControlFormat, + const css::uno::Sequence< css::beans::NamedValue >& _rSettings + ); + + /** notifySystemWindow adds or remove the given window _pToRegister at the Systemwindow found when search _pWindow. + @param pWindow + The window which is used to search for the SystemWindow. + @param pToRegister + The window which should be added or removed on the TaskPaneList. + @param rMemFunc + The member function which should be called at the SystemWindow when found. + Possible values are: + ::comphelper::mem_fun(&TaskPaneList::AddWindow) + ::comphelper::mem_fun(&TaskPaneList::RemoveWindow) + */ + void notifySystemWindow(vcl::Window const * pWindow, vcl::Window* pToRegister, const ::comphelper::mem_fun1_t<TaskPaneList, vcl::Window*>& rMemFunc); + + + const sal_Int16 ISOVER_IGNORE_CUSTOMSHAPES = 1; + + /** checks whether the given rectangle overlapps another OUnoObject object in that view. + * + * \param _rRect + * \param _rPage + * \param _bAllObjects if <TRUE/> all objects are taken into account, otherwise only not marked ones + * \return the object which is overlapped, otherwise <NULL/> + */ + SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects = false,SdrObject const * _pIgnore = nullptr, sal_Int16 _nIgnoreType=0); + + SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnoreList[], int _nIgnoreListLength); + + /** checks whether the given OUnoObject object rectangle overlapps another object in that view. + * + * \param _pObj + * \param _rPage + * \param _rView + * \return the object which is overlapped, otherwise <NULL/>. If the given object is not of type OUnoObject <NULL/> will be returned. + */ + SdrObject* isOver(SdrObject const * _pObj,SdrPage const & _rPage,SdrView const & _rView); + + /** retrieves the names of the parameters of the command which the given RowSet is bound to + */ + css::uno::Sequence< OUString > + getParameterNames( const css::uno::Reference< css::sdbc::XRowSet >& _rxRowSet ); + + /** ensures that no control overlaps the given one. + * + * \param pControl the control which should place in the section without overlapping + * \param _pReportSection the section + * \param _bInsert sal_True when the control should be inserted, otherwise not. + */ + void correctOverlapping(SdrObject* pControl,OReportSection const & _aReportSection,bool _bInsert = true); + + /** returns a Rectangle of a given SdrObject + * + * \param pControl the SdrObject + */ + + tools::Rectangle getRectangleFromControl(SdrObject* pControl); + + /** sets the map mode at the window + @param _aZoom the zoom scale + @param _rWindow where to set the map mode + */ + void setZoomFactor(const Fraction& _aZoom, vcl::Window& _rWindow); +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_UITOOLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/ViewsWindow.hxx b/reportdesign/source/ui/inc/ViewsWindow.hxx new file mode 100644 index 000000000..f83e28ca8 --- /dev/null +++ b/reportdesign/source/ui/inc/ViewsWindow.hxx @@ -0,0 +1,294 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX + +#include <com/sun/star/report/XSection.hpp> +#include <vcl/window.hxx> +#include <svtools/colorcfg.hxx> +#include "ReportDefines.hxx" +#include "SectionView.hxx" +#include <unotools/options.hxx> +#include <vector> + +#include "MarkedSection.hxx" +#include "SectionWindow.hxx" + +class SdrHdl; + +namespace rptui +{ + class OReportWindow; + class OReportSection; + class OSectionView; + enum class ControlModification; + + struct RectangleLess + { + enum CompareMode { POS_LEFT,POS_RIGHT,POS_UPPER,POS_DOWN,POS_CENTER_HORIZONTAL,POS_CENTER_VERTICAL }; + CompareMode m_eCompareMode; + Point m_aRefPoint; + RectangleLess(CompareMode _eCompareMode,const Point& _rRefPoint ) : m_eCompareMode(_eCompareMode),m_aRefPoint(_rRefPoint){} + bool operator() (const tools::Rectangle& lhs, const tools::Rectangle& rhs) const + { + switch(m_eCompareMode) + { + case POS_LEFT: + return lhs.Left() < rhs.Left(); + case POS_RIGHT: + return lhs.Right() >= rhs.Right(); + case POS_UPPER: + return lhs.Top() < rhs.Top(); + case POS_DOWN: + return lhs.Bottom() >= rhs.Bottom(); + case POS_CENTER_HORIZONTAL: + return std::abs(m_aRefPoint.X() - lhs.Center().X()) < std::abs(m_aRefPoint.X() - rhs.Center().X()); + case POS_CENTER_VERTICAL: + return std::abs(lhs.Center().Y() - m_aRefPoint.Y()) < std::abs(rhs.Center().Y() - m_aRefPoint.Y()); + } + return false; + } + }; + + class OViewsWindow : public vcl::Window + , public utl::ConfigurationListener + , public IMarkedSection + { + typedef ::std::multimap<tools::Rectangle,::std::pair<SdrObject*,OSectionView*>,RectangleLess> TRectangleMap; + public: + typedef ::std::vector< VclPtr<OSectionWindow> > TSectionsMap; + + private: + TSectionsMap m_aSections; + svtools::ColorConfig m_aColorConfig; + VclPtr<OReportWindow> m_pParent; + OUString m_sShapeType; + bool m_bInUnmark; + + void ImplInitSettings(); + /** returns the iterator at pos _nPos or the end() + */ + TSectionsMap::iterator getIteratorAtPos(sal_uInt16 _nPos); + void collectRectangles(TRectangleMap& _rMap); + static void collectBoundResizeRect(const TRectangleMap& _rSortRectangles, ControlModification _nControlModification,bool _bAlignAtSection,tools::Rectangle& _rBound,tools::Rectangle& _rResize); + void impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet); + + OViewsWindow(OViewsWindow const &) = delete; + void operator =(OViewsWindow const &) = delete; + protected: + virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; + // Window overrides + virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) override; + + virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const tools::Rectangle& rRect ) override; + virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override; + public: + OViewsWindow( + OReportWindow* _pReportWindow); + virtual ~OViewsWindow() override; + virtual void dispose() override; + + // Window overrides + virtual void Resize() override; + + void resize(const OSectionWindow& _rSectionWindow); + + OReportWindow* getView() const { return m_pParent; } + + /** removes the section at the given position. + * + * \param _nPosition Zero based. + */ + void removeSection(sal_uInt16 _nPosition); + + /** adds a new section at position _nPosition. + If the section is <NULL/> nothing happens. + If the position is grater than the current elements, the section will be appended. + */ + void addSection(const css::uno::Reference< css::report::XSection >& _xSection + ,const OUString& _sColorEntry + ,sal_uInt16 _nPosition); + + sal_uInt16 getSectionCount() const; + /** return the section at the given position + * + * \param _nPos + * \return the section at this pos or an empty section + */ + OSectionWindow* getSectionWindow(const sal_uInt16 _nPos) const; + + /** turns the grid on or off + * + * \param _bVisible + */ + void toggleGrid(bool _bVisible); + void setGridSnap(bool bOn); + void setDragStripes(bool bOn); + + /** returns the total accumulated height of all sections until _pSection is reached + */ + sal_Int32 getTotalHeight() const; + + bool empty() const { return m_aSections.empty(); } + void SetMode( DlgEdMode m_eMode ); + void SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType); + const OUString& GetInsertObjString() const { return m_sShapeType;} + /** copies the current selection in this section + */ + void Copy(); + + /** returns if paste is allowed + * + * \return <TRUE/> if paste is allowed + */ + bool IsPasteAllowed() const; + + /** paste a new control in this section + */ + void Paste(); + + /** Deletes the current selection in this section + * + */ + void Delete(); + + /** All objects will be marked. + */ + void SelectAll(const SdrObjKind _nObjectType); + + /** returns <TRUE/> when an object is marked + */ + bool HasSelection() const; + + /** unmark all objects on the views without the given one. + * + * @param _pSectionView The view where the objects should not be unmarked. + */ + void unmarkAllObjects(OSectionView const * _pSectionView); + + /** returns the report section window for the given xsection + @param _xSection the section + */ + OSectionWindow* getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const; + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** the section as marked or not marked + @param _pSectionView the section where to set the marked flag + @param _bMark the marked flag + */ + void setMarked(OSectionView const * _pSectionView, bool _bMark); + void setMarked(const css::uno::Reference< css::report::XSection>& _xSection, bool _bMark); + void setMarked(const css::uno::Sequence< css::uno::Reference< css::report::XReportComponent> >& _xShape, bool _bMark); + + // IMarkedSection + OSectionWindow* getMarkedSection(NearSectionAccess nsa = CURRENT) const override; + virtual void markSection(const sal_uInt16 _nPos) override; + + /** align all marked objects in all sections + */ + void alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection); + + /** creates a default object + * + */ + void createDefault(); + + /** shows or hides the ruler. + */ + void showRuler(bool _bShow); + + /** returns the currently set shape type. + * + * \return \member m_sShapeType + */ + const OUString& getShapeType() const { return m_sShapeType; } + + /** returns the current position in the list + */ + sal_uInt16 getPosition(const OSectionWindow* _pSectionWindow) const; + + /** calls on every section BrkAction + * + */ + void BrkAction(); + void BegMarkObj(const Point& _aPnt,const OSectionView* _pSection); + + private: + void BegDragObj_createInvisibleObjectAtPosition(const tools::Rectangle& _aRect, const OSectionView& _rSection); + void EndDragObj_removeInvisibleObjects(); + Point m_aDragDelta; + ::std::vector<SdrObject*> m_aBegDragTempList; + public: + void BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection); + void EndDragObj(bool _bDragIntoNewSection,const OSectionView* _pSection,const Point& _aPnt); + + void EndAction(); + void ForceMarkedToAnotherPage(); + bool IsAction() const; + bool IsDragObj() const; + void handleKey(const vcl::KeyCode& _rCode); + void stopScrollTimer(); + + /** return the section at the given point which is relative to the given section + * + * \param _pSection the section which is used as reference point + * \param _rPnt the point, it will be changed that it is inside the section which will be returned + * \return the section + */ + OSectionView* getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt); + + void MovAction(const Point& rPnt,const OSectionView* _pSection, bool _bControlKeySet); + + sal_uInt32 getMarkedObjectCount() const; + + /** fills the positions of all collapsed sections. + * + * \param _rCollapsedPositions Out parameter which holds afterwards all positions of the collapsed sections. + */ + void fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const; + + /** collapse all sections given by their position + * + * \param _aCollapsedSections The position of the sections which should be collapsed. + */ + void collapseSections(const css::uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections); + + /** zoom the ruler and view windows + */ + void zoom(const Fraction& _aZoom); + + void scrollChildren(const Point& _aThumbPos); + + /** fills the vector with all selected control models + /param _rSelection The vector will be filled and will not be cleared before. + */ + void fillControlModelSelection(::std::vector< css::uno::Reference< css::uno::XInterface > >& _rSelection) const; + }; + +} // rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_VIEWSWINDOW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/dlgedclip.hxx b/reportdesign/source/ui/inc/dlgedclip.hxx new file mode 100644 index 000000000..0290a0293 --- /dev/null +++ b/reportdesign/source/ui/inc/dlgedclip.hxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX + +#include <vcl/transfer.hxx> +#include <com/sun/star/beans/NamedValue.hpp> + +namespace rptui +{ +// OReportExchange + +/** \class OReportExchange + * \brief defines a clipboard format for copying selection elements. + * \ingroup reportdesign_source_ui_report + * + * + */ +class OReportExchange : public TransferableHelper +{ +public: + typedef css::uno::Sequence<css::beans::NamedValue> TSectionElements; + + /** Constructs a new exchange object with section elements + * + * \param _rCopyElements the elements to copy. Each section is one entry. The value must be a sequence of elements. + * \return + */ + OReportExchange(const TSectionElements& _rCopyElements); + + /** checks whether or not a descriptor can be extracted from the data flavor vector given + * + * \param _rFlavors + available flavors + * \return + */ + static bool canExtract(const DataFlavorExVector& _rFlavors); + + /** extract the section elements + * + * \param _rData the clipboard data + * \return the copied elements + */ + static TSectionElements extractCopies(const TransferableDataHelper& _rData); + + /** returns the format id. + * + * \return the registered format id + */ + static SotClipboardFormatId getDescriptorFormatId(); + +protected: + // TransferableHelper overridables + virtual void AddSupportedFormats() override; + virtual bool GetData(const css::datatransfer::DataFlavor& rFlavor, + const OUString& rDestDoc) override; + +private: + TSectionElements m_aCopyElements; +}; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDCLIP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/dlgedfac.hxx b/reportdesign/source/ui/inc/dlgedfac.hxx new file mode 100644 index 000000000..6a79ef780 --- /dev/null +++ b/reportdesign/source/ui/inc/dlgedfac.hxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX + +#include <svx/svdobj.hxx> +#include <tools/link.hxx> + +namespace rptui +{ +// DlgEdFactory + +class DlgEdFactory +{ +public: + DlgEdFactory(); + ~DlgEdFactory() COVERITY_NOEXCEPT_FALSE; + + DECL_STATIC_LINK(DlgEdFactory, MakeObject, SdrObjCreatorParams, SdrObject*); +}; +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFAC_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/dlgedfunc.hxx b/reportdesign/source/ui/inc/dlgedfunc.hxx new file mode 100644 index 000000000..403f548e0 --- /dev/null +++ b/reportdesign/source/ui/inc/dlgedfunc.hxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX + +#include <tools/gen.hxx> +#include <vcl/event.hxx> +#include <vcl/timer.hxx> +#include <com/sun/star/uno/XInterface.hpp> + +class Timer; +class MouseEvent; +class Point; +class SdrTextObj; +class SdrObject; +namespace rptui +{ + +class OReportSection; +class OSectionView; + + +// DlgEdFunc + + +class DlgEdFunc /* : public LinkHdl */ +{ + DlgEdFunc(const DlgEdFunc&) = delete; + void operator =(const DlgEdFunc&) = delete; +protected: + VclPtr<OReportSection> m_pParent; + OSectionView& m_rView; + Timer aScrollTimer; + Point m_aMDPos; + css::uno::Reference<css::uno::XInterface> m_xOverlappingObj; + SdrObject * m_pOverlappingObj; + Color m_nOverlappedControlColor; + Color m_nOldColor; + bool m_bSelectionMode; + bool m_bUiActive; + bool m_bShowPropertyBrowser; + + DECL_LINK( ScrollTimeout, Timer *, void ); + void ForceScroll( const Point& rPos ); + /** checks that no other object is overlapped. + * + * \param rMEvt + */ + void checkMovementAllowed(const MouseEvent& rMEvt); + + /** sets the correct mouse pointer when moving an object + * + * \param rMEvt + * \return <TRUE/> when the pointer was already set. + */ + bool setMovementPointer(const MouseEvent& rMEvt); + + bool isRectangleHit(const MouseEvent& rMEvt); + /** + returns true, as long as only customshapes in the marked list, + custom shapes can drop every where + */ + bool isOnlyCustomShapeMarked() const; + + /** activate object if it is of type OBJ_OLE2 + */ + void activateOle(SdrObject* _pObj); + + void checkTwoClicks(const MouseEvent& rMEvt); + +public: + DlgEdFunc( OReportSection* pParent ); + virtual ~DlgEdFunc(); + + virtual bool MouseButtonDown( const MouseEvent& rMEvt ); + virtual bool MouseButtonUp( const MouseEvent& rMEvt ); + virtual bool MouseMove( const MouseEvent& rMEvt ); + + /** checks if the keycode is known by the child windows + @param _rCode the keycode + @return <TRUE/> if the keycode is handled otherwise <FALSE/> + */ + bool handleKeyEvent(const KeyEvent& _rEvent); + + /** returns <TRUE/> if the mouse event is over an existing object + * + * \param rMEvt + * \return <TRUE/> if overlapping, otherwise <FALSE/> + */ + bool isOverlapping(const MouseEvent& rMEvt); + void setOverlappedControlColor(Color _nColor); + void stopScrollTimer(); + + /** deactivate all ole object + */ + void deactivateOle(bool _bSelect = false); + + bool isUiActive() const { return m_bUiActive; } +protected: + void colorizeOverlappedObject(SdrObject* _pOverlappedObj); + void unColorizeOverlappedObj(); + + +}; + + +// DlgEdFuncInsert + + +class DlgEdFuncInsert : public DlgEdFunc +{ +public: + DlgEdFuncInsert( OReportSection* pParent ); + virtual ~DlgEdFuncInsert() override; + + virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual bool MouseButtonUp( const MouseEvent& rMEvt ) override; + virtual bool MouseMove( const MouseEvent& rMEvt ) override; +}; + + +// DlgEdFuncSelect + + +class DlgEdFuncSelect : public DlgEdFunc +{ +public: + DlgEdFuncSelect( OReportSection* pParent ); + virtual ~DlgEdFuncSelect() override; + + virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override; + virtual bool MouseButtonUp( const MouseEvent& rMEvt ) override; + virtual bool MouseMove( const MouseEvent& rMEvt ) override; +}; + +} +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGEDFUNC_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/dlgpage.hxx b/reportdesign/source/ui/inc/dlgpage.hxx new file mode 100644 index 000000000..0e40bd0c6 --- /dev/null +++ b/reportdesign/source/ui/inc/dlgpage.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX + +#include <sfx2/tabdlg.hxx> + +namespace rptui +{ +/************************************************************************* +|* +|* Page setup tab dialog +|* +\************************************************************************/ +class ORptPageDialog : public SfxTabDialogController +{ +private: + ORptPageDialog(const ORptPageDialog&) = delete; + void operator=(const ORptPageDialog&) = delete; + +public: + ORptPageDialog(weld::Window* pParent, const SfxItemSet* pAttr, const OUString& rDialog); + virtual void PageCreated(const OString& rId, SfxTabPage& rPage) override; +}; + +} // namespace rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_DLGPAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/metadata.hxx b/reportdesign/source/ui/inc/metadata.hxx new file mode 100644 index 000000000..c5ea24a82 --- /dev/null +++ b/reportdesign/source/ui/inc/metadata.hxx @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX + +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/inspection/XPropertyHandler.hpp> +#include <o3tl/typed_flags_set.hxx> + +#include <string_view> +#include <vector> + + //= UI flags (for all browsable properties) +enum class PropUIFlags { + NONE = 0x0001, // no special flag + Composeable = 0x0002, // the property is "composeable", i.e. an intersection of property + // sets should expose it, if all elements do + DataProperty = 0x0004 // the property is to appear on the "Data" page +}; +namespace o3tl { + template<> struct typed_flags<PropUIFlags> : is_typed_flags<PropUIFlags, 0x0007> {}; +} + + +namespace rptui +{ + + + struct OPropertyInfoImpl; + + + //= OPropertyInfoService + + class OPropertyInfoService final + { + public: + // IPropertyInfoService + static sal_Int32 getPropertyId(const OUString& _rName); + static OUString getPropertyTranslation(sal_Int32 _nId); + static OString getPropertyHelpId(sal_Int32 _nId); + static PropUIFlags getPropertyUIFlags(sal_Int32 _nId); + static void getExcludeProperties(::std::vector< css::beans::Property >& _rExcludeProperties,const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler); + + static bool isComposable( + const OUString& _rPropertyName, + const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler + ); + + private: + static const OPropertyInfoImpl* getPropertyInfo(); + + static const OPropertyInfoImpl* getPropertyInfo(const OUString& _rName); + static const OPropertyInfoImpl* getPropertyInfo(sal_Int32 _nId); + + OPropertyInfoService(const OPropertyInfoService&) = delete; + void operator =(const OPropertyInfoService&) = delete; + OPropertyInfoService() = delete; + + static sal_uInt16 s_nCount; + static OPropertyInfoImpl* s_pPropertyInfos; + // TODO: a real structure which allows quick access by name as well as by id + }; + + + //= HelpIdUrl + + /// small helper to translate help ids into help urls + class HelpIdUrl + { + public: + static OUString getHelpURL( std::string_view _sHelpId ); + }; + + + //= property ids (for all browsable properties) + //= The ID is used for the view order in the property browser. + + + #define PROPERTY_ID_FORCENEWPAGE 1 + #define PROPERTY_ID_NEWROWORCOL 2 + #define PROPERTY_ID_KEEPTOGETHER 3 + #define PROPERTY_ID_CANGROW 4 + #define PROPERTY_ID_CANSHRINK 5 + #define PROPERTY_ID_REPEATSECTION 6 + #define PROPERTY_ID_PRESERVEIRI 7 + #define PROPERTY_ID_VISIBLE 8 + #define PROPERTY_ID_GROUPKEEPTOGETHER 9 + #define PROPERTY_ID_PAGEHEADEROPTION 10 + #define PROPERTY_ID_PAGEFOOTEROPTION 11 + #define PROPERTY_ID_POSITIONX 12 + #define PROPERTY_ID_POSITIONY 13 + #define PROPERTY_ID_WIDTH 14 + #define PROPERTY_ID_HEIGHT 15 + #define PROPERTY_ID_AUTOGROW 16 + #define PROPERTY_ID_FORMULA 17 + #define PROPERTY_ID_CONDITIONALPRINTEXPRESSION 18 + #define PROPERTY_ID_PRINTREPEATEDVALUES 19 + #define PROPERTY_ID_PRINTWHENGROUPCHANGE 20 + #define PROPERTY_ID_INITIALFORMULA 21 + #define PROPERTY_ID_STARTNEWCOLUMN 22 + #define PROPERTY_ID_TYPE 23 + #define PROPERTY_ID_DATAFIELD 24 + #define PROPERTY_ID_CHARFONTNAME 25 + #define PROPERTY_ID_DEEPTRAVERSING 26 + #define PROPERTY_ID_PREEVALUATED 27 + + #define PROPERTY_ID_BACKTRANSPARENT 28 + #define PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT 29 + #define PROPERTY_ID_BACKCOLOR 30 + #define PROPERTY_ID_CONTROLBACKGROUND 31 + + #define PROPERTY_ID_FORMULALIST 32 + #define PROPERTY_ID_SCOPE 33 + #define PROPERTY_ID_RESETPAGENUMBER 34 + #define PROPERTY_ID_CHARTTYPE 35 + #define PROPERTY_ID_MASTERFIELDS 36 + #define PROPERTY_ID_DETAILFIELDS 37 + #define PROPERTY_ID_PREVIEW_COUNT 38 + #define PROPERTY_ID_AREA 39 + #define PROPERTY_ID_MIMETYPE 40 + + #define PROPERTY_ID_FONT 41 + #define PROPERTY_ID_PARAADJUST 42 + #define PROPERTY_ID_VERTICALALIGN 43 + + +} // namespace rptui + + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_METADATA_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/propbrw.hxx b/reportdesign/source/ui/inc/propbrw.hxx new file mode 100644 index 000000000..5b697df05 --- /dev/null +++ b/reportdesign/source/ui/inc/propbrw.hxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX + +#include <com/sun/star/frame/XFrame2.hpp> +#include <com/sun/star/inspection/XObjectInspector.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <svl/SfxBroadcaster.hxx> +#include <svl/lstner.hxx> +#include <vcl/dockwin.hxx> +#include <vcl/layout.hxx> +#include <svx/svdmark.hxx> + +namespace rptui +{ + +class OSectionView; +class ODesignView; +class OObjectBase; + +// PropBrw + + +class PropBrw final : public DockingWindow , public SfxListener, public SfxBroadcaster +{ + VclPtr<VclVBox> m_xContentArea; + + css::uno::Reference< css::uno::XComponentContext > + m_xInspectorContext; + css::uno::Reference< css::uno::XComponentContext > + m_xORB; + css::uno::Reference< css::frame::XFrame2 > + m_xMeAsFrame; + css::uno::Reference< css::inspection::XObjectInspector > + m_xBrowserController; + css::uno::Reference< css::uno::XInterface> + m_xLastSection; /// is the previously displayed section + OUString m_sLastActivePage; + VclPtr<ODesignView> m_pDesignView; + OSectionView* m_pView; + bool m_bInitialStateChange; + + PropBrw(PropBrw const &) = delete; + void operator =(PropBrw const &) = delete; + + virtual bool Close() override; + + css::uno::Sequence< css::uno::Reference< css::uno::XInterface> > + CreateCompPropSet(const SdrMarkList& rMarkList); + + void implSetNewObject( + const css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >& _aObjects = css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >()); + + static OUString GetHeadlineName( + const css::uno::Sequence< css::uno::Reference< css::uno::XInterface> >& _aObjects); + + void implDetachController(); + css::uno::Reference< css::uno::XInterface> CreateComponentPair(OObjectBase* _pObj); + css::uno::Reference< css::uno::XInterface> CreateComponentPair( + const css::uno::Reference< css::uno::XInterface>& _xFormComponent + ,const css::uno::Reference< css::uno::XInterface>& _xReportComponent); + DECL_LINK( OnAsyncGetFocus, void*, void ); + +public: + PropBrw(const css::uno::Reference< css::uno::XComponentContext >& _xORB + ,Window* pParent + ,ODesignView* _pDesignView); + virtual ~PropBrw() override; + virtual void dispose() override; + + virtual void LoseFocus() override; + + void Update( OSectionView* m_pView ); + void Update( const css::uno::Reference< css::uno::XInterface>& _xReportComponent); + OUString getCurrentPage() const; + void setCurrentPage(const OUString& _sLastActivePage); + + ::Size getMinimumSize() const; +}; + +} // rptui + +#endif // INCLUDED_REPORTDESIGN_SOURCE_UI_INC_PROPBRW_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inc/statusbarcontroller.hxx b/reportdesign/source/ui/inc/statusbarcontroller.hxx new file mode 100644 index 000000000..13bfb7706 --- /dev/null +++ b/reportdesign/source/ui/inc/statusbarcontroller.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STATUSBARCONTROLLER_HXX +#define INCLUDED_REPORTDESIGN_SOURCE_UI_INC_STATUSBARCONTROLLER_HXX + +#include <svtools/statusbarcontroller.hxx> +#include <comphelper/uno3.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase1.hxx> + +class SfxStatusBarControl; +namespace rptui +{ + typedef ::cppu::ImplHelper1 < css::lang::XServiceInfo> OStatusbarController_BASE; + class OStatusbarController : public ::svt::StatusbarController, + public OStatusbarController_BASE + { + css::uno::Reference< css::frame::XStatusbarController > m_rController; + sal_uInt16 m_nSlotId; + sal_uInt16 m_nId; + public: + OStatusbarController(const css::uno::Reference< css::uno::XComponentContext >& _rxORB); + + private: + void SAL_CALL dispose() override; + // XInterface + DECLARE_XINTERFACE( ) + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual css::uno::Sequence< OUString> SAL_CALL getSupportedServiceNames() override; + // need by registration + + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + + // XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + // XUpdatable + virtual void SAL_CALL update() override; + + // XStatusListener + virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) override; + + // XStatusbarController + virtual sal_Bool SAL_CALL mouseButtonDown( const css::awt::MouseEvent& aMouseEvent ) override; + virtual sal_Bool SAL_CALL mouseMove( const css::awt::MouseEvent& aMouseEvent ) override; + virtual sal_Bool SAL_CALL mouseButtonUp( const css::awt::MouseEvent& aMouseEvent ) override; + virtual void SAL_CALL command( const css::awt::Point& aPos, + ::sal_Int32 nCommand, + sal_Bool bMouseEvent, + const css::uno::Any& aData ) override; + virtual void SAL_CALL paint( const css::uno::Reference< css::awt::XGraphics >& xGraphics, + const css::awt::Rectangle& rOutputRectangle, + ::sal_Int32 nStyle ) override; + virtual void SAL_CALL click( const css::awt::Point& aPos ) override; + virtual void SAL_CALL doubleClick( const css::awt::Point& aPos ) override; + }; +} +#endif // DBAUI_STATUSBARCONTROLLER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inspection/DataProviderHandler.cxx b/reportdesign/source/ui/inspection/DataProviderHandler.cxx new file mode 100644 index 000000000..9e789db4c --- /dev/null +++ b/reportdesign/source/ui/inspection/DataProviderHandler.cxx @@ -0,0 +1,513 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <string_view> + +#include <DataProviderHandler.hxx> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <comphelper/propertysequence.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <strings.hxx> +#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp> +#include <com/sun/star/inspection/PropertyControlType.hpp> +#include <com/sun/star/inspection/PropertyLineElement.hpp> +#include <com/sun/star/lang/NullPointerException.hpp> +#include <com/sun/star/chart/ChartDataRowSource.hpp> +#include <com/sun/star/chart2/FormattedString.hpp> +#include <com/sun/star/chart2/XTitled.hpp> +#include <com/sun/star/chart2/XTitle.hpp> +#include <com/sun/star/chart2/data/XDataReceiver.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/script/Converter.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <metadata.hxx> +#include <osl/mutex.hxx> +#include <tools/diagnose_ex.h> +#include <core_resource.hxx> +#include <helpids.h> +#include <strings.hrc> +#include <PropertyForward.hxx> + +namespace rptui +{ + +using namespace ::com::sun::star; + +DataProviderHandler::DataProviderHandler(uno::Reference< uno::XComponentContext > const & context) + :DataProviderHandler_Base(m_aMutex) + ,m_xContext(context) +{ + try + { + m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext); + m_xTypeConverter = script::Converter::create(m_xContext); + + }catch(const uno::Exception &) + { + } +} + +OUString SAL_CALL DataProviderHandler::getImplementationName( ) +{ + return "com.sun.star.comp.report.DataProviderHandler"; +} + +sal_Bool SAL_CALL DataProviderHandler::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL DataProviderHandler::getSupportedServiceNames( ) +{ + return { "com.sun.star.report.inspection.DataProviderHandler" }; +} + +// override WeakComponentImplHelperBase::disposing() +// This function is called upon disposing the component, +// if your component needs special work when it becomes +// disposed, do it here. +void SAL_CALL DataProviderHandler::disposing() +{ + ::comphelper::disposeComponent(m_xFormComponentHandler); + ::comphelper::disposeComponent( m_xMasterDetails ); + ::comphelper::disposeComponent(m_xTypeConverter); +} +void SAL_CALL DataProviderHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener) +{ + m_xFormComponentHandler->addEventListener(xListener); +} + +void SAL_CALL DataProviderHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) +{ + m_xFormComponentHandler->removeEventListener(aListener); +} + +// inspection::XPropertyHandler: + +/********************************************************************************/ +void SAL_CALL DataProviderHandler::inspect(const uno::Reference< uno::XInterface > & Component) +{ + try + { + uno::Reference< container::XNameContainer > xNameCont(Component,uno::UNO_QUERY); + static const OUStringLiteral sFormComponent(u"FormComponent"); + if ( xNameCont->hasByName(sFormComponent) ) + { + uno::Reference<beans::XPropertySet> xProp(xNameCont->getByName(sFormComponent),uno::UNO_QUERY); + static const OUStringLiteral sModel(u"Model"); + if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(sModel) ) + { + m_xChartModel.set(xProp->getPropertyValue(sModel),uno::UNO_QUERY); + if ( m_xChartModel.is() ) + m_xFormComponent = m_xChartModel->getDataProvider(); + } + } + m_xDataProvider.set(m_xFormComponent,uno::UNO_QUERY); + m_xReportComponent.set( xNameCont->getByName("ReportComponent"), uno::UNO_QUERY ); + if ( m_xDataProvider.is() ) + { + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair aPropertyMediation; + aPropertyMediation.emplace( PROPERTY_MASTERFIELDS, TPropertyConverter(PROPERTY_MASTERFIELDS,aNoConverter) ); + aPropertyMediation.emplace( PROPERTY_DETAILFIELDS, TPropertyConverter(PROPERTY_DETAILFIELDS,aNoConverter) ); + + m_xMasterDetails = new OPropertyMediator( m_xDataProvider, m_xReportComponent, std::move(aPropertyMediation), true ); + } + } + catch(const uno::Exception &) + { + throw lang::NullPointerException(); + } + if ( m_xFormComponent.is() ) + { + m_xFormComponentHandler->inspect(m_xFormComponent); + } +} + +uno::Any SAL_CALL DataProviderHandler::getPropertyValue(const OUString & PropertyName) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + uno::Any aPropertyValue; + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + // TODO: We need a possibility to get the UI of the selected chart type + // LEM: this business of ignoring ChartType seems very fishy! + //if( m_xChartModel.is() ) + //{ + // uno::Reference< chart2::XDiagram > xDiagram( m_xChartModel->getFirstDiagram() ); + // if( xDiagram.is() ) + // { + // OUString sChartTypes; + // uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW ); + // const uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems()); + // const uno::Reference< chart2::XCoordinateSystem >* pIter = aCooSysSeq.getConstArray(); + // const uno::Reference< chart2::XCoordinateSystem >* pEnd = pIter + aCooSysSeq.getLength(); + // for(;pIter != pEnd;++pIter) + // { + // const uno::Reference< chart2::XChartTypeContainer > xCTCnt( *pIter, uno::UNO_QUERY_THROW ); + // const uno::Sequence< uno::Reference< chart2::XChartType > > aCTSeq( xCTCnt->getChartTypes()); + // const uno::Reference< chart2::XChartType >* pChartTypeIter = aCTSeq.getConstArray(); + // const uno::Reference< chart2::XChartType >* pChartTypeEnd = pChartTypeIter + aCTSeq.getLength(); + // for(;pChartTypeIter != pChartTypeEnd;++pChartTypeIter) + // { + // sChartTypes += (*pChartTypeIter)->getChartType(); + // sChartTypes += ";"; + // } + // } + // aPropertyValue;// <<= sChartTypes; + // } + //} + break; + case PROPERTY_ID_PREVIEW_COUNT: + if (m_xDataProvider) // tdf#117159 crash with chart in database report otherwise + aPropertyValue <<= m_xDataProvider->getRowLimit(); + break; + default: + aPropertyValue = m_xFormComponentHandler->getPropertyValue( PropertyName ); + break; + } + return aPropertyValue; +} + +void SAL_CALL DataProviderHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + break; + case PROPERTY_ID_PREVIEW_COUNT: + m_xDataProvider->setPropertyValue(PropertyName,Value); + break; + default: + m_xFormComponentHandler->setPropertyValue(PropertyName, Value); + break; + } +} + +void DataProviderHandler::impl_updateChartTitle_throw(const uno::Any& _aValue) +{ + uno::Reference<chart2::XTitled> xTitled(m_xChartModel,uno::UNO_QUERY); + if ( !xTitled.is() ) + return; + + uno::Reference<chart2::XTitle> xTitle = xTitled->getTitleObject(); + if ( !xTitle.is() ) + { + xTitle.set(m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.chart2.Title",m_xContext),uno::UNO_QUERY); + xTitled->setTitleObject(xTitle); + } + if ( xTitle.is() ) + { + uno::Reference< chart2::XFormattedString2> xFormatted = chart2::FormattedString::create(m_xContext); + OUString sStr; + _aValue >>= sStr; + xFormatted->setString(sStr); + xTitle->setText({ xFormatted }); + } +} + +beans::PropertyState SAL_CALL DataProviderHandler::getPropertyState(const OUString & PropertyName) +{ + return m_xFormComponentHandler->getPropertyState(PropertyName); +} + +inspection::LineDescriptor SAL_CALL DataProviderHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & _xControlFactory) +{ + inspection::LineDescriptor aOut; + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + aOut.PrimaryButtonId = UID_RPT_PROP_CHARTTYPE_DLG; + aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::TextField , true); + aOut.HasPrimaryButton = true; + break; + case PROPERTY_ID_PREVIEW_COUNT: + aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::NumericField , false); + break; + case PROPERTY_ID_MASTERFIELDS: + case PROPERTY_ID_DETAILFIELDS: + aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::StringListField , false); + aOut.PrimaryButtonId = UID_RPT_PROP_DLG_LINKFIELDS; + aOut.HasPrimaryButton = true; + break; + default: + aOut = m_xFormComponentHandler->describePropertyLine(PropertyName, _xControlFactory); + } + if ( nId != -1 ) + { + aOut.Category = (OPropertyInfoService::getPropertyUIFlags(nId ) & PropUIFlags::DataProperty) ? + std::u16string_view(u"Data") + : + std::u16string_view(u"General"); + aOut.HelpURL = HelpIdUrl::getHelpURL( OPropertyInfoService::getPropertyHelpId( nId ) ); + aOut.DisplayName = OPropertyInfoService::getPropertyTranslation(nId); + } + return aOut; +} + +uno::Any SAL_CALL DataProviderHandler::convertToPropertyValue(const OUString & _rPropertyValue, const uno::Any & _rControlValue) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + uno::Any aPropertyValue( _rControlValue ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(_rPropertyValue); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + break; + case PROPERTY_ID_PREVIEW_COUNT: + try + { + aPropertyValue = m_xTypeConverter->convertTo( _rControlValue, ::cppu::UnoType<sal_Int32>::get()); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "DataProviderHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" ); + } + break; + case PROPERTY_ID_MASTERFIELDS: + case PROPERTY_ID_DETAILFIELDS: + break; + default: + aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(_rPropertyValue, _rControlValue); + } + return aPropertyValue; +} + +uno::Any SAL_CALL DataProviderHandler::convertToControlValue(const OUString & _rPropertyName, const uno::Any & _rPropertyValue, const uno::Type & ControlValueType) +{ + uno::Any aControlValue( _rPropertyValue ); + if ( !aControlValue.hasValue() ) + // NULL is converted to NULL + return aControlValue; + + ::osl::MutexGuard aGuard( m_aMutex ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(_rPropertyName); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + break; + case PROPERTY_ID_MASTERFIELDS: + case PROPERTY_ID_DETAILFIELDS: + case PROPERTY_ID_PREVIEW_COUNT: + try + { + aControlValue = m_xTypeConverter->convertTo( _rPropertyValue, ControlValueType); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" ); + } + break; + default: + aControlValue = m_xFormComponentHandler->convertToControlValue(_rPropertyName, _rPropertyValue, ControlValueType); + } + return aControlValue; +} + +void SAL_CALL DataProviderHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & Listener) +{ + m_xFormComponentHandler->addPropertyChangeListener(Listener); +} + +void SAL_CALL DataProviderHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener) +{ + m_xFormComponentHandler->removePropertyChangeListener(_rxListener); +} + +uno::Sequence< beans::Property > SAL_CALL DataProviderHandler::getSupportedProperties() +{ + ::std::vector< beans::Property > aNewProps; + if( m_xChartModel.is() ) + { + rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler ); + beans::Property aValue; + static const std::u16string_view s_pProperties[] = + { + u"" PROPERTY_CHARTTYPE + ,u"" PROPERTY_MASTERFIELDS + ,u"" PROPERTY_DETAILFIELDS + ,u"" PROPERTY_PREVIEW_COUNT + }; + + for (const auto & rName : s_pProperties) + { + aValue.Name = rName; + aNewProps.push_back(aValue); + } + } + return uno::Sequence< beans::Property >(aNewProps.data(), aNewProps.size()); +} + +uno::Sequence< OUString > SAL_CALL DataProviderHandler::getSupersededProperties() +{ + uno::Sequence< OUString > aRet { PROPERTY_TITLE }; // have a look at OPropertyInfoService::getExcludeProperties + return aRet; +} + +uno::Sequence< OUString > SAL_CALL DataProviderHandler::getActuatingProperties() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Sequence< OUString > aSeq { PROPERTY_TITLE }; + return ::comphelper::concatSequences(m_xFormComponentHandler->getActuatingProperties(),aSeq); +} + +sal_Bool SAL_CALL DataProviderHandler::isComposable( const OUString& _rPropertyName ) +{ + return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler ); +} + +inspection::InteractiveSelectionResult SAL_CALL DataProviderHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & out_Data, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI) +{ + if ( !_rxInspectorUI.is() ) + throw lang::NullPointerException(); + + inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled; + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_CHARTTYPE: + if ( impl_dialogChartType_nothrow(aGuard) ) + eResult = inspection::InteractiveSelectionResult_ObtainedValue; + break; + case PROPERTY_ID_MASTERFIELDS: + case PROPERTY_ID_DETAILFIELDS: + if ( impl_dialogLinkedFields_nothrow( aGuard ) ) + eResult = inspection::InteractiveSelectionResult_Success; + break; + default: + eResult = m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, out_Data, _rxInspectorUI); + } + + return eResult; +} + +void SAL_CALL DataProviderHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ActuatingPropertyName == PROPERTY_COMMAND ) + { + if ( NewValue != OldValue ) + { + uno::Reference< report::XReportDefinition> xReport = m_xReportComponent->getSection()->getReportDefinition(); + bool bDoEnableMasterDetailFields = xReport.is() && !xReport->getCommand().isEmpty() && !m_xDataProvider->getCommand().isEmpty(); + InspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, inspection::PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields ); + InspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, inspection::PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields ); + + bool bModified = xReport->isModified(); + // this fills the chart again + ::comphelper::NamedValueCollection aArgs; + aArgs.put( "CellRangeRepresentation", uno::Any( OUString( "all" ) ) ); + aArgs.put( "HasCategories", uno::Any( true ) ); + aArgs.put( "FirstCellAsLabel", uno::Any( true ) ); + aArgs.put( "DataRowSource", uno::Any( chart::ChartDataRowSource_COLUMNS ) ); + uno::Reference< chart2::data::XDataReceiver > xReceiver(m_xChartModel,uno::UNO_QUERY_THROW); + xReceiver->setArguments( aArgs.getPropertyValues() ); + if ( !bModified ) + xReport->setModified(false); + } + m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit); + } + else if ( ActuatingPropertyName == PROPERTY_TITLE ) + { + if ( NewValue != OldValue ) + impl_updateChartTitle_throw(NewValue); + } + else + { + const sal_Int32 nId = OPropertyInfoService::getPropertyId(ActuatingPropertyName); + switch(nId) + { + + case PROPERTY_ID_MASTERFIELDS: + break; + case PROPERTY_ID_DETAILFIELDS: + break; + default: + m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit); + } + } +} + +sal_Bool SAL_CALL DataProviderHandler::suspend(sal_Bool Suspend) +{ + return m_xFormComponentHandler->suspend(Suspend); +} +bool DataProviderHandler::impl_dialogLinkedFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const +{ + uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence( + { + {"ParentWindow", m_xContext->getValueByName("DialogParentWindow")}, + {"Detail", uno::Any(m_xDataProvider)}, + {"Master", uno::Any(m_xReportComponent->getSection()->getReportDefinition())}, + {"Explanation", uno::Any(RptResId(TranslateId(nullptr, RID_STR_EXPLANATION)))}, + {"DetailLabel", uno::Any(RptResId(RID_STR_DETAILLABEL))}, + {"MasterLabel", uno::Any(RptResId(RID_STR_MASTERLABEL))}, + })); + + uno::Reference< ui::dialogs::XExecutableDialog > xDialog( + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "org.openoffice.comp.form.ui.MasterDetailLinkDialog", aSeq, m_xContext), + uno::UNO_QUERY); + + _rClearBeforeDialog.clear(); + return ( xDialog->execute() != 0 ); +} + +bool DataProviderHandler::impl_dialogChartType_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const +{ + uno::Sequence<uno::Any> aSeq(comphelper::InitAnyPropertySequence( + { + {"ParentWindow", m_xContext->getValueByName("DialogParentWindow")}, + {"ChartModel", uno::Any(m_xChartModel)} + })); + + uno::Reference< ui::dialogs::XExecutableDialog > xDialog( + m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.chart2.ChartTypeDialog", aSeq, m_xContext), + uno::UNO_QUERY); + + _rClearBeforeDialog.clear(); + return ( xDialog->execute() != 0 ); +} + +} // namespace rptui + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_DataProviderHandler_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptui::DataProviderHandler(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inspection/DefaultInspection.cxx b/reportdesign/source/ui/inspection/DefaultInspection.cxx new file mode 100644 index 000000000..80269f433 --- /dev/null +++ b/reportdesign/source/ui/inspection/DefaultInspection.cxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <DefaultInspection.hxx> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <strings.hrc> +#include <core_resource.hxx> +#include <helpids.h> +#include <cppuhelper/supportsservice.hxx> +#include <tools/debug.hxx> +#include <metadata.hxx> +#include <tools/urlobj.hxx> + + +namespace rptui +{ + OUString HelpIdUrl::getHelpURL( std::string_view sHelpId ) + { + OUString aTmp( OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8) ); + DBG_ASSERT( INetURLObject( aTmp ).GetProtocol() == INetProtocol::NotValid, "Wrong HelpId!" ); + return INET_HID_SCHEME + aTmp; + } + + using namespace com::sun::star::uno; + using namespace com::sun::star; + using com::sun::star::inspection::PropertyCategoryDescriptor; + + + //= DefaultComponentInspectorModel + + + DefaultComponentInspectorModel::DefaultComponentInspectorModel( const Reference< XComponentContext >& _rxContext) + :m_xContext( _rxContext ) + ,m_bConstructed( false ) + ,m_bHasHelpSection( false ) + ,m_bIsReadOnly(false) + ,m_nMinHelpTextLines( 3 ) + ,m_nMaxHelpTextLines( 8 ) + { + } + + DefaultComponentInspectorModel::~DefaultComponentInspectorModel() + { + } + + OUString SAL_CALL DefaultComponentInspectorModel::getImplementationName( ) + { + return "com.sun.star.comp.report.DefaultComponentInspectorModel"; + } + + sal_Bool SAL_CALL DefaultComponentInspectorModel::supportsService( const OUString& ServiceName ) + { + return cppu::supportsService(this, ServiceName); + } + + Sequence< OUString > SAL_CALL DefaultComponentInspectorModel::getSupportedServiceNames( ) + { + return { "com.sun.star.report.inspection.DefaultComponentInspectorModel" }; + } + + Sequence< Any > SAL_CALL DefaultComponentInspectorModel::getHandlerFactories() + { + // service names for all our handlers + return Sequence<Any> { + Any(OUString( "com.sun.star.report.inspection.ReportComponentHandler")), + Any(OUString( "com.sun.star.form.inspection.EditPropertyHandler")), + Any(OUString( "com.sun.star.report.inspection.DataProviderHandler")), + Any(OUString( "com.sun.star.report.inspection.GeometryHandler")) + }; + } + + sal_Bool SAL_CALL DefaultComponentInspectorModel::getHasHelpSection() + { + ::osl::MutexGuard aGuard(m_aMutex); + return m_bHasHelpSection; + } + + + ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getMinHelpTextLines() + { + ::osl::MutexGuard aGuard(m_aMutex); + return m_nMinHelpTextLines; + } + + sal_Bool SAL_CALL DefaultComponentInspectorModel::getIsReadOnly() + { + ::osl::MutexGuard aGuard(m_aMutex); + return m_bIsReadOnly; + } + + void SAL_CALL DefaultComponentInspectorModel::setIsReadOnly( sal_Bool _isreadonly ) + { + ::osl::MutexGuard aGuard(m_aMutex); + m_bIsReadOnly = _isreadonly; + } + + + ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getMaxHelpTextLines() + { + ::osl::MutexGuard aGuard(m_aMutex); + return m_nMaxHelpTextLines; + } + + void SAL_CALL DefaultComponentInspectorModel::initialize( const Sequence< Any >& _arguments ) + { + ::osl::MutexGuard aGuard(m_aMutex); + if ( m_bConstructed ) + throw ucb::AlreadyInitializedException(); + + if ( !_arguments.hasElements() ) + { // constructor: "createDefault()" + m_bConstructed = true; + return; + } + + if ( _arguments.getLength() == 2 ) + { // constructor: "createWithHelpSection( long, long )" + sal_Int32 nMinHelpTextLines( 0 ), nMaxHelpTextLines( 0 ); + if ( !( _arguments[0] >>= nMinHelpTextLines ) || !( _arguments[1] >>= nMaxHelpTextLines ) ) + throw lang::IllegalArgumentException( OUString(), *this, 0 ); + createWithHelpSection( nMinHelpTextLines, nMaxHelpTextLines ); + return; + } + + throw lang::IllegalArgumentException( OUString(), *this, 0 ); + } + + + void DefaultComponentInspectorModel::createWithHelpSection( sal_Int32 _nMinHelpTextLines, sal_Int32 _nMaxHelpTextLines ) + { + if ( ( _nMinHelpTextLines <= 0 ) || ( _nMaxHelpTextLines <= 0 ) || ( _nMinHelpTextLines > _nMaxHelpTextLines ) ) + throw lang::IllegalArgumentException( OUString(), *this, 0 ); + + m_bHasHelpSection = true; + m_nMinHelpTextLines = _nMinHelpTextLines; + m_nMaxHelpTextLines = _nMaxHelpTextLines; + m_bConstructed = true; + } + + Sequence< PropertyCategoryDescriptor > SAL_CALL DefaultComponentInspectorModel::describeCategories( ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + const struct + { + const char* programmaticName; + TranslateId uiNameResId; + OString helpId; + } aCategories[] = { + { "General", RID_STR_PROPPAGE_DEFAULT, HID_RPT_PROPDLG_TAB_GENERAL }, + { "Data", RID_STR_PROPPAGE_DATA, HID_RPT_PROPDLG_TAB_DATA }, + }; + + const size_t nCategories = SAL_N_ELEMENTS( aCategories ); + Sequence< PropertyCategoryDescriptor > aReturn( nCategories ); + PropertyCategoryDescriptor* pReturn = aReturn.getArray(); + for ( size_t i=0; i<nCategories; ++i, ++pReturn ) + { + pReturn->ProgrammaticName = OUString::createFromAscii( aCategories[i].programmaticName ); + pReturn->UIName = RptResId( aCategories[i].uiNameResId ); + pReturn->HelpURL = HelpIdUrl::getHelpURL( aCategories[i].helpId ); + } + + return aReturn; + } + + + ::sal_Int32 SAL_CALL DefaultComponentInspectorModel::getPropertyOrderIndex( const OUString& _rPropertyName ) + { + ::osl::MutexGuard aGuard(m_aMutex); + const sal_Int32 nPropertyId( OPropertyInfoService::getPropertyId( _rPropertyName ) ); + if ( nPropertyId != -1 ) + return nPropertyId; + + if ( !m_xComponent.is() ) + try + { + m_xComponent.set(m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.form.inspection.DefaultFormComponentInspectorModel",m_xContext),UNO_QUERY_THROW); + } + catch(const Exception &) + { + return 0; + } + + return m_xComponent->getPropertyOrderIndex(_rPropertyName); + } + + +} // namespace rptui + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_DefaultComponentInspectorModel_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptui::DefaultComponentInspectorModel(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inspection/GeometryHandler.cxx b/reportdesign/source/ui/inspection/GeometryHandler.cxx new file mode 100644 index 000000000..66852237b --- /dev/null +++ b/reportdesign/source/ui/inspection/GeometryHandler.cxx @@ -0,0 +1,2215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <iterator> +#include <map> +#include <string_view> + +#include <GeometryHandler.hxx> + +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <comphelper/property.hxx> +#include <comphelper/mimeconfighelper.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <strings.hxx> +#include <reportformula.hxx> + +#include <i18nutil/searchopt.hxx> +#include <unotools/textsearch.hxx> +#include <unotools/localedatawrapper.hxx> + +#include <toolkit/helper/vclunohelper.hxx> +#include <unotools/syslocale.hxx> +#include <tools/diagnose_ex.h> +#include <tools/resary.hxx> +#include <com/sun/star/lang/NullPointerException.hpp> +#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp> +#include <com/sun/star/inspection/StringRepresentation.hpp> +#include <com/sun/star/inspection/PropertyControlType.hpp> +#include <com/sun/star/inspection/XStringListControl.hpp> +#include <com/sun/star/report/Function.hpp> +#include <com/sun/star/report/XReportDefinition.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <com/sun/star/script/Converter.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/FilterDialog.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/util/SearchAlgorithms2.hpp> +#include <com/sun/star/util/MeasureUnit.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/inspection/XNumericControl.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> + +#include <tools/fldunit.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> + +#include <core_resource.hxx> +#include <stringarray.hrc> +#include <strings.hrc> +#include <RptDef.hxx> +#include <UITools.hxx> + +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> + +#include <metadata.hxx> +#include <sfx2/docfilt.hxx> + +#include <helpids.h> +#include <toolkit/helper/convert.hxx> +#include <o3tl/functional.hxx> +#include <o3tl/safeint.hxx> + +#define DATA_OR_FORMULA 0 +#define FUNCTION 1 +#define COUNTER 2 +#define USER_DEF_FUNCTION 3 +#define UNDEF_DATA 4 + + +namespace rptui +{ + +using namespace ::com::sun::star; + +namespace{ + +OUString lcl_getQuotedFunctionName(std::u16string_view _sFunction) +{ + return OUString::Concat("[") + _sFunction + "]"; +} + +OUString lcl_getQuotedFunctionName(const uno::Reference< report::XFunction>& _xFunction) +{ + return lcl_getQuotedFunctionName(_xFunction->getName()); +} + +void lcl_collectFunctionNames(const uno::Reference< report::XFunctions>& _xFunctions,TFunctions& _rFunctionNames) +{ + uno::Reference< report::XFunctionsSupplier> xParent(_xFunctions->getParent(),uno::UNO_QUERY_THROW); + const sal_Int32 nCount = _xFunctions->getCount(); + for (sal_Int32 i = 0; i < nCount ; ++i) + { + uno::Reference< report::XFunction > xFunction(_xFunctions->getByIndex(i),uno::UNO_QUERY_THROW); + _rFunctionNames.emplace( lcl_getQuotedFunctionName(xFunction),TFunctionPair(xFunction,xParent) ); + } +} + +void lcl_collectFunctionNames(const uno::Reference< report::XSection>& _xSection,TFunctions& _rFunctionNames) +{ + const uno::Reference< report::XReportDefinition> xReportDefinition = _xSection->getReportDefinition(); + const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups(); + sal_Int32 nPos = -1; + uno::Reference< report::XGroup> xGroup = _xSection->getGroup(); + if ( xGroup.is() ) + nPos = getPositionInIndexAccess(xGroups,xGroup); + else if ( _xSection == xReportDefinition->getDetail() ) + nPos = xGroups->getCount()-1; + + for (sal_Int32 i = 0 ; i <= nPos ; ++i) + { + xGroup.set(xGroups->getByIndex(i),uno::UNO_QUERY_THROW); + lcl_collectFunctionNames(xGroup->getFunctions(),_rFunctionNames); + } + lcl_collectFunctionNames(xReportDefinition->getFunctions(),_rFunctionNames); +} + +void lcl_convertFormulaTo(const uno::Any& _aPropertyValue,uno::Any& _rControlValue) +{ + OUString sName; + _aPropertyValue >>= sName; + const sal_Int32 nLen = sName.getLength(); + if ( nLen ) + { + ReportFormula aFormula( sName ); + _rControlValue <<= aFormula.getUndecoratedContent(); + } +} + +// return value rounded to the nearest multiple of base +// if equidistant of two multiples, round up (for positive numbers) +// T is assumed to be an integer type +template <typename T, T base> T lcl_round(T value) +{ + OSL_ENSURE(value >= 0, "lcl_round: positive numbers only please"); + const T threshold = (base % 2 == 0) ? (base/2) : (base/2 + 1); + const T rest = value % base; + if ( rest >= threshold ) + return value + (base - rest); + else + return value - rest; +} + +} // anonymous namespace + +bool GeometryHandler::impl_isDataField(const OUString& _sName) const +{ + bool bIsField = ( ::std::find( m_aFieldNames.begin(), m_aFieldNames.end(), _sName ) != m_aFieldNames.end() ); + + if ( !bIsField ) + { + bIsField = ( ::std::find( m_aParamNames.begin(), m_aParamNames.end(), _sName ) != m_aParamNames.end() ); + } + return bIsField; +} + +OUString GeometryHandler::impl_convertToFormula( const uno::Any& _rControlValue ) +{ + OUString sName; + _rControlValue >>= sName; + + if ( sName.isEmpty() ) + return sName; + + ReportFormula aParser( sName ); + if ( aParser.isValid() ) + return sName; + + return ReportFormula(impl_isDataField(sName) ? ReportFormula::Field : ReportFormula::Expression, sName).getCompleteFormula(); +} + +GeometryHandler::GeometryHandler(uno::Reference< uno::XComponentContext > const & context) + : GeometryHandler_Base(m_aMutex) + , m_aPropertyListeners(m_aMutex) + , m_xContext(context) + , m_nDataFieldType(0) + , m_bNewFunction(false) + , m_bIn(false) +{ + try + { + m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext); + m_xTypeConverter = script::Converter::create(context); + loadDefaultFunctions(); + } + catch(const uno::Exception&) + { + } +} + +GeometryHandler::~GeometryHandler() +{ +} + +OUString SAL_CALL GeometryHandler::getImplementationName( ) +{ + return "com.sun.star.comp.report.GeometryHandler"; +} + +sal_Bool SAL_CALL GeometryHandler::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL GeometryHandler::getSupportedServiceNames( ) +{ + return { "com.sun.star.report.inspection.GeometryHandler" }; +} + +// override WeakComponentImplHelperBase::disposing() +// This function is called upon disposing the component, +// if your component needs special work when it becomes +// disposed, do it here. +void SAL_CALL GeometryHandler::disposing() +{ + try + { + ::comphelper::disposeComponent(m_xFormComponentHandler); + ::comphelper::disposeComponent(m_xTypeConverter); + if ( m_xReportComponent.is() && m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) ) + m_xReportComponent->removePropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this )); + + m_xReportComponent.clear(); + m_xRowSet.clear(); + m_aPropertyListeners.clear(); + } + catch(uno::Exception&) + {} +} +void SAL_CALL GeometryHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener) +{ + m_xFormComponentHandler->addEventListener(xListener); +} + +void SAL_CALL GeometryHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) +{ + m_xFormComponentHandler->removeEventListener(aListener); +} + +// inspection::XPropertyHandler: + +/********************************************************************************/ +void SAL_CALL GeometryHandler::inspect( const uno::Reference< uno::XInterface > & _rxInspectee ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_sScope.clear(); + m_sDefaultFunction.clear(); + m_bNewFunction = false; + m_nDataFieldType = 0; + m_xFunction.clear(); + m_aFunctionNames.clear(); + try + { + if ( m_xReportComponent.is() && m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) ) + m_xReportComponent->removePropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this )); + + const uno::Reference< container::XNameContainer > xObjectAsContainer( _rxInspectee, uno::UNO_QUERY ); + m_xReportComponent.set( xObjectAsContainer->getByName("ReportComponent"), uno::UNO_QUERY ); + + static const OUStringLiteral sRowSet(u"RowSet"); + if ( xObjectAsContainer->hasByName( sRowSet ) ) + { + const uno::Any aRowSet( xObjectAsContainer->getByName(sRowSet) ); + aRowSet >>= m_xRowSet; + // forward the rowset to our delegator handler + uno::Reference< beans::XPropertySet > xProp( m_xFormComponentHandler,uno::UNO_QUERY ); + xProp->setPropertyValue( sRowSet, aRowSet ); + + m_aParamNames = getParameterNames( m_xRowSet ); + impl_initFieldList_nothrow(m_aFieldNames); + if ( m_xReportComponent->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) ) + m_xReportComponent->addPropertyChangeListener(PROPERTY_DATAFIELD,static_cast< beans::XPropertyChangeListener* >( this )); + } + + const uno::Reference< report::XReportComponent> xReportComponent( m_xReportComponent, uno::UNO_QUERY); + uno::Reference< report::XSection> xSection( m_xReportComponent, uno::UNO_QUERY ); + if ( !xSection.is() && xReportComponent.is() ) + xSection = xReportComponent->getSection(); + if ( xSection.is() ) + lcl_collectFunctionNames( xSection, m_aFunctionNames ); + } + catch(const uno::Exception &) + { + throw lang::NullPointerException(); + } + m_xFormComponentHandler->inspect(m_xReportComponent); +} + +uno::Any SAL_CALL GeometryHandler::getPropertyValue(const OUString & PropertyName) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + uno::Any aPropertyValue; + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_CONDITIONALPRINTEXPRESSION: + case PROPERTY_ID_INITIALFORMULA: + case PROPERTY_ID_FORMULA: + case PROPERTY_ID_DATAFIELD: + aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName ); + lcl_convertFormulaTo(aPropertyValue,aPropertyValue); + if ( PROPERTY_ID_DATAFIELD == nId ) + { + OUString sDataField; + aPropertyValue >>= sDataField; + switch(m_nDataFieldType) + { + case DATA_OR_FORMULA: + break; + case FUNCTION: + if ( isDefaultFunction(sDataField,sDataField) ) + aPropertyValue <<= sDataField; + else if ( sDataField.isEmpty() ) + aPropertyValue = uno::Any(); + break; + case COUNTER: + case USER_DEF_FUNCTION: + aPropertyValue = uno::Any(); + break; + } + + } + break; + case PROPERTY_ID_TYPE: + { + const sal_uInt32 nOldDataFieldType = m_nDataFieldType; + m_nDataFieldType = impl_getDataFieldType_throw(); + if ( UNDEF_DATA == m_nDataFieldType ) + m_nDataFieldType = nOldDataFieldType; + aPropertyValue <<= m_nDataFieldType; + } + break; + case PROPERTY_ID_FORMULALIST: + case PROPERTY_ID_SCOPE: + { + uno::Any aDataField = m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ); + lcl_convertFormulaTo(aDataField,aDataField); + OUString sDataField; + aDataField >>= sDataField; + switch(m_nDataFieldType) + { + case DATA_OR_FORMULA: + break; + case FUNCTION: + if ( isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true) ) + aPropertyValue <<= (PROPERTY_ID_FORMULALIST == nId ? m_sDefaultFunction : m_sScope); + break; + case USER_DEF_FUNCTION: + if ( !sDataField.isEmpty() && PROPERTY_ID_FORMULALIST == nId ) + aPropertyValue = aDataField; + break; + case COUNTER: + if ( PROPERTY_ID_SCOPE == nId && impl_isCounterFunction_throw(sDataField,m_sScope) ) + aPropertyValue <<= m_sScope; + break; + } + + } + break; + case PROPERTY_ID_BACKCOLOR: + case PROPERTY_ID_CONTROLBACKGROUND: + { + aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName ); + Color nColor = COL_TRANSPARENT; + if ( (aPropertyValue >>= nColor) && COL_TRANSPARENT == nColor ) + aPropertyValue.clear(); + } + break; + case PROPERTY_ID_MIMETYPE: + { + OUString sValue; + m_xReportComponent->getPropertyValue( PropertyName ) >>= sValue; + aPropertyValue <<= impl_ConvertMimeTypeToUI_nothrow(sValue); + } + break; + default: + aPropertyValue = m_xReportComponent->getPropertyValue( PropertyName ); + break; + } + return aPropertyValue; +} + +void SAL_CALL GeometryHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + uno::Any aNewValue = Value; + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + bool bHandled = false; + switch(nId) + { + case PROPERTY_ID_INITIALFORMULA: + case PROPERTY_ID_FORMULA: + break; + case PROPERTY_ID_DATAFIELD: + { + OBlocker aBlocker(m_bIn); + m_xReportComponent->setPropertyValue(PropertyName, aNewValue); + bHandled = true; + const OUString sOldFunctionName = m_sDefaultFunction; + const OUString sOldScope = m_sScope; + + uno::Any aPropertyValue; + lcl_convertFormulaTo(Value,aPropertyValue); + OUString sDataField; + aPropertyValue >>= sDataField; + + m_sScope.clear(); + m_sDefaultFunction.clear(); + m_xFunction.clear(); + const sal_uInt32 nOldDataFieldType = m_nDataFieldType; + if ( !sDataField.isEmpty() ) + { + if ( isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true) ) + m_nDataFieldType = FUNCTION; + else if ( m_aFunctionNames.find(sDataField) != m_aFunctionNames.end() ) + m_nDataFieldType = USER_DEF_FUNCTION; + } + + resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType); + } + break; + case PROPERTY_ID_TYPE: + { + bHandled = true; + Value >>= m_nDataFieldType; + + const OUString sOldFunctionName = m_sDefaultFunction; + const OUString sOldScope = m_sScope; + m_sDefaultFunction.clear(); + m_sScope.clear(); + + if ( m_nDataFieldType == COUNTER ) + { + impl_setCounterFunction_throw(); + } + else + { + if ( m_bNewFunction ) + removeFunction(); + m_xFunction.clear(); + OBlocker aBlocker(m_bIn); + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(OUString())); + } + resetOwnProperties(aGuard,sOldFunctionName,sOldScope,m_nDataFieldType); + } + break; + case PROPERTY_ID_FORMULALIST: + { + bHandled = true; + OUString sFunction; + if ( !(Value >>= sFunction) || sFunction.isEmpty() ) + { + if ( m_nDataFieldType == FUNCTION ) + { + m_sDefaultFunction.clear(); + if ( m_bNewFunction ) + removeFunction(); + m_xFunction.clear(); + + beans::PropertyChangeEvent aEvent; + aEvent.PropertyName = PROPERTY_SCOPE; + aEvent.OldValue <<= m_sScope; + m_sScope.clear(); + aEvent.NewValue <<= m_sScope; + aGuard.clear(); + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aEvent ); + } + else if ( m_nDataFieldType == USER_DEF_FUNCTION ) + { + OBlocker aBlocker(m_bIn); + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(OUString())); + } + } + else if ( m_nDataFieldType == USER_DEF_FUNCTION ) + { + OBlocker aBlocker(m_bIn); + const sal_uInt32 nNewDataType = impl_getDataFieldType_throw(sFunction); + if ( nNewDataType != UNDEF_DATA && nNewDataType != m_nDataFieldType ) + { + const OUString sOldFunctionName = m_sDefaultFunction; + const OUString sOldScope = m_sScope; + m_sScope.clear(); + m_sDefaultFunction.clear(); + m_xFunction.clear(); + if ( nNewDataType == COUNTER ) + impl_isCounterFunction_throw(sFunction,m_sScope); + else + { + OUString sNamePostfix; + OUString sDataField; + const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix); + isDefaultFunction(sFunction,sDataField,xFunctionsSupplier,true); + } + const sal_uInt32 nOldDataFieldType = m_nDataFieldType; + m_nDataFieldType = nNewDataType; + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sFunction)))); + resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType); + } + else + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sFunction)))); + } + else if ( m_nDataFieldType == FUNCTION ) + { + uno::Any aPropertyValue = m_xReportComponent->getPropertyValue(PROPERTY_DATAFIELD); + lcl_convertFormulaTo(aPropertyValue,aPropertyValue); + OUString sDataField; + aPropertyValue >>= sDataField; + if ( m_nDataFieldType == FUNCTION && (!isDefaultFunction(sDataField,sDataField) || m_sDefaultFunction != sFunction) ) + { + if ( m_bNewFunction ) + removeFunction(); + // function currently does not exist + createDefaultFunction(aGuard,sFunction,sDataField); + m_sDefaultFunction = sFunction; + } + } + } + + break; + case PROPERTY_ID_SCOPE: + if ( !(Value >>= m_sScope) ) + m_sScope.clear(); + else + { + if ( m_bNewFunction ) + removeFunction(); + if ( m_nDataFieldType == COUNTER ) + impl_setCounterFunction_throw(); + else + { + OSL_ENSURE(m_xFunction.is(),"Where is my function gone!"); + + OUString sNamePostfix; + const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix); + + OUString sQuotedFunctionName(lcl_getQuotedFunctionName(m_xFunction)); + if ( isDefaultFunction(sQuotedFunctionName,sQuotedFunctionName,xFunctionsSupplier,true) ) + m_bNewFunction = false; + else + { + OUString sDefaultFunctionName; + OUString sDataField; + OSL_VERIFY( impl_isDefaultFunction_nothrow(m_xFunction,sDataField,sDefaultFunctionName) ); + m_sDefaultFunction = sDefaultFunctionName; + createDefaultFunction(aGuard,m_sDefaultFunction,sDataField); + } + } + } + bHandled = true; + break; + case PROPERTY_ID_POSITIONX: + case PROPERTY_ID_POSITIONY: + case PROPERTY_ID_HEIGHT: + case PROPERTY_ID_WIDTH: + { + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY); + if ( xSourceReportComponent.is() ) // check only report components + { + sal_Int32 nNewValue = 0; + Value >>= nNewValue; + OSL_ENSURE(nNewValue >= 0, "A position/dimension should not be negative!"); + nNewValue = lcl_round<sal_Int32, 10>(nNewValue); + awt::Point aAwtPoint = xSourceReportComponent->getPosition(); + awt::Size aAwtSize = xSourceReportComponent->getSize(); + if ( nId == PROPERTY_ID_POSITIONX ) + aAwtPoint.X = nNewValue; + else if ( nId == PROPERTY_ID_POSITIONY ) + aAwtPoint.Y = nNewValue; + else if ( nId == PROPERTY_ID_HEIGHT ) + aAwtSize.Height = nNewValue; + else if ( nId == PROPERTY_ID_WIDTH ) + aAwtSize.Width = nNewValue; + + checkPosAndSize(aAwtPoint,aAwtSize); + } + } + break; + case PROPERTY_ID_FONT: + { + const uno::Reference< report::XReportControlFormat > xReportControlFormat( m_xReportComponent,uno::UNO_QUERY_THROW ); + uno::Sequence< beans::NamedValue > aFontSettings; + OSL_VERIFY( Value >>= aFontSettings ); + applyCharacterSettings( xReportControlFormat, aFontSettings ); + bHandled = true; + } + break; + case PROPERTY_ID_MIMETYPE: + { + OUString sValue; + Value >>= sValue; + aNewValue <<= impl_ConvertUIToMimeType_nothrow(sValue); + } + break; + default: + break; + } + + if ( !bHandled ) + m_xReportComponent->setPropertyValue(PropertyName, aNewValue); +} + + +beans::PropertyState SAL_CALL GeometryHandler::getPropertyState(const OUString & PropertyName) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + return m_xFormComponentHandler->getPropertyState(PropertyName); +} + +void GeometryHandler::implCreateListLikeControl( + const uno::Reference< inspection::XPropertyControlFactory >& _rxControlFactory + ,inspection::LineDescriptor & out_Descriptor + ,const TranslateId* pResId + ,bool _bReadOnlyControl + ,bool _bTrueIfListBoxFalseIfComboBox + ) +{ + std::vector<OUString> aList; + for (const TranslateId* pItem = pResId; *pItem; ++pItem) + aList.push_back(RptResId(*pItem)); + implCreateListLikeControl(_rxControlFactory, out_Descriptor, aList, _bReadOnlyControl, _bTrueIfListBoxFalseIfComboBox); +} + +void GeometryHandler::implCreateListLikeControl( + const uno::Reference< inspection::XPropertyControlFactory >& _rxControlFactory + ,inspection::LineDescriptor & out_Descriptor + ,const ::std::vector< OUString>& _aEntries + ,bool _bReadOnlyControl + ,bool _bTrueIfListBoxFalseIfComboBox + ) +{ + const uno::Reference< inspection::XStringListControl > xListControl( + _rxControlFactory->createPropertyControl( + _bTrueIfListBoxFalseIfComboBox ? inspection::PropertyControlType::ListBox : inspection::PropertyControlType::ComboBox, _bReadOnlyControl + ), + uno::UNO_QUERY_THROW + ); + + out_Descriptor.Control = xListControl.get(); + for (auto const& it : _aEntries) + { + xListControl->appendListEntry(it); + } +} + + +inspection::LineDescriptor SAL_CALL GeometryHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & _xControlFactory) +{ + inspection::LineDescriptor aOut; + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_FORCENEWPAGE: + case PROPERTY_ID_NEWROWORCOL: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_FORCENEWPAGE_CONST,false,true); + break; + case PROPERTY_ID_GROUPKEEPTOGETHER: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_GROUPKEEPTOGETHER_CONST,false,true); + break; + case PROPERTY_ID_PAGEHEADEROPTION: + case PROPERTY_ID_PAGEFOOTEROPTION: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_REPORTPRINTOPTION_CONST,false,true); + break; + case PROPERTY_ID_FORMULALIST: + { + ::std::vector< OUString > aList; + impl_fillFormulaList_nothrow(aList); + implCreateListLikeControl(_xControlFactory,aOut,aList,false,true); + } + break; + case PROPERTY_ID_SCOPE: + { + ::std::vector< OUString > aList; + impl_fillScopeList_nothrow(aList); + implCreateListLikeControl(_xControlFactory,aOut,aList,false,true); + } + break; + case PROPERTY_ID_MIMETYPE: + { + ::std::vector< OUString > aList; + impl_fillMimeTypes_nothrow(aList); + implCreateListLikeControl(_xControlFactory,aOut,aList,false,true); + } + break; + case PROPERTY_ID_TYPE: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_TYPE_CONST,false,true); + break; + case PROPERTY_ID_VISIBLE: + case PROPERTY_ID_CANGROW: + case PROPERTY_ID_CANSHRINK: + case PROPERTY_ID_REPEATSECTION: + case PROPERTY_ID_PRINTREPEATEDVALUES: + case PROPERTY_ID_STARTNEWCOLUMN: + case PROPERTY_ID_RESETPAGENUMBER: + case PROPERTY_ID_PRINTWHENGROUPCHANGE: + case PROPERTY_ID_KEEPTOGETHER: + case PROPERTY_ID_DEEPTRAVERSING: + case PROPERTY_ID_PREEVALUATED: + case PROPERTY_ID_PRESERVEIRI: + case PROPERTY_ID_BACKTRANSPARENT: + case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT: + { + const TranslateId* pResId = RID_STR_BOOL; + if ( PROPERTY_ID_KEEPTOGETHER == nId && uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is()) + pResId = RID_STR_KEEPTOGETHER_CONST; + implCreateListLikeControl(_xControlFactory,aOut,pResId,false,true); + } + break; + case PROPERTY_ID_INITIALFORMULA: + case PROPERTY_ID_FORMULA: + aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA; + aOut.HasPrimaryButton = true; + aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::MultiLineTextField , false); + break; + case PROPERTY_ID_CONDITIONALPRINTEXPRESSION: + aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA; + aOut.HasPrimaryButton = true; + aOut.Control = _xControlFactory->createPropertyControl(inspection::PropertyControlType::MultiLineTextField , false); + break; + case PROPERTY_ID_DATAFIELD: + { + uno::Reference< inspection::XStringListControl > xListControl( + _xControlFactory->createPropertyControl( + m_nDataFieldType == DATA_OR_FORMULA ? inspection::PropertyControlType::ComboBox : inspection::PropertyControlType::ListBox, false + ), + uno::UNO_QUERY_THROW + ); + + if ( m_nDataFieldType == DATA_OR_FORMULA ) + { + aOut.PrimaryButtonId = UID_RPT_PROP_FORMULA; + aOut.HasPrimaryButton = true; + } + + aOut.Control = xListControl.get(); + if ( m_nDataFieldType == USER_DEF_FUNCTION ) + { + // add function names + ::std::for_each(m_aFunctionNames.begin(), m_aFunctionNames.end(), + [&xListControl] (const TFunctions::value_type& func) { + xListControl->appendListEntry(func.first); + }); + } + else + { + for (auto const& it : std::as_const(m_aFieldNames)) + { + xListControl->appendListEntry(it); + } + for (auto const& it : std::as_const(m_aParamNames)) + { + xListControl->appendListEntry(it); + } + } + } + break; + case PROPERTY_ID_BACKCOLOR: + case PROPERTY_ID_CONTROLBACKGROUND: + aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::ColorListBox, false ); + break; + case PROPERTY_ID_FONT: + aOut.PrimaryButtonId = UID_RPT_RPT_PROP_DLG_FONT_TYPE; + aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::TextField, true ); + aOut.HasPrimaryButton = true; + break; + case PROPERTY_ID_AREA: + aOut.PrimaryButtonId = UID_RPT_RPT_PROP_DLG_AREA; + aOut.Control = _xControlFactory->createPropertyControl( inspection::PropertyControlType::TextField, true ); + aOut.HasPrimaryButton = true; + break; + case PROPERTY_ID_VERTICALALIGN: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_VERTICAL_ALIGN_CONST,false,true); + break; + case PROPERTY_ID_PARAADJUST: + implCreateListLikeControl(_xControlFactory,aOut,RID_STR_PARAADJUST_CONST,false,true); + break; + default: + { + aOut = m_xFormComponentHandler->describePropertyLine(PropertyName, _xControlFactory); + } + } + + if ( nId != -1 ) + { + aOut.Category = (OPropertyInfoService::getPropertyUIFlags(nId ) & PropUIFlags::DataProperty) ? + std::u16string_view(u"Data") + : + std::u16string_view(u"General"); + aOut.HelpURL = HelpIdUrl::getHelpURL( OPropertyInfoService::getPropertyHelpId( nId ) ); + aOut.DisplayName = OPropertyInfoService::getPropertyTranslation(nId); + } + + if ( ( nId == PROPERTY_ID_POSITIONX ) + || ( nId == PROPERTY_ID_POSITIONY ) + || ( nId == PROPERTY_ID_WIDTH ) + || ( nId == PROPERTY_ID_HEIGHT ) + ) + { + const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum(); + const sal_Int16 nDisplayUnit = VCLUnoHelper::ConvertToMeasurementUnit( MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH, 1 ); + uno::Reference< inspection::XNumericControl > xNumericControl(aOut.Control,uno::UNO_QUERY); + xNumericControl->setDecimalDigits( 2 ); + xNumericControl->setValueUnit( util::MeasureUnit::MM_100TH ); + uno::Reference< drawing::XShapeDescriptor> xShapeDesc(m_xReportComponent,uno::UNO_QUERY); + bool bSetMin = !xShapeDesc.is() || xShapeDesc->getShapeType() != "com.sun.star.drawing.CustomShape"; + if ( bSetMin ) + xNumericControl->setMinValue(beans::Optional<double>(true,0.0)); + if ( nDisplayUnit != -1 ) + xNumericControl->setDisplayUnit( nDisplayUnit ); + uno::Reference< report::XReportComponent> xComp(m_xReportComponent,uno::UNO_QUERY); + if ( xComp.is() && xComp->getSection().is() ) + { + uno::Reference< report::XReportDefinition > xReport = xComp->getSection()->getReportDefinition(); + OSL_ENSURE(xReport.is(),"Why is the report definition NULL!"); + if ( xReport.is() ) + { + const awt::Size aSize = getStyleProperty<awt::Size>(xReport,PROPERTY_PAPERSIZE); + const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReport,PROPERTY_LEFTMARGIN); + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReport,PROPERTY_RIGHTMARGIN); + switch(nId) + { + case PROPERTY_ID_POSITIONX: + case PROPERTY_ID_WIDTH: + if ( bSetMin ) + xNumericControl->setMinValue(beans::Optional<double>(true,0.0)); + xNumericControl->setMaxValue(beans::Optional<double>(true,double(aSize.Width - nLeftMargin - nRightMargin))); + if ( PROPERTY_ID_WIDTH == nId ) + { + uno::Reference<report::XFixedLine> xFixedLine(m_xReportComponent,uno::UNO_QUERY); + if ( xFixedLine.is() && xFixedLine->getOrientation() == 1 ) // vertical + xNumericControl->setMinValue(beans::Optional<double>(true,0.08 )); + } + break; + default: + break; + } + } + } + else if ( PROPERTY_ID_HEIGHT == nId ) + { + const uno::Reference< report::XSection> xSection(m_xReportComponent,uno::UNO_QUERY); + if ( xSection.is() ) + { + sal_Int32 nHeight = 0; + const sal_Int32 nCount = xSection->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference<drawing::XShape> xShape(xSection->getByIndex(i),uno::UNO_QUERY); + nHeight = ::std::max<sal_Int32>(nHeight,xShape->getPosition().Y + xShape->getSize().Height); + } + xNumericControl->setMinValue(beans::Optional<double>(true,nHeight )); + } + } + } + return aOut; +} + +beans::Property GeometryHandler::getProperty(const OUString & PropertyName) +{ + uno::Sequence< beans::Property > aProps = getSupportedProperties(); + const beans::Property* pIter = aProps.getConstArray(); + const beans::Property* pEnd = pIter + aProps.getLength(); + const beans::Property* pFind = ::std::find_if(pIter, pEnd, + [&PropertyName] (const beans::Property& x) -> bool { + return x.Name == PropertyName; + }); + if ( pFind == pEnd ) + return beans::Property(); + return *pFind; +} +uno::Any GeometryHandler::getConstantValue(bool _bToControlValue,const TranslateId* pResId,const uno::Any& _aValue,const OUString& _sConstantName,const OUString & PropertyName ) +{ + std::vector<OUString> aList; + for (const TranslateId* pItem = pResId; *pItem; ++pItem) + aList.push_back(RptResId(*pItem)); + uno::Sequence< OUString > aSeq(aList.size()); + auto aSeqRange = asNonConstRange(aSeq); + for (size_t i = 0; i < aList.size(); ++i) + aSeqRange[i] = aList[i]; + + uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::createConstant( m_xContext,m_xTypeConverter,_sConstantName,aSeq); + if ( _bToControlValue ) + { + return uno::Any( xConversionHelper->convertToControlValue( _aValue ) ); + } + else + { + OUString sControlValue; + _aValue >>= sControlValue; + const beans::Property aProp = getProperty(PropertyName); + return xConversionHelper->convertToPropertyValue( sControlValue, aProp.Type ); + } +} + +uno::Any SAL_CALL GeometryHandler::convertToPropertyValue(const OUString & PropertyName, const uno::Any & _rControlValue) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + uno::Any aPropertyValue( _rControlValue ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_FORCENEWPAGE: + case PROPERTY_ID_NEWROWORCOL: + aPropertyValue = getConstantValue(false,RID_STR_FORCENEWPAGE_CONST,_rControlValue,"com.sun.star.report.ForceNewPage",PropertyName); + break; + case PROPERTY_ID_GROUPKEEPTOGETHER: + aPropertyValue = getConstantValue(false,RID_STR_GROUPKEEPTOGETHER_CONST,_rControlValue,"com.sun.star.report.GroupKeepTogether",PropertyName); + break; + case PROPERTY_ID_PAGEHEADEROPTION: + case PROPERTY_ID_PAGEFOOTEROPTION: + aPropertyValue = getConstantValue(false,RID_STR_REPORTPRINTOPTION_CONST,_rControlValue,"com.sun.star.report.ReportPrintOption",PropertyName); + break; + case PROPERTY_ID_BACKCOLOR: + case PROPERTY_ID_CONTROLBACKGROUND: + if ( !_rControlValue.hasValue() ) + { + aPropertyValue <<= COL_TRANSPARENT; + break; + } + [[fallthrough]]; + + case PROPERTY_ID_KEEPTOGETHER: + if ( uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is()) + { + aPropertyValue = getConstantValue(false,RID_STR_KEEPTOGETHER_CONST,_rControlValue,"com.sun.star.report.KeepTogether",PropertyName); + break; + } + [[fallthrough]]; + + case PROPERTY_ID_VISIBLE: + case PROPERTY_ID_CANGROW: + case PROPERTY_ID_CANSHRINK: + case PROPERTY_ID_REPEATSECTION: + case PROPERTY_ID_PRINTREPEATEDVALUES: + case PROPERTY_ID_STARTNEWCOLUMN: + case PROPERTY_ID_RESETPAGENUMBER: + case PROPERTY_ID_PRINTWHENGROUPCHANGE: + case PROPERTY_ID_DEEPTRAVERSING: + case PROPERTY_ID_PREEVALUATED: + case PROPERTY_ID_PRESERVEIRI: + case PROPERTY_ID_BACKTRANSPARENT: + case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT: + { + if ( aPropertyValue.hasValue() ) + { + const beans::Property aProp = getProperty(PropertyName); + if ( aPropertyValue.getValueType().equals( aProp.Type ) ) + // nothing to do, type is already as desired + return aPropertyValue; + + if ( _rControlValue.getValueType().getTypeClass() == uno::TypeClass_STRING ) + { + OUString sControlValue; + _rControlValue >>= sControlValue; + + const uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::create( m_xContext,m_xTypeConverter ); + aPropertyValue = xConversionHelper->convertToPropertyValue( sControlValue, aProp.Type ); + } + else + { + try + { + aPropertyValue = m_xTypeConverter->convertTo( _rControlValue, aProp.Type ); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToPropertyValue: caught an exception while converting via TypeConverter!" ); + } + } + } + + break; + } + case PROPERTY_ID_CONDITIONALPRINTEXPRESSION: + case PROPERTY_ID_INITIALFORMULA: + case PROPERTY_ID_FORMULA: + return uno::Any( impl_convertToFormula( _rControlValue ) ); + case PROPERTY_ID_DATAFIELD: + { + OUString sDataField; + _rControlValue >>= sDataField; + if ( isDefaultFunction(sDataField,sDataField) ) + { + OSL_ENSURE(m_xFunction.is(),"No function set!"); + aPropertyValue <<= impl_convertToFormula( uno::Any(lcl_getQuotedFunctionName(m_xFunction)) ); + } + else + aPropertyValue <<= impl_convertToFormula( _rControlValue ); + } + break; + case PROPERTY_ID_POSITIONX: + { + aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(PropertyName, _rControlValue); + sal_Int32 nPosX = 0; + aPropertyValue >>= nPosX; + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY); + if ( xSourceReportComponent->getSection().is() ) + nPosX += getStyleProperty<sal_Int32>(xSourceReportComponent->getSection()->getReportDefinition(),PROPERTY_LEFTMARGIN); + aPropertyValue <<= nPosX; + } + break; + case PROPERTY_ID_FONT: + aPropertyValue = m_xFormComponentHandler->convertToPropertyValue(PROPERTY_FONT, _rControlValue); + break; + case PROPERTY_ID_SCOPE: + case PROPERTY_ID_FORMULALIST: + case PROPERTY_ID_AREA: + aPropertyValue = _rControlValue; + break; + case PROPERTY_ID_TYPE: + { + OUString sValue; + _rControlValue >>= sValue; + + sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND); + sal_uInt32 i = 0; + for (const TranslateId* pItem = RID_STR_TYPE_CONST; *pItem; ++pItem) + { + if (sValue == RptResId(*pItem)) + { + nFound = i; + break; + } + ++i; + } + if (nFound != RESARRAY_INDEX_NOTFOUND) + aPropertyValue <<= nFound; + } + break; + case PROPERTY_ID_MIMETYPE: + aPropertyValue = _rControlValue; + break; + case PROPERTY_ID_VERTICALALIGN: + { + OUString sValue; + _rControlValue >>= sValue; + + sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND); + sal_uInt32 i = 0; + for (const TranslateId* pItem = RID_STR_VERTICAL_ALIGN_CONST; *pItem; ++pItem) + { + if (sValue == RptResId(*pItem)) + { + nFound = i; + break; + } + ++i; + } + if (nFound != RESARRAY_INDEX_NOTFOUND) + aPropertyValue <<= static_cast<style::VerticalAlignment>(nFound); + } + break; + case PROPERTY_ID_PARAADJUST: + { + OUString sValue; + _rControlValue >>= sValue; + + sal_uInt32 nFound(RESARRAY_INDEX_NOTFOUND); + sal_uInt32 i = 0; + for (const TranslateId* pItem = RID_STR_PARAADJUST_CONST; *pItem; ++pItem) + { + if (sValue == RptResId(*pItem)) + { + nFound = i; + break; + } + ++i; + } + + if (nFound != RESARRAY_INDEX_NOTFOUND) + aPropertyValue <<= static_cast<sal_Int16>(nFound); + } + break; + default: + return m_xFormComponentHandler->convertToPropertyValue(PropertyName, _rControlValue); + } + return aPropertyValue; +} + +uno::Any SAL_CALL GeometryHandler::convertToControlValue(const OUString & PropertyName, const uno::Any & _rPropertyValue, const uno::Type & _rControlValueType) +{ + uno::Any aControlValue( _rPropertyValue ); + if ( !aControlValue.hasValue() ) + // NULL is converted to NULL + return aControlValue; + + uno::Any aPropertyValue(_rPropertyValue); + + ::osl::MutexGuard aGuard( m_aMutex ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(PropertyName); + switch(nId) + { + case PROPERTY_ID_AREA: + break; + case PROPERTY_ID_FORCENEWPAGE: + case PROPERTY_ID_NEWROWORCOL: + aControlValue = getConstantValue(true,RID_STR_FORCENEWPAGE_CONST,aPropertyValue,"com.sun.star.report.ForceNewPage",PropertyName); + break; + case PROPERTY_ID_GROUPKEEPTOGETHER: + aControlValue = getConstantValue(true,RID_STR_GROUPKEEPTOGETHER_CONST,aPropertyValue,"com.sun.star.report.GroupKeepTogether",PropertyName); + break; + case PROPERTY_ID_PAGEHEADEROPTION: + case PROPERTY_ID_PAGEFOOTEROPTION: + aControlValue = getConstantValue(true,RID_STR_REPORTPRINTOPTION_CONST,aPropertyValue,"com.sun.star.report.ReportPrintOption",PropertyName); + break; + case PROPERTY_ID_KEEPTOGETHER: + if ( uno::Reference< report::XGroup>(m_xReportComponent,uno::UNO_QUERY).is()) + { + aControlValue = getConstantValue(true,RID_STR_KEEPTOGETHER_CONST,aPropertyValue,"com.sun.star.report.KeepTogether",PropertyName); + break; + } + [[fallthrough]]; + case PROPERTY_ID_VISIBLE: + case PROPERTY_ID_CANGROW: + case PROPERTY_ID_CANSHRINK: + case PROPERTY_ID_REPEATSECTION: + case PROPERTY_ID_PRINTREPEATEDVALUES: + case PROPERTY_ID_STARTNEWCOLUMN: + case PROPERTY_ID_RESETPAGENUMBER: + case PROPERTY_ID_PRINTWHENGROUPCHANGE: + case PROPERTY_ID_DEEPTRAVERSING: + case PROPERTY_ID_PREEVALUATED: + case PROPERTY_ID_PRESERVEIRI: + case PROPERTY_ID_BACKTRANSPARENT: + case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT: + { + if ( _rControlValueType.getTypeClass() == uno::TypeClass_STRING ) + { + const uno::Reference< inspection::XStringRepresentation > xConversionHelper = inspection::StringRepresentation::create( m_xContext,m_xTypeConverter ); + aControlValue <<= xConversionHelper->convertToControlValue( aPropertyValue ); + } + else + { + try + { + aControlValue = m_xTypeConverter->convertTo( aPropertyValue, _rControlValueType ); + } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::convertToControlValue: caught an exception while converting via TypeConverter!" ); + } + } + break; + } + case PROPERTY_ID_CONDITIONALPRINTEXPRESSION: + case PROPERTY_ID_INITIALFORMULA: + case PROPERTY_ID_FORMULA: + lcl_convertFormulaTo(aPropertyValue,aControlValue); + break; + case PROPERTY_ID_DATAFIELD: + { + OUString sValue; + aControlValue >>= sValue; + if ( isDefaultFunction(sValue,sValue) ) + aControlValue <<= sValue; + else + lcl_convertFormulaTo(aPropertyValue,aControlValue); + } + break; + case PROPERTY_ID_FONT: + aControlValue = m_xFormComponentHandler->convertToControlValue(PROPERTY_FONT, aPropertyValue, _rControlValueType); + break; + case PROPERTY_ID_POSITIONX: + { + sal_Int32 nPosX = 0; + aPropertyValue >>= nPosX; + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY); + if ( xSourceReportComponent->getSection().is() ) + nPosX -= getStyleProperty<sal_Int32>(xSourceReportComponent->getSection()->getReportDefinition(),PROPERTY_LEFTMARGIN); + aPropertyValue <<= nPosX; + aControlValue = m_xFormComponentHandler->convertToControlValue(PropertyName, aPropertyValue, _rControlValueType); + } + break; + case PROPERTY_ID_FORMULALIST: + aControlValue <<= m_sDefaultFunction; + break; + case PROPERTY_ID_SCOPE: + aControlValue <<= m_sScope; + break; + case PROPERTY_ID_MIMETYPE: + aControlValue = aPropertyValue; + break; + case PROPERTY_ID_TYPE: + { + if (m_nDataFieldType < SAL_N_ELEMENTS(RID_STR_TYPE_CONST) - 1) + aControlValue <<= RptResId(RID_STR_TYPE_CONST[m_nDataFieldType]); + } + break; + case PROPERTY_ID_VERTICALALIGN: + { + style::VerticalAlignment nParagraphVertAlign = style::VerticalAlignment_TOP; + aPropertyValue >>= nParagraphVertAlign; + if (sal_uInt32(nParagraphVertAlign) < SAL_N_ELEMENTS(RID_STR_VERTICAL_ALIGN_CONST) - 1) + aControlValue <<= RptResId(RID_STR_VERTICAL_ALIGN_CONST[static_cast<sal_uInt32>(nParagraphVertAlign)]); + } + break; + case PROPERTY_ID_PARAADJUST: + { + sal_Int16 nParagraphAdjust = sal_Int16(style::ParagraphAdjust_LEFT); + aPropertyValue >>= nParagraphAdjust; + if (o3tl::make_unsigned(nParagraphAdjust) < SAL_N_ELEMENTS(RID_STR_PARAADJUST_CONST) - 1) + aControlValue <<= RptResId(RID_STR_PARAADJUST_CONST[nParagraphAdjust]); + } + break; + case PROPERTY_ID_BACKCOLOR: + case PROPERTY_ID_CONTROLBACKGROUND: + { + Color nColor = COL_TRANSPARENT; + if ( (aPropertyValue >>= nColor) && COL_TRANSPARENT == nColor ) + aPropertyValue.clear(); + } + [[fallthrough]]; + default: + aControlValue = m_xFormComponentHandler->convertToControlValue(PropertyName, aPropertyValue, _rControlValueType); + } + return aControlValue; +} +void SAL_CALL GeometryHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_aPropertyListeners.addInterface( _rxListener ); + m_xFormComponentHandler->addPropertyChangeListener(_rxListener); +} + +void SAL_CALL GeometryHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + m_aPropertyListeners.removeInterface( _rxListener ); + m_xFormComponentHandler->removePropertyChangeListener(_rxListener); +} + + +uno::Sequence< beans::Property > SAL_CALL GeometryHandler::getSupportedProperties() +{ + ::std::vector< beans::Property > aNewProps; + aNewProps.reserve(20); // only a guess + rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler ); + + const OUString pIncludeProperties[] = + { + OUString(PROPERTY_FORCENEWPAGE) + ,OUString(PROPERTY_KEEPTOGETHER) + ,OUString(PROPERTY_CANGROW) + ,OUString(PROPERTY_CANSHRINK) + ,OUString(PROPERTY_REPEATSECTION) + ,OUString(PROPERTY_PRINTREPEATEDVALUES) + ,OUString(PROPERTY_CONDITIONALPRINTEXPRESSION) + ,OUString(PROPERTY_STARTNEWCOLUMN) + ,OUString(PROPERTY_RESETPAGENUMBER) + ,OUString(PROPERTY_PRINTWHENGROUPCHANGE) + ,OUString(PROPERTY_VISIBLE) + ,OUString(PROPERTY_PAGEHEADEROPTION) + ,OUString(PROPERTY_PAGEFOOTEROPTION) + ,OUString("ControlLabel") + ,OUString(PROPERTY_POSITIONX) + ,OUString(PROPERTY_POSITIONY) + ,OUString(PROPERTY_WIDTH) + ,OUString(PROPERTY_HEIGHT) + ,OUString(PROPERTY_AUTOGROW) + ,OUString(PROPERTY_PREEVALUATED) + ,OUString(PROPERTY_DEEPTRAVERSING) + ,OUString(PROPERTY_FORMULA) + ,OUString(PROPERTY_INITIALFORMULA) + ,OUString(PROPERTY_PRESERVEIRI) + ,OUString(PROPERTY_DATAFIELD) + ,OUString(PROPERTY_FONT) + ,OUString(PROPERTY_BACKCOLOR) + ,OUString(PROPERTY_BACKTRANSPARENT) + ,OUString(PROPERTY_CONTROLBACKGROUND) + ,OUString(PROPERTY_CONTROLBACKGROUNDTRANSPARENT) + ,OUString(PROPERTY_LABEL) + ,OUString(PROPERTY_MIMETYPE) + ,OUString(PROPERTY_VERTICALALIGN) + ,OUString(PROPERTY_PARAADJUST) + }; + const uno::Reference < beans::XPropertySetInfo > xInfo = m_xReportComponent->getPropertySetInfo(); + const uno::Sequence< beans::Property> aSeq = xInfo->getProperties(); + for (const auto & rIncludeProp : pIncludeProperties) + { + const beans::Property* pFind = ::std::find_if(aSeq.begin(), aSeq.end(), + [&rIncludeProp] (const beans::Property& x) -> bool { + return x.Name == rIncludeProp; + }); + if ( pFind != aSeq.end() ) + { + // special case for controls which contain a data field + if ( PROPERTY_DATAFIELD == rIncludeProp ) + { + beans::Property aValue; + aValue.Name = PROPERTY_FORMULALIST; + aNewProps.push_back(aValue); + aValue.Name = PROPERTY_SCOPE; + aNewProps.push_back(aValue); + aValue.Name = PROPERTY_TYPE; + aNewProps.push_back(aValue); + } + aNewProps.push_back(*pFind); + } + } + + // special property for shapes +// if ( uno::Reference< report::XShape>(m_xReportComponent,uno::UNO_QUERY).is() ) +// { +// beans::Property aValue; +// aValue.Name = PROPERTY_AREA; +// aNewProps.push_back(aValue); +// } + // re-enable when the remaining issues of #i88727# are fixed + + return uno::Sequence< beans::Property > (&(*aNewProps.begin()),aNewProps.size()); +} + +uno::Sequence< OUString > SAL_CALL GeometryHandler::getSupersededProperties() +{ + uno::Sequence< OUString > aRet; + const uno::Reference<report::XReportDefinition> xReport(m_xReportComponent,uno::UNO_QUERY); + if ( xReport.is() && !uno::Reference< report::XSection>(xReport->getParent(),uno::UNO_QUERY).is() ) + { + aRet.realloc(5); + OUString* pIter = aRet.getArray(); + *pIter++ = PROPERTY_POSITIONX; + *pIter++ = PROPERTY_POSITIONY; + *pIter++ = PROPERTY_WIDTH; + *pIter++ = PROPERTY_HEIGHT; + *pIter++ = PROPERTY_DATAFIELD; + } + return aRet; +} + +uno::Sequence< OUString > SAL_CALL GeometryHandler::getActuatingProperties() +{ + ::osl::MutexGuard aGuard( m_aMutex ); + + uno::Sequence< OUString > aSeq + { + PROPERTY_BACKTRANSPARENT, + PROPERTY_CONTROLBACKGROUNDTRANSPARENT, + PROPERTY_FORMULALIST, + PROPERTY_TYPE, + PROPERTY_DATAFIELD + }; + + return ::comphelper::concatSequences(m_xFormComponentHandler->getActuatingProperties(),aSeq); +} + +sal_Bool SAL_CALL GeometryHandler::isComposable(const OUString & _rPropertyName) +{ + return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler ); +} + +inspection::InteractiveSelectionResult SAL_CALL GeometryHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & _rData, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI) +{ + if ( !_rxInspectorUI.is() ) + throw lang::NullPointerException(); + if (PropertyName == PROPERTY_FILTER) + { + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled; + OUString sClause; + if ( impl_dialogFilter_nothrow( sClause, aGuard ) ) + { + _rData <<= sClause; + eResult = inspection::InteractiveSelectionResult_ObtainedValue; + } + return eResult; + } + else if (PropertyName == PROPERTY_FONT) + { + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled; + const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY); + const uno::Reference< report::XReportControlFormat> xReportControlFormat(m_xReportComponent,uno::UNO_QUERY); + aGuard.clear(); + + uno::Sequence< beans::NamedValue > aFontSettings; + if ( rptui::openCharDialog( xReportControlFormat, xInspectorWindow, aFontSettings ) ) + { + _rData <<= aFontSettings; + eResult = inspection::InteractiveSelectionResult_ObtainedValue; + } + return eResult; + } + else if ( PropertyName == PROPERTY_FORMULA + || PropertyName == PROPERTY_INITIALFORMULA + || PropertyName == PROPERTY_DATAFIELD + || PropertyName == PROPERTY_CONDITIONALPRINTEXPRESSION) + { + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + + OUString sFormula; + m_xReportComponent->getPropertyValue(PropertyName) >>= sFormula; + const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY); + uno::Reference< uno::XComponentContext > xContext = m_xContext; + uno::Reference< beans::XPropertySet > xRowSet( m_xRowSet,uno::UNO_QUERY); + aGuard.clear(); + + inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled; + if ( rptui::openDialogFormula_nothrow( sFormula, xContext,xInspectorWindow,xRowSet ) ) + { + _rData <<= sFormula; + eResult = inspection::InteractiveSelectionResult_ObtainedValue; + } + return eResult; + } + else if (PropertyName == PROPERTY_AREA) + { + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + + inspection::InteractiveSelectionResult eResult = inspection::InteractiveSelectionResult_Cancelled; + const uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY); + const uno::Reference< report::XShape> xShape(m_xReportComponent,uno::UNO_QUERY); + aGuard.clear(); + + if ( rptui::openAreaDialog( xShape, xInspectorWindow) ) + { + eResult = inspection::InteractiveSelectionResult_ObtainedValue; + beans::PropertyChangeEvent aScopeEvent; + aScopeEvent.PropertyName = PROPERTY_FILLCOLOR; + aScopeEvent.NewValue = xShape->getPropertyValue(PROPERTY_FILLCOLOR); + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent ); + } + return eResult; + } + + + return m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, _rData, _rxInspectorUI); +} + +void SAL_CALL GeometryHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & _rxInspectorUI, sal_Bool _bFirstTimeInit) +{ + if ( !_rxInspectorUI.is() ) + throw lang::NullPointerException(); + + ::osl::MutexGuard aGuard( m_aMutex ); + const sal_Int32 nId = OPropertyInfoService::getPropertyId(ActuatingPropertyName); + switch(nId) + { + case PROPERTY_ID_TYPE: + { + sal_uInt32 nNewVal = 0; + NewValue >>= nNewVal; + switch(nNewVal) + { + case DATA_OR_FORMULA: + _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD); + _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,true); + _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,false); + _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,false); + OSL_ENSURE(m_sDefaultFunction.isEmpty(),"Why is the m_sDefaultFunction set?"); + OSL_ENSURE(m_sScope.isEmpty(),"Why is the m_sScope set?"); + break; + case FUNCTION: + _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD); + _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST); + _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,true); + _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,!m_sDefaultFunction.isEmpty()); + _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,!m_sScope.isEmpty()); + break; + case USER_DEF_FUNCTION: + _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,false); + _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,true); + _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST); + _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,false); + break; + case COUNTER: + _rxInspectorUI->enablePropertyUI(PROPERTY_DATAFIELD,false); + _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,false); + _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,true); + break; + } + } + break; + case PROPERTY_ID_DATAFIELD: + { + bool bEnable = (m_nDataFieldType != DATA_OR_FORMULA && m_nDataFieldType != COUNTER ); + if ( bEnable ) + { + OUString sValue; + m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ) >>= sValue; + bEnable = !sValue.isEmpty(); + } + _rxInspectorUI->enablePropertyUI(PROPERTY_FORMULALIST,bEnable); + if ( bEnable ) + { + _rxInspectorUI->rebuildPropertyUI(PROPERTY_DATAFIELD); + _rxInspectorUI->rebuildPropertyUI(PROPERTY_FORMULALIST); + } + m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, _rxInspectorUI, _bFirstTimeInit); + } + break; + case PROPERTY_ID_FORMULALIST: + { + _rxInspectorUI->enablePropertyUI(PROPERTY_SCOPE,m_nDataFieldType == FUNCTION || m_nDataFieldType == COUNTER); + } + break; + case PROPERTY_ID_BACKTRANSPARENT: + case PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT: + { + bool bValue = false; + NewValue >>= bValue; + bValue = !bValue; + _rxInspectorUI->enablePropertyUI(PROPERTY_BACKCOLOR,bValue); + _rxInspectorUI->enablePropertyUI(PROPERTY_CONTROLBACKGROUND,bValue); + } + break; + default: + m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, _rxInspectorUI, _bFirstTimeInit); + break; + } +} + +sal_Bool SAL_CALL GeometryHandler::suspend(sal_Bool Suspend) +{ + return m_xFormComponentHandler->suspend(Suspend); +} + +bool GeometryHandler::impl_dialogFilter_nothrow( OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const +{ + _out_rSelectedClause.clear(); + bool bSuccess = false; + ::dbtools::SQLExceptionInfo aErrorInfo; + uno::Reference< awt::XWindow > xInspectorWindow; + uno::Reference< lang::XMultiComponentFactory > xFactory; + try + { + xFactory = m_xContext->getServiceManager(); + xInspectorWindow.set(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY); + uno::Reference<sdbc::XConnection> xCon(m_xContext->getValueByName("ActiveConnection") ,uno::UNO_QUERY); + if ( !xCon.is() ) + return false; + + uno::Reference< beans::XPropertySet> xRowSetProp(m_xRowSet,uno::UNO_QUERY); + if ( !m_xRowSet.is() ) + { + m_xRowSet.set(xFactory->createInstanceWithContext("com.sun.star.sdb.RowSet",m_xContext),uno::UNO_QUERY); + xRowSetProp.set(m_xRowSet,uno::UNO_QUERY); + xRowSetProp->setPropertyValue(PROPERTY_ACTIVECONNECTION,uno::Any(xCon)); + ::comphelper::copyProperties(m_xReportComponent,xRowSetProp); + } + + // get a composer for the statement which the form is currently based on + uno::Reference< sdb::XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( xRowSetProp, m_xContext, nullptr ) ); + OSL_ENSURE( xComposer.is(), "GeometryHandler::impl_dialogFilter_nothrow: could not obtain a composer!" ); + if ( !xComposer.is() ) + return false; + + // create the dialog + uno::Reference< ui::dialogs::XExecutableDialog > xDialog = sdb::FilterDialog::createWithQuery(m_xContext, xComposer, m_xRowSet, xInspectorWindow); + + const OUString sPropertyUIName(RptResId(RID_STR_FILTER)); + // initialize the dialog + xDialog->setTitle( sPropertyUIName ); + + _rClearBeforeDialog.clear(); + bSuccess = ( xDialog->execute() != 0 ); + if ( bSuccess ) + _out_rSelectedClause = xComposer->getFilter(); + } + catch (const sdb::SQLContext& e) { aErrorInfo = e; } + catch (const sdbc::SQLWarning& e) { aErrorInfo = e; } + catch (const sdbc::SQLException& e) { aErrorInfo = e; } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_dialogFilter_nothrow" ); + } + + if ( aErrorInfo.isValid() ) + ::dbtools::showError( aErrorInfo, xInspectorWindow, m_xContext ); + + return bSuccess; +} + +void GeometryHandler::checkPosAndSize( const awt::Point& _aNewPos, + const awt::Size& _aSize) +{ + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY); + const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY); + if ( !xSection.is() || uno::Reference< report::XShape>(xSourceReportComponent,uno::UNO_QUERY).is() ) // shapes can overlap. + return; + + ::Point aPos(VCLPoint(_aNewPos)); + if ( aPos.X() < 0 || aPos.Y() < 0 ) // TODO: have to check size with pos aka || (aPos.X() + aAwtSize.Width) > m_xSection->getReportDefinition()-> + throw beans::PropertyVetoException(RptResId(RID_STR_ILLEGAL_POSITION),xSourceReportComponent); + + ::tools::Rectangle aSourceRect(aPos,VCLSize(_aSize)); + + const sal_Int32 nCount = xSection->getCount(); + for (sal_Int32 i = 0; i < nCount ; ++i) + { + const uno::Reference< report::XReportComponent> xReportComponent(xSection->getByIndex(i),uno::UNO_QUERY); + if ( xReportComponent.is() && xReportComponent != xSourceReportComponent ) + { + const ::tools::Rectangle aBoundRect(VCLPoint(xReportComponent->getPosition()),VCLSize(xReportComponent->getSize())); + const ::tools::Rectangle aRect = aSourceRect.GetIntersection(aBoundRect); + if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) ) + throw beans::PropertyVetoException(RptResId( RID_STR_OVERLAP_OTHER_CONTROL),xSourceReportComponent); + } + } +} + +void GeometryHandler::impl_fillFormulaList_nothrow(::std::vector< OUString >& out_rList) const +{ + if ( m_nDataFieldType == FUNCTION ) + { + for (auto const& it : m_aDefaultFunctions) + { + out_rList.push_back(it.getName()); + } + } + else if ( m_nDataFieldType == USER_DEF_FUNCTION ) + ::std::transform( m_aFunctionNames.begin(), + m_aFunctionNames.end(), + ::std::back_inserter(out_rList), + ::o3tl::select1st< TFunctions::value_type >() ); +} + +OUString GeometryHandler::impl_ConvertUIToMimeType_nothrow(const OUString& _sUIName) const +{ + ::std::vector< OUString > aList; + impl_fillMimeTypes_nothrow(aList); + OUString sRet; + ::std::vector< OUString >::const_iterator aFind = ::std::find(aList.begin(),aList.end(),_sUIName); + if ( aFind != aList.end() ) + { + const std::size_t nPos = aFind - aList.begin(); + const uno::Reference< report::XReportDefinition> xReportDefinition(m_xReportComponent,uno::UNO_QUERY); + if ( xReportDefinition.is() ) + { + const uno::Sequence< OUString > aMimeTypes( xReportDefinition->getAvailableMimeTypes() ); + sRet = aMimeTypes[nPos]; + } + } + return sRet; +} + +OUString GeometryHandler::impl_ConvertMimeTypeToUI_nothrow(const OUString& _sMimetype) const +{ + ::comphelper::MimeConfigurationHelper aMimeHelper(m_xContext); + OUString sRet; + std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilter( aMimeHelper.GetDocServiceNameFromMediaType(_sMimetype) ); + if ( pFilter ) + sRet = pFilter->GetUIName(); + if ( sRet.isEmpty() ) + sRet = _sMimetype; + return sRet; +} + +void GeometryHandler::impl_fillMimeTypes_nothrow(::std::vector< OUString >& _out_rList) const +{ + try + { + const uno::Reference< report::XReportDefinition> xReportDefinition(m_xReportComponent,uno::UNO_QUERY); + if ( xReportDefinition.is() ) + { + const uno::Sequence< OUString > aMimeTypes( xReportDefinition->getAvailableMimeTypes() ); + for(const OUString& rMimeType : aMimeTypes) + { + const OUString sDocName( impl_ConvertMimeTypeToUI_nothrow(rMimeType) ); + if ( !sDocName.isEmpty() ) + _out_rList.push_back(sDocName); + } + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } +} + +void GeometryHandler::impl_fillScopeList_nothrow(::std::vector< OUString >& _out_rList) const +{ + try + { + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW); + const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW); + + const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups(); + sal_Int32 nPos = -1; + uno::Reference< report::XGroup> xGroup = xSection->getGroup(); + if ( xGroup.is() ) + nPos = getPositionInIndexAccess(xGroups,xGroup); + else if ( xSection == xReportDefinition->getDetail() ) + nPos = xGroups->getCount()-1; + + const OUString sGroup = RptResId(RID_STR_SCOPE_GROUP); + for (sal_Int32 i = 0 ; i <= nPos ; ++i) + { + xGroup.set(xGroups->getByIndex(i),uno::UNO_QUERY_THROW); + OUString sGroupName = sGroup.replaceFirst("%1",xGroup->getExpression()); + _out_rList.push_back(sGroupName); + } + _out_rList.push_back(xReportDefinition->getName()); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } +} + +uno::Reference< report::XFunctionsSupplier> GeometryHandler::fillScope_throw(OUString& _rsNamePostfix) +{ + uno::Reference< report::XFunctionsSupplier> xReturn; + + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW); + const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW); + const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + if ( m_sScope.isEmpty() ) + { + const uno::Reference< report::XGroup> xGroup = xSection->getGroup(); + if ( xGroup.is() ) + { + OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP); + _rsNamePostfix = xGroup->getExpression(); + m_sScope = sGroupName.replaceFirst("%1",_rsNamePostfix); + xReturn = xGroup.get(); + } + else if ( xSection == xReportDefinition->getDetail() ) + { + const uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups(); + const sal_Int32 nCount = xGroups->getCount(); + if ( nCount ) + { + const uno::Reference< report::XGroup> xGroup2(xGroups->getByIndex(nCount - 1),uno::UNO_QUERY_THROW); + OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP); + _rsNamePostfix = xGroup2->getExpression(); + m_sScope = sGroupName.replaceFirst("%1",_rsNamePostfix); + xReturn = xGroup2.get(); + } + } + if ( m_sScope.isEmpty() ) + { + xReturn = xReportDefinition.get(); + _rsNamePostfix = m_sScope = xReportDefinition->getName(); + } + } + else if ( m_sScope == xReportDefinition->getName() ) + { + xReturn = xReportDefinition.get(); + _rsNamePostfix = m_sScope; + } + else + { + uno::Reference< report::XGroups> xGroups = xReportDefinition->getGroups(); + const sal_Int32 nCount = xGroups->getCount(); + + for (sal_Int32 i = 0 ; i < nCount; ++i) + { + const uno::Reference< report::XGroup> xGroup(xGroups->getByIndex(i),uno::UNO_QUERY_THROW); + OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP); + if ( m_sScope == sGroupName.replaceFirst("%1",xGroup->getExpression()) ) + { + _rsNamePostfix = xGroup->getExpression(); + xReturn = xGroup.get(); + break; + } + } + + } + OSL_ENSURE(xReturn.is(),"Why don't we have a functionssupplier here!"); + + return xReturn; +} + +bool GeometryHandler::isDefaultFunction( const OUString& _sQuotedFunction + ,OUString& _rDataField + ,const uno::Reference< report::XFunctionsSupplier>& _xFunctionsSupplier + ,bool _bSet) const +{ + bool bDefaultFunction = false; + try + { + const uno::Reference< report::XReportComponent> xSourceReportComponent(m_xReportComponent,uno::UNO_QUERY_THROW); + const uno::Reference< report::XSection> xSection(xSourceReportComponent->getParent(),uno::UNO_QUERY_THROW); + const uno::Reference< report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + + ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(_sQuotedFunction); + while ( aFind.first != aFind.second ) + { + if ( !_xFunctionsSupplier.is() || _xFunctionsSupplier == aFind.first->second.second ) + { + const beans::Optional< OUString> aInitialFormula = aFind.first->second.first->getInitialFormula(); + if ( aInitialFormula.IsPresent ) + { + OUString sDefaultFunctionName; + bDefaultFunction = impl_isDefaultFunction_nothrow(aFind.first->second.first,_rDataField,sDefaultFunctionName); + if ( bDefaultFunction ) + { + m_xFunction = aFind.first->second.first; + if ( _bSet ) + { + m_sDefaultFunction = sDefaultFunctionName; + uno::Reference< report::XGroup> xGroup(aFind.first->second.second,uno::UNO_QUERY); + if ( xGroup.is() ) + { + OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP); + m_sScope = sGroupName.replaceFirst("%1",xGroup->getExpression()); + } + else + m_sScope = xReportDefinition->getName(); + } + } + break; + } + } + ++(aFind.first); + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + return bDefaultFunction; +} + +bool GeometryHandler::impl_isDefaultFunction_nothrow( const uno::Reference< report::XFunction>& _xFunction + ,OUString& _rDataField + ,OUString& _rsDefaultFunctionName) const +{ + bool bDefaultFunction = false; + try + { + const OUString sFormula( _xFunction->getFormula() ); + i18nutil::SearchOptions2 aSearchOptions; + aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::REGEXP; + aSearchOptions.searchFlag = 0x00000100; + auto aIter = std::find_if(m_aDefaultFunctions.begin(), m_aDefaultFunctions.end(), + [&aSearchOptions, &sFormula](const DefaultFunction& rDefaultFunction) { + aSearchOptions.searchString = rDefaultFunction.m_sSearchString; + utl::TextSearch aTextSearch( aSearchOptions); + sal_Int32 start = 0; + sal_Int32 end = sFormula.getLength(); + return aTextSearch.SearchForward(sFormula, &start, &end) && start == 0 && end == sFormula.getLength(); + }); + if (aIter != m_aDefaultFunctions.end()) // default function found + { + sal_Int32 start = 0; + sal_Int32 end = sFormula.getLength(); + aSearchOptions.searchString = "\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]"; + utl::TextSearch aDataSearch( aSearchOptions); + (void)aDataSearch.SearchForward(sFormula, &start, &end); + ++start; + _rDataField = sFormula.copy(start,end-start-1); + _rsDefaultFunctionName = aIter->m_sName; + bDefaultFunction = true; + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + return bDefaultFunction; +} + +void GeometryHandler::loadDefaultFunctions() +{ + if ( !m_aDefaultFunctions.empty() ) + return; + + m_aCounterFunction.m_bPreEvaluated = false; + m_aCounterFunction.m_sName = RptResId(RID_STR_F_COUNTER); + m_aCounterFunction.m_sFormula = "rpt:[%FunctionName] + 1"; + m_aCounterFunction.m_sSearchString = "rpt:\\[[:alpha:]+([:space:]*[:alnum:]*)*\\][:space:]*\\+[:space:]*[:digit:]*"; + m_aCounterFunction.m_sInitialFormula.IsPresent = true; + m_aCounterFunction.m_sInitialFormula.Value = "rpt:1"; + + DefaultFunction aDefault; + + aDefault.m_bPreEvaluated = true; + + aDefault.m_sName = RptResId(RID_STR_F_ACCUMULATION); + aDefault.m_sFormula = "rpt:[%Column] + [%FunctionName]"; + aDefault.m_sSearchString = "rpt:\\[[:alpha:]+([:space:]*[:alnum:]*)*\\][:space:]*\\+[:space:]*\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]"; + aDefault.m_sInitialFormula.IsPresent = true; + aDefault.m_sInitialFormula.Value = "rpt:[%Column]"; + m_aDefaultFunctions.push_back(aDefault); + + aDefault.m_sName = RptResId(RID_STR_F_MINIMUM); + aDefault.m_sFormula = "rpt:IF([%Column] < [%FunctionName];[%Column];[%FunctionName])"; + aDefault.m_sSearchString = "rpt:IF\\((\\[[:alpha:]+([:space:]*[:alnum:]*)*\\])[:space:]*<[:space:]*(\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]);[:space:]*\\1[:space:]*;[:space:]*\\3[:space:]*\\)"; + aDefault.m_sInitialFormula.IsPresent = true; + aDefault.m_sInitialFormula.Value = "rpt:[%Column]"; + m_aDefaultFunctions.push_back(aDefault); + + aDefault.m_sName = RptResId(RID_STR_F_MAXIMUM); + aDefault.m_sFormula = "rpt:IF([%Column] > [%FunctionName];[%Column];[%FunctionName])"; + aDefault.m_sSearchString = "rpt:IF\\((\\[[:alpha:]+([:space:]*[:alnum:]*)*\\])[:space:]*>[:space:]*(\\[[:alpha:]+([:space:]*[:alnum:]*)*\\]);[:space:]*\\1[:space:]*;[:space:]*\\3[:space:]*\\)"; + aDefault.m_sInitialFormula.IsPresent = true; + aDefault.m_sInitialFormula.Value = "rpt:[%Column]"; + m_aDefaultFunctions.push_back(aDefault); +} + +void GeometryHandler::createDefaultFunction(::osl::ResettableMutexGuard& _aGuard ,const OUString& _sFunction,std::u16string_view _sDataField) +{ + try + { + OUString sNamePostfix; + const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix); + + auto aIter = std::find_if(m_aDefaultFunctions.begin(), m_aDefaultFunctions.end(), + [&_sFunction](const DefaultFunction& rDefaultFunction) { return rDefaultFunction.m_sName == _sFunction; }); + if (aIter != m_aDefaultFunctions.end()) + { + const OUString sFunctionName( _sFunction + _sDataField + sNamePostfix); + const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(sFunctionName)); + + beans::PropertyChangeEvent aEvent; + aEvent.PropertyName = PROPERTY_SCOPE; + aEvent.OldValue <<= m_sScope; + + ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(sQuotedFunctionName); + while ( aFind.first != aFind.second ) + { + if ( xFunctionsSupplier == aFind.first->second.second ) + { + m_xFunction = aFind.first->second.first; + OUString sTemp; + isDefaultFunction(sQuotedFunctionName,sTemp,uno::Reference< report::XFunctionsSupplier>(),true); // implicitly sets the m_sScope + break; + } + ++(aFind.first); + } + if ( aFind.first == aFind.second ) + impl_createFunction(sFunctionName,_sDataField,*aIter); + + OBlocker aBlocker(m_bIn); + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any( impl_convertToFormula( uno::Any(sQuotedFunctionName) ))); + aEvent.NewValue <<= m_sScope; + _aGuard.clear(); + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aEvent ); + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } +} + +void GeometryHandler::removeFunction() +{ + if ( !m_xFunction.is() ) + return; + + const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(m_xFunction)); + ::std::pair<TFunctions::iterator,TFunctions::iterator> aFind = m_aFunctionNames.equal_range(sQuotedFunctionName); + while ( aFind.first != aFind.second ) + { + if ( aFind.first->second.first == m_xFunction ) + { + uno::Reference< report::XFunctions> xFunctions = aFind.first->second.second->getFunctions(); + xFunctions->removeByIndex(xFunctions->getCount() - 1 ); /// TODO: insert new method in XFunctions: removeFunction(xfunction) + m_aFunctionNames.erase(aFind.first); + m_bNewFunction = false; + break; + } + ++(aFind.first); + } +} + +void GeometryHandler::resetOwnProperties(::osl::ResettableMutexGuard& _aGuard,const OUString& _sOldFunctionName,const OUString& _sOldScope,const sal_uInt32 _nOldDataFieldType) +{ + const OUString sNewFunction = m_sDefaultFunction; + const OUString sNewScope = m_sScope; + const sal_uInt32 nNewDataFieldType = m_nDataFieldType; + _aGuard.clear(); + if ( _nOldDataFieldType != nNewDataFieldType ) + { + beans::PropertyChangeEvent aScopeEvent; + aScopeEvent.PropertyName = PROPERTY_TYPE; + aScopeEvent.OldValue <<= _nOldDataFieldType; + aScopeEvent.NewValue <<= nNewDataFieldType; + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent ); + } + if ( _sOldFunctionName != sNewFunction ) + { + beans::PropertyChangeEvent aFormulaEvent; + aFormulaEvent.PropertyName = PROPERTY_FORMULALIST; + aFormulaEvent.OldValue <<= _sOldFunctionName; + aFormulaEvent.NewValue <<= sNewFunction; + + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aFormulaEvent ); + } + if ( _sOldScope != sNewScope ) + { + beans::PropertyChangeEvent aScopeEvent; + aScopeEvent.PropertyName = PROPERTY_SCOPE; + aScopeEvent.OldValue <<= _sOldScope; + aScopeEvent.NewValue <<= sNewScope; + m_aPropertyListeners.notifyEach( &beans::XPropertyChangeListener::propertyChange, aScopeEvent ); + } + + _aGuard.reset(); +} + +void GeometryHandler::impl_initFieldList_nothrow( uno::Sequence< OUString >& _rFieldNames ) const +{ + _rFieldNames.realloc(0); + try + { + uno::Reference< awt::XWindow> xInspectorWindow(m_xContext->getValueByName("DialogParentWindow") ,uno::UNO_QUERY); + weld::WaitObject aWaitCursor(Application::GetFrameWeld(xInspectorWindow)); + + // get the form of the control we're inspecting + uno::Reference< beans::XPropertySet > xFormSet( m_xRowSet, uno::UNO_QUERY ); + if ( !xFormSet.is() ) + return; + + OUString sObjectName; + OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName ); + // when there is no command we don't need to ask for columns + uno::Reference<sdbc::XConnection> xCon(m_xContext->getValueByName("ActiveConnection") ,uno::UNO_QUERY); + if ( !sObjectName.isEmpty() && xCon.is() ) + { + sal_Int32 nObjectType = sdb::CommandType::COMMAND; + OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType ); + + _rFieldNames = ::dbtools::getFieldNamesByCommandDescriptor( xCon, nObjectType, sObjectName ); + } + } + catch (uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_initFieldList_nothrow" ); + } +} + +bool GeometryHandler::impl_isCounterFunction_throw(const OUString& _sQuotedFunctionName,OUString& Out_sScope) const +{ + ::std::pair<TFunctions::const_iterator,TFunctions::const_iterator> aFind = m_aFunctionNames.equal_range(_sQuotedFunctionName); + while ( aFind.first != aFind.second ) + { + const beans::Optional< OUString> aInitialFormula = aFind.first->second.first->getInitialFormula(); + if ( aInitialFormula.IsPresent ) + { + const OUString sFormula( aFind.first->second.first->getFormula() ); + i18nutil::SearchOptions2 aSearchOptions; + aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::REGEXP; + aSearchOptions.searchFlag = 0x00000100; + aSearchOptions.searchString = m_aCounterFunction.m_sSearchString; + utl::TextSearch aTextSearch( aSearchOptions); + sal_Int32 start = 0; + sal_Int32 end = sFormula.getLength(); + if ( aTextSearch.SearchForward(sFormula,&start,&end) && start == 0 && end == sFormula.getLength()) // counter function found + { + const uno::Reference< report::XGroup > xGroup(aFind.first->second.second,uno::UNO_QUERY); + if ( xGroup.is() ) + { + OUString sGroupName = RptResId(RID_STR_SCOPE_GROUP); + Out_sScope = sGroupName.replaceFirst("%1",xGroup->getExpression()); + } + else + Out_sScope = uno::Reference< report::XReportDefinition >(aFind.first->second.second,uno::UNO_QUERY_THROW)->getName(); + break; + } + } + ++(aFind.first); + } + return aFind.first != aFind.second; +} + +void GeometryHandler::impl_createFunction(const OUString& _sFunctionName,std::u16string_view _sDataField,const DefaultFunction& _aFunction) +{ + if ( m_bNewFunction ) + removeFunction(); + + const OUString sQuotedFunctionName(lcl_getQuotedFunctionName(_sFunctionName)); + m_xFunction.set(report::Function::create(m_xContext)); + m_xFunction->setName( _sFunctionName ); + + static const OUStringLiteral sPlaceHolder1(u"%Column"); + static const OUStringLiteral sPlaceHolder2(u"%FunctionName"); + OUString sFormula(_aFunction.m_sFormula); + sFormula = sFormula.replaceAll(sPlaceHolder1,_sDataField); + sFormula = sFormula.replaceAll(sPlaceHolder2,_sFunctionName); + + m_xFunction->setFormula(sFormula); + m_xFunction->setPreEvaluated(_aFunction.m_bPreEvaluated); + m_xFunction->setDeepTraversing(false); + if ( _aFunction.m_sInitialFormula.IsPresent ) + { + beans::Optional< OUString> aInitialFormula = _aFunction.m_sInitialFormula; + OUString sInitialFormula = aInitialFormula.Value; + sInitialFormula = sInitialFormula.replaceAll(sPlaceHolder1,_sDataField); + sInitialFormula = sInitialFormula.replaceAll(sPlaceHolder2,_sFunctionName); + aInitialFormula.Value = sInitialFormula; + m_xFunction->setInitialFormula( aInitialFormula ); + } + OUString sNamePostfix; + const uno::Reference< report::XFunctionsSupplier> xFunctionsSupplier = fillScope_throw(sNamePostfix); + const uno::Reference< container::XIndexContainer> xFunctions(xFunctionsSupplier->getFunctions(),uno::UNO_QUERY_THROW); + xFunctions->insertByIndex(xFunctions->getCount(),uno::Any(m_xFunction)); + m_aFunctionNames.emplace(sQuotedFunctionName,TFunctionPair(m_xFunction,xFunctionsSupplier)); + m_bNewFunction = true; +} + +void GeometryHandler::impl_setCounterFunction_throw() +{ + OUString sNamePostfix; + fillScope_throw(sNamePostfix); + OUString sFunctionName = m_aCounterFunction.m_sName + sNamePostfix; + const OUString sQuotedFunctionName = lcl_getQuotedFunctionName(sFunctionName); + OUString sScope; + if ( !(!sFunctionName.isEmpty() && m_aFunctionNames.find(sQuotedFunctionName) != m_aFunctionNames.end() && impl_isCounterFunction_throw(sQuotedFunctionName,sScope)) ) + impl_createFunction(sFunctionName,{},m_aCounterFunction); + + OBlocker aBlocker(m_bIn); + m_xReportComponent->setPropertyValue(PROPERTY_DATAFIELD,uno::Any(impl_convertToFormula( uno::Any(sQuotedFunctionName)))); +} + +sal_uInt32 GeometryHandler::impl_getDataFieldType_throw(const OUString& _sDataField) const +{ + sal_uInt32 nDataFieldType = UNDEF_DATA; + OUString sDataField; + if ( !_sDataField.isEmpty() ) + sDataField = _sDataField; + else + { + uno::Any aDataField( m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ) ); + lcl_convertFormulaTo(aDataField,aDataField); + aDataField >>= sDataField; + } + + if ( !sDataField.isEmpty() ) + { + if ( impl_isDataField(sDataField) ) + nDataFieldType = DATA_OR_FORMULA; + else if ( isDefaultFunction(sDataField,sDataField) ) + nDataFieldType = FUNCTION; + else if ( m_aFunctionNames.find(sDataField) != m_aFunctionNames.end() ) + { + nDataFieldType = USER_DEF_FUNCTION; + OUString sScope; + if ( impl_isCounterFunction_throw(sDataField,sScope) ) + nDataFieldType = COUNTER; + } + else + nDataFieldType = DATA_OR_FORMULA; + } + return nDataFieldType; +} + +// XEventListener +void SAL_CALL GeometryHandler::disposing(const lang::EventObject& ) +{ +} +// XPropertyChangeListener +void SAL_CALL GeometryHandler::propertyChange(const beans::PropertyChangeEvent& /*evt*/) +{ + ::osl::ResettableMutexGuard aGuard( m_aMutex ); + if ( m_bIn ) + return; + + const sal_uInt32 nOldDataFieldType = m_nDataFieldType; + const OUString sOldFunctionName = m_sDefaultFunction; + const OUString sOldScope = m_sScope; + m_sDefaultFunction.clear(); + m_sScope.clear(); + m_nDataFieldType = impl_getDataFieldType_throw(); + if ( UNDEF_DATA == m_nDataFieldType ) + m_nDataFieldType = nOldDataFieldType; + uno::Any aDataField = m_xReportComponent->getPropertyValue( PROPERTY_DATAFIELD ); + lcl_convertFormulaTo(aDataField,aDataField); + OUString sDataField; + aDataField >>= sDataField; + switch(m_nDataFieldType) + { + case FUNCTION: + isDefaultFunction(sDataField,sDataField,uno::Reference< report::XFunctionsSupplier>(),true); + break; + case COUNTER: + impl_isCounterFunction_throw(sDataField,m_sScope); + break; + default: + ; + } + + resetOwnProperties(aGuard,sOldFunctionName,sOldScope,nOldDataFieldType); +} + +} // namespace rptui + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_GeometryHandler_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptui::GeometryHandler(context)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inspection/ReportComponentHandler.cxx b/reportdesign/source/ui/inspection/ReportComponentHandler.cxx new file mode 100644 index 000000000..28b33acc4 --- /dev/null +++ b/reportdesign/source/ui/inspection/ReportComponentHandler.cxx @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportComponentHandler.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/NullPointerException.hpp> +#include <comphelper/types.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/form/inspection/FormComponentPropertyHandler.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <metadata.hxx> + + +namespace rptui +{ + +using namespace ::com::sun::star; + +ReportComponentHandler::ReportComponentHandler(uno::Reference< uno::XComponentContext > const & context) + :ReportComponentHandler_Base(m_aMutex) + ,m_xContext(context) +{ + try + { + m_xFormComponentHandler = form::inspection::FormComponentPropertyHandler::create(m_xContext); + + }catch(const uno::Exception &) + { + } +} + +OUString SAL_CALL ReportComponentHandler::getImplementationName( ) +{ + return "com.sun.star.comp.report.ReportComponentHandler"; +} + +sal_Bool SAL_CALL ReportComponentHandler::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getSupportedServiceNames( ) +{ + return { "com.sun.star.report.inspection.ReportComponentHandler" }; +} + +// override WeakComponentImplHelperBase::disposing() +// This function is called upon disposing the component, +// if your component needs special work when it becomes +// disposed, do it here. +void SAL_CALL ReportComponentHandler::disposing() +{ + ::comphelper::disposeComponent(m_xFormComponentHandler); +} +void SAL_CALL ReportComponentHandler::addEventListener(const uno::Reference< lang::XEventListener > & xListener) +{ + m_xFormComponentHandler->addEventListener(xListener); +} + +void SAL_CALL ReportComponentHandler::removeEventListener(const uno::Reference< lang::XEventListener > & aListener) +{ + m_xFormComponentHandler->removeEventListener(aListener); +} + +// inspection::XPropertyHandler: + +/********************************************************************************/ +void SAL_CALL ReportComponentHandler::inspect(const uno::Reference< uno::XInterface > & Component) +{ + try + { + uno::Reference< container::XNameContainer > xNameCont(Component,uno::UNO_QUERY); + static const OUStringLiteral sFormComponent(u"FormComponent"); + if ( xNameCont->hasByName(sFormComponent) ) + xNameCont->getByName(sFormComponent) >>= m_xFormComponent; + static const OUStringLiteral sRowSet(u"RowSet"); + if ( xNameCont->hasByName(sRowSet) ) + { + uno::Reference<beans::XPropertySet> xProp(m_xFormComponentHandler,uno::UNO_QUERY); + xProp->setPropertyValue(sRowSet,xNameCont->getByName(sRowSet)); + } + } + catch(const uno::Exception &) + { + throw lang::NullPointerException(); + } + if ( m_xFormComponent.is() ) + { + m_xFormComponentHandler->inspect(m_xFormComponent); + } +} + +uno::Any SAL_CALL ReportComponentHandler::getPropertyValue(const OUString & PropertyName) +{ + return m_xFormComponentHandler->getPropertyValue(PropertyName); +} + +void SAL_CALL ReportComponentHandler::setPropertyValue(const OUString & PropertyName, const uno::Any & Value) +{ + m_xFormComponentHandler->setPropertyValue(PropertyName, Value); +} + +beans::PropertyState SAL_CALL ReportComponentHandler::getPropertyState(const OUString & PropertyName) +{ + return m_xFormComponentHandler->getPropertyState(PropertyName); +} + +inspection::LineDescriptor SAL_CALL ReportComponentHandler::describePropertyLine(const OUString & PropertyName, const uno::Reference< inspection::XPropertyControlFactory > & ControlFactory) +{ + return m_xFormComponentHandler->describePropertyLine(PropertyName, ControlFactory); +} + +uno::Any SAL_CALL ReportComponentHandler::convertToPropertyValue(const OUString & PropertyName, const uno::Any & ControlValue) +{ + return m_xFormComponentHandler->convertToPropertyValue(PropertyName, ControlValue); +} + +uno::Any SAL_CALL ReportComponentHandler::convertToControlValue(const OUString & PropertyName, const uno::Any & PropertyValue, const uno::Type & ControlValueType) +{ + return m_xFormComponentHandler->convertToControlValue(PropertyName, PropertyValue, ControlValueType); +} + +void SAL_CALL ReportComponentHandler::addPropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & Listener) +{ + m_xFormComponentHandler->addPropertyChangeListener(Listener); +} + +void SAL_CALL ReportComponentHandler::removePropertyChangeListener(const uno::Reference< beans::XPropertyChangeListener > & _rxListener) +{ + m_xFormComponentHandler->removePropertyChangeListener(_rxListener); +} + +uno::Sequence< beans::Property > SAL_CALL ReportComponentHandler::getSupportedProperties() +{ + ::std::vector< beans::Property > aNewProps; + rptui::OPropertyInfoService::getExcludeProperties( aNewProps, m_xFormComponentHandler ); + + return uno::Sequence< beans::Property >(aNewProps.data(), aNewProps.size()); +} + +uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getSupersededProperties() +{ + uno::Sequence< OUString > aRet; + return aRet; +} + +uno::Sequence< OUString > SAL_CALL ReportComponentHandler::getActuatingProperties() +{ + return m_xFormComponentHandler->getActuatingProperties(); +} + +sal_Bool SAL_CALL ReportComponentHandler::isComposable( const OUString& _rPropertyName ) +{ + return OPropertyInfoService::isComposable( _rPropertyName, m_xFormComponentHandler ); +} + +inspection::InteractiveSelectionResult SAL_CALL ReportComponentHandler::onInteractivePropertySelection(const OUString & PropertyName, sal_Bool Primary, uno::Any & out_Data, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI) +{ + return m_xFormComponentHandler->onInteractivePropertySelection(PropertyName, Primary, out_Data, InspectorUI); +} + +void SAL_CALL ReportComponentHandler::actuatingPropertyChanged(const OUString & ActuatingPropertyName, const uno::Any & NewValue, const uno::Any & OldValue, const uno::Reference< inspection::XObjectInspectorUI > & InspectorUI, sal_Bool FirstTimeInit) +{ + m_xFormComponentHandler->actuatingPropertyChanged(ActuatingPropertyName, NewValue, OldValue, InspectorUI, FirstTimeInit); +} + +sal_Bool SAL_CALL ReportComponentHandler::suspend(sal_Bool Suspend) +{ + return m_xFormComponentHandler->suspend(Suspend); +} + + +} // namespace rptui + + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_ReportComponentHandler_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptui::ReportComponentHandler(context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/inspection/metadata.cxx b/reportdesign/source/ui/inspection/metadata.cxx new file mode 100644 index 000000000..59bbdb21d --- /dev/null +++ b/reportdesign/source/ui/inspection/metadata.cxx @@ -0,0 +1,293 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <metadata.hxx> +#include <com/sun/star/inspection/XPropertyHandler.hpp> +#include <core_resource.hxx> +#include <helpids.h> +#include <strings.hrc> +#include <strings.hxx> + +#include <algorithm> +#include <string_view> + +namespace rptui +{ + + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star; + + + //= OPropertyInfoImpl + + struct OPropertyInfoImpl + { + OUString sName; + OUString sTranslation; + OString sHelpId; + sal_Int32 nId; + PropUIFlags nUIFlags; + + OPropertyInfoImpl( + const OUString& rName, + sal_Int32 _nId, + const OUString& aTranslation, + const OString& _sHelpId, + PropUIFlags _nUIFlags); + }; + + + OPropertyInfoImpl::OPropertyInfoImpl(const OUString& _rName, sal_Int32 _nId, + const OUString& aString, const OString& sHid, PropUIFlags _nUIFlags) + :sName(_rName) + ,sTranslation(aString) + ,sHelpId(sHid) + ,nId(_nId) + ,nUIFlags(_nUIFlags) + { + } + + namespace { + + // compare PropertyInfo + struct PropertyInfoLessByName + { + bool operator()( const OPropertyInfoImpl& _lhs, const OPropertyInfoImpl& _rhs ) + { + return _lhs.sName < _rhs.sName; + } + }; + + } + + //= OPropertyInfoService + + sal_uInt16 OPropertyInfoService::s_nCount = 0; + OPropertyInfoImpl* OPropertyInfoService::s_pPropertyInfos = nullptr; + + const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo() + { + if ( s_pPropertyInfos ) + return s_pPropertyInfos; + + static OPropertyInfoImpl aPropertyInfos[] = + { + OPropertyInfoImpl(PROPERTY_FORCENEWPAGE, PROPERTY_ID_FORCENEWPAGE, RptResId(RID_STR_FORCENEWPAGE), HID_RPT_PROP_FORCENEWPAGE, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_NEWROWORCOL, PROPERTY_ID_NEWROWORCOL, RptResId(RID_STR_NEWROWORCOL), HID_RPT_PROP_NEWROWORCOL, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_KEEPTOGETHER, PROPERTY_ID_KEEPTOGETHER, RptResId(RID_STR_KEEPTOGETHER), HID_RPT_PROP_KEEPTOGETHER, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CANGROW, PROPERTY_ID_CANGROW, RptResId(RID_STR_CANGROW), HID_RPT_PROP_CANGROW, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CANSHRINK, PROPERTY_ID_CANSHRINK, RptResId(RID_STR_CANSHRINK), HID_RPT_PROP_CANSHRINK, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_REPEATSECTION, PROPERTY_ID_REPEATSECTION, RptResId(RID_STR_REPEATSECTION), HID_RPT_PROP_REPEATSECTION, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PRINTREPEATEDVALUES, PROPERTY_ID_PRINTREPEATEDVALUES, RptResId(RID_STR_PRINTREPEATEDVALUES), HID_RPT_PROP_PRINTREPEATEDVALUES, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CONDITIONALPRINTEXPRESSION, PROPERTY_ID_CONDITIONALPRINTEXPRESSION, RptResId(RID_STR_CONDITIONALPRINTEXPRESSION), HID_RPT_PROP_CONDITIONALPRINTEXPRESSION, + PropUIFlags::Composeable ), + OPropertyInfoImpl(PROPERTY_STARTNEWCOLUMN, PROPERTY_ID_STARTNEWCOLUMN, RptResId(RID_STR_STARTNEWCOLUMN), HID_RPT_PROP_STARTNEWCOLUMN, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_RESETPAGENUMBER, PROPERTY_ID_RESETPAGENUMBER, RptResId(RID_STR_RESETPAGENUMBER), HID_RPT_PROP_RESETPAGENUMBER, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PRINTWHENGROUPCHANGE, PROPERTY_ID_PRINTWHENGROUPCHANGE, RptResId(RID_STR_PRINTWHENGROUPCHANGE), HID_RPT_PROP_PRINTWHENGROUPCHANGE, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_VISIBLE, PROPERTY_ID_VISIBLE, RptResId(RID_STR_VISIBLE), HID_RPT_PROP_VISIBLE, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_GROUPKEEPTOGETHER, PROPERTY_ID_GROUPKEEPTOGETHER, RptResId(RID_STR_GROUPKEEPTOGETHER), HID_RPT_PROP_GROUPKEEPTOGETHER, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PAGEHEADEROPTION, PROPERTY_ID_PAGEHEADEROPTION, RptResId(RID_STR_PAGEHEADEROPTION), HID_RPT_PROP_PAGEHEADEROPTION, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PAGEFOOTEROPTION, PROPERTY_ID_PAGEFOOTEROPTION, RptResId(RID_STR_PAGEFOOTEROPTION), HID_RPT_PROP_PAGEFOOTEROPTION, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_POSITIONX, PROPERTY_ID_POSITIONX, RptResId(RID_STR_POSITIONX), HID_RPT_PROP_RPT_POSITIONX, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_POSITIONY, PROPERTY_ID_POSITIONY, RptResId(RID_STR_POSITIONY), HID_RPT_PROP_RPT_POSITIONY, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_WIDTH, PROPERTY_ID_WIDTH, RptResId(RID_STR_WIDTH), HID_RPT_PROP_RPT_WIDTH, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_HEIGHT, PROPERTY_ID_HEIGHT, RptResId(RID_STR_HEIGHT), HID_RPT_PROP_RPT_HEIGHT, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_AUTOGROW, PROPERTY_ID_AUTOGROW, RptResId(RID_STR_AUTOGROW), HID_RPT_PROP_RPT_AUTOGROW, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_FONT, PROPERTY_ID_FONT, RptResId(RID_STR_FONT), HID_RPT_PROP_RPT_FONT, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PREEVALUATED, PROPERTY_ID_PREEVALUATED, RptResId(RID_STR_PREEVALUATED), HID_RPT_PROP_PREEVALUATED, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_DEEPTRAVERSING, PROPERTY_ID_DEEPTRAVERSING, RptResId(RID_STR_DEEPTRAVERSING), HID_RPT_PROP_DEEPTRAVERSING, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_FORMULA, PROPERTY_ID_FORMULA, RptResId(RID_STR_FORMULA), HID_RPT_PROP_FORMULA, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_INITIALFORMULA, PROPERTY_ID_INITIALFORMULA, RptResId(RID_STR_INITIALFORMULA), HID_RPT_PROP_INITIALFORMULA, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_TYPE, PROPERTY_ID_TYPE, RptResId(RID_STR_TYPE), HID_RPT_PROP_TYPE, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_DATAFIELD,PROPERTY_ID_DATAFIELD, RptResId(RID_STR_DATAFIELD), HID_RPT_PROP_DATAFIELD, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_FORMULALIST, PROPERTY_ID_FORMULALIST, RptResId(RID_STR_FORMULALIST), HID_RPT_PROP_FORMULALIST, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_SCOPE, PROPERTY_ID_SCOPE, RptResId(RID_STR_SCOPE), HID_RPT_PROP_SCOPE, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_PRESERVEIRI, PROPERTY_ID_PRESERVEIRI, RptResId(RID_STR_PRESERVEIRI), HID_RPT_PROP_PRESERVEIRI, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_BACKCOLOR, PROPERTY_ID_BACKCOLOR, RptResId(RID_STR_BACKCOLOR), HID_RPT_PROP_BACKCOLOR, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CONTROLBACKGROUND, PROPERTY_ID_CONTROLBACKGROUND, RptResId(RID_STR_BACKCOLOR), HID_RPT_PROP_BACKCOLOR, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_BACKTRANSPARENT, PROPERTY_ID_BACKTRANSPARENT, RptResId(RID_STR_BACKTRANSPARENT), HID_RPT_PROP_BACKTRANSPARENT, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CONTROLBACKGROUNDTRANSPARENT, PROPERTY_ID_CONTROLBACKGROUNDTRANSPARENT, RptResId(RID_STR_CONTROLBACKGROUNDTRANSPARENT), HID_RPT_PROP_CONTROLBACKGROUNDTRANSPARENT, + PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_CHARTTYPE, PROPERTY_ID_CHARTTYPE, RptResId(RID_STR_CHARTTYPE), HID_RPT_PROP_CHARTTYPE, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_PREVIEW_COUNT, PROPERTY_ID_PREVIEW_COUNT, RptResId(RID_STR_PREVIEW_COUNT), HID_RPT_PROP_PREVIEW_COUNT, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_MASTERFIELDS, PROPERTY_ID_MASTERFIELDS, RptResId(RID_STR_MASTERFIELDS), HID_RPT_PROP_MASTERFIELDS, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_DETAILFIELDS, PROPERTY_ID_DETAILFIELDS, RptResId(RID_STR_DETAILFIELDS), HID_RPT_PROP_DETAILFIELDS, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_AREA, PROPERTY_ID_AREA, RptResId(RID_STR_AREA), HID_RPT_PROP_AREA, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_MIMETYPE, PROPERTY_ID_MIMETYPE, RptResId(RID_STR_MIMETYPE), HID_RPT_PROP_MIMETYPE, PropUIFlags::Composeable | PropUIFlags::DataProperty), + OPropertyInfoImpl(PROPERTY_PARAADJUST, PROPERTY_ID_PARAADJUST, RptResId(RID_STR_PARAADJUST), HID_RPT_PROP_PARAADJUST, PropUIFlags::Composeable), + OPropertyInfoImpl(PROPERTY_VERTICALALIGN, PROPERTY_ID_VERTICALALIGN, RptResId(RID_STR_VERTICALALIGN), HID_RPT_PROP_VERTICALALIGN, PropUIFlags::Composeable) + }; + + s_pPropertyInfos = aPropertyInfos; + s_nCount = SAL_N_ELEMENTS(aPropertyInfos); + ::std::sort( aPropertyInfos, aPropertyInfos + SAL_N_ELEMENTS(aPropertyInfos), PropertyInfoLessByName() ); + + return s_pPropertyInfos; + } + + + sal_Int32 OPropertyInfoService::getPropertyId(const OUString& _rName) + { + const OPropertyInfoImpl* pInfo = getPropertyInfo(_rName); + return pInfo ? pInfo->nId : -1; + } + + + OUString OPropertyInfoService::getPropertyTranslation(sal_Int32 _nId) + { + const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId); + return pInfo ? pInfo->sTranslation : OUString(); + } + + + OString OPropertyInfoService::getPropertyHelpId(sal_Int32 _nId) + { + const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId); + return pInfo ? pInfo->sHelpId : OString(); + } + + + PropUIFlags OPropertyInfoService::getPropertyUIFlags(sal_Int32 _nId) + { + const OPropertyInfoImpl* pInfo = getPropertyInfo(_nId); + return pInfo ? pInfo->nUIFlags : PropUIFlags::NONE; + } + + + const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo(const OUString& _rName) + { + // initialization + if(!s_pPropertyInfos) + getPropertyInfo(); + OPropertyInfoImpl aSearch(_rName, 0, OUString(), "", PropUIFlags::NONE); + + const OPropertyInfoImpl* pPropInfo = ::std::lower_bound( + s_pPropertyInfos, s_pPropertyInfos + s_nCount, aSearch, PropertyInfoLessByName() ); + + if ( ( pPropInfo < s_pPropertyInfos + s_nCount ) && pPropInfo->sName == _rName ) + return pPropInfo; + + return nullptr; + } + + + const OPropertyInfoImpl* OPropertyInfoService::getPropertyInfo(sal_Int32 _nId) + { + // initialization + if(!s_pPropertyInfos) + getPropertyInfo(); + + // TODO: a real structure which allows quick access by name as well as by id + for (sal_uInt16 i = 0; i < s_nCount; i++) + if (s_pPropertyInfos[i].nId == _nId) + return &s_pPropertyInfos[i]; + + return nullptr; + } + + + bool OPropertyInfoService::isComposable( const OUString& _rPropertyName, const css::uno::Reference< css::inspection::XPropertyHandler >& _rxFormComponentHandler ) + { + sal_Int32 nId = getPropertyId( _rPropertyName ); + if ( nId != -1 ) + { + PropUIFlags nFlags = getPropertyUIFlags( nId ); + return bool( nFlags & PropUIFlags::Composeable ); + } + + return _rxFormComponentHandler->isComposable( _rPropertyName ); + } + + + void OPropertyInfoService::getExcludeProperties(::std::vector< beans::Property >& _rExcludeProperties,const css::uno::Reference< css::inspection::XPropertyHandler >& _xFormComponentHandler) + { + const uno::Sequence< beans::Property > aProps = _xFormComponentHandler->getSupportedProperties(); + static const std::u16string_view pExcludeProperties[] = + { + u"Enabled", + u"Printable", + u"WordBreak", + u"MultiLine", + u"Tag", + u"HelpText", + u"HelpURL", + u"MaxTextLen", + u"ReadOnly", + u"Tabstop", + u"TabIndex", + u"ValueMin", + u"ValueMax", + u"Spin", + u"SpinValue", + u"SpinValueMin", + u"SpinValueMax", + u"DefaultSpinValue", + u"SpinIncrement", + u"Repeat", + u"RepeatDelay", + u"ControlLabel", /// TODO: has to be checked + u"LabelControl", + u"Title", // comment this out if you want to have title feature for charts + u"" PROPERTY_MAXTEXTLEN, + u"" PROPERTY_EFFECTIVEDEFAULT, + u"" PROPERTY_EFFECTIVEMAX, + u"" PROPERTY_EFFECTIVEMIN, + u"HideInactiveSelection", + u"SubmitAction", + u"InputRequired", + u"VerticalAlign", + u"" PROPERTY_ALIGN, + u"" PROPERTY_EMPTY_IS_NULL, + u"" PROPERTY_FILTERPROPOSAL + ,u"" PROPERTY_POSITIONX + ,u"" PROPERTY_POSITIONY + ,u"" PROPERTY_WIDTH + ,u"" PROPERTY_HEIGHT + ,u"" PROPERTY_AUTOGROW + ,u"" PROPERTY_FONT + ,u"" PROPERTY_LABEL + ,u"" PROPERTY_LINECOLOR + ,u"" PROPERTY_BORDER + ,u"" PROPERTY_BORDERCOLOR + ,u"" PROPERTY_BACKTRANSPARENT + ,u"" PROPERTY_CONTROLBACKGROUND + ,u"" PROPERTY_BACKGROUNDCOLOR + ,u"" PROPERTY_CONTROLBACKGROUNDTRANSPARENT + ,u"" PROPERTY_FORMULALIST + ,u"" PROPERTY_SCOPE + ,u"" PROPERTY_TYPE + ,u"" PROPERTY_DATASOURCENAME + ,u"" PROPERTY_VERTICALALIGN + }; + + for (beans::Property const & prop : aProps) + { + size_t nPos = 0; + for (; nPos < SAL_N_ELEMENTS(pExcludeProperties) && pExcludeProperties[nPos] != prop.Name; ++nPos ) + ; + if ( nPos == SAL_N_ELEMENTS(pExcludeProperties) ) + _rExcludeProperties.push_back(prop); + } + } + + +} // namespace pcr + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/misc/ColorListener.cxx b/reportdesign/source/ui/misc/ColorListener.cxx new file mode 100644 index 000000000..48fa67902 --- /dev/null +++ b/reportdesign/source/ui/misc/ColorListener.cxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ColorListener.hxx> +#include <svl/hint.hxx> +#include <vcl/settings.hxx> +#include <vcl/event.hxx> + +#include <strings.hxx> + + +namespace rptui +{ + +OColorListener::OColorListener(vcl::Window* _pParent ,const OUString& _sColorEntry) +: Window(_pParent) +,m_sColorEntry(_sColorEntry) +,m_nColor(COL_LIGHTBLUE) +,m_bCollapsed(false) +,m_bMarked(false) +{ + StartListening(m_aExtendedColorConfig); + m_nColor = m_aExtendedColorConfig.GetColorValue(CFG_REPORTDESIGNER,m_sColorEntry).getColor(); + m_nTextBoundaries = m_aColorConfig.GetColorValue(::svtools::DOCBOUNDARIES).nColor; +} + +OColorListener::~OColorListener() +{ + disposeOnce(); +} + +void OColorListener::dispose() +{ + EndListening(m_aExtendedColorConfig); + vcl::Window::dispose(); +} + +void OColorListener::Notify(SfxBroadcaster & /*rBc*/, SfxHint const & rHint) +{ + if (rHint.GetId() == SfxHintId::ColorsChanged) + { + m_nColor = m_aExtendedColorConfig.GetColorValue(CFG_REPORTDESIGNER,m_sColorEntry).getColor(); + m_nTextBoundaries = m_aColorConfig.GetColorValue(::svtools::DOCBOUNDARIES).nColor; + Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase); + } +} + +void OColorListener::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void OColorListener::setCollapsed(bool _bCollapsed) +{ + if ( m_bCollapsed != _bCollapsed ) + { + m_bCollapsed = _bCollapsed; + m_aCollapsedLink.Call(*this); + } +} + +void OColorListener::setMarked(bool _bMark) +{ + if ( m_bMarked != _bMark) + { + m_bMarked = _bMark; + Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase); + } +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/misc/FunctionHelper.cxx b/reportdesign/source/ui/misc/FunctionHelper.cxx new file mode 100644 index 000000000..547567178 --- /dev/null +++ b/reportdesign/source/ui/misc/FunctionHelper.cxx @@ -0,0 +1,268 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <FunctionHelper.hxx> + +#include <o3tl/safeint.hxx> +#include <tools/diagnose_ex.h> +#include <formula/funcvarargs.h> + + +namespace rptui +{ + + using namespace ::com::sun::star; + +FunctionManager::FunctionManager(const uno::Reference< report::meta::XFunctionManager>& _xMgr) +: m_xMgr(_xMgr) +{ +} +FunctionManager::~FunctionManager() +{ +} +sal_Unicode FunctionManager::getSingleToken(const formula::IFunctionManager::EToken _eToken) const +{ + switch(_eToken) + { + case eOk: + return '('; + case eClose: + return ')'; + case eSep: + return ';'; + case eArrayOpen: + return '{'; + case eArrayClose: + return '}'; + } + return 0; +} + +sal_uInt32 FunctionManager::getCount() const +{ + return m_xMgr->getCount(); +} + +const formula::IFunctionCategory* FunctionManager::getCategory(sal_uInt32 _nPos) const +{ + if ( _nPos >= m_aCategoryIndex.size() ) + { + uno::Reference< report::meta::XFunctionCategory> xCategory = m_xMgr->getCategory(_nPos); + auto pCategory = std::make_shared<FunctionCategory>(this,_nPos + 1,xCategory); + m_aCategoryIndex.push_back( m_aCategories.emplace(xCategory->getName(),pCategory).first ); + } + return m_aCategoryIndex[_nPos]->second.get(); +} + +void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& /*_rLastRUFunctions*/) const +{ +} + +std::shared_ptr< FunctionDescription > FunctionManager::get(const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) const +{ + std::shared_ptr< FunctionDescription > pDesc; + if ( _xFunctionDescription.is() ) + { + const OUString sFunctionName = _xFunctionDescription->getName(); + TFunctionsMap::const_iterator aFunctionFind = m_aFunctions.find(sFunctionName); + if ( aFunctionFind == m_aFunctions.end() ) + { + const uno::Reference< report::meta::XFunctionCategory> xCategory = _xFunctionDescription->getCategory(); + const OUString sCategoryName = xCategory->getName(); + TCategoriesMap::iterator aCategoryFind = m_aCategories.find(sCategoryName); + if ( aCategoryFind == m_aCategories.end() ) + { + aCategoryFind = m_aCategories.emplace(sCategoryName,std::make_shared< FunctionCategory > (this,xCategory->getNumber() + 1,xCategory)).first; + m_aCategoryIndex.push_back( aCategoryFind ); + } + aFunctionFind = m_aFunctions.emplace(sFunctionName,std::make_shared<FunctionDescription>(aCategoryFind->second.get(),_xFunctionDescription)).first; + } + pDesc = aFunctionFind->second; + } + return pDesc; +} + +FunctionCategory::FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const uno::Reference< report::meta::XFunctionCategory>& _xCategory) +: m_xCategory(_xCategory) +,m_nFunctionCount(_xCategory->getCount()) +, m_nNumber(_nPos) +,m_pFunctionManager(_pFMgr) +{ +} + +sal_uInt32 FunctionCategory::getCount() const +{ + return m_nFunctionCount; +} + +const formula::IFunctionDescription* FunctionCategory::getFunction(sal_uInt32 _nPos) const +{ + if ( _nPos >= m_aFunctions.size() && _nPos < m_nFunctionCount ) + { + uno::Reference< report::meta::XFunctionDescription> xFunctionDescription = m_xCategory->getFunction(_nPos); + std::shared_ptr< FunctionDescription > pFunction = m_pFunctionManager->get(xFunctionDescription); + m_aFunctions.push_back( pFunction ); + } + return m_aFunctions[_nPos].get(); +} + +sal_uInt32 FunctionCategory::getNumber() const +{ + return m_nNumber; +} + +OUString FunctionCategory::getName() const +{ + return m_xCategory->getName(); +} + +FunctionDescription::FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory,const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) +: m_xFunctionDescription(_xFunctionDescription) +, m_pFunctionCategory(_pFunctionCategory) +{ + m_aParameter = m_xFunctionDescription->getArguments(); +} +OUString FunctionDescription::getFunctionName() const +{ + return m_xFunctionDescription->getName(); +} + +const formula::IFunctionCategory* FunctionDescription::getCategory() const +{ + return m_pFunctionCategory; +} + +OUString FunctionDescription::getDescription() const +{ + return m_xFunctionDescription->getDescription(); +} + +sal_Int32 FunctionDescription::getSuppressedArgumentCount() const +{ + return m_aParameter.getLength(); +} + +OUString FunctionDescription::getFormula(const ::std::vector< OUString >& _aArguments) const +{ + OUString sFormula; + try + { + sFormula = m_xFunctionDescription->createFormula(uno::Sequence< OUString >(_aArguments.data(), _aArguments.size())); + } + catch(const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + return sFormula; +} + +void FunctionDescription::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const +{ + const sal_Int32 nCount = m_aParameter.getLength(); + for(sal_Int32 i = 0;i < nCount; ++i) + { + _rArguments.push_back(i); + } +} + +void FunctionDescription::initArgumentInfo() const +{ +} + +OUString FunctionDescription::getSignature() const +{ + return m_xFunctionDescription->getSignature(); +} + +OString FunctionDescription::getHelpId() const +{ + return OString(); +} + +bool FunctionDescription::isHidden() const +{ + return false; +} + +sal_uInt32 FunctionDescription::getParameterCount() const +{ + return m_aParameter.getLength(); +} + +sal_uInt32 FunctionDescription::getVarArgsStart() const +{ + /* XXX there are no variable number of arguments, are there? Nevertheless + * consider the varargs handling of the Function Wizard and return a value + * within the bounds of parameters. */ + // Don't use defines/constants that could change in future, parameter count + // could be part of an implicit stable API. + // offapi/com/sun/star/report/meta/XFunctionDescription.idl doesn't tell. + const sal_uInt32 nVarArgs30 = 30; // ugly hard coded old VAR_ARGS of formula::ParaWin + const sal_uInt32 nPairedVarArgs60 = 60; // ugly hard coded old PAIRED_VAR_ARGS of formula::ParaWin + const sal_uInt32 nVarArgs255 = 255; // ugly hard coded new VAR_ARGS of formula::ParaWin + const sal_uInt32 nPairedVarArgs510 = 510; // ugly hard coded new PAIRED_VAR_ARGS of formula::ParaWin + sal_uInt32 nLen = m_aParameter.getLength(); + // If the value of VAR_ARGS changes then adapt *and* maintain implicit API + // stability, ie. old code using the old VAR_ARGS and PAIRED_VAR_ARGS + // values must still be handled. It is *not* sufficient to simply change + // the values here. + static_assert(nVarArgs255 == VAR_ARGS && nPairedVarArgs510 == PAIRED_VAR_ARGS, + "VAR_ARGS or PAIRED_VAR_ARGS has unexpected value"); + if (nLen >= nPairedVarArgs510) + nLen -= nPairedVarArgs510; + else if (nLen >= nVarArgs255) + nLen -= nVarArgs255; + else if (nLen >= nPairedVarArgs60) + nLen -= nPairedVarArgs60; + else if (nLen >= nVarArgs30) + nLen -= nVarArgs30; + return nLen ? nLen - 1 : 0; +} + +sal_uInt32 FunctionDescription::getVarArgsLimit() const +{ + return 0; +} + +OUString FunctionDescription::getParameterName(sal_uInt32 _nPos) const +{ + if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) ) + return m_aParameter[_nPos].Name; + return OUString(); +} + +OUString FunctionDescription::getParameterDescription(sal_uInt32 _nPos) const +{ + if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) ) + return m_aParameter[_nPos].Description; + return OUString(); +} + +bool FunctionDescription::isParameterOptional(sal_uInt32 _nPos) const +{ + if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) ) + return m_aParameter[_nPos].IsOptional; + return false; +} + + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/misc/RptUndo.cxx b/reportdesign/source/ui/misc/RptUndo.cxx new file mode 100644 index 000000000..60d0927d6 --- /dev/null +++ b/reportdesign/source/ui/misc/RptUndo.cxx @@ -0,0 +1,385 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <RptUndo.hxx> +#include <strings.hxx> +#include <rptui_slotid.hrc> +#include <UITools.hxx> +#include <UndoEnv.hxx> + +#include <dbaccess/IController.hxx> +#include <com/sun/star/report/XSection.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> + +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/types.hxx> +#include <svx/unoshape.hxx> +#include <utility> +#include <tools/diagnose_ex.h> + +#include <functional> + +namespace rptui +{ + using namespace ::com::sun::star; + using namespace uno; + using namespace lang; + using namespace beans; + using namespace awt; + using namespace util; + using namespace container; + using namespace report; + + +namespace +{ + void lcl_collectElements(const uno::Reference< report::XSection >& _xSection,::std::vector< uno::Reference< drawing::XShape> >& _rControls) + { + if ( _xSection.is() ) + { + sal_Int32 nCount = _xSection->getCount(); + _rControls.reserve(nCount); + while ( nCount ) + { + uno::Reference< drawing::XShape> xShape(_xSection->getByIndex(nCount-1),uno::UNO_QUERY); + _rControls.push_back(xShape); + _xSection->remove(xShape); + --nCount; + } + } + } + + void lcl_insertElements(const uno::Reference< report::XSection >& _xSection,const ::std::vector< uno::Reference< drawing::XShape> >& _aControls) + { + if ( !_xSection.is() ) + return; + + ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aIter = _aControls.rbegin(); + ::std::vector< uno::Reference< drawing::XShape> >::const_reverse_iterator aEnd = _aControls.rend(); + for (; aIter != aEnd; ++aIter) + { + try + { + const awt::Point aPos = (*aIter)->getPosition(); + const awt::Size aSize = (*aIter)->getSize(); + _xSection->add(*aIter); + (*aIter)->setPosition( aPos ); + (*aIter)->setSize( aSize ); + } + catch(const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_insertElements"); + } + } + } + + void lcl_setValues(const uno::Reference< report::XSection >& _xSection,const ::std::vector< ::std::pair< OUString ,uno::Any> >& _aValues) + { + if ( !_xSection.is() ) + return; + + for (const auto& [rPropName, rValue] : _aValues) + { + try + { + _xSection->setPropertyValue(rPropName, rValue); + } + catch(const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "lcl_setValues"); + } + } + } +} + + +OSectionUndo::OSectionUndo(OReportModel& _rMod + ,sal_uInt16 _nSlot + ,Action _eAction + ,TranslateId pCommentID) +: OCommentUndoAction(_rMod,pCommentID) +,m_eAction(_eAction) +,m_nSlot(_nSlot) +,m_bInserted(false) +{ +} + +OSectionUndo::~OSectionUndo() +{ + if ( m_bInserted ) + return; + + OXUndoEnvironment& rEnv = static_cast< OReportModel& >( rMod ).GetUndoEnv(); + for (uno::Reference<drawing::XShape>& xShape : m_aControls) + { + rEnv.RemoveElement(xShape); + +#if OSL_DEBUG_LEVEL > 0 + SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>( xShape ); + SdrObject* pObject = pShape ? pShape->GetSdrObject() : nullptr; + OSL_ENSURE( pShape && pShape->HasSdrObjectOwnership() && pObject && !pObject->IsInserted(), + "OSectionUndo::~OSectionUndo: inconsistency in the shape/object ownership!" ); +#endif + try + { + comphelper::disposeComponent(xShape); + } + catch(const uno::Exception &) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + } +} + +void OSectionUndo::collectControls(const uno::Reference< report::XSection >& _xSection) +{ + m_aControls.clear(); + try + { + // copy all properties for restoring + uno::Reference< beans::XPropertySetInfo> xInfo = _xSection->getPropertySetInfo(); + const uno::Sequence< beans::Property> aSeq = xInfo->getProperties(); + for(const beans::Property& rProp : aSeq) + { + if ( 0 == (rProp.Attributes & beans::PropertyAttribute::READONLY) ) + m_aValues.emplace_back(rProp.Name,_xSection->getPropertyValue(rProp.Name)); + } + lcl_collectElements(_xSection,m_aControls); + } + catch(uno::Exception&) + { + } +} + +void OSectionUndo::Undo() +{ + try + { + switch ( m_eAction ) + { + case Inserted: + implReRemove(); + break; + + case Removed: + implReInsert(); + break; + } + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Undo" ); + } +} + +void OSectionUndo::Redo() +{ + try + { + switch ( m_eAction ) + { + case Inserted: + implReInsert(); + break; + + case Removed: + implReRemove(); + break; + } + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OSectionUndo::Redo" ); + } +} + +OReportSectionUndo::OReportSectionUndo( + OReportModel& _rMod, sal_uInt16 _nSlot, + ::std::function<uno::Reference<report::XSection>(OReportHelper*)> _pMemberFunction, + const uno::Reference<report::XReportDefinition>& _xReport, Action _eAction) + : OSectionUndo(_rMod, _nSlot, _eAction, {}) + , m_aReportHelper(_xReport) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ + if( m_eAction == Removed ) + collectControls(m_pMemberFunction(&m_aReportHelper)); +} + +OReportSectionUndo::~OReportSectionUndo() +{ +} + +void OReportSectionUndo::implReInsert( ) +{ + const uno::Sequence< beans::PropertyValue > aArgs; + m_pController->executeChecked(m_nSlot,aArgs); + uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aReportHelper); + lcl_insertElements(xSection,m_aControls); + lcl_setValues(xSection,m_aValues); + m_bInserted = true; +} + +void OReportSectionUndo::implReRemove( ) +{ + if( m_eAction == Removed ) + collectControls(m_pMemberFunction(&m_aReportHelper)); + const uno::Sequence< beans::PropertyValue > aArgs; + m_pController->executeChecked(m_nSlot,aArgs); + m_bInserted = false; +} + +OGroupSectionUndo::OGroupSectionUndo( + OReportModel& _rMod, sal_uInt16 _nSlot, + ::std::function<uno::Reference<report::XSection>(OGroupHelper*)> _pMemberFunction, + const uno::Reference<report::XGroup>& _xGroup, Action _eAction, TranslateId pCommentID) + : OSectionUndo(_rMod, _nSlot, _eAction, pCommentID) + , m_aGroupHelper(_xGroup) + , m_pMemberFunction(std::move(_pMemberFunction)) +{ + if( m_eAction == Removed ) + { + uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper); + if ( xSection.is() ) + m_sName = xSection->getName(); + collectControls(xSection); + } +} + +OUString OGroupSectionUndo::GetComment() const +{ + if ( m_sName.isEmpty() ) + { + try + { + uno::Reference< report::XSection > xSection = const_cast<OGroupSectionUndo*>(this)->m_pMemberFunction(&const_cast<OGroupSectionUndo*>(this)->m_aGroupHelper); + + if ( xSection.is() ) + m_sName = xSection->getName(); + } + catch (const uno::Exception&) + { + } + } + return m_strComment + m_sName; +} + +void OGroupSectionUndo::implReInsert( ) +{ + const OUString aHeaderFooterOnName(SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON)); + uno::Sequence< beans::PropertyValue > aArgs{ + comphelper::makePropertyValue(aHeaderFooterOnName, true), + comphelper::makePropertyValue(PROPERTY_GROUP, m_aGroupHelper.getGroup()) + }; + m_pController->executeChecked(m_nSlot,aArgs); + + uno::Reference< report::XSection > xSection = m_pMemberFunction(&m_aGroupHelper); + lcl_insertElements(xSection,m_aControls); + lcl_setValues(xSection,m_aValues); + m_bInserted = true; +} + +void OGroupSectionUndo::implReRemove( ) +{ + if( m_eAction == Removed ) + collectControls(m_pMemberFunction(&m_aGroupHelper)); + + const OUString aHeaderFooterOnName(SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON)); + uno::Sequence< beans::PropertyValue > aArgs{ + comphelper::makePropertyValue(aHeaderFooterOnName, false), + comphelper::makePropertyValue(PROPERTY_GROUP, m_aGroupHelper.getGroup()) + }; + + m_pController->executeChecked(m_nSlot,aArgs); + m_bInserted = false; +} + + +OGroupUndo::OGroupUndo(OReportModel& _rMod + ,TranslateId pCommentID + ,Action _eAction + ,const uno::Reference< report::XGroup>& _xGroup + ,const uno::Reference< report::XReportDefinition >& _xReportDefinition) +: OCommentUndoAction(_rMod,pCommentID) +,m_xGroup(_xGroup) +,m_xReportDefinition(_xReportDefinition) +,m_eAction(_eAction) +{ + m_nLastPosition = getPositionInIndexAccess(m_xReportDefinition->getGroups(),m_xGroup); +} + +void OGroupUndo::implReInsert( ) +{ + try + { + m_xReportDefinition->getGroups()->insertByIndex(m_nLastPosition,uno::Any(m_xGroup)); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while undoing remove group"); + } +} + +void OGroupUndo::implReRemove( ) +{ + try + { + m_xReportDefinition->getGroups()->removeByIndex(m_nLastPosition); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while redoing remove group"); + } +} + +void OGroupUndo::Undo() +{ + switch ( m_eAction ) + { + case Inserted: + implReRemove(); + break; + + case Removed: + implReInsert(); + break; + } + +} + +void OGroupUndo::Redo() +{ + switch ( m_eAction ) + { + case Inserted: + implReInsert(); + break; + + case Removed: + implReRemove(); + break; + } +} + + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/misc/UITools.cxx b/reportdesign/source/ui/misc/UITools.cxx new file mode 100644 index 000000000..9e00b4ad5 --- /dev/null +++ b/reportdesign/source/ui/misc/UITools.cxx @@ -0,0 +1,1064 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <memory> +#include <toolkit/helper/convert.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <SectionView.hxx> +#include <UITools.hxx> +#include <Formula.hxx> +#include <FunctionHelper.hxx> +#include <reportformula.hxx> + +#include <tools/diagnose_ex.h> + +#include <vcl/settings.hxx> +#include <vcl/syswin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/unohelp.hxx> +#include <vcl/window.hxx> + +#include <com/sun/star/lang/NullPointerException.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <svx/svdpool.hxx> + +#include <editeng/charscaleitem.hxx> +#include <editeng/brushitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/emphasismarkitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/crossedoutitem.hxx> +#include <editeng/contouritem.hxx> +#include <editeng/langitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/shdditem.hxx> +#include <editeng/escapementitem.hxx> +#include <editeng/wrlmitem.hxx> +#include <editeng/cmapitem.hxx> +#include <editeng/kernitem.hxx> +#include <editeng/blinkitem.hxx> +#include <editeng/flstitem.hxx> +#include <editeng/autokernitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/justifyitem.hxx> +#include <svx/drawitem.hxx> +#include <editeng/twolinesitem.hxx> +#include <editeng/charreliefitem.hxx> +#include <editeng/charrotateitem.hxx> +#include <editeng/charhiddenitem.hxx> +#include <editeng/memberids.h> +#include <svx/xgrscit.hxx> +#include <svx/svditer.hxx> +#include <svx/xtable.hxx> +#include <svx/svdview.hxx> +#include <svx/svdpage.hxx> +#include <svx/svxdlg.hxx> +#include <svx/unoprov.hxx> +#include <svx/svxids.hrc> + +#include <unotools/charclass.hxx> +#include <svtools/ctrltool.hxx> +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include <svl/sharedstringpool.hxx> + +#include <comphelper/propmultiplex.hxx> +#include <comphelper/namedvaluecollection.hxx> + +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> + +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/report/XShape.hpp> +#include <com/sun/star/sdb/XParametersSupplier.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <i18nlangtag/languagetag.hxx> +#include <dlgpage.hxx> +#include <strings.hxx> +#include <core_resource.hxx> +#include <RptObject.hxx> +#include <RptDef.hxx> +#include <strings.hrc> +#include <ReportDefinition.hxx> +#include <RptModel.hxx> + +#include <svx/xflbckit.hxx> +#include <svx/xflbmpit.hxx> +#include <svx/xflbmsli.hxx> +#include <svx/xflbmsxy.hxx> +#include <svx/xflbmtit.hxx> +#include <svx/xflboxy.hxx> +#include <svx/xflbstit.hxx> +#include <svx/xflbtoxy.hxx> + +#include <svx/xbtmpit.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xflclit.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xsflclit.hxx> + +/// Note that we deliberately overlap an existing item id, so that we can have contiguous item ids for +/// the static defaults. +#define ITEMID_FIRST XATTR_FILL_LAST + +#define ITEMID_FONT TypedWhichId<SvxFontItem>(ITEMID_FIRST) +#define ITEMID_FONTHEIGHT TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 1) +#define ITEMID_LANGUAGE TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 2) + +#define ITEMID_POSTURE TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 3) +#define ITEMID_WEIGHT TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 4) +#define ITEMID_SHADOWED TypedWhichId<SvxShadowedItem>(ITEMID_FIRST + 5) +#define ITEMID_WORDLINEMODE TypedWhichId<SvxWordLineModeItem>(ITEMID_FIRST + 6) +#define ITEMID_CONTOUR TypedWhichId<SvxContourItem>(ITEMID_FIRST + 7) +#define ITEMID_CROSSEDOUT TypedWhichId<SvxCrossedOutItem>(ITEMID_FIRST + 8) +#define ITEMID_UNDERLINE TypedWhichId<SvxUnderlineItem>(ITEMID_FIRST + 9) + +#define ITEMID_COLOR TypedWhichId<SvxColorItem>(ITEMID_FIRST + 10) +#define ITEMID_KERNING TypedWhichId<SvxKerningItem>(ITEMID_FIRST + 11) +#define ITEMID_CASEMAP TypedWhichId<SvxCaseMapItem>(ITEMID_FIRST + 12) + +#define ITEMID_ESCAPEMENT TypedWhichId<SvxEscapementItem>(ITEMID_FIRST + 13) +#define ITEMID_FONTLIST ITEMID_FIRST + 14 +#define ITEMID_AUTOKERN TypedWhichId<SvxAutoKernItem>(ITEMID_FIRST + 15) +#define ITEMID_COLOR_TABLE TypedWhichId<SvxColorListItem>(ITEMID_FIRST + 16) +#define ITEMID_BLINK TypedWhichId<SvxBlinkItem>(ITEMID_FIRST + 17) +#define ITEMID_EMPHASISMARK TypedWhichId<SvxEmphasisMarkItem>(ITEMID_FIRST + 18) +#define ITEMID_TWOLINES TypedWhichId<SvxTwoLinesItem>(ITEMID_FIRST + 19) +#define ITEMID_CHARROTATE TypedWhichId<SvxCharRotateItem>(ITEMID_FIRST + 20) +#define ITEMID_CHARSCALE_W TypedWhichId<SvxCharScaleWidthItem>(ITEMID_FIRST + 21) +#define ITEMID_CHARRELIEF TypedWhichId<SvxCharReliefItem>(ITEMID_FIRST + 22) +#define ITEMID_CHARHIDDEN TypedWhichId<SvxCharHiddenItem>(ITEMID_FIRST + 23) +#define ITEMID_BRUSH TypedWhichId<SvxBrushItem>(ITEMID_FIRST + 24) +#define ITEMID_HORJUSTIFY TypedWhichId<SvxHorJustifyItem>(ITEMID_FIRST + 25) +#define ITEMID_VERJUSTIFY TypedWhichId<SvxVerJustifyItem>(ITEMID_FIRST + 26) +#define ITEMID_FONT_ASIAN TypedWhichId<SvxFontItem>(ITEMID_FIRST + 27) +#define ITEMID_FONTHEIGHT_ASIAN TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 28) +#define ITEMID_LANGUAGE_ASIAN TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 29) +#define ITEMID_POSTURE_ASIAN TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 30) +#define ITEMID_WEIGHT_ASIAN TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 31) +#define ITEMID_FONT_COMPLEX TypedWhichId<SvxFontItem>(ITEMID_FIRST + 32) +#define ITEMID_FONTHEIGHT_COMPLEX TypedWhichId<SvxFontHeightItem>(ITEMID_FIRST + 33) +#define ITEMID_LANGUAGE_COMPLEX TypedWhichId<SvxLanguageItem>(ITEMID_FIRST + 34) +#define ITEMID_POSTURE_COMPLEX TypedWhichId<SvxPostureItem>(ITEMID_FIRST + 35) +#define ITEMID_WEIGHT_COMPLEX TypedWhichId<SvxWeightItem>(ITEMID_FIRST + 36) + +#define WESTERN 0 +#define ASIAN 1 +#define COMPLEX 2 + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace formula; + +void adjustSectionName(const uno::Reference< report::XGroup >& _xGroup,sal_Int32 _nPos) +{ + OSL_ENSURE(_xGroup.is(),"Group is NULL -> GPF"); + if ( _xGroup->getHeaderOn() && _xGroup->getHeader()->getName().isEmpty() ) + { + OUString sName = RptResId(RID_STR_GROUPHEADER) + OUString::number(_nPos); + _xGroup->getHeader()->setName(sName); + } + + if ( _xGroup->getFooterOn() && _xGroup->getFooter()->getName().isEmpty() ) + { + OUString sName = RptResId(RID_STR_GROUPFOOTER) + OUString::number(_nPos); + _xGroup->getFooter()->setName(sName); + } +} + +::rtl::Reference< comphelper::OPropertyChangeMultiplexer> addStyleListener(const uno::Reference< report::XReportDefinition >& _xReportDefinition,::comphelper::OPropertyChangeListener* _pListener) +{ + ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> pRet; + if ( _xReportDefinition.is() ) + { + uno::Reference<beans::XPropertySet> xPageStyle(getUsedStyle(_xReportDefinition),uno::UNO_QUERY); + if ( xPageStyle.is() ) + { + pRet = new comphelper::OPropertyChangeMultiplexer(_pListener,xPageStyle); + pRet->addProperty(PROPERTY_LEFTMARGIN); + pRet->addProperty(PROPERTY_RIGHTMARGIN); + pRet->addProperty(PROPERTY_PAPERSIZE); + pRet->addProperty(PROPERTY_BACKCOLOR); + } + } + return pRet; +} + + +namespace +{ + + vcl::Font lcl_getReportControlFont( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, awt::FontDescriptor& _out_rControlFont ,sal_uInt16 _nWichFont) + { + if ( !_rxReportControlFormat.is() ) + throw uno::RuntimeException(); + + switch(_nWichFont) + { + case WESTERN: + _out_rControlFont = _rxReportControlFormat->getFontDescriptor(); + break; + case ASIAN: + _out_rControlFont = _rxReportControlFormat->getFontDescriptorAsian(); + break; + case COMPLEX: + _out_rControlFont = _rxReportControlFormat->getFontDescriptorComplex(); + break; + + } + + vcl::Font aDefaultFont = Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetAppFont(); + return VCLUnoHelper::CreateFont( _out_rControlFont, aDefaultFont ); + } + + + vcl::Font lcl_getReportControlFont( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat,sal_uInt16 _nWhich ) + { + awt::FontDescriptor aAwtFont; + return lcl_getReportControlFont( _rxReportControlFormat, aAwtFont, _nWhich ); + } + + vcl::Font lcl_setFont(const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + SfxItemSet& _rItemSet,sal_uInt16 _nWhich,sal_uInt16 _nFont, sal_uInt16 _nFontHeight,sal_uInt16 _nLanguage,sal_uInt16 _nPosture, sal_uInt16 _nWeight) + { + // fill it + awt::FontDescriptor aControlFont; + const vcl::Font aFont( lcl_getReportControlFont( _rxReportControlFormat, aControlFont,_nWhich ) ); + + SvxFontItem aFontItem(_nFont); + aFontItem.PutValue( uno::Any( aControlFont ), 0 ); + _rItemSet.Put(aFontItem); + + _rItemSet.Put(SvxFontHeightItem(o3tl::convert(aFont.GetFontHeight(), o3tl::Length::pt, o3tl::Length::twip), 100, _nFontHeight)); + lang::Locale aLocale; + switch(_nWhich) + { + default: + aLocale = _rxReportControlFormat->getCharLocale(); + break; + case ASIAN: + aLocale = _rxReportControlFormat->getCharLocaleAsian(); + break; + case COMPLEX: + aLocale = _rxReportControlFormat->getCharLocaleComplex(); + break; + } + + _rItemSet.Put(SvxLanguageItem(LanguageTag(aLocale).makeFallback().getLanguageType(),_nLanguage)); + + _rItemSet.Put(SvxPostureItem(aFont.GetItalic(),_nPosture)); + _rItemSet.Put(SvxWeightItem(aFont.GetWeight(),_nWeight)); + return aFont; + } + + void lcl_fillShapeToItems( const uno::Reference<report::XShape >& _xShape,SfxItemSet& _rItemSet ) + { + uno::Reference< beans::XPropertySetInfo> xInfo = _xShape->getPropertySetInfo(); + SvxUnoPropertyMapProvider aMap; + const SfxItemPropertyMap& rPropertyMap = aMap.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool())->getPropertyMap(); + for (const auto pProp : rPropertyMap.getPropertyEntries()) + { + if ( xInfo->hasPropertyByName(pProp->aName) ) + { + const SfxPoolItem* pItem = _rItemSet.GetItem(pProp->nWID); + if ( pItem ) + { + ::std::unique_ptr<SfxPoolItem> pClone(pItem->CloneSetWhich(pProp->nWID)); + pClone->PutValue(_xShape->getPropertyValue(pProp->aName), pProp->nMemberId); + _rItemSet.Put(std::move(pClone)); + } + } + } + } + + void lcl_fillItemsToShape( const uno::Reference<report::XShape >& _xShape,const SfxItemSet& _rItemSet ) + { + const uno::Reference< beans::XPropertySetInfo> xInfo = _xShape->getPropertySetInfo(); + SvxUnoPropertyMapProvider aMap; + const SfxItemPropertyMap& rPropertyMap = aMap.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool())->getPropertyMap(); + for (const auto pProp : rPropertyMap.getPropertyEntries()) + { + if ( SfxItemState::SET == _rItemSet.GetItemState(pProp->nWID) && xInfo->hasPropertyByName(pProp->aName) ) + { + if ( ( pProp->nFlags & beans::PropertyAttribute::READONLY ) != beans::PropertyAttribute::READONLY ) + { + const SfxPoolItem* pItem = _rItemSet.GetItem(pProp->nWID); + if ( pItem ) + { + uno::Any aValue; + pItem->QueryValue(aValue, pProp->nMemberId); + try + { + _xShape->setPropertyValue(pProp->aName, aValue); + } + catch(uno::Exception&) + { // shapes have a bug so we ignore this one. + } + } + } + } + } + } + + void lcl_CharPropertiesToItems( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + SfxItemSet& _rItemSet ) + { + if ( !_rxReportControlFormat.is() ) + throw lang::NullPointerException(); + + uno::Reference< beans::XPropertySet > xSet(_rxReportControlFormat,uno::UNO_QUERY_THROW); + + // fill it + const vcl::Font aFont( lcl_setFont(_rxReportControlFormat, _rItemSet,WESTERN,ITEMID_FONT,ITEMID_FONTHEIGHT,ITEMID_LANGUAGE,ITEMID_POSTURE,ITEMID_WEIGHT ) ); + + _rItemSet.Put(SvxShadowedItem(_rxReportControlFormat->getCharShadowed(),ITEMID_SHADOWED)); + _rItemSet.Put(SvxWordLineModeItem(aFont.IsWordLineMode(),ITEMID_WORDLINEMODE)); + _rItemSet.Put(SvxContourItem(_rxReportControlFormat->getCharContoured(),ITEMID_CONTOUR)); + _rItemSet.Put(SvxAutoKernItem(_rxReportControlFormat->getCharAutoKerning(),ITEMID_AUTOKERN)); + _rItemSet.Put(SvxCrossedOutItem(aFont.GetStrikeout(),ITEMID_CROSSEDOUT)); + _rItemSet.Put(SvxCaseMapItem(static_cast<SvxCaseMap>(_rxReportControlFormat->getCharCaseMap()),ITEMID_CASEMAP)); + + _rItemSet.Put(SvxEscapementItem(_rxReportControlFormat->getCharEscapement(),_rxReportControlFormat->getCharEscapementHeight(),ITEMID_ESCAPEMENT)); + _rItemSet.Put(SvxBlinkItem(_rxReportControlFormat->getCharFlash(),ITEMID_BLINK)); + _rItemSet.Put(SvxCharHiddenItem(_rxReportControlFormat->getCharHidden(),ITEMID_CHARHIDDEN)); + _rItemSet.Put(SvxTwoLinesItem(_rxReportControlFormat->getCharCombineIsOn(),_rxReportControlFormat->getCharCombinePrefix().toChar(),_rxReportControlFormat->getCharCombineSuffix().toChar(),ITEMID_TWOLINES)); + SvxUnderlineItem aUnderLineItem(aFont.GetUnderline(),ITEMID_UNDERLINE); + aUnderLineItem.SetColor(Color(ColorTransparency, _rxReportControlFormat->getCharUnderlineColor())); + _rItemSet.Put(aUnderLineItem); + _rItemSet.Put(SvxKerningItem(_rxReportControlFormat->getCharKerning(),ITEMID_KERNING)); + _rItemSet.Put(SvxEmphasisMarkItem(static_cast<FontEmphasisMark>(_rxReportControlFormat->getCharEmphasis()),ITEMID_EMPHASISMARK)); + _rItemSet.Put(SvxCharReliefItem(static_cast<FontRelief>(_rxReportControlFormat->getCharRelief()),ITEMID_CHARRELIEF)); + _rItemSet.Put(SvxColorItem(::Color(ColorTransparency, _rxReportControlFormat->getCharColor()),ITEMID_COLOR)); + _rItemSet.Put(SvxCharRotateItem(Degree10(_rxReportControlFormat->getCharRotation()),false,ITEMID_CHARROTATE)); + _rItemSet.Put(SvxCharScaleWidthItem(_rxReportControlFormat->getCharScaleWidth(),ITEMID_CHARSCALE_W)); + + SvxHorJustifyItem aHorJustifyItem(ITEMID_HORJUSTIFY); + aHorJustifyItem.PutValue(xSet->getPropertyValue(PROPERTY_PARAADJUST),MID_HORJUST_ADJUST); + _rItemSet.Put(aHorJustifyItem); + SvxVerJustifyItem aVerJustifyItem(ITEMID_VERJUSTIFY); + aVerJustifyItem.PutValue(xSet->getPropertyValue(PROPERTY_VERTICALALIGN),MID_HORJUST_ADJUST); + _rItemSet.Put(aVerJustifyItem); + + uno::Reference< report::XShape> xShape(_rxReportControlFormat,uno::UNO_QUERY); + if ( !xShape.is() ) + _rItemSet.Put(SvxBrushItem(::Color(ColorTransparency, _rxReportControlFormat->getControlBackground()),ITEMID_BRUSH)); + + lcl_setFont(_rxReportControlFormat, _rItemSet,ASIAN,ITEMID_FONT_ASIAN,ITEMID_FONTHEIGHT_ASIAN,ITEMID_LANGUAGE_ASIAN,ITEMID_POSTURE_ASIAN,ITEMID_WEIGHT_ASIAN ); + lcl_setFont(_rxReportControlFormat, _rItemSet,COMPLEX,ITEMID_FONT_COMPLEX,ITEMID_FONTHEIGHT_COMPLEX,ITEMID_LANGUAGE_COMPLEX,ITEMID_POSTURE_COMPLEX,ITEMID_WEIGHT_COMPLEX ); + } + + + void lcl_pushBack( uno::Sequence< beans::NamedValue >& _out_rProperties, const OUString& _sName, const uno::Any& _rValue ) + { + sal_Int32 nLen( _out_rProperties.getLength() ); + _out_rProperties.realloc( nLen + 1 ); + _out_rProperties.getArray()[ nLen ] = beans::NamedValue( _sName, _rValue ); + } + + + void lcl_initAwtFont( const vcl::Font& _rOriginalFont, const SfxItemSet& _rItemSet, awt::FontDescriptor& _out_rAwtFont, + TypedWhichId<SvxFontItem> _nFont, TypedWhichId<SvxFontHeightItem> _nFontHeight, + TypedWhichId<SvxPostureItem> _nPosture, TypedWhichId<SvxWeightItem> _nWeight) + { + vcl::Font aNewFont( _rOriginalFont ); + if ( const SvxFontItem* pFontItem = _rItemSet.GetItemIfSet( _nFont) ) + { + aNewFont.SetFamilyName(pFontItem->GetFamilyName()); + aNewFont.SetStyleName(pFontItem->GetStyleName()); + aNewFont.SetFamily(pFontItem->GetFamily()); + aNewFont.SetPitch(pFontItem->GetPitch()); + aNewFont.SetCharSet(pFontItem->GetCharSet()); + } + if ( const SvxFontHeightItem* pFontItem = _rItemSet.GetItemIfSet( _nFontHeight ) ) + { + aNewFont.SetFontHeight(o3tl::convert(pFontItem->GetHeight(), o3tl::Length::twip, o3tl::Length::pt)); + } + if ( const SvxPostureItem* pPostureItem = _rItemSet.GetItemIfSet( _nPosture) ) + { + aNewFont.SetItalic(pPostureItem->GetPosture()); + } + if ( const SvxWeightItem* pWeightItem = _rItemSet.GetItemIfSet( _nWeight ) ) + { + aNewFont.SetWeight(pWeightItem->GetWeight()); + } + if ( const SvxWordLineModeItem* pWordLineItem = _rItemSet.GetItemIfSet( ITEMID_WORDLINEMODE ) ) + { + aNewFont.SetWordLineMode(pWordLineItem->GetValue()); + } + if ( const SvxCrossedOutItem* pCrossedOutItem = _rItemSet.GetItemIfSet( ITEMID_CROSSEDOUT ) ) + { + aNewFont.SetStrikeout(pCrossedOutItem->GetStrikeout()); + } + if ( const SvxCharRotateItem* pRotateItem = _rItemSet.GetItemIfSet( ITEMID_CHARROTATE ) ) + { + aNewFont.SetOrientation(pRotateItem->GetValue()); + } + if ( const SvxCharScaleWidthItem* pCharItem = _rItemSet.GetItemIfSet( ITEMID_CHARSCALE_W ) ) + { + aNewFont.SetWidthType(vcl::unohelper::ConvertFontWidth(pCharItem->GetValue())); + } + if ( const SvxUnderlineItem* pUnderlineItem = _rItemSet.GetItemIfSet( ITEMID_UNDERLINE ) ) + { + aNewFont.SetUnderline(pUnderlineItem->GetLineStyle()); + } + if ( const SvxColorItem* pColorItem = _rItemSet.GetItemIfSet( ITEMID_COLOR ) ) + { + aNewFont.SetColor(pColorItem->GetValue()); + } + + _out_rAwtFont = VCLUnoHelper::CreateFontDescriptor( aNewFont ); + } + + + void lcl_itemsToCharProperties( const vcl::Font& _rOriginalControlFont,const vcl::Font& _rOriginalControlFontAsian,const vcl::Font& _rOriginalControlFontComplex, const SfxItemSet& _rItemSet, uno::Sequence< beans::NamedValue >& _out_rProperties ) + { + // create an AWT font + awt::FontDescriptor aAwtFont; + lcl_initAwtFont( _rOriginalControlFont, _rItemSet, aAwtFont,ITEMID_FONT,ITEMID_FONTHEIGHT,ITEMID_POSTURE, ITEMID_WEIGHT); + lcl_pushBack( _out_rProperties, "Font", uno::Any( aAwtFont ) ); + lcl_initAwtFont( _rOriginalControlFontAsian, _rItemSet, aAwtFont,ITEMID_FONT_ASIAN,ITEMID_FONTHEIGHT_ASIAN,ITEMID_POSTURE_ASIAN, ITEMID_WEIGHT_ASIAN); + lcl_pushBack( _out_rProperties, "FontAsian", uno::Any( aAwtFont ) ); + lcl_initAwtFont( _rOriginalControlFontComplex, _rItemSet, aAwtFont,ITEMID_FONT_COMPLEX,ITEMID_FONTHEIGHT_COMPLEX,ITEMID_POSTURE_COMPLEX, ITEMID_WEIGHT_COMPLEX); + lcl_pushBack( _out_rProperties, "FontComplex", uno::Any( aAwtFont ) ); + + // properties which cannot be represented in an AWT font need to be preserved directly + if ( const SvxShadowedItem* pShadowedItem = _rItemSet.GetItemIfSet( ITEMID_SHADOWED) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARSHADOWED, uno::Any( pShadowedItem->GetValue() ) ); + if ( const SvxContourItem* pContourItem = _rItemSet.GetItemIfSet( ITEMID_CONTOUR ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARCONTOURED, uno::Any( pContourItem->GetValue() ) ); + if ( const SvxUnderlineItem* pUnderlineItem = _rItemSet.GetItemIfSet( ITEMID_UNDERLINE ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARUNDERLINECOLOR, uno::Any( pUnderlineItem->GetColor() ) ); + if ( const SvxHorJustifyItem* pJustifyItem = _rItemSet.GetItemIfSet( ITEMID_HORJUSTIFY ) ) + { + uno::Any aValue; + pJustifyItem->QueryValue(aValue,MID_HORJUST_ADJUST); + lcl_pushBack( _out_rProperties, PROPERTY_PARAADJUST, aValue ); + } + if ( const SvxVerJustifyItem* pJustifyItem = _rItemSet.GetItemIfSet( ITEMID_VERJUSTIFY ) ) + { + uno::Any aValue; + pJustifyItem->QueryValue(aValue,MID_HORJUST_ADJUST); + lcl_pushBack( _out_rProperties, PROPERTY_VERTICALALIGN, aValue ); + } + if ( const SvxCharReliefItem* pReliefItem = _rItemSet.GetItemIfSet( ITEMID_CHARRELIEF ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARRELIEF, uno::Any( static_cast< sal_Int16 >( pReliefItem->GetEnumValue() ) ) ); + if ( const SvxCharHiddenItem* pHiddenItem = _rItemSet.GetItemIfSet( ITEMID_CHARHIDDEN ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARHIDDEN, uno::Any( pHiddenItem->GetValue() ) ); + if ( const SvxAutoKernItem* pKernItem = _rItemSet.GetItemIfSet( ITEMID_AUTOKERN ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARAUTOKERNING, uno::Any( pKernItem->GetValue() ) ); + if ( const SvxBrushItem* pBrushItem = _rItemSet.GetItemIfSet( ITEMID_BRUSH ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CONTROLBACKGROUND, uno::Any( pBrushItem->GetColor() ) ); + if ( const SvxBlinkItem* pBlinkItem = _rItemSet.GetItemIfSet( ITEMID_BLINK ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARFLASH, uno::Any( pBlinkItem->GetValue() ) ); + if ( const SvxEmphasisMarkItem* pMarkItem = _rItemSet.GetItemIfSet( ITEMID_EMPHASISMARK ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHAREMPHASIS, uno::Any( static_cast< sal_Int16 >( pMarkItem->GetEmphasisMark() ) ) ); + if ( const SvxTwoLinesItem* pLinesItem = _rItemSet.GetItemIfSet( ITEMID_TWOLINES ) ) + { + lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINEISON, uno::Any( pLinesItem->GetValue() ) ); + lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINEPREFIX, uno::Any( OUString( pLinesItem->GetStartBracket() ) ) ); + lcl_pushBack( _out_rProperties, PROPERTY_CHARCOMBINESUFFIX, uno::Any( OUString( pLinesItem->GetEndBracket() ) ) ); + } + if ( const SvxColorItem* pColorItem = _rItemSet.GetItemIfSet( ITEMID_COLOR ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARCOLOR, uno::Any( pColorItem->GetValue() ) ); + if ( const SvxKerningItem* pKernItem = _rItemSet.GetItemIfSet( ITEMID_KERNING ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARKERNING, uno::Any( pKernItem->GetValue() ) ); + if ( const SvxCaseMapItem* pCaseMapItem = _rItemSet.GetItemIfSet( ITEMID_CASEMAP ) ) + lcl_pushBack( _out_rProperties, PROPERTY_CHARCASEMAP, uno::Any( pCaseMapItem->GetEnumValue() ) ); + struct Items { + TypedWhichId<SvxLanguageItem> nWhich; + OUString sPropertyName; + }; + const Items pItems[] = { {ITEMID_LANGUAGE,OUString(PROPERTY_CHARLOCALE)} + ,{ITEMID_LANGUAGE_ASIAN,OUString(PROPERTY_CHARLOCALEASIAN)} + ,{ITEMID_LANGUAGE_COMPLEX,OUString(PROPERTY_CHARLOCALECOMPLEX)} + }; + for(const auto & k : pItems) + { + if ( const SvxLanguageItem* pLanguageItem = _rItemSet.GetItemIfSet( k.nWhich ) ) + { + lang::Locale aCharLocale( LanguageTag( pLanguageItem->GetLanguage()).getLocale()); + lcl_pushBack( _out_rProperties, k.sPropertyName, uno::Any( aCharLocale ) ); + } + } + if ( const SvxEscapementItem* pEscapementItem = _rItemSet.GetItemIfSet( ITEMID_ESCAPEMENT ) ) + { + lcl_pushBack( _out_rProperties, PROPERTY_CHARESCAPEMENT, uno::Any( pEscapementItem->GetEsc() ) ); + lcl_pushBack( _out_rProperties, PROPERTY_CHARESCAPEMENTHEIGHT, uno::Any(static_cast<sal_Int8>(pEscapementItem->GetProportionalHeight())) ); + } + } + + + template< class ATTRIBUTE_TYPE > + void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName, + const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + void (SAL_CALL report::XReportControlFormat::*pSetter)( ATTRIBUTE_TYPE ) ) + { + ATTRIBUTE_TYPE aAttributeValue = ATTRIBUTE_TYPE(); + if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) ) + (_rxReportControlFormat.get()->*pSetter)( aAttributeValue ); + } + + + void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName, + const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + void (SAL_CALL report::XReportControlFormat::*pSetter)( const OUString& ) ) + { + OUString aAttributeValue; + if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) ) + (_rxReportControlFormat.get()->*pSetter)( aAttributeValue ); + } + + + void lcl_applyFontAttribute( const ::comphelper::NamedValueCollection& _rAttrValues, const OUString& _pAttributeName, + const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + void (SAL_CALL report::XReportControlFormat::*pSetter)( const lang::Locale& ) ) + { + lang::Locale aAttributeValue; + if ( _rAttrValues.get_ensureType( _pAttributeName, aAttributeValue ) ) + (_rxReportControlFormat.get()->*pSetter)( aAttributeValue ); + } +} + + +bool openCharDialog( const uno::Reference<report::XReportControlFormat >& _rxReportControlFormat, + const uno::Reference< awt::XWindow>& _rxParentWindow, uno::Sequence< beans::NamedValue >& _out_rNewValues ) +{ + OSL_PRECOND( _rxReportControlFormat.is() && _rxParentWindow.is(), "openCharDialog: invalid parameters!" ); + if ( !_rxReportControlFormat.is() || !_rxParentWindow.is() ) + return false; + + _out_rNewValues = uno::Sequence< beans::NamedValue >(); + + + // UNO->ItemSet + static SfxItemInfo aItemInfos[] = + { + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + { 0, true }, + + { SID_ATTR_CHAR_FONT, true }, + { SID_ATTR_CHAR_FONTHEIGHT, true }, + { SID_ATTR_CHAR_LANGUAGE, true }, + { SID_ATTR_CHAR_POSTURE, true }, + { SID_ATTR_CHAR_WEIGHT, true }, + { SID_ATTR_CHAR_SHADOWED, true }, + { SID_ATTR_CHAR_WORDLINEMODE, true }, + { SID_ATTR_CHAR_CONTOUR, true }, + { SID_ATTR_CHAR_STRIKEOUT, true }, + { SID_ATTR_CHAR_UNDERLINE, true }, + { SID_ATTR_CHAR_COLOR, true }, + { SID_ATTR_CHAR_KERNING, true }, + { SID_ATTR_CHAR_CASEMAP, true }, + { SID_ATTR_CHAR_ESCAPEMENT, true }, + { SID_ATTR_CHAR_FONTLIST, true }, + { SID_ATTR_CHAR_AUTOKERN, true }, + { SID_COLOR_TABLE, true }, + { SID_ATTR_FLASH, true }, + { SID_ATTR_CHAR_EMPHASISMARK, true }, + { SID_ATTR_CHAR_TWO_LINES, true }, + { SID_ATTR_CHAR_ROTATED, true }, + { SID_ATTR_CHAR_SCALEWIDTH, true }, + { SID_ATTR_CHAR_RELIEF, true }, + { SID_ATTR_CHAR_HIDDEN, true }, + { SID_ATTR_BRUSH, true }, + { SID_ATTR_ALIGN_HOR_JUSTIFY, true }, + { SID_ATTR_ALIGN_VER_JUSTIFY, true }, + + // Asian + { SID_ATTR_CHAR_CJK_FONT, true }, + { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, + { SID_ATTR_CHAR_CJK_LANGUAGE, true }, + { SID_ATTR_CHAR_CJK_POSTURE, true }, + { SID_ATTR_CHAR_CJK_WEIGHT, true }, + // Complex + { SID_ATTR_CHAR_CTL_FONT, true }, + { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, + { SID_ATTR_CHAR_CTL_LANGUAGE, true }, + { SID_ATTR_CHAR_CTL_POSTURE, true }, + { SID_ATTR_CHAR_CTL_WEIGHT, true } + }; + FontList aFontList(Application::GetDefaultDevice()); + XColorListRef pColorList( XColorList::CreateStdColorList() ); + const Graphic aNullGraphic; + const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color + const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color + const XGradient aNullGrad(COL_BLACK, COL_WHITE); + const XHatch aNullHatch(aNullLineCol); + std::vector<SfxPoolItem*> pDefaults + { + new XFillStyleItem, + new XFillColorItem("", aNullFillCol), + new XFillGradientItem(aNullGrad), + new XFillHatchItem(aNullHatch), + new XFillBitmapItem(aNullGraphic), + new XFillTransparenceItem, + new XGradientStepCountItem, + new XFillBmpTileItem, + new XFillBmpPosItem, + new XFillBmpSizeXItem, + new XFillBmpSizeYItem, + new XFillFloatTransparenceItem(aNullGrad, false), + new XSecondaryFillColorItem("", aNullFillCol), + new XFillBmpSizeLogItem, + new XFillBmpTileOffsetXItem, + new XFillBmpTileOffsetYItem, + new XFillBmpStretchItem, + new XFillBmpPosOffsetXItem, + new XFillBmpPosOffsetYItem, + new XFillBackgroundItem, + + new SvxFontItem(ITEMID_FONT), + new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT), + new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE), + new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE), + new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT), + + new SvxShadowedItem(false,ITEMID_SHADOWED), + new SvxWordLineModeItem(false,ITEMID_WORDLINEMODE), + new SvxContourItem(false,ITEMID_CONTOUR), + new SvxCrossedOutItem(STRIKEOUT_NONE,ITEMID_CROSSEDOUT), + new SvxUnderlineItem(LINESTYLE_NONE,ITEMID_UNDERLINE), + + new SvxColorItem(ITEMID_COLOR), + new SvxKerningItem(0,ITEMID_KERNING), + new SvxCaseMapItem(SvxCaseMap::NotMapped,ITEMID_CASEMAP), + new SvxEscapementItem(ITEMID_ESCAPEMENT), + new SvxFontListItem(&aFontList,ITEMID_FONTLIST), + new SvxAutoKernItem(false,ITEMID_AUTOKERN), + new SvxColorListItem(pColorList,ITEMID_COLOR_TABLE), + new SvxBlinkItem(false,ITEMID_BLINK), + new SvxEmphasisMarkItem(FontEmphasisMark::NONE,ITEMID_EMPHASISMARK), + new SvxTwoLinesItem(true,0,0,ITEMID_TWOLINES), + new SvxCharRotateItem(0_deg10,false,ITEMID_CHARROTATE), + new SvxCharScaleWidthItem(100,ITEMID_CHARSCALE_W), + new SvxCharReliefItem(FontRelief::NONE,ITEMID_CHARRELIEF), + new SvxCharHiddenItem(false,ITEMID_CHARHIDDEN), + new SvxBrushItem(ITEMID_BRUSH), + new SvxHorJustifyItem(ITEMID_HORJUSTIFY), + new SvxVerJustifyItem(ITEMID_VERJUSTIFY), +// Asian + new SvxFontItem(ITEMID_FONT_ASIAN), + new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT_ASIAN), + new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE_ASIAN), + new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE_ASIAN), + new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT_ASIAN), +// Complex + new SvxFontItem(ITEMID_FONT_COMPLEX), + new SvxFontHeightItem(240,100,ITEMID_FONTHEIGHT_COMPLEX), + new SvxLanguageItem(LANGUAGE_GERMAN,ITEMID_LANGUAGE_COMPLEX), + new SvxPostureItem(ITALIC_NONE,ITEMID_POSTURE_COMPLEX), + new SvxWeightItem(WEIGHT_NORMAL,ITEMID_WEIGHT_COMPLEX) + + }; + + OSL_ASSERT( pDefaults.size() == SAL_N_ELEMENTS(aItemInfos) ); + + static const WhichRangesContainer pRanges(svl::Items< + XATTR_FILLSTYLE, XATTR_FILLBACKGROUND, + ITEMID_FONT, ITEMID_WEIGHT_COMPLEX + >); + + rtl::Reference<SfxItemPool> pPool(new SfxItemPool("ReportCharProperties", XATTR_FILL_FIRST,ITEMID_WEIGHT_COMPLEX, aItemInfos, &pDefaults)); + // not needed for font height pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why + pPool->FreezeIdRanges(); // the same + bool bSuccess = false; + try + { + SfxItemSet aDescriptor( *pPool, pRanges ); + lcl_CharPropertiesToItems( _rxReportControlFormat, aDescriptor ); + + { // want the dialog to be destroyed before our set + ORptPageDialog aDlg(Application::GetFrameWeld(_rxParentWindow), &aDescriptor, "CharDialog"); + uno::Reference< report::XShape > xShape( _rxReportControlFormat, uno::UNO_QUERY ); + if ( xShape.is() ) + aDlg.RemoveTabPage("background"); + bSuccess = aDlg.run() == RET_OK; + if ( bSuccess ) + { + lcl_itemsToCharProperties( lcl_getReportControlFont( _rxReportControlFormat,WESTERN ), + lcl_getReportControlFont( _rxReportControlFormat,ASIAN ), + lcl_getReportControlFont( _rxReportControlFormat,COMPLEX ), *aDlg.GetOutputItemSet(), _out_rNewValues ); + } + } + } + catch(uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + pPool.clear(); + for (SfxPoolItem* pDefault : pDefaults) + delete pDefault; + + return bSuccess; +} + +bool openAreaDialog( const uno::Reference<report::XShape >& _xShape,const uno::Reference< awt::XWindow>& _rxParentWindow ) +{ + OSL_PRECOND( _xShape.is() && _rxParentWindow.is(), "openAreaDialog: invalid parameters!" ); + if ( !_xShape.is() || !_rxParentWindow.is() ) + return false; + + std::shared_ptr<rptui::OReportModel> pModel = ::reportdesign::OReportDefinition::getSdrModel(_xShape->getSection()->getReportDefinition()); + + weld::Window* pParent = Application::GetFrameWeld(_rxParentWindow); + + bool bSuccess = false; + try + { + SfxItemPool& rItemPool = pModel->GetItemPool(); + SfxItemSet aDescriptor( rItemPool, rItemPool.GetFirstWhich(), rItemPool.GetLastWhich() ); + lcl_fillShapeToItems(_xShape, aDescriptor); + + { // want the dialog to be destroyed before our set + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + ScopedVclPtr<AbstractSvxAreaTabDialog> pDialog( + pFact->CreateSvxAreaTabDialog(pParent, &aDescriptor, pModel.get(), true, false)); + if ( RET_OK == pDialog->Execute() ) + { + bSuccess = true; + lcl_fillItemsToShape(_xShape,*pDialog->GetOutputItemSet()); + } + } + } + catch(uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + return bSuccess; +} + + +void applyCharacterSettings( const uno::Reference< report::XReportControlFormat >& _rxReportControlFormat, const uno::Sequence< beans::NamedValue >& _rSettings ) +{ + ::comphelper::NamedValueCollection aSettings( _rSettings ); + + try + { + awt::FontDescriptor aAwtFont; + if ( aSettings.get( "Font" ) >>= aAwtFont ) + { + OUString sTemp = aAwtFont.Name; + aAwtFont.Name.clear(); // hack to + _rxReportControlFormat->setFontDescriptor( aAwtFont ); + _rxReportControlFormat->setCharFontName( sTemp ); + } + if ( aSettings.get( "FontAsian" ) >>= aAwtFont ) + { + OUString sTemp = aAwtFont.Name; + aAwtFont.Name.clear(); // hack to + _rxReportControlFormat->setFontDescriptorAsian( aAwtFont ); + _rxReportControlFormat->setCharFontNameAsian( sTemp ); + } + if ( aSettings.get( "FontComplex" ) >>= aAwtFont ) + { + OUString sTemp = aAwtFont.Name; + aAwtFont.Name.clear(); // hack to + _rxReportControlFormat->setFontDescriptorComplex( aAwtFont ); + _rxReportControlFormat->setCharFontNameComplex( sTemp ); + } + + lcl_applyFontAttribute( aSettings, PROPERTY_CHARSHADOWED, _rxReportControlFormat, &report::XReportControlFormat::setCharShadowed ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCONTOURED, _rxReportControlFormat, &report::XReportControlFormat::setCharContoured ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARUNDERLINECOLOR, _rxReportControlFormat, &report::XReportControlFormat::setCharUnderlineColor ); + lcl_applyFontAttribute( aSettings, PROPERTY_PARAADJUST, _rxReportControlFormat, &report::XReportControlFormat::setParaAdjust ); + lcl_applyFontAttribute( aSettings, PROPERTY_VERTICALALIGN, _rxReportControlFormat, &report::XReportControlFormat::setVerticalAlign ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARRELIEF, _rxReportControlFormat, &report::XReportControlFormat::setCharRelief ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARHIDDEN, _rxReportControlFormat, &report::XReportControlFormat::setCharHidden ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARAUTOKERNING, _rxReportControlFormat, &report::XReportControlFormat::setCharAutoKerning ); + lcl_applyFontAttribute( aSettings, PROPERTY_CONTROLBACKGROUND, _rxReportControlFormat, &report::XReportControlFormat::setControlBackground ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARFLASH, _rxReportControlFormat, &report::XReportControlFormat::setCharFlash ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHAREMPHASIS, _rxReportControlFormat, &report::XReportControlFormat::setCharEmphasis ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINEISON, _rxReportControlFormat, &report::XReportControlFormat::setCharCombineIsOn ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINEPREFIX, _rxReportControlFormat, &report::XReportControlFormat::setCharCombinePrefix ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOMBINESUFFIX, _rxReportControlFormat, &report::XReportControlFormat::setCharCombineSuffix ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCOLOR, _rxReportControlFormat, &report::XReportControlFormat::setCharColor ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARKERNING, _rxReportControlFormat, &report::XReportControlFormat::setCharKerning ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARCASEMAP, _rxReportControlFormat, &report::XReportControlFormat::setCharCaseMap ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALE, _rxReportControlFormat, &report::XReportControlFormat::setCharLocale ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARESCAPEMENT, _rxReportControlFormat, &report::XReportControlFormat::setCharEscapement ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARESCAPEMENTHEIGHT, _rxReportControlFormat, &report::XReportControlFormat::setCharEscapementHeight ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALEASIAN, _rxReportControlFormat, &report::XReportControlFormat::setCharLocaleAsian ); + lcl_applyFontAttribute( aSettings, PROPERTY_CHARLOCALECOMPLEX, _rxReportControlFormat, &report::XReportControlFormat::setCharLocaleComplex ); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void notifySystemWindow(vcl::Window const * _pWindow, vcl::Window* _pToRegister, const ::comphelper::mem_fun1_t<TaskPaneList,vcl::Window*>& rMemFunc) +{ + OSL_ENSURE(_pWindow,"Window can not be null!"); + SystemWindow* pSystemWindow = _pWindow ? _pWindow->GetSystemWindow() : nullptr; + if ( pSystemWindow ) + { + rMemFunc( pSystemWindow->GetTaskPaneList(), _pToRegister ); + } +} + +SdrObject* isOver(const tools::Rectangle& _rRect, SdrPage const & _rPage, SdrView const & _rView, bool _bAllObjects, SdrObject const * _pIgnore, sal_Int16 _nIgnoreType) +{ + SdrObject* pOverlappedObj = nullptr; + SdrObjListIter aIter(&_rPage,SdrIterMode::DeepNoGroups); + + while( !pOverlappedObj ) + { + SdrObject* pObjIter = aIter.Next(); + if( !pObjIter ) + break; + if ( _pIgnore != pObjIter + && (_bAllObjects || !_rView.IsObjMarked(pObjIter)) + && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr)) + { + if (_nIgnoreType == ISOVER_IGNORE_CUSTOMSHAPES && pObjIter->GetObjIdentifier() == SdrObjKind::CustomShape) + { + continue; + } + + if (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr) + { + tools::Rectangle aRect = _rRect.GetIntersection(pObjIter->GetLastBoundRect()); + if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) ) + pOverlappedObj = pObjIter; + } + } + } + return pOverlappedObj; +} + +static bool checkArrayForOccurrence(SdrObject const * _pObjToCheck, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnore[], int _nListLength) +{ + for(int i=0;i<_nListLength;i++) + { + SdrObject *pIgnore = _pIgnore[i].get(); + if (pIgnore == _pObjToCheck) + { + return true; + } + } + return false; +} + +SdrObject* isOver(const tools::Rectangle& _rRect,SdrPage const & _rPage,SdrView const & _rView,bool _bAllObjects, std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> _pIgnoreList[], int _nIgnoreListLength) +{ + SdrObject* pOverlappedObj = nullptr; + SdrObjListIter aIter(&_rPage,SdrIterMode::DeepNoGroups); + + while( !pOverlappedObj ) + { + SdrObject* pObjIter = aIter.Next(); + if( !pObjIter ) + break; + if (checkArrayForOccurrence(pObjIter, _pIgnoreList, _nIgnoreListLength)) + { + continue; + } + + if ( (_bAllObjects || !_rView.IsObjMarked(pObjIter)) + && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr) ) + { + tools::Rectangle aRect = _rRect.GetIntersection(pObjIter->GetLastBoundRect()); + if ( !aRect.IsEmpty() && (aRect.Left() != aRect.Right() && aRect.Top() != aRect.Bottom() ) ) + pOverlappedObj = pObjIter; + } + } + return pOverlappedObj; +} + + +SdrObject* isOver(SdrObject const * _pObj,SdrPage const & _rPage,SdrView const & _rView) +{ + SdrObject* pOverlappedObj = nullptr; + if (dynamic_cast<OUnoObject const *>(_pObj) != nullptr || dynamic_cast<OOle2Obj const *>(_pObj) != nullptr) // this doesn't need to be done for shapes + { + tools::Rectangle aRect = _pObj->GetCurrentBoundRect(); + pOverlappedObj = isOver(aRect,_rPage,_rView,false/*_bUnMarkedObjects*/,_pObj); + } + return pOverlappedObj; +} + + +uno::Sequence< OUString > getParameterNames( const uno::Reference< sdbc::XRowSet >& _rxRowSet ) +{ + uno::Sequence< OUString > aNames; + + try + { + uno::Reference< sdb::XParametersSupplier > xSuppParams( _rxRowSet, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xParams( xSuppParams->getParameters() ); + if ( xParams.is() ) + { + sal_Int32 count( xParams->getCount() ); + aNames.realloc( count ); + auto pNames = aNames.getArray(); + + uno::Reference< beans::XPropertySet > xParam; + OUString sParamName; + for ( sal_Int32 i=0; i<count; ++i ) + { + xParam.set( xParams->getByIndex(i), uno::UNO_QUERY_THROW ); + OSL_VERIFY( xParam->getPropertyValue( PROPERTY_NAME ) >>= sParamName ); + pNames[i] = sParamName; + } + } + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + return aNames; +} + +tools::Rectangle getRectangleFromControl(SdrObject* _pControl) +{ + if (_pControl) + { + uno::Reference< report::XReportComponent > xComponent( _pControl->getUnoShape(), uno::UNO_QUERY); + if (xComponent.is()) + { + tools::Rectangle aRect(VCLPoint(xComponent->getPosition()),VCLSize(xComponent->getSize())); + aRect.setHeight(aRect.getHeight() + 1); + aRect.setWidth(aRect.getWidth() + 1); + return aRect; + } + } + return tools::Rectangle(); +} + +// check overlapping +void correctOverlapping(SdrObject* _pControl,OReportSection const & _aReportSection,bool _bInsert) +{ + OSectionView& rSectionView = _aReportSection.getSectionView(); + uno::Reference< report::XReportComponent> xComponent(_pControl->getUnoShape(),uno::UNO_QUERY); + tools::Rectangle aRect = getRectangleFromControl(_pControl); + + bool bOverlapping = true; + while ( bOverlapping ) + { + SdrObject* pOverlappedObj = isOver(aRect,*_aReportSection.getPage(),rSectionView,true, _pControl); + bOverlapping = pOverlappedObj != nullptr; + if ( bOverlapping ) + { + const tools::Rectangle& aLogicRect = pOverlappedObj->GetLogicRect(); + aRect.Move(0,aLogicRect.Top() + aLogicRect.getHeight() - aRect.Top()); + xComponent->setPositionY(aRect.Top()); + } + } + if (_bInsert) // now insert objects + rSectionView.InsertObjectAtView(_pControl,*rSectionView.GetSdrPageView(), SdrInsertFlags::ADDMARK); +} + +void setZoomFactor(const Fraction& _aZoom, vcl::Window& _rWindow) +{ + MapMode aMapMode( _rWindow.GetMapMode() ); + aMapMode.SetScaleX(_aZoom); + aMapMode.SetScaleY(_aZoom); + _rWindow.SetMapMode(aMapMode); +} + +bool openDialogFormula_nothrow( OUString& _in_out_rFormula + , const css::uno::Reference< css::uno::XComponentContext >& _xContext + , const uno::Reference< awt::XWindow>& _xInspectorWindow + , const css::uno::Reference < css::beans::XPropertySet >& _xRowSet + ) +{ + OSL_PRECOND( _xInspectorWindow.is(), "openDialogFormula_nothrow: invalid parameters!" ); + if ( !_xInspectorWindow.is() ) + return false; + bool bSuccess = false; + ::dbtools::SQLExceptionInfo aErrorInfo; + uno::Reference< awt::XWindow > xInspectorWindow; + uno::Reference< lang::XMultiComponentFactory > xFactory; + uno::Reference<lang::XMultiServiceFactory> xServiceFactory; + try + { + xFactory = _xContext->getServiceManager(); + xServiceFactory.set(xFactory,uno::UNO_QUERY); + + uno::Reference< report::meta::XFunctionManager> xMgr(xFactory->createInstanceWithContext("org.libreoffice.report.pentaho.SOFunctionManager",_xContext),uno::UNO_QUERY); + if ( xMgr.is() ) + { + auto pFormulaManager = std::make_shared<FunctionManager>(xMgr); + ReportFormula aFormula( _in_out_rFormula ); + + CharClass aCC(_xContext, LanguageTag(LANGUAGE_SYSTEM)); + svl::SharedStringPool aStringPool(aCC); + + FormulaDialog aDlg( + Application::GetFrameWeld(_xInspectorWindow), xServiceFactory, pFormulaManager, + aFormula.getUndecoratedContent(), _xRowSet, aStringPool); + + bSuccess = aDlg.run() == RET_OK; + if ( bSuccess ) + { + OUString sFormula = aDlg.getCurrentFormula(); + if ( sFormula[0] == '=' ) + _in_out_rFormula = OUString::Concat("rpt:") + sFormula.subView(1); + else + _in_out_rFormula = "rpt:" + sFormula; + } + } + } + catch (const sdb::SQLContext& e) { aErrorInfo = e; } + catch (const sdbc::SQLWarning& e) { aErrorInfo = e; } + catch (const sdbc::SQLException& e) { aErrorInfo = e; } + catch( const uno::Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "GeometryHandler::impl_dialogFilter_nothrow" ); + } + + if ( aErrorInfo.isValid() ) + ::dbtools::showError( aErrorInfo, xInspectorWindow, _xContext ); + + return bSuccess; +} + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/misc/statusbarcontroller.cxx b/reportdesign/source/ui/misc/statusbarcontroller.cxx new file mode 100644 index 000000000..22f2d7714 --- /dev/null +++ b/reportdesign/source/ui/misc/statusbarcontroller.cxx @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <statusbarcontroller.hxx> + +#include <cppuhelper/supportsservice.hxx> +#include <comphelper/types.hxx> +#include <svx/zoomsliderctrl.hxx> +#include <svx/zoomctrl.hxx> +#include <svx/svxids.hrc> +#include <sfx2/zoomitem.hxx> +#include <svx/zoomslideritem.hxx> + +#include <vcl/svapp.hxx> +#include <vcl/status.hxx> +#include <osl/mutex.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +namespace rptui +{ + using namespace svt; + using namespace com::sun::star::uno; + using namespace com::sun::star::beans; + using namespace com::sun::star::lang; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::util; + +OUString SAL_CALL OStatusbarController::getImplementationName() +{ + return "com.sun.star.report.comp.StatusbarController"; +} + +sal_Bool SAL_CALL OStatusbarController::supportsService( const OUString& ServiceName ) +{ + return cppu::supportsService(this, ServiceName); +} + +Sequence< OUString> SAL_CALL OStatusbarController::getSupportedServiceNames() +{ + return { "com.sun.star.frame.StatusbarController" }; +} + +IMPLEMENT_FORWARD_XINTERFACE2(OStatusbarController, ::svt::StatusbarController,OStatusbarController_BASE) + +OStatusbarController::OStatusbarController(const Reference< XComponentContext >& rxContext) +: ::svt::StatusbarController(rxContext, Reference< XFrame >(), OUString(), 0) +,m_nSlotId(0) +,m_nId(1) +{ +} + +void SAL_CALL OStatusbarController::initialize( const Sequence< Any >& _rArguments ) +{ + StatusbarController::initialize(_rArguments); + SolarMutexGuard aSolarMutexGuard; + ::osl::MutexGuard aGuard(m_aMutex); + + VclPtr< StatusBar > pStatusBar = static_cast<StatusBar*>(VCLUnoHelper::GetWindow(m_xParentWindow)); + if ( !pStatusBar ) + return; + + const sal_uInt16 nCount = pStatusBar->GetItemCount(); + for (sal_uInt16 nPos = 0; nPos < nCount; ++nPos) + { + const sal_uInt16 nItemId = pStatusBar->GetItemId(nPos); + if ( pStatusBar->GetItemCommand(nItemId) == m_aCommandURL ) + { + m_nId = nItemId; + break; + } + } + + rtl::Reference<SfxStatusBarControl> pController; + if ( m_aCommandURL == ".uno:ZoomSlider" ) + { + m_nSlotId = SID_ATTR_ZOOMSLIDER; + pController = new SvxZoomSliderControl(m_nSlotId,m_nId,*pStatusBar); + } + else if ( m_aCommandURL == ".uno:Zoom" ) + { + m_nSlotId = SID_ATTR_ZOOM; + pController = new SvxZoomStatusBarControl(m_nSlotId,m_nId,*pStatusBar); + } + + if ( pController ) + { + m_rController.set( pController ); + if ( m_rController.is() ) + { + m_rController->initialize(_rArguments); + m_rController->update(); + } + } + + addStatusListener(m_aCommandURL); + update(); +} +// XStatusListener +void SAL_CALL OStatusbarController::statusChanged( const FeatureStateEvent& _aEvent) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard(m_aMutex); + + if ( !m_rController.is() ) + return; + + if ( m_aCommandURL == ".uno:ZoomSlider" ) + { + Sequence< PropertyValue > aSeq; + if ( (_aEvent.State >>= aSeq) && aSeq.getLength() == 2 ) + { + SvxZoomSliderItem aZoomSlider(100,20,400); + aZoomSlider.PutValue(_aEvent.State, 0); + static_cast<SvxZoomSliderControl*>(m_rController.get())->StateChangedAtStatusBarControl(m_nSlotId,SfxItemState::DEFAULT,&aZoomSlider); + } + } + else if ( m_aCommandURL == ".uno:Zoom" ) + { + Sequence< PropertyValue > aSeq; + if ( (_aEvent.State >>= aSeq) && aSeq.getLength() == 3 ) + { + SvxZoomItem aZoom; + aZoom.PutValue(_aEvent.State, 0 ); + static_cast<SvxZoomStatusBarControl*>(m_rController.get())->StateChangedAtStatusBarControl(m_nSlotId,SfxItemState::DEFAULT,&aZoom); + } + } +} + +// XStatusbarController +sal_Bool SAL_CALL OStatusbarController::mouseButtonDown(const css::awt::MouseEvent& _aEvent) +{ + return m_rController.is() && m_rController->mouseButtonDown(_aEvent); +} + +sal_Bool SAL_CALL OStatusbarController::mouseMove( const css::awt::MouseEvent& _aEvent) +{ + return m_rController.is() && m_rController->mouseMove(_aEvent); +} + +sal_Bool SAL_CALL OStatusbarController::mouseButtonUp( const css::awt::MouseEvent& _aEvent) +{ + return m_rController.is() && m_rController->mouseButtonUp(_aEvent); +} + +void SAL_CALL OStatusbarController::command( + const css::awt::Point& aPos, + ::sal_Int32 nCommand, + sal_Bool bMouseEvent, + const css::uno::Any& aData ) +{ + if ( m_rController.is() ) + m_rController->command( aPos, nCommand, bMouseEvent, aData ); +} + +void SAL_CALL OStatusbarController::paint( + const css::uno::Reference< css::awt::XGraphics >& xGraphics, + const css::awt::Rectangle& rOutputRectangle, + ::sal_Int32 nStyle ) +{ + if ( m_rController.is() ) + m_rController->paint( xGraphics, rOutputRectangle, nStyle ); +} + +void SAL_CALL OStatusbarController::click( + const css::awt::Point& aPos ) +{ + if ( m_rController.is() ) + m_rController->click( aPos ); +} + +void SAL_CALL OStatusbarController::doubleClick( + const css::awt::Point& aPos ) +{ + if ( m_rController.is() ) + m_rController->doubleClick( aPos ); +} + +void SAL_CALL OStatusbarController::update() +{ + ::svt::StatusbarController::update(); + if ( m_rController.is() ) + m_rController->update(); +} + +// XComponent +void SAL_CALL OStatusbarController::dispose() +{ + if ( m_rController.is() ) + ::comphelper::disposeComponent( m_rController ); + + svt::StatusbarController::dispose(); +} + +} // rptui + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_OStatusbarController_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new rptui::OStatusbarController(context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/DesignView.cxx b/reportdesign/source/ui/report/DesignView.cxx new file mode 100644 index 000000000..ab213479b --- /dev/null +++ b/reportdesign/source/ui/report/DesignView.cxx @@ -0,0 +1,686 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <DesignView.hxx> +#include <ReportController.hxx> +#include <svtools/acceleratorexecute.hxx> +#include <unotools/viewoptions.hxx> +#include <RptDef.hxx> +#include <UITools.hxx> +#include <RptObject.hxx> +#include <propbrw.hxx> +#include <helpids.h> +#include <SectionView.hxx> +#include <ReportSection.hxx> +#include <rptui_slotid.hrc> +#include <AddField.hxx> +#include <ScrollHelper.hxx> +#include <Navigator.hxx> +#include <SectionWindow.hxx> + +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + +#include <algorithm> + +namespace rptui +{ +using namespace ::dbaui; +using namespace ::utl; +using namespace ::com::sun::star; +using namespace uno; +using namespace lang; +using namespace beans; +using namespace container; + +#define START_SIZE_TASKPANE 30 +#define COLSET_ID 1 +#define REPORT_ID 2 +#define TASKPANE_ID 3 + +namespace { + +class OTaskWindow : public vcl::Window +{ + VclPtr<PropBrw> m_pPropWin; +public: + explicit OTaskWindow(vcl::Window* _pParent) : Window(_pParent),m_pPropWin(nullptr){} + virtual ~OTaskWindow() override { disposeOnce(); } + virtual void dispose() override { m_pPropWin.clear(); vcl::Window::dispose(); } + + void setPropertyBrowser(PropBrw* _pPropWin) + { + m_pPropWin = _pPropWin; + } + + virtual void Resize() override + { + const Size aSize = GetOutputSizePixel(); + if ( m_pPropWin && aSize.Height() && aSize.Width() ) + m_pPropWin->SetSizePixel(aSize); + } +}; + +} + + + +ODesignView::ODesignView( vcl::Window* pParent, + const Reference< XComponentContext >& _rxOrb, + OReportController& _rController) : + ODataView( pParent, _rController, _rxOrb, WB_DIALOGCONTROL ) + ,m_aSplitWin(VclPtr<SplitWindow>::Create(this)) + ,m_rReportController( _rController ) + ,m_aScrollWindow(VclPtr<rptui::OScrollWindowHelper>::Create(this)) + ,m_pPropWin(nullptr) + ,m_pCurrentView(nullptr) + ,m_aMarkIdle("reportdesign ODesignView Mark Idle") + ,m_eMode( DlgEdMode::Select ) + ,m_eActObj( SdrObjKind::NONE ) + ,m_aGridSizeCoarse( 1000, 1000 ) // #i93595# 100TH_MM changed to grid using coarse 1 cm grid + ,m_aGridSizeFine( 250, 250 ) // and a 0,25 cm subdivision for better visualisation + ,m_bDeleted( false ) +{ + SetHelpId(UID_RPT_RPT_APP_VIEW); + ImplInitSettings(); + + SetMapMode( MapMode( MapUnit::Map100thMM ) ); + + // now create the task pane on the right side :-) + m_pTaskPane = VclPtr<OTaskWindow>::Create(this); + + m_aSplitWin->InsertItem( COLSET_ID,100,SPLITWINDOW_APPEND, 0, SplitWindowItemFlags::PercentSize | SplitWindowItemFlags::ColSet ); + m_aSplitWin->InsertItem( REPORT_ID, m_aScrollWindow.get(), 100, SPLITWINDOW_APPEND, COLSET_ID, SplitWindowItemFlags::PercentSize); + + // set up splitter + m_aSplitWin->SetSplitHdl(LINK(this, ODesignView,SplitHdl)); + m_aSplitWin->SetAlign(WindowAlign::Left); + m_aSplitWin->Show(); + + m_aMarkIdle.SetInvokeHandler( LINK( this, ODesignView, MarkTimeout ) ); +} + + +ODesignView::~ODesignView() +{ + disposeOnce(); +} + +void ODesignView::dispose() +{ + m_bDeleted = true; + Hide(); + m_aScrollWindow->Hide(); + m_aMarkIdle.Stop(); + if ( m_pPropWin ) + { + notifySystemWindow(this,m_pPropWin,::comphelper::mem_fun(&TaskPaneList::RemoveWindow)); + m_pPropWin.disposeAndClear(); + } + if ( m_xAddField ) + { + SvtViewOptions aDlgOpt( EViewType::Window, UID_RPT_RPT_APP_VIEW ); + aDlgOpt.SetWindowState(OStringToOUString(m_xAddField->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US)); + + if (m_xAddField->getDialog()->get_visible()) + m_xAddField->response(RET_CANCEL); + + m_xAddField.reset(); + } + if ( m_xReportExplorer ) + { + SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xReportExplorer->get_help_id(), RTL_TEXTENCODING_UTF8)); + aDlgOpt.SetWindowState(OStringToOUString(m_xReportExplorer->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US)); + + if (m_xReportExplorer->getDialog()->get_visible()) + m_xReportExplorer->response(RET_CANCEL); + + m_xReportExplorer.reset(); + } + + m_pTaskPane.disposeAndClear(); + m_aScrollWindow.disposeAndClear(); + m_aSplitWin.disposeAndClear(); + dbaui::ODataView::dispose(); +} + +void ODesignView::initialize() +{ + SetMapMode( MapMode( MapUnit::Map100thMM ) ); + m_aScrollWindow->initialize(); + m_aScrollWindow->Show(); +} + +void ODesignView::DataChanged( const DataChangedEvent& rDCEvt ) +{ + ODataView::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +bool ODesignView::PreNotify( NotifyEvent& rNEvt ) +{ + bool bRet = ODataView::PreNotify(rNEvt); // 1 := has to be handled here + switch(rNEvt.GetType()) + { + case MouseNotifyEvent::KEYINPUT: + { + if ( m_pPropWin && m_pPropWin->HasChildPathFocus() ) + return false; + if (m_xAddField && m_xAddField->getDialog()->has_toplevel_focus()) + return false; + if ( m_xReportExplorer && m_xReportExplorer->getDialog()->has_toplevel_focus()) + return false; + const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent(); + if ( handleKeyEvent(*pKeyEvent) ) + bRet = true; + else if ( bRet && m_pAccel ) + { + const vcl::KeyCode& rCode = pKeyEvent->GetKeyCode(); + util::URL aUrl; + aUrl.Complete = m_pAccel->findCommand(svt::AcceleratorExecute::st_VCLKey2AWTKey(rCode)); + if ( aUrl.Complete.isEmpty() || !m_xController->isCommandEnabled( aUrl.Complete ) ) + bRet = false; + } + break; + } + default: + break; + } + + return bRet; +} + +void ODesignView::resizeDocumentView(tools::Rectangle& _rPlayground) +{ + if ( !_rPlayground.IsEmpty() ) + { + const Size aPlaygroundSize( _rPlayground.GetSize() ); + + // calc the split pos, and forward it to the controller + sal_Int32 nSplitPos = getController().getSplitPos(); + if ( 0 != aPlaygroundSize.Width() ) + { + if ( ( -1 == nSplitPos ) + || ( nSplitPos >= aPlaygroundSize.Width() ) + ) + { + tools::Long nMinWidth = static_cast<tools::Long>(0.1*aPlaygroundSize.Width()); + if ( m_pPropWin && m_pPropWin->IsVisible() ) + nMinWidth = m_pPropWin->GetMinOutputSizePixel().Width(); + nSplitPos = static_cast<sal_Int32>(_rPlayground.Right() - nMinWidth); + getController().setSplitPos(nSplitPos); + } + } + + if ( m_aSplitWin->IsItemValid(TASKPANE_ID) ) + { + // normalize the split pos + const tools::Long nSplitterWidth = StyleSettings::GetSplitSize(); + Point aTaskPanePos(nSplitPos + nSplitterWidth, _rPlayground.Top()); + if (m_pTaskPane && m_pTaskPane->IsVisible() && m_pPropWin) + { + aTaskPanePos.setX( aPlaygroundSize.Width() - m_pTaskPane->GetSizePixel().Width() ); + sal_Int32 nMinWidth = m_pPropWin->getMinimumSize().Width(); + if ( nMinWidth > (aPlaygroundSize.Width() - aTaskPanePos.X()) ) + { + aTaskPanePos.setX( aPlaygroundSize.Width() - nMinWidth ); + } + nSplitPos = aTaskPanePos.X() - nSplitterWidth; + getController().setSplitPos(nSplitPos); + + const tools::Long nTaskPaneSize = static_cast<tools::Long>((aPlaygroundSize.Width() - aTaskPanePos.X())*100/aPlaygroundSize.Width()); + if ( m_aSplitWin->GetItemSize( TASKPANE_ID ) != nTaskPaneSize ) + { + m_aSplitWin->SetItemSize( REPORT_ID, 99 - nTaskPaneSize ); + m_aSplitWin->SetItemSize( TASKPANE_ID, nTaskPaneSize ); + } + } + } + // set the size of the report window + m_aSplitWin->SetPosSizePixel( _rPlayground.TopLeft(),aPlaygroundSize ); + } + // just for completeness: there is no space left, we occupied it all ... + _rPlayground.SetPos( _rPlayground.BottomRight() ); + _rPlayground.SetSize( Size( 0, 0 ) ); + +} + +IMPL_LINK_NOARG(ODesignView, MarkTimeout, Timer *, void) +{ + if ( m_pPropWin && m_pPropWin->IsVisible() ) + { + m_pPropWin->Update(m_pCurrentView); + uno::Reference<beans::XPropertySet> xProp(m_xReportComponent,uno::UNO_QUERY); + if ( xProp.is() ) + { + m_pPropWin->Update(xProp); + static_cast<OTaskWindow*>(m_pTaskPane.get())->Resize(); + } + Resize(); + } +} + + +void ODesignView::SetMode( DlgEdMode _eNewMode ) +{ + m_eMode = _eNewMode; + if ( m_eMode == DlgEdMode::Select ) + m_eActObj = SdrObjKind::NONE; + + m_aScrollWindow->SetMode(_eNewMode); +} + +void ODesignView::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType ) +{ + m_eActObj = eObj; + m_aScrollWindow->SetInsertObj( eObj,_sShapeType ); +} + +OUString const & ODesignView::GetInsertObjString() const +{ + return m_aScrollWindow->GetInsertObjString(); +} + + +void ODesignView::Cut() +{ + Copy(); + Delete(); +} + + +void ODesignView::Copy() +{ + m_aScrollWindow->Copy(); +} + + +void ODesignView::Paste() +{ + m_aScrollWindow->Paste(); +} + +void ODesignView::Delete() +{ + m_aScrollWindow->Delete(); +} + +bool ODesignView::HasSelection() const +{ + return m_aScrollWindow->HasSelection(); +} + + +bool ODesignView::IsPasteAllowed() const +{ + return m_aScrollWindow->IsPasteAllowed(); +} + + +void ODesignView::UpdatePropertyBrowserDelayed(OSectionView& _rView) +{ + if ( m_pCurrentView != &_rView ) + { + if ( m_pCurrentView ) + m_aScrollWindow->setMarked(m_pCurrentView,false); + m_pCurrentView = &_rView; + m_aScrollWindow->setMarked(m_pCurrentView, true); + m_xReportComponent.clear(); + DlgEdHint aHint( RPTUI_HINT_SELECTIONCHANGED ); + Broadcast( aHint ); + } + m_aMarkIdle.Start(); +} + + +void ODesignView::toggleGrid(bool _bGridVisible) +{ + m_aScrollWindow->toggleGrid(_bGridVisible); +} + +sal_uInt16 ODesignView::getSectionCount() const +{ + return m_aScrollWindow->getSectionCount(); +} + +void ODesignView::showRuler(bool _bShow) +{ + m_aScrollWindow->showRuler(_bShow); +} + +void ODesignView::removeSection(sal_uInt16 _nPosition) +{ + m_aScrollWindow->removeSection(_nPosition); +} + +void ODesignView::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition) +{ + m_aScrollWindow->addSection(_xSection,_sColorEntry,_nPosition); +} + +void ODesignView::GetFocus() +{ + Window::GetFocus(); + + if ( !m_bDeleted ) + { + OSectionWindow* pSectionWindow = m_aScrollWindow->getMarkedSection(); + if ( pSectionWindow ) + pSectionWindow->GrabFocus(); + } +} + +void ODesignView::ImplInitSettings() +{ + SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() )); + GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); + SetTextFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); +} + +IMPL_LINK_NOARG( ODesignView, SplitHdl, SplitWindow*, void ) +{ + const Size aOutputSize = GetOutputSizePixel(); + const tools::Long nTest = aOutputSize.Width() * m_aSplitWin->GetItemSize(TASKPANE_ID) / 100; + tools::Long nMinWidth = static_cast<tools::Long>(0.1*aOutputSize.Width()); + if ( m_pPropWin && m_pPropWin->IsVisible() ) + nMinWidth = m_pPropWin->GetMinOutputSizePixel().Width(); + + if ( (aOutputSize.Width() - nTest) >= nMinWidth && nTest > m_aScrollWindow->getMaxMarkerWidth() ) + { + getController().setSplitPos(nTest); + } +} + +void ODesignView::SelectAll(const SdrObjKind _nObjectType) +{ + m_aScrollWindow->SelectAll(_nObjectType); +} + +void ODesignView::unmarkAllObjects() +{ + m_aScrollWindow->unmarkAllObjects(); +} + +void ODesignView::togglePropertyBrowser(bool _bToggleOn) +{ + if ( !m_pPropWin && _bToggleOn ) + { + m_pPropWin = VclPtr<PropBrw>::Create(getController().getORB(), m_pTaskPane,this); + m_pPropWin->Invalidate(); + static_cast<OTaskWindow*>(m_pTaskPane.get())->setPropertyBrowser(m_pPropWin); + notifySystemWindow(this,m_pPropWin,::comphelper::mem_fun(&TaskPaneList::AddWindow)); + } + if ( !(m_pPropWin && _bToggleOn != m_pPropWin->IsVisible()) ) + return; + + if ( !m_pCurrentView && !m_xReportComponent.is() ) + m_xReportComponent = getController().getReportDefinition(); + + const bool bWillBeVisible = _bToggleOn; + m_pPropWin->Show(bWillBeVisible); + m_pTaskPane->Show(bWillBeVisible); + m_pTaskPane->Invalidate(); + + if ( bWillBeVisible ) + m_aSplitWin->InsertItem( TASKPANE_ID, m_pTaskPane,START_SIZE_TASKPANE, SPLITWINDOW_APPEND, COLSET_ID, SplitWindowItemFlags::PercentSize); + else + m_aSplitWin->RemoveItem(TASKPANE_ID); + + if ( bWillBeVisible ) + m_aMarkIdle.Start(); +} + +void ODesignView::showProperties(const uno::Reference< uno::XInterface>& _xReportComponent) +{ + if ( m_xReportComponent != _xReportComponent ) + { + m_xReportComponent = _xReportComponent; + if ( m_pCurrentView ) + m_aScrollWindow->setMarked(m_pCurrentView,false); + m_pCurrentView = nullptr; + m_aMarkIdle.Start(); + } +} + +bool ODesignView::isReportExplorerVisible() const +{ + return m_xReportExplorer && m_xReportExplorer->getDialog()->get_visible(); +} + +void ODesignView::toggleReportExplorer() +{ + if ( !m_xReportExplorer ) + { + OReportController& rReportController = getController(); + m_xReportExplorer = std::make_shared<ONavigator>(GetFrameWeld(), rReportController); + SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xReportExplorer->get_help_id(), RTL_TEXTENCODING_UTF8)); + if ( aDlgOpt.Exists() ) + m_xReportExplorer->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US)); + } + + if (!m_xReportExplorer->getDialog()->get_visible()) + weld::DialogController::runAsync(m_xReportExplorer, [this](sal_Int32 /*nResult*/) { m_xReportExplorer.reset(); }); + else + m_xReportExplorer->response(RET_CANCEL); +} + +bool ODesignView::isAddFieldVisible() const +{ + return m_xAddField && m_xAddField->getDialog()->get_visible(); +} + +void ODesignView::toggleAddField() +{ + if (!m_xAddField) + { + uno::Reference< report::XReportDefinition > xReport(m_xReportComponent,uno::UNO_QUERY); + uno::Reference< report::XReportComponent > xReportComponent(m_xReportComponent,uno::UNO_QUERY); + OReportController& rReportController = getController(); + if ( !m_pCurrentView && !xReport.is() ) + { + if ( xReportComponent.is() ) + xReport = xReportComponent->getSection()->getReportDefinition(); + else + xReport = rReportController.getReportDefinition().get(); + } + else if ( m_pCurrentView ) + { + uno::Reference< report::XSection > xSection = m_pCurrentView->getReportSection()->getSection(); + xReport = xSection->getReportDefinition(); + } + uno::Reference < beans::XPropertySet > xSet(rReportController.getRowSet(),uno::UNO_QUERY); + m_xAddField = std::make_shared<OAddFieldWindow>(GetFrameWeld(), xSet); + m_xAddField->SetCreateHdl(LINK( &rReportController, OReportController, OnCreateHdl ) ); + SvtViewOptions aDlgOpt( EViewType::Window, UID_RPT_RPT_APP_VIEW ); + if ( aDlgOpt.Exists() ) + m_xAddField->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US)); + m_xAddField->Update(); + } + if (!m_xAddField->getDialog()->get_visible()) + weld::DialogController::runAsync(m_xAddField, [this](sal_Int32 /*nResult*/) { m_xAddField.reset(); }); + else + m_xAddField->response(RET_CANCEL); +} + +uno::Reference< report::XSection > ODesignView::getCurrentSection() const +{ + uno::Reference< report::XSection > xSection; + if ( m_pCurrentView ) + xSection = m_pCurrentView->getReportSection()->getSection(); + + return xSection; +} + +uno::Reference< report::XReportComponent > ODesignView::getCurrentControlModel() const +{ + uno::Reference< report::XReportComponent > xModel; + if ( m_pCurrentView ) + { + xModel = m_pCurrentView->getReportSection()->getCurrentControlModel(); + } + return xModel; +} + +OSectionWindow* ODesignView::getMarkedSection(NearSectionAccess nsa) const +{ + return m_aScrollWindow->getMarkedSection(nsa); +} + +OSectionWindow* ODesignView::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const +{ + return m_aScrollWindow->getSectionWindow(_xSection); +} + +void ODesignView::markSection(const sal_uInt16 _nPos) +{ + m_aScrollWindow->markSection(_nPos); +} + +void ODesignView::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const +{ + m_aScrollWindow->fillCollapsedSections(_rCollapsedPositions); +} + +void ODesignView::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollapsedSections) +{ + m_aScrollWindow->collapseSections(_aCollapsedSections); +} + +OUString ODesignView::getCurrentPage() const +{ + return m_pPropWin ? m_pPropWin->getCurrentPage() : OUString(); +} + +void ODesignView::setCurrentPage(const OUString& _sLastActivePage) +{ + if ( m_pPropWin ) + m_pPropWin->setCurrentPage(_sLastActivePage); +} + +void ODesignView::alignMarkedObjects(ControlModification _nControlModification,bool _bAlignAtSection) +{ + m_aScrollWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection); +} + +bool ODesignView::handleKeyEvent(const KeyEvent& _rEvent) +{ + if ( m_pPropWin && m_pPropWin->HasChildPathFocus() ) + return false; + if (m_xAddField && m_xAddField->getDialog()->has_toplevel_focus()) + return false; + if (m_xReportExplorer && m_xReportExplorer->getDialog()->has_toplevel_focus()) + return false; + return m_aScrollWindow->handleKeyEvent(_rEvent); +} + +void ODesignView::setMarked(const uno::Reference< report::XSection>& _xSection,bool _bMark) +{ + m_aScrollWindow->setMarked(_xSection,_bMark); + if ( _bMark ) + UpdatePropertyBrowserDelayed(getMarkedSection()->getReportSection().getSectionView()); + else + m_pCurrentView = nullptr; +} + +void ODesignView::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes,bool _bMark) +{ + m_aScrollWindow->setMarked(_aShapes,_bMark); + if ( _aShapes.hasElements() && _bMark ) + showProperties(_aShapes[0]); + else + m_xReportComponent.clear(); +} + +void ODesignView::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsLeft() ) + { + const uno::Sequence< beans::PropertyValue> aArgs; + getController().executeChecked(SID_SELECT_REPORT,aArgs); + } + ODataView::MouseButtonDown(rMEvt); +} + +uno::Any ODesignView::getCurrentlyShownProperty() const +{ + uno::Any aRet; + OSectionWindow* pSectionWindow = getMarkedSection(); + if ( pSectionWindow ) + { + ::std::vector< uno::Reference< uno::XInterface > > aSelection; + pSectionWindow->getReportSection().fillControlModelSelection(aSelection); + if ( !aSelection.empty() ) + { + uno::Sequence< uno::Reference< report::XReportComponent > > aSeq(aSelection.size()); + std::transform( + aSelection.begin(), aSelection.end(), aSeq.getArray(), + [](const auto& rxInterface) + { return uno::Reference<report::XReportComponent>(rxInterface, uno::UNO_QUERY); }); + aRet <<= aSeq; + } + } + return aRet; +} + +void ODesignView::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const +{ + m_aScrollWindow->fillControlModelSelection(_rSelection); +} + +void ODesignView::setGridSnap(bool bOn) +{ + m_aScrollWindow->setGridSnap(bOn); + +} + +void ODesignView::setDragStripes(bool bOn) +{ + m_aScrollWindow->setDragStripes(bOn); +} + +bool ODesignView::isHandleEvent() const +{ + return m_pPropWin && m_pPropWin->HasChildPathFocus(); +} + +sal_uInt32 ODesignView::getMarkedObjectCount() const +{ + return m_aScrollWindow->getMarkedObjectCount(); +} + +void ODesignView::zoom(const Fraction& _aZoom) +{ + m_aScrollWindow->zoom(_aZoom); +} + +sal_uInt16 ODesignView::getZoomFactor(SvxZoomType _eType) const +{ + return m_aScrollWindow->getZoomFactor(_eType); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/EndMarker.cxx b/reportdesign/source/ui/report/EndMarker.cxx new file mode 100644 index 000000000..fdd28f4db --- /dev/null +++ b/reportdesign/source/ui/report/EndMarker.cxx @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <EndMarker.hxx> +#include <ColorChanger.hxx> +#include <SectionWindow.hxx> + +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <vcl/gradient.hxx> +#include <vcl/lineinfo.hxx> +#include <vcl/event.hxx> + + +#define CORNER_SPACE 5 + +namespace rptui +{ + +OEndMarker::OEndMarker(vcl::Window* _pParent ,const OUString& _sColorEntry) + : OColorListener(_pParent, _sColorEntry) +{ + ImplInitSettings(); +} + +OEndMarker::~OEndMarker() +{ +} + +void OEndMarker::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) +{ + Fraction aCornerSpace(tools::Long(CORNER_SPACE)); + aCornerSpace *= rRenderContext.GetMapMode().GetScaleX(); + const tools::Long nCornerSpace = tools::Long(aCornerSpace); + + Size aSize = GetSizePixel(); + aSize.AdjustWidth(nCornerSpace ); + tools::Rectangle aWholeRect(Point(-nCornerSpace,0),aSize); + tools::PolyPolygon aPoly; + aPoly.Insert( tools::Polygon(aWholeRect,nCornerSpace,nCornerSpace)); + + Color aStartColor(m_nColor); + aStartColor.IncreaseLuminance(10); + sal_uInt16 nHue = 0; + sal_uInt16 nSat = 0; + sal_uInt16 nBri = 0; + aStartColor.RGBtoHSB(nHue, nSat, nBri); + nSat += 40; + Color aEndColor(Color::HSBtoRGB(nHue, nSat, nBri)); + Gradient aGradient(GradientStyle::Linear, aStartColor, aEndColor); + aGradient.SetSteps(static_cast<sal_uInt16>(aSize.Height())); + + rRenderContext.DrawGradient(PixelToLogic(aPoly), aGradient); + if (m_bMarked) + { + tools::Rectangle aRect(Point(-nCornerSpace, nCornerSpace), + Size(aSize.Width() - nCornerSpace, + aSize.Height() - nCornerSpace - nCornerSpace)); + ColorChanger aColors(GetOutDev(), COL_WHITE, COL_WHITE); + rRenderContext.DrawPolyLine( tools::Polygon(PixelToLogic(aRect)), LineInfo(LineStyle::Solid, 2)); + } +} + +void OEndMarker::ImplInitSettings() +{ + EnableChildTransparentMode(); + SetParentClipMode( ParentClipMode::NoClip ); + SetPaintTransparent( true ); + + SetBackground( Wallpaper( svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor) ); + GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetShadowColor() ); +} + +void OEndMarker::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( !rMEvt.IsLeft() && !rMEvt.IsRight()) + return; + static_cast<OSectionWindow*>(GetParent())->showProperties(); +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/FixedTextColor.cxx b/reportdesign/source/ui/report/FixedTextColor.cxx new file mode 100644 index 000000000..b0dd3c496 --- /dev/null +++ b/reportdesign/source/ui/report/FixedTextColor.cxx @@ -0,0 +1,193 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <FixedTextColor.hxx> +#include <com/sun/star/report/XFixedText.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> + +#include <RptObject.hxx> +#include <RptModel.hxx> +#include <RptPage.hxx> +#include <ReportSection.hxx> +#include <ReportController.hxx> +#include <strings.hxx> + +#include <tools/color.hxx> + +// DBG_UNHANDLED_EXCEPTION +#include <tools/diagnose_ex.h> + +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +namespace rptui +{ + using namespace ::com::sun::star; + + + FixedTextColor::FixedTextColor(const OReportController& _aController) + :m_rReportController(_aController) + { + } + + + FixedTextColor::~FixedTextColor() + { + } + + + void FixedTextColor::notifyPropertyChange( const beans::PropertyChangeEvent& _rEvent ) + { + uno::Reference< report::XFixedText > xFixedText( _rEvent.Source, uno::UNO_QUERY ); + if ( ! xFixedText.is() ) + { + return; + } + + try + { + uno::Reference< lang::XComponent > xComponent( xFixedText, uno::UNO_QUERY_THROW ); + handle(xComponent); + } + catch (uno::Exception const&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + + void FixedTextColor::setPropertyTextColor(const uno::Reference< awt::XVclWindowPeer >& _xVclWindowPeer, Color _nTextColor) + { + _xVclWindowPeer->setProperty(PROPERTY_TEXTCOLOR, uno::Any(_nTextColor)); + } + + + void FixedTextColor::notifyElementInserted( const uno::Reference< uno::XInterface >& _rxElement ) + { + handle(_rxElement); + } + + + void FixedTextColor::handle( const uno::Reference< uno::XInterface >& _rxElement ) + { + uno::Reference< report::XFixedText > xFixedText( _rxElement, uno::UNO_QUERY ); + if ( ! xFixedText.is() ) + { + return; + } + + try + { + bool bIsDark = false; + const Color nBackColor( ColorTransparency, xFixedText->getControlBackground() ); + if (nBackColor == COL_TRANSPARENT) + { + uno::Reference <report::XSection> xSection(xFixedText->getParent(), uno::UNO_QUERY_THROW); + + bool bSectionBackColorIsTransparent = xSection->getBackTransparent(); + if (bSectionBackColorIsTransparent) + { + // Label Transparent, Section Transparent set LabelTextColor + const StyleSettings& aStyleSettings = Application::GetSettings().GetStyleSettings(); + Color aWindowColor = aStyleSettings.GetWindowColor(); + bIsDark = aWindowColor.IsDark(); + } + else + { + css::util::Color aColor2 = xSection->getBackColor(); + Color aBackColor(ColorTransparency, aColor2); + bIsDark = aBackColor.IsDark(); + } + } + else + { + Color aLabelBackColor(nBackColor); + bIsDark = aLabelBackColor.IsDark(); + } + + uno::Reference<awt::XVclWindowPeer> xVclWindowPeer = getVclWindowPeer(xFixedText); + if (bIsDark) + { + const StyleSettings& aStyleSettings = Application::GetSettings().GetStyleSettings(); + Color aLabelTextColor = aStyleSettings.GetLabelTextColor(); + setPropertyTextColor(xVclWindowPeer, aLabelTextColor); + } + else + { + util::Color aLabelColor = xFixedText->getCharColor(); + setPropertyTextColor(xVclWindowPeer, ::Color(ColorTransparency, aLabelColor)); + } + + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + + // XPropertyChangeListener + uno::Reference<awt::XControl> FixedTextColor::getXControl(const uno::Reference< report::XFixedText >& _xFixedText) + { + + uno::Reference<awt::XControl> xControl; + OReportController *pController = const_cast<OReportController *>(&m_rReportController); + + std::shared_ptr<OReportModel> pModel = pController->getSdrModel(); + + uno::Reference<report::XSection> xSection(_xFixedText->getSection()); + if ( xSection.is() ) + { + OReportPage *pPage = pModel->getPage(xSection); + const size_t nIndex = pPage->getIndexOf(_xFixedText); + if (nIndex < pPage->GetObjCount() ) + { + SdrObject *pObject = pPage->GetObj(nIndex); + OUnoObject* pUnoObj = dynamic_cast<OUnoObject*>(pObject); + if ( pUnoObj ) // this doesn't need to be done for shapes + { + OSectionWindow* pSectionWindow = pController->getSectionWindow(xSection); + if (pSectionWindow != nullptr) + { + OReportSection& aOutputDevice = pSectionWindow->getReportSection(); // OutputDevice + OSectionView& aSdrView = aOutputDevice.getSectionView(); // SdrView + xControl = pUnoObj->GetUnoControl(aSdrView, *aOutputDevice.GetOutDev()); + } + } + } + } + return xControl; + } + + + uno::Reference<awt::XVclWindowPeer> FixedTextColor::getVclWindowPeer(const uno::Reference< report::XFixedText >& _xComponent) + { + uno::Reference<awt::XVclWindowPeer> xVclWindowPeer; + uno::Reference<awt::XControl> xControl = getXControl(_xComponent); + + xVclWindowPeer.set( xControl->getPeer(), uno::UNO_QUERY); + + return xVclWindowPeer; + } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx new file mode 100644 index 000000000..d4fec971e --- /dev/null +++ b/reportdesign/source/ui/report/FormattedFieldBeautifier.cxx @@ -0,0 +1,177 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + + +#include <FormattedFieldBeautifier.hxx> + +#include <com/sun/star/report/XFormattedField.hpp> +#include <com/sun/star/awt/XVclWindowPeer.hpp> + +#include <RptObject.hxx> +#include <RptModel.hxx> +#include <RptPage.hxx> +#include <ReportSection.hxx> +#include <ReportController.hxx> +#include <strings.hxx> +#include <reportformula.hxx> + +#include <svtools/extcolorcfg.hxx> + +// DBG_UNHANDLED_EXCEPTION +#include <tools/diagnose_ex.h> + +namespace rptui +{ + using namespace ::com::sun::star; + + + FormattedFieldBeautifier::FormattedFieldBeautifier(const OReportController& _aController) + :m_rReportController(_aController) + ,m_nTextColor(COL_AUTO) + { + } + + + Color FormattedFieldBeautifier::getTextColor() + { + if (m_nTextColor == COL_AUTO) + { + svtools::ExtendedColorConfig aConfig; + m_nTextColor = aConfig.GetColorValue(CFG_REPORTDESIGNER, DBTEXTBOXBOUNDCONTENT).getColor(); + } + return m_nTextColor; + } + + + FormattedFieldBeautifier::~FormattedFieldBeautifier() + { + } + + + void FormattedFieldBeautifier::setPlaceholderText( const uno::Reference< uno::XInterface >& _rxComponent ) + { + try + { + uno::Reference< report::XFormattedField > xControlModel( _rxComponent, uno::UNO_QUERY ); + if ( xControlModel.is() ) + { + OUString sDataField = xControlModel->getDataField(); + + if ( !sDataField.isEmpty() ) + { + ReportFormula aFormula( sDataField ); + bool bSet = true; + if ( aFormula.getType() == ReportFormula::Field ) + { + const OUString& sColumnName = aFormula.getFieldName(); + OUString sLabel = m_rReportController.getColumnLabel_throw(sColumnName); + if ( !sLabel.isEmpty() ) + { + sDataField = "=" + sLabel; + bSet = false; + } + } + if ( bSet ) + sDataField = aFormula.getEqualUndecoratedContent(); + } + + setPlaceholderText( getVclWindowPeer( xControlModel ), sDataField ); + } + } + catch (const uno::Exception &) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + + void FormattedFieldBeautifier::setPlaceholderText( const uno::Reference< awt::XVclWindowPeer >& _xVclWindowPeer, const OUString& _rText ) + { + OSL_ENSURE( _xVclWindowPeer.is(), "FormattedFieldBeautifier::setPlaceholderText: invalid peer!" ); + if ( !_xVclWindowPeer.is() ) + throw uno::RuntimeException(); + + // the actual text + _xVclWindowPeer->setProperty(PROPERTY_TEXT, uno::Any(_rText)); + // the text color + _xVclWindowPeer->setProperty(PROPERTY_TEXTCOLOR, uno::Any(getTextColor())); + // font->italic + uno::Any aFontDescriptor = _xVclWindowPeer->getProperty(PROPERTY_FONTDESCRIPTOR); + awt::FontDescriptor aFontDescriptorStructure; + aFontDescriptor >>= aFontDescriptorStructure; + aFontDescriptorStructure.Slant = css::awt::FontSlant_ITALIC; + _xVclWindowPeer->setProperty(PROPERTY_FONTDESCRIPTOR, uno::Any(aFontDescriptorStructure)); + } + + + void FormattedFieldBeautifier::notifyPropertyChange( const beans::PropertyChangeEvent& _rEvent ) + { + if ( _rEvent.PropertyName != "DataField" ) + // not interested in + return; + + setPlaceholderText( _rEvent.Source ); + } + + + void FormattedFieldBeautifier::handle( const uno::Reference< uno::XInterface >& _rxElement ) + { + setPlaceholderText( _rxElement ); + } + + + void FormattedFieldBeautifier::notifyElementInserted( const uno::Reference< uno::XInterface >& _rxElement ) + { + handle( _rxElement ); + } + + + uno::Reference<awt::XVclWindowPeer> FormattedFieldBeautifier::getVclWindowPeer(const uno::Reference< report::XReportComponent >& _xComponent) + { + uno::Reference<awt::XVclWindowPeer> xVclWindowPeer; + + std::shared_ptr<OReportModel> pModel = m_rReportController.getSdrModel(); + + uno::Reference<report::XSection> xSection(_xComponent->getSection()); + if ( xSection.is() ) + { + OReportPage *pPage = pModel->getPage(xSection); + const size_t nIndex = pPage->getIndexOf(_xComponent); + if (nIndex < pPage->GetObjCount() ) + { + SdrObject *pObject = pPage->GetObj(nIndex); + OUnoObject* pUnoObj = dynamic_cast<OUnoObject*>(pObject); + if ( pUnoObj ) // this doesn't need to be done for shapes + { + OSectionWindow* pSectionWindow = m_rReportController.getSectionWindow(xSection); + if (pSectionWindow != nullptr) + { + OReportSection& aOutputDevice = pSectionWindow->getReportSection(); // OutputDevice + OSectionView& aSdrView = aOutputDevice.getSectionView(); // SdrView + uno::Reference<awt::XControl> xControl = pUnoObj->GetUnoControl(aSdrView, *aOutputDevice.GetOutDev()); + xVclWindowPeer.set( xControl->getPeer(), uno::UNO_QUERY); + } + } + } + } + return xVclWindowPeer; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx new file mode 100644 index 000000000..82edfba92 --- /dev/null +++ b/reportdesign/source/ui/report/ReportController.cxx @@ -0,0 +1,4365 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ReportController.hxx> +#include <ReportDefinition.hxx> +#include <CondFormat.hxx> +#include <UITools.hxx> +#include <AddField.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <DateTime.hxx> + +#include <sfx2/filedlghelper.hxx> +#include <tools/diagnose_ex.h> +#include <rptui_slotid.hrc> +#include <reportformula.hxx> + +#include <comphelper/documentconstants.hxx> +#include <unotools/mediadescriptor.hxx> +#include <comphelper/propertysequence.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/types.hxx> + +#include <connectivity/dbtools.hxx> +#include <com/sun/star/style/XStyle.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/util/NumberFormatter.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker3.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/report/XImageControl.hpp> +#include <com/sun/star/report/XFixedLine.hpp> +#include <com/sun/star/report/Function.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/sdb/XParametersSupplier.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#include <com/sun/star/embed/EmbedMapUnits.hpp> +#include <com/sun/star/awt/FontWeight.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/frame/status/FontHeight.hpp> +#include <com/sun/star/report/ReportEngine.hpp> +#include <com/sun/star/report/XFormattedField.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> + +#include <vcl/svapp.hxx> + +#include <i18nutil/paper.hxx> +#include <svx/fmview.hxx> +#include <editeng/memberids.h> +#include <svx/svxids.hrc> +#include <svx/svdobj.hxx> +#include <svx/unomid.hxx> +#include <svx/dataaccessdescriptor.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xflclit.hxx> +#include <svx/xflgrit.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xbtmpit.hxx> +#include <svx/xflftrit.hxx> +#include <svx/xsflclit.hxx> +#include <svx/xflbckit.hxx> +#include <svx/xflbmpit.hxx> +#include <svx/xflbmsli.hxx> +#include <svx/xflbmsxy.hxx> +#include <svx/xflbmtit.hxx> +#include <svx/xflboxy.hxx> +#include <svx/xflbstit.hxx> +#include <svx/xflbtoxy.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xgrscit.hxx> +#include <editeng/svxenum.hxx> +#include <svx/pageitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/sizeitem.hxx> +#include <sfx2/zoomitem.hxx> +#include <svx/zoomslideritem.hxx> +#include <editeng/brushitem.hxx> +#include <svx/flagsdef.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svxdlg.hxx> + +#include <core_resource.hxx> +#include <DesignView.hxx> +#include <RptObject.hxx> +#include <RptUndo.hxx> +#include <strings.hxx> +#include <RptDef.hxx> +#include <ReportSection.hxx> +#include <SectionView.hxx> +#include <UndoActions.hxx> +#include <dlgpage.hxx> +#include <strings.hrc> + +#include <svl/itempool.hxx> +#include <svl/itemset.hxx> +#include <svtools/cliplistener.hxx> +#include <unotools/syslocale.hxx> +#include <unotools/viewoptions.hxx> +#include <unotools/localedatawrapper.hxx> + +#include <osl/mutex.hxx> +#include <PropertyForward.hxx> +#include <SectionWindow.hxx> + +#include <toolkit/helper/convert.hxx> +#include <GroupsSorting.hxx> +#include <PageNumber.hxx> +#include <UndoEnv.hxx> + +#include <memory> +#include <string_view> + +#include <cppuhelper/exc_hlp.hxx> +#include <unotools/confignode.hxx> + +#include <ReportControllerObserver.hxx> + +#define MAX_ROWS_FOR_PREVIEW 20 + +#define RPTUI_ID_LRSPACE TypedWhichId<SvxLRSpaceItem>(XATTR_FILL_FIRST - 8) +#define RPTUI_ID_ULSPACE TypedWhichId<SvxULSpaceItem>(XATTR_FILL_FIRST - 7) +#define RPTUI_ID_PAGE TypedWhichId<SvxPageItem>(XATTR_FILL_FIRST - 6) +#define RPTUI_ID_SIZE TypedWhichId<SvxSizeItem>(XATTR_FILL_FIRST - 5) +#define RPTUI_ID_PAGE_MODE XATTR_FILL_FIRST - 4 +#define RPTUI_ID_START XATTR_FILL_FIRST - 3 +#define RPTUI_ID_END XATTR_FILL_FIRST - 2 +#define RPTUI_ID_BRUSH TypedWhichId<SvxBrushItem>(XATTR_FILL_FIRST - 1) +/// Note that we deliberately overlap an existing item id, so that we can have contiguous item ids for +/// the static defaults. +#define RPTUI_ID_METRIC XATTR_FILL_LAST + +using namespace ::com::sun::star; +using namespace uno; +using namespace io; +using namespace beans; +using namespace frame; +using namespace util; +using namespace lang; +using namespace container; +using namespace sdbcx; +using namespace sdbc; +using namespace sdb; +using namespace ui; +using namespace ui::dialogs; +using namespace ::dbtools; +using namespace ::rptui; +using namespace ::dbaui; +using namespace ::comphelper; +using namespace ::cppu; + + +namespace +{ + void lcl_setFontWPU_nothrow(const uno::Reference< report::XReportControlFormat>& _xReportControlFormat,const sal_Int32 _nId) + { + if ( !_xReportControlFormat.is() ) + return; + + try + { + awt::FontDescriptor aFontDescriptor = _xReportControlFormat->getFontDescriptor(); + switch(_nId) + { + case SID_ATTR_CHAR_WEIGHT: + aFontDescriptor.Weight = (awt::FontWeight::NORMAL + awt::FontWeight::BOLD) - aFontDescriptor.Weight; + break; + case SID_ATTR_CHAR_POSTURE: + aFontDescriptor.Slant = static_cast<awt::FontSlant>(static_cast<sal_Int16>(awt::FontSlant_ITALIC) - static_cast<sal_Int16>(aFontDescriptor.Slant)); + break; + case SID_ATTR_CHAR_UNDERLINE: + aFontDescriptor.Underline = awt::FontUnderline::SINGLE - aFontDescriptor.Underline; + break; + default: + OSL_FAIL("Illegal value in default!"); + break; + } + + _xReportControlFormat->setFontDescriptor(aFontDescriptor); + } + catch(const beans::UnknownPropertyException&) + { + } + } +} + + +static void lcl_getReportControlFormat(const Sequence< PropertyValue >& aArgs, + ODesignView* _pView, + uno::Reference< awt::XWindow>& _xWindow, + ::std::vector< uno::Reference< uno::XInterface > >& _rControlsFormats) +{ + uno::Reference< report::XReportControlFormat> xReportControlFormat; + if ( aArgs.hasElements() ) + { + SequenceAsHashMap aMap(aArgs); + xReportControlFormat = aMap.getUnpackedValueOrDefault(REPORTCONTROLFORMAT,uno::Reference< report::XReportControlFormat>()); + _xWindow = aMap.getUnpackedValueOrDefault(CURRENT_WINDOW,uno::Reference< awt::XWindow>()); + } + + if ( !xReportControlFormat.is() ) + { + _pView->fillControlModelSelection(_rControlsFormats); + } + else + { + uno::Reference<uno::XInterface> xInterface(xReportControlFormat); + _rControlsFormats.push_back(xInterface); + } + + if ( !_xWindow.is() ) + _xWindow = VCLUnoHelper::GetInterface(_pView); +} + +OUString SAL_CALL OReportController::getImplementationName() +{ + return "com.sun.star.report.comp.ReportDesign"; +} + +Sequence< OUString> SAL_CALL OReportController::getSupportedServiceNames() +{ + return { "com.sun.star.sdb.ReportDesign" }; +} + +#define PROPERTY_ID_ZOOMVALUE 1 + + +OReportController::OReportController(Reference< XComponentContext > const & xContext) + :OReportController_BASE(xContext) + ,OPropertyStateContainer(OGenericUnoController_Base::rBHelper) + ,m_aSelectionListeners( getMutex() ) + ,m_sMode("normal") + ,m_nSplitPos(-1) + ,m_nPageNum(-1) + ,m_nSelectionCount(0) + ,m_nAspect(0) + ,m_nZoomValue(100) + ,m_eZoomType(SvxZoomType::PERCENT) + ,m_bShowRuler(true) + ,m_bGridVisible(true) + ,m_bGridUse(true) + ,m_bShowProperties(true) + ,m_bHelplinesMove(true) + ,m_bChartEnabled(false) + ,m_bChartEnabledAsked(false) + ,m_bInGeneratePreview(false) +{ + // new Observer + m_pReportControllerObserver = new OXReportControllerObserver(*this); + registerProperty("ZoomValue", PROPERTY_ID_ZOOMVALUE, + beans::PropertyAttribute::BOUND | beans::PropertyAttribute::TRANSIENT, + &m_nZoomValue, ::cppu::UnoType<sal_Int16>::get()); + +} + +OReportController::~OReportController() +{ +} + +IMPLEMENT_FORWARD_XTYPEPROVIDER2(OReportController,OReportController_BASE,OReportController_Listener) +IMPLEMENT_FORWARD_XINTERFACE2(OReportController,OReportController_BASE,OReportController_Listener) + +void OReportController::disposing() +{ + + if ( m_pClipboardNotifier.is() ) + { + m_pClipboardNotifier->ClearCallbackLink(); + m_pClipboardNotifier->RemoveListener( getView() ); + m_pClipboardNotifier.clear(); + } + if ( m_xGroupsFloater ) + { + SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xGroupsFloater->get_help_id(), RTL_TEXTENCODING_UTF8)); + aDlgOpt.SetWindowState(OStringToOUString(m_xGroupsFloater->getDialog()->get_window_state(WindowStateMask::All), RTL_TEXTENCODING_ASCII_US)); + if (m_xGroupsFloater->getDialog()->get_visible()) + m_xGroupsFloater->response(RET_CANCEL); + m_xGroupsFloater.reset(); + } + + try + { + m_xHoldAlive.clear(); + m_xColumns.clear(); + ::comphelper::disposeComponent( m_xRowSet ); + ::comphelper::disposeComponent( m_xRowSetMediator ); + ::comphelper::disposeComponent( m_xFormatter ); + } + catch(const uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while disposing row sets."); + } + m_xRowSet.clear(); + m_xRowSetMediator.clear(); + + if ( m_xReportDefinition.is() ) + { + try + { + OSectionWindow* pSectionWindow = nullptr; + if ( getDesignView() ) + pSectionWindow = getDesignView()->getMarkedSection(); + if ( pSectionWindow ) + pSectionWindow->getReportSection().deactivateOle(); + clearUndoManager(); + if ( m_aReportModel ) + listen(false); + m_pReportControllerObserver->Clear(); + m_pReportControllerObserver.clear(); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + + { + EventObject aDisposingEvent( *this ); + m_aSelectionListeners.disposeAndClear( aDisposingEvent ); + } + + OReportController_BASE::disposing(); + + + try + { + m_xReportDefinition.clear(); + m_aReportModel.reset(); + m_xFrameLoader.clear(); + m_xReportEngine.clear(); + } + catch(const uno::Exception&) + { + } + if ( getDesignView() ) + EndListening( *getDesignView() ); + clearView(); +} + +FeatureState OReportController::GetState(sal_uInt16 _nId) const +{ + FeatureState aReturn; + // (disabled automatically) + aReturn.bEnabled = false; + // check this first + if ( !getView() ) + return aReturn; + + switch (_nId) + { + case SID_RPT_TEXTDOCUMENT: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = (m_xReportDefinition.is() && m_xReportDefinition->getMimeType() == MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII); + break; + case SID_RPT_SPREADSHEET: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = (m_xReportDefinition.is() && m_xReportDefinition->getMimeType() == MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII); + break; + case SID_REPORTHEADER_WITHOUT_UNDO: + case SID_REPORTFOOTER_WITHOUT_UNDO: + case SID_REPORTHEADERFOOTER: + { + aReturn.bEnabled = isEditable(); + OUString sText = RptResId((m_xReportDefinition.is() && m_xReportDefinition->getReportHeaderOn()) ? RID_STR_REPORTHEADERFOOTER_DELETE : RID_STR_REPORTHEADERFOOTER_INSERT); + aReturn.sTitle = sText; + } + break; + case SID_PAGEHEADER_WITHOUT_UNDO: + case SID_PAGEFOOTER_WITHOUT_UNDO: + case SID_PAGEHEADERFOOTER: + { + aReturn.bEnabled = isEditable(); + OUString sText = RptResId((m_xReportDefinition.is() && m_xReportDefinition->getPageHeaderOn()) ? RID_STR_PAGEHEADERFOOTER_DELETE : RID_STR_PAGEHEADERFOOTER_INSERT); + aReturn.sTitle = sText; + } + break; + case SID_GROUP_APPEND: + case SID_GROUP_REMOVE: + case SID_GROUPHEADER_WITHOUT_UNDO: + case SID_GROUPHEADER: + case SID_GROUPFOOTER_WITHOUT_UNDO: + case SID_GROUPFOOTER: + aReturn.bEnabled = isEditable(); + break; + case SID_ADD_CONTROL_PAIR: + aReturn.bEnabled = isEditable(); + break; + case SID_REDO: + case SID_UNDO: + { + size_t ( SfxUndoManager::*retrieveCount )( bool const ) const = + ( _nId == SID_UNDO ) ? &SfxUndoManager::GetUndoActionCount : &SfxUndoManager::GetRedoActionCount; + + SfxUndoManager& rUndoManager( getUndoManager() ); + aReturn.bEnabled = ( rUndoManager.*retrieveCount )( SfxUndoManager::TopLevel ) > 0; + if ( aReturn.bEnabled ) + { + // TODO: add "Undo/Redo: prefix" + OUString ( SfxUndoManager::*retrieveComment )( size_t, bool const ) const = + ( _nId == SID_UNDO ) ? &SfxUndoManager::GetUndoActionComment : &SfxUndoManager::GetRedoActionComment; + aReturn.sTitle = (rUndoManager.*retrieveComment)( 0, SfxUndoManager::TopLevel ); + } + } + break; + case SID_GETUNDOSTRINGS: + case SID_GETREDOSTRINGS: + { + size_t ( SfxUndoManager::*retrieveCount )( bool const ) const = + ( _nId == SID_GETUNDOSTRINGS ) ? &SfxUndoManager::GetUndoActionCount : &SfxUndoManager::GetRedoActionCount; + + OUString ( SfxUndoManager::*retrieveComment )( size_t, bool const ) const = + ( _nId == SID_GETUNDOSTRINGS ) ? &SfxUndoManager::GetUndoActionComment : &SfxUndoManager::GetRedoActionComment; + + SfxUndoManager& rUndoManager( getUndoManager() ); + size_t nCount(( rUndoManager.*retrieveCount )( SfxUndoManager::TopLevel )); + Sequence<OUString> aSeq(nCount); + auto aSeqRange = asNonConstRange(aSeq); + for (size_t n = 0; n < nCount; ++n) + aSeqRange[n] = (rUndoManager.*retrieveComment)( n, SfxUndoManager::TopLevel ); + aReturn.aValue <<= aSeq; + aReturn.bEnabled = true; + } + break; + case SID_OBJECT_RESIZING: + case SID_OBJECT_SMALLESTWIDTH: + case SID_OBJECT_SMALLESTHEIGHT: + case SID_OBJECT_GREATESTWIDTH: + case SID_OBJECT_GREATESTHEIGHT: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection(); + if ( aReturn.bEnabled ) + aReturn.bEnabled = m_nSelectionCount > 1; + break; + + case SID_DISTRIBUTE_HLEFT: + case SID_DISTRIBUTE_HCENTER: + case SID_DISTRIBUTE_HDISTANCE: + case SID_DISTRIBUTE_HRIGHT: + case SID_DISTRIBUTE_VTOP: + case SID_DISTRIBUTE_VCENTER: + case SID_DISTRIBUTE_VDISTANCE: + case SID_DISTRIBUTE_VBOTTOM: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection(); + if ( aReturn.bEnabled ) + { + OSectionView* pSectionView = getCurrentSectionView(); + aReturn.bEnabled = pSectionView && pSectionView->GetMarkedObjectCount() > 2; + } + break; + case SID_ARRANGEMENU: + case SID_FRAME_DOWN: + case SID_FRAME_UP: + case SID_FRAME_TO_TOP: + case SID_FRAME_TO_BOTTOM: + case SID_OBJECT_HEAVEN: + case SID_OBJECT_HELL: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection(); + if ( aReturn.bEnabled ) + { + OSectionView* pSectionView = getCurrentSectionView(); + aReturn.bEnabled = pSectionView && pSectionView->OnlyShapesMarked(); + if ( aReturn.bEnabled ) + { + if ( SID_OBJECT_HEAVEN == _nId ) + aReturn.bEnabled = pSectionView->GetLayerIdOfMarkedObjects() != RPT_LAYER_FRONT; + else if ( SID_OBJECT_HELL == _nId ) + aReturn.bEnabled = pSectionView->GetLayerIdOfMarkedObjects() != RPT_LAYER_BACK; + } + } + break; + + case SID_SECTION_SHRINK: + case SID_SECTION_SHRINK_TOP: + case SID_SECTION_SHRINK_BOTTOM: + { + sal_Int32 nCount = 0; + uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection(); + if ( xSection.is() ) + { + nCount = xSection->getCount(); + } + aReturn.bEnabled = isEditable() && nCount > 0; + } + break; + case SID_OBJECT_ALIGN: + case SID_OBJECT_ALIGN_LEFT: + case SID_OBJECT_ALIGN_CENTER: + case SID_OBJECT_ALIGN_RIGHT: + case SID_OBJECT_ALIGN_UP: + case SID_OBJECT_ALIGN_MIDDLE: + case SID_OBJECT_ALIGN_DOWN: + case SID_SECTION_ALIGN: + case SID_SECTION_ALIGN_LEFT: + case SID_SECTION_ALIGN_CENTER: + case SID_SECTION_ALIGN_RIGHT: + case SID_SECTION_ALIGN_UP: + case SID_SECTION_ALIGN_MIDDLE: + case SID_SECTION_ALIGN_DOWN: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection(); + break; + case SID_CUT: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection() && !getDesignView()->isHandleEvent(); + break; + case SID_COPY: + aReturn.bEnabled = getDesignView()->HasSelection() && !getDesignView()->isHandleEvent(); + break; + case SID_PASTE: + aReturn.bEnabled = isEditable() && !getDesignView()->isHandleEvent() && getDesignView()->IsPasteAllowed(); + break; + case SID_SELECTALL: + aReturn.bEnabled = !getDesignView()->isHandleEvent(); + break; + case SID_SELECTALL_IN_SECTION: + aReturn.bEnabled = !getDesignView()->isHandleEvent(); + if ( aReturn.bEnabled ) + aReturn.bEnabled = getCurrentSectionView() != nullptr; + break; + case SID_ESCAPE: + aReturn.bEnabled = getDesignView()->GetMode() == DlgEdMode::Insert; + break; + case SID_TERMINATE_INPLACEACTIVATION: + aReturn.bEnabled = true; + break; + case SID_SELECT_ALL_EDITS: + case SID_SELECT_ALL_LABELS: + aReturn.bEnabled = true; + break; + case SID_RPT_NEW_FUNCTION: + aReturn.bEnabled = isEditable(); + break; + case SID_COLLAPSE_SECTION: + case SID_EXPAND_SECTION: + case SID_NEXT_MARK: + case SID_PREV_MARK: + aReturn.bEnabled = isEditable() && !getDesignView()->isHandleEvent(); + break; + case SID_SELECT: + case SID_SELECT_REPORT: + aReturn.bEnabled = true; + break; + case SID_EXECUTE_REPORT: + aReturn.bEnabled = isConnected() && m_xReportDefinition.is(); + break; + case SID_DELETE: + aReturn.bEnabled = isEditable() && getDesignView()->HasSelection() && !getDesignView()->isHandleEvent(); + if ( aReturn.bEnabled ) + { + OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection(); + if ( pSectionWindow ) + aReturn.bEnabled = !pSectionWindow->getReportSection().isUiActive(); + } + { + OUString sText = RptResId(RID_STR_DELETE); + aReturn.sTitle = sText; + } + break; + case SID_GRID_VISIBLE: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = m_bGridVisible; + break; + case SID_GRID_USE: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = m_bGridUse; + break; + case SID_HELPLINES_MOVE: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = m_bHelplinesMove; + break; + case SID_RULER: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = m_bShowRuler; + break; + case SID_OBJECT_SELECT: + aReturn.bEnabled = true; + aReturn.bChecked = getDesignView()->GetMode() == DlgEdMode::Select; + break; + case SID_INSERT_DIAGRAM: + aReturn.bEnabled = isEditable(); + aReturn.bInvisible = !m_bChartEnabled; + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::OLE2; + break; + case SID_FM_FIXEDTEXT: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignFixedText; + break; + case SID_INSERT_HFIXEDLINE: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignHorizontalFixedLine; + break; + case SID_INSERT_VFIXEDLINE: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignVerticalFixedLine; + break; + case SID_FM_EDIT: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignFormattedField; + break; + case SID_FM_IMAGECONTROL: + aReturn.bEnabled = isEditable(); + aReturn.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::ReportDesignImageControl; + break; + case SID_DRAWTBX_CS_BASIC: + case SID_DRAWTBX_CS_BASIC1: + case SID_DRAWTBX_CS_BASIC2: + case SID_DRAWTBX_CS_BASIC3: + case SID_DRAWTBX_CS_BASIC4: + case SID_DRAWTBX_CS_BASIC5: + case SID_DRAWTBX_CS_BASIC6: + case SID_DRAWTBX_CS_BASIC7: + case SID_DRAWTBX_CS_BASIC8: + case SID_DRAWTBX_CS_BASIC9: + case SID_DRAWTBX_CS_BASIC10: + case SID_DRAWTBX_CS_BASIC11: + case SID_DRAWTBX_CS_BASIC12: + case SID_DRAWTBX_CS_BASIC13: + case SID_DRAWTBX_CS_BASIC14: + case SID_DRAWTBX_CS_BASIC15: + case SID_DRAWTBX_CS_BASIC16: + case SID_DRAWTBX_CS_BASIC17: + case SID_DRAWTBX_CS_BASIC18: + case SID_DRAWTBX_CS_BASIC19: + case SID_DRAWTBX_CS_BASIC20: + case SID_DRAWTBX_CS_BASIC21: + case SID_DRAWTBX_CS_BASIC22: + impl_fillCustomShapeState_nothrow("diamond",aReturn); + break; + case SID_DRAWTBX_CS_SYMBOL: + case SID_DRAWTBX_CS_SYMBOL1: + case SID_DRAWTBX_CS_SYMBOL2: + case SID_DRAWTBX_CS_SYMBOL3: + case SID_DRAWTBX_CS_SYMBOL4: + case SID_DRAWTBX_CS_SYMBOL5: + case SID_DRAWTBX_CS_SYMBOL6: + case SID_DRAWTBX_CS_SYMBOL7: + case SID_DRAWTBX_CS_SYMBOL8: + case SID_DRAWTBX_CS_SYMBOL9: + case SID_DRAWTBX_CS_SYMBOL10: + case SID_DRAWTBX_CS_SYMBOL11: + case SID_DRAWTBX_CS_SYMBOL12: + case SID_DRAWTBX_CS_SYMBOL13: + case SID_DRAWTBX_CS_SYMBOL14: + case SID_DRAWTBX_CS_SYMBOL15: + case SID_DRAWTBX_CS_SYMBOL16: + case SID_DRAWTBX_CS_SYMBOL17: + case SID_DRAWTBX_CS_SYMBOL18: + impl_fillCustomShapeState_nothrow("smiley",aReturn); + break; + case SID_DRAWTBX_CS_ARROW: + case SID_DRAWTBX_CS_ARROW1: + case SID_DRAWTBX_CS_ARROW2: + case SID_DRAWTBX_CS_ARROW3: + case SID_DRAWTBX_CS_ARROW4: + case SID_DRAWTBX_CS_ARROW5: + case SID_DRAWTBX_CS_ARROW6: + case SID_DRAWTBX_CS_ARROW7: + case SID_DRAWTBX_CS_ARROW8: + case SID_DRAWTBX_CS_ARROW9: + case SID_DRAWTBX_CS_ARROW10: + case SID_DRAWTBX_CS_ARROW11: + case SID_DRAWTBX_CS_ARROW12: + case SID_DRAWTBX_CS_ARROW13: + case SID_DRAWTBX_CS_ARROW14: + case SID_DRAWTBX_CS_ARROW15: + case SID_DRAWTBX_CS_ARROW16: + case SID_DRAWTBX_CS_ARROW17: + case SID_DRAWTBX_CS_ARROW18: + case SID_DRAWTBX_CS_ARROW19: + case SID_DRAWTBX_CS_ARROW20: + case SID_DRAWTBX_CS_ARROW21: + case SID_DRAWTBX_CS_ARROW22: + case SID_DRAWTBX_CS_ARROW23: + case SID_DRAWTBX_CS_ARROW24: + case SID_DRAWTBX_CS_ARROW25: + case SID_DRAWTBX_CS_ARROW26: + impl_fillCustomShapeState_nothrow("left-right-arrow",aReturn); + break; + case SID_DRAWTBX_CS_STAR: + case SID_DRAWTBX_CS_STAR1: + case SID_DRAWTBX_CS_STAR2: + case SID_DRAWTBX_CS_STAR3: + case SID_DRAWTBX_CS_STAR4: + case SID_DRAWTBX_CS_STAR5: + case SID_DRAWTBX_CS_STAR6: + case SID_DRAWTBX_CS_STAR7: + case SID_DRAWTBX_CS_STAR8: + case SID_DRAWTBX_CS_STAR9: + case SID_DRAWTBX_CS_STAR10: + case SID_DRAWTBX_CS_STAR11: + case SID_DRAWTBX_CS_STAR12: + impl_fillCustomShapeState_nothrow("star5",aReturn); + break; + case SID_DRAWTBX_CS_FLOWCHART: + case SID_DRAWTBX_CS_FLOWCHART1: + case SID_DRAWTBX_CS_FLOWCHART2: + case SID_DRAWTBX_CS_FLOWCHART3: + case SID_DRAWTBX_CS_FLOWCHART4: + case SID_DRAWTBX_CS_FLOWCHART5: + case SID_DRAWTBX_CS_FLOWCHART6: + case SID_DRAWTBX_CS_FLOWCHART7: + case SID_DRAWTBX_CS_FLOWCHART8: + case SID_DRAWTBX_CS_FLOWCHART9: + case SID_DRAWTBX_CS_FLOWCHART10: + case SID_DRAWTBX_CS_FLOWCHART11: + case SID_DRAWTBX_CS_FLOWCHART12: + case SID_DRAWTBX_CS_FLOWCHART13: + case SID_DRAWTBX_CS_FLOWCHART14: + case SID_DRAWTBX_CS_FLOWCHART15: + case SID_DRAWTBX_CS_FLOWCHART16: + case SID_DRAWTBX_CS_FLOWCHART17: + case SID_DRAWTBX_CS_FLOWCHART18: + case SID_DRAWTBX_CS_FLOWCHART19: + case SID_DRAWTBX_CS_FLOWCHART20: + case SID_DRAWTBX_CS_FLOWCHART21: + case SID_DRAWTBX_CS_FLOWCHART22: + case SID_DRAWTBX_CS_FLOWCHART23: + case SID_DRAWTBX_CS_FLOWCHART24: + case SID_DRAWTBX_CS_FLOWCHART25: + case SID_DRAWTBX_CS_FLOWCHART26: + case SID_DRAWTBX_CS_FLOWCHART27: + case SID_DRAWTBX_CS_FLOWCHART28: + impl_fillCustomShapeState_nothrow("flowchart-internal-storage",aReturn); + break; + case SID_DRAWTBX_CS_CALLOUT: + case SID_DRAWTBX_CS_CALLOUT1: + case SID_DRAWTBX_CS_CALLOUT2: + case SID_DRAWTBX_CS_CALLOUT3: + case SID_DRAWTBX_CS_CALLOUT4: + case SID_DRAWTBX_CS_CALLOUT5: + case SID_DRAWTBX_CS_CALLOUT6: + case SID_DRAWTBX_CS_CALLOUT7: + impl_fillCustomShapeState_nothrow("round-rectangular-callout",aReturn); + break; + case SID_RPT_SHOWREPORTEXPLORER: + aReturn.bEnabled = m_xReportDefinition.is(); + aReturn.bChecked = getDesignView() && getDesignView()->isReportExplorerVisible(); + break; + case SID_FM_ADD_FIELD: + aReturn.bEnabled = isConnected() && isEditable() && m_xReportDefinition.is() + && !m_xReportDefinition->getCommand().isEmpty(); + aReturn.bChecked = getDesignView() && getDesignView()->isAddFieldVisible(); + break; + case SID_SHOW_PROPERTYBROWSER: + aReturn.bEnabled = true; + aReturn.bChecked = m_bShowProperties; + break; + case SID_PROPERTYBROWSER_LAST_PAGE: + aReturn.bEnabled = true; + aReturn.aValue <<= m_sLastActivePage; + break; + case SID_SPLIT_POSITION: + aReturn.bEnabled = true; + aReturn.aValue <<= getSplitPos(); + break; + case SID_SAVEDOC: + case SID_SAVEASDOC: + case SID_SAVEACOPY: + aReturn.bEnabled = isConnected() && isEditable(); + break; + case SID_EDITDOC: + aReturn.bChecked = isEditable(); + break; + case SID_PAGEDIALOG: + aReturn.bEnabled = isEditable(); + break; + case SID_BACKGROUND_COLOR: + impl_fillState_nothrow(PROPERTY_CONTROLBACKGROUND,aReturn); + break; + case SID_ATTR_CHAR_COLOR_BACKGROUND: + aReturn.bEnabled = isEditable(); + { + uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection(); + if ( xSection.is() ) + try + { + aReturn.aValue <<= xSection->getBackColor(); + const uno::Reference< report::XReportControlModel> xControlModel(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY); + aReturn.bEnabled = !xControlModel.is(); + } + catch(const beans::UnknownPropertyException&) + { + } + else + aReturn.bEnabled = false; + } + break; + case SID_SORTINGANDGROUPING: + aReturn.bEnabled = true; + aReturn.bChecked = m_xGroupsFloater && m_xGroupsFloater->getDialog()->get_visible(); + break; + case SID_ATTR_CHAR_WEIGHT: + case SID_ATTR_CHAR_POSTURE: + case SID_ATTR_CHAR_UNDERLINE: + impl_fillState_nothrow(PROPERTY_FONTDESCRIPTOR,aReturn); + if ( aReturn.bEnabled ) + { + awt::FontDescriptor aFontDescriptor; + aReturn.aValue >>= aFontDescriptor; + aReturn.aValue.clear(); + + switch(_nId) + { + case SID_ATTR_CHAR_WEIGHT: + aReturn.bChecked = awt::FontWeight::BOLD == aFontDescriptor.Weight; + break; + case SID_ATTR_CHAR_POSTURE: + aReturn.bChecked = awt::FontSlant_ITALIC == aFontDescriptor.Slant; + break; + case SID_ATTR_CHAR_UNDERLINE: + aReturn.bChecked = awt::FontUnderline::SINGLE == aFontDescriptor.Underline; + break; + default: + ; + } + } + break; + case SID_ATTR_CHAR_COLOR: + case SID_ATTR_CHAR_COLOR2: + impl_fillState_nothrow(PROPERTY_CHARCOLOR,aReturn); + break; + case SID_ATTR_CHAR_FONT: + impl_fillState_nothrow(PROPERTY_FONTDESCRIPTOR,aReturn); + break; + case SID_ATTR_CHAR_FONTHEIGHT: + impl_fillState_nothrow(PROPERTY_CHARHEIGHT,aReturn); + if ( aReturn.aValue.hasValue() ) + { + frame::status::FontHeight aFontHeight; + aReturn.aValue >>= aFontHeight.Height; + aReturn.aValue <<= aFontHeight; // another type is needed here, so + } + break; + case SID_ATTR_PARA_ADJUST_LEFT: + case SID_ATTR_PARA_ADJUST_CENTER: + case SID_ATTR_PARA_ADJUST_RIGHT: + case SID_ATTR_PARA_ADJUST_BLOCK: + impl_fillState_nothrow(PROPERTY_PARAADJUST,aReturn); + if ( aReturn.bEnabled ) + { + ::sal_Int16 nParaAdjust = 0; + if ( aReturn.aValue >>= nParaAdjust ) + { + switch(static_cast<style::ParagraphAdjust>(nParaAdjust)) + { + case style::ParagraphAdjust_LEFT: + aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_LEFT; + break; + case style::ParagraphAdjust_RIGHT: + aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_RIGHT; + break; + case style::ParagraphAdjust_BLOCK: + case style::ParagraphAdjust_STRETCH: + aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_BLOCK; + break; + case style::ParagraphAdjust_CENTER: + aReturn.bChecked = _nId == SID_ATTR_PARA_ADJUST_CENTER; + break; + default: break; + } + } + aReturn.aValue.clear(); + } + break; + + case SID_INSERT_GRAPHIC: + aReturn.bEnabled = m_xReportDefinition.is() && isEditable() && getDesignView()->getCurrentSection().is(); + break; + case SID_CHAR_DLG: + case SID_SETCONTROLDEFAULTS: + aReturn.bEnabled = m_xReportDefinition.is() && isEditable(); + if ( aReturn.bEnabled ) + { + ::std::vector< uno::Reference< uno::XInterface > > aSelection; + getDesignView()->fillControlModelSelection(aSelection); + aReturn.bEnabled = !aSelection.empty() + && std::all_of(aSelection.begin(), aSelection.end(), [](const uno::Reference<uno::XInterface>& rxInterface) { + return !uno::Reference<report::XFixedLine>(rxInterface, uno::UNO_QUERY).is() + && !uno::Reference<report::XImageControl>(rxInterface, uno::UNO_QUERY).is() + && uno::Reference<report::XReportControlFormat>(rxInterface, uno::UNO_QUERY).is(); }); + } + break; + case SID_CONDITIONALFORMATTING: + { + const uno::Reference< report::XFormattedField> xFormattedField(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY); + aReturn.bEnabled = xFormattedField.is(); + } + break; + case SID_INSERT_FLD_PGNUMBER: + case SID_DATETIME: + aReturn.bEnabled = m_xReportDefinition.is() && isEditable() && getDesignView()->getCurrentSection().is(); + break; + case SID_EXPORTDOC: + case SID_EXPORTDOCASPDF: + aReturn.bEnabled = m_xReportDefinition.is(); + break; + case SID_PRINTPREVIEW: + aReturn.bEnabled = false; + break; + case SID_ATTR_ZOOM: + aReturn.bEnabled = true; + { + SvxZoomItem aZoom(m_eZoomType,m_nZoomValue); + aZoom.SetValueSet(SvxZoomEnableFlags::N50|SvxZoomEnableFlags::N75|SvxZoomEnableFlags::N100|SvxZoomEnableFlags::N200); + aZoom.QueryValue(aReturn.aValue); + } + break; + case SID_ATTR_ZOOMSLIDER: + aReturn.bEnabled = true; + { + SvxZoomSliderItem aZoomSlider(m_nZoomValue,20,400); + aZoomSlider.AddSnappingPoint(50); + aZoomSlider.AddSnappingPoint(75); + aZoomSlider.AddSnappingPoint(100); + aZoomSlider.AddSnappingPoint(200); + aZoomSlider.QueryValue(aReturn.aValue); + } + break; + default: + aReturn = OReportController_BASE::GetState(_nId); + } + return aReturn; +} + + +namespace +{ + /** extracts a background color from a dispatched SID_BACKGROUND_COLOR call + + The dispatch might originate from either the toolbar, or the conditional + formatting dialog. In both cases, argument formats are different. + */ + util::Color lcl_extractBackgroundColor( const Sequence< PropertyValue >& _rDispatchArgs ) + { + util::Color aColor( COL_TRANSPARENT ); + if ( _rDispatchArgs.getLength() == 1 ) + { + OSL_VERIFY( _rDispatchArgs[0].Value >>= aColor ); + } + else + { + SequenceAsHashMap aMap( _rDispatchArgs ); + aColor = aMap.getUnpackedValueOrDefault( PROPERTY_FONTCOLOR, aColor ); + } + return aColor; + } +} + + +void OReportController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + bool bForceBroadcast = false; + switch(_nId) + { + case SID_RPT_TEXTDOCUMENT: + if ( m_xReportDefinition.is() ) + m_xReportDefinition->setMimeType( MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ); + break; + case SID_RPT_SPREADSHEET: + if (m_xReportDefinition.is() ) + m_xReportDefinition->setMimeType( MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ); + break; + case SID_REPORTHEADER_WITHOUT_UNDO: + case SID_REPORTFOOTER_WITHOUT_UNDO: + case SID_REPORTHEADERFOOTER: + switchReportSection(_nId); + break; + case SID_PAGEHEADER_WITHOUT_UNDO: + case SID_PAGEFOOTER_WITHOUT_UNDO: + case SID_PAGEHEADERFOOTER: + switchPageSection(_nId); + break; + case SID_GROUP_APPEND: + case SID_GROUP_REMOVE: + modifyGroup(_nId == SID_GROUP_APPEND,aArgs); + break; + case SID_GROUPHEADER_WITHOUT_UNDO: + case SID_GROUPHEADER: + createGroupSection(SID_GROUPHEADER == _nId,true,aArgs); + break; + case SID_GROUPFOOTER_WITHOUT_UNDO: + case SID_GROUPFOOTER: + createGroupSection(SID_GROUPFOOTER == _nId,false,aArgs); + break; + case SID_ADD_CONTROL_PAIR: + addPairControls(aArgs); + break; + case SID_REDO: + case SID_UNDO: + { + const OXUndoEnvironment::OUndoMode aLock( m_aReportModel->GetUndoEnv() ); + bool ( SfxUndoManager::*doXDo )() = + ( _nId == SID_UNDO ) ? &SfxUndoManager::Undo : &SfxUndoManager::Redo; + SfxUndoManager& rUndoManager( getUndoManager() ); + + sal_Int16 nCount(1); + if (aArgs.hasElements() && aArgs[0].Name != "KeyModifier") + aArgs[0].Value >>= nCount; + while (nCount--) + (rUndoManager.*doXDo)(); + InvalidateAll(); + if (m_xGroupsFloater && m_xGroupsFloater->getDialog()->get_visible()) + m_xGroupsFloater->UpdateData(); + } + break; + case SID_CUT: + executeMethodWithUndo(RID_STR_UNDO_REMOVE_SELECTION,::std::mem_fn(&ODesignView::Cut)); + break; + case SID_COPY: + getDesignView()->Copy(); + break; + case SID_PASTE: + executeMethodWithUndo(RID_STR_UNDO_PASTE,::std::mem_fn(&ODesignView::Paste)); + break; + + case SID_FRAME_TO_TOP: + case SID_FRAME_DOWN: + case SID_FRAME_UP: + case SID_FRAME_TO_BOTTOM: + case SID_OBJECT_HEAVEN: + case SID_OBJECT_HELL: + changeZOrder(_nId); + break; + case SID_DISTRIBUTE_HLEFT: + case SID_DISTRIBUTE_HCENTER: + case SID_DISTRIBUTE_HDISTANCE: + case SID_DISTRIBUTE_HRIGHT: + case SID_DISTRIBUTE_VTOP: + case SID_DISTRIBUTE_VCENTER: + case SID_DISTRIBUTE_VDISTANCE: + case SID_DISTRIBUTE_VBOTTOM: + { + OSectionView* pSectionView = getCurrentSectionView(); + if ( pSectionView ) + pSectionView->DistributeMarkedObjects(_nId); + } + break; + case SID_OBJECT_SMALLESTWIDTH: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::WIDTH_SMALLEST); + break; + case SID_OBJECT_SMALLESTHEIGHT: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::HEIGHT_SMALLEST); + break; + case SID_OBJECT_GREATESTWIDTH: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::WIDTH_GREATEST); + break; + case SID_OBJECT_GREATESTHEIGHT: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::HEIGHT_GREATEST); + break; + case SID_SECTION_ALIGN_LEFT: + case SID_OBJECT_ALIGN_LEFT: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::LEFT,SID_SECTION_ALIGN_LEFT == _nId); + break; + case SID_SECTION_ALIGN_CENTER: + case SID_OBJECT_ALIGN_CENTER: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::CENTER_HORIZONTAL,SID_SECTION_ALIGN_CENTER == _nId); + break; + case SID_SECTION_ALIGN_RIGHT: + case SID_OBJECT_ALIGN_RIGHT: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::RIGHT,SID_SECTION_ALIGN_RIGHT == _nId); + break; + case SID_SECTION_ALIGN_UP: + case SID_OBJECT_ALIGN_UP: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::TOP,SID_SECTION_ALIGN_UP == _nId); + break; + case SID_SECTION_ALIGN_MIDDLE: + case SID_OBJECT_ALIGN_MIDDLE: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::CENTER_VERTICAL,SID_SECTION_ALIGN_MIDDLE == _nId); + break; + case SID_SECTION_ALIGN_DOWN: + case SID_OBJECT_ALIGN_DOWN: + alignControlsWithUndo(RID_STR_UNDO_ALIGNMENT,ControlModification::BOTTOM,SID_SECTION_ALIGN_DOWN == _nId); + break; + + case SID_SECTION_SHRINK_BOTTOM: + case SID_SECTION_SHRINK_TOP: + case SID_SECTION_SHRINK: + { + uno::Reference<report::XSection> xSection = getDesignView()->getCurrentSection(); + shrinkSection(RID_STR_UNDO_SHRINK, xSection, _nId); + } + break; + + case SID_SELECTALL: + getDesignView()->SelectAll(SdrObjKind::NONE); + break; + case SID_SELECTALL_IN_SECTION: + { + OSectionView* pSectionView = getCurrentSectionView(); + if ( pSectionView ) + pSectionView->MarkAll(); + } + break; + case SID_ESCAPE: + getDesignView()->SetMode(DlgEdMode::Select); + InvalidateFeature( SID_OBJECT_SELECT ); + break; + case SID_SELECT_ALL_EDITS: + getDesignView()->SelectAll(SdrObjKind::ReportDesignFormattedField); + break; + case SID_SELECT_ALL_LABELS: + getDesignView()->SelectAll(SdrObjKind::ReportDesignFixedText); + break; + case SID_TERMINATE_INPLACEACTIVATION: + { + OSectionWindow* pSection = getDesignView()->getMarkedSection(); + if ( pSection ) + pSection->getReportSection().deactivateOle(); + } + break; + case SID_SELECT: + if ( aArgs.getLength() == 1 ) + select(aArgs[0].Value); + break; + case SID_SELECT_REPORT: + select(uno::Any(m_xReportDefinition)); + break; + case SID_EXECUTE_REPORT: + getView()->PostUserEvent(LINK(this, OReportController,OnExecuteReport)); + break; + case SID_RPT_NEW_FUNCTION: + createNewFunction(aArgs[0].Value); + break; + case SID_COLLAPSE_SECTION: + collapseSection(true); + break; + case SID_EXPAND_SECTION: + collapseSection(false); + break; + case SID_NEXT_MARK: + markSection(true); + break; + case SID_PREV_MARK: + markSection(false); + break; + case SID_DELETE: + if ( aArgs.getLength() == 1 ) + { + uno::Reference< report::XFunction> xFunction; + aArgs[0].Value >>= xFunction; + if ( xFunction.is() ) + { + uno::Reference< report::XFunctions> xFunctions(xFunction->getParent(),uno::UNO_QUERY_THROW); + sal_Int32 nIndex = getPositionInIndexAccess(xFunctions, xFunction); + const OUString sUndoAction = RptResId(RID_STR_UNDO_REMOVE_FUNCTION); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + xFunctions->removeByIndex(nIndex); + select(uno::Any(xFunctions->getParent())); + InvalidateFeature( SID_UNDO ); + } + } + else + executeMethodWithUndo(RID_STR_UNDO_REMOVE_SELECTION,::std::mem_fn(&ODesignView::Delete)); + break; + case SID_GRID_USE: + m_bGridUse = !m_bGridUse; + getDesignView()->setGridSnap(m_bGridUse); + break; + case SID_HELPLINES_MOVE: + m_bHelplinesMove = !m_bHelplinesMove; + getDesignView()->setDragStripes(m_bHelplinesMove); + break; + case SID_GRID_VISIBLE: + m_bGridVisible = !m_bGridVisible; + getDesignView()->toggleGrid(m_bGridVisible); + break; + case SID_RULER: + m_bShowRuler = !m_bShowRuler; + getDesignView()->showRuler(m_bShowRuler); + break; + case SID_OBJECT_SELECT: + getDesignView()->SetMode(DlgEdMode::Select); + InvalidateAll(); + break; + case SID_INSERT_DIAGRAM: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::OLE2); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_FM_FIXEDTEXT: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::ReportDesignFixedText ); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_INSERT_HFIXEDLINE: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::ReportDesignHorizontalFixedLine ); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_INSERT_VFIXEDLINE: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::ReportDesignVerticalFixedLine ); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_FM_EDIT: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::ReportDesignFormattedField ); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_FM_IMAGECONTROL: + getDesignView()->SetMode( DlgEdMode::Insert ); + getDesignView()->SetInsertObj( SdrObjKind::ReportDesignImageControl ); + createDefaultControl(aArgs); + InvalidateAll(); + break; + case SID_DRAWTBX_CS_BASIC: + case SID_DRAWTBX_CS_BASIC1: + case SID_DRAWTBX_CS_BASIC2: + case SID_DRAWTBX_CS_BASIC3: + case SID_DRAWTBX_CS_BASIC4: + case SID_DRAWTBX_CS_BASIC5: + case SID_DRAWTBX_CS_BASIC6: + case SID_DRAWTBX_CS_BASIC7: + case SID_DRAWTBX_CS_BASIC8: + case SID_DRAWTBX_CS_BASIC9: + case SID_DRAWTBX_CS_BASIC10: + case SID_DRAWTBX_CS_BASIC11: + case SID_DRAWTBX_CS_BASIC12: + case SID_DRAWTBX_CS_BASIC13: + case SID_DRAWTBX_CS_BASIC14: + case SID_DRAWTBX_CS_BASIC15: + case SID_DRAWTBX_CS_BASIC16: + case SID_DRAWTBX_CS_BASIC17: + case SID_DRAWTBX_CS_BASIC18: + case SID_DRAWTBX_CS_BASIC19: + case SID_DRAWTBX_CS_BASIC20: + case SID_DRAWTBX_CS_BASIC21: + case SID_DRAWTBX_CS_BASIC22: + case SID_DRAWTBX_CS_SYMBOL1: + case SID_DRAWTBX_CS_SYMBOL2: + case SID_DRAWTBX_CS_SYMBOL3: + case SID_DRAWTBX_CS_SYMBOL4: + case SID_DRAWTBX_CS_SYMBOL5: + case SID_DRAWTBX_CS_SYMBOL6: + case SID_DRAWTBX_CS_SYMBOL7: + case SID_DRAWTBX_CS_SYMBOL8: + case SID_DRAWTBX_CS_SYMBOL9: + case SID_DRAWTBX_CS_SYMBOL10: + case SID_DRAWTBX_CS_SYMBOL11: + case SID_DRAWTBX_CS_SYMBOL12: + case SID_DRAWTBX_CS_SYMBOL13: + case SID_DRAWTBX_CS_SYMBOL14: + case SID_DRAWTBX_CS_SYMBOL15: + case SID_DRAWTBX_CS_SYMBOL16: + case SID_DRAWTBX_CS_SYMBOL17: + case SID_DRAWTBX_CS_SYMBOL18: + case SID_DRAWTBX_CS_ARROW1: + case SID_DRAWTBX_CS_ARROW2: + case SID_DRAWTBX_CS_ARROW3: + case SID_DRAWTBX_CS_ARROW4: + case SID_DRAWTBX_CS_ARROW5: + case SID_DRAWTBX_CS_ARROW6: + case SID_DRAWTBX_CS_ARROW7: + case SID_DRAWTBX_CS_ARROW8: + case SID_DRAWTBX_CS_ARROW9: + case SID_DRAWTBX_CS_ARROW10: + case SID_DRAWTBX_CS_ARROW11: + case SID_DRAWTBX_CS_ARROW12: + case SID_DRAWTBX_CS_ARROW13: + case SID_DRAWTBX_CS_ARROW14: + case SID_DRAWTBX_CS_ARROW15: + case SID_DRAWTBX_CS_ARROW16: + case SID_DRAWTBX_CS_ARROW17: + case SID_DRAWTBX_CS_ARROW18: + case SID_DRAWTBX_CS_ARROW19: + case SID_DRAWTBX_CS_ARROW20: + case SID_DRAWTBX_CS_ARROW21: + case SID_DRAWTBX_CS_ARROW22: + case SID_DRAWTBX_CS_ARROW23: + case SID_DRAWTBX_CS_ARROW24: + case SID_DRAWTBX_CS_ARROW25: + case SID_DRAWTBX_CS_ARROW26: + case SID_DRAWTBX_CS_STAR1: + case SID_DRAWTBX_CS_STAR2: + case SID_DRAWTBX_CS_STAR3: + case SID_DRAWTBX_CS_STAR4: + case SID_DRAWTBX_CS_STAR5: + case SID_DRAWTBX_CS_STAR6: + case SID_DRAWTBX_CS_STAR7: + case SID_DRAWTBX_CS_STAR8: + case SID_DRAWTBX_CS_STAR9: + case SID_DRAWTBX_CS_STAR10: + case SID_DRAWTBX_CS_STAR11: + case SID_DRAWTBX_CS_STAR12: + case SID_DRAWTBX_CS_FLOWCHART1: + case SID_DRAWTBX_CS_FLOWCHART2: + case SID_DRAWTBX_CS_FLOWCHART3: + case SID_DRAWTBX_CS_FLOWCHART4: + case SID_DRAWTBX_CS_FLOWCHART5: + case SID_DRAWTBX_CS_FLOWCHART6: + case SID_DRAWTBX_CS_FLOWCHART7: + case SID_DRAWTBX_CS_FLOWCHART8: + case SID_DRAWTBX_CS_FLOWCHART9: + case SID_DRAWTBX_CS_FLOWCHART10: + case SID_DRAWTBX_CS_FLOWCHART11: + case SID_DRAWTBX_CS_FLOWCHART12: + case SID_DRAWTBX_CS_FLOWCHART13: + case SID_DRAWTBX_CS_FLOWCHART14: + case SID_DRAWTBX_CS_FLOWCHART15: + case SID_DRAWTBX_CS_FLOWCHART16: + case SID_DRAWTBX_CS_FLOWCHART17: + case SID_DRAWTBX_CS_FLOWCHART18: + case SID_DRAWTBX_CS_FLOWCHART19: + case SID_DRAWTBX_CS_FLOWCHART20: + case SID_DRAWTBX_CS_FLOWCHART21: + case SID_DRAWTBX_CS_FLOWCHART22: + case SID_DRAWTBX_CS_FLOWCHART23: + case SID_DRAWTBX_CS_FLOWCHART24: + case SID_DRAWTBX_CS_FLOWCHART25: + case SID_DRAWTBX_CS_FLOWCHART26: + case SID_DRAWTBX_CS_FLOWCHART27: + case SID_DRAWTBX_CS_FLOWCHART28: + case SID_DRAWTBX_CS_CALLOUT1: + case SID_DRAWTBX_CS_CALLOUT2: + case SID_DRAWTBX_CS_CALLOUT3: + case SID_DRAWTBX_CS_CALLOUT4: + case SID_DRAWTBX_CS_CALLOUT5: + case SID_DRAWTBX_CS_CALLOUT6: + case SID_DRAWTBX_CS_CALLOUT7: + case SID_DRAWTBX_CS_SYMBOL: + case SID_DRAWTBX_CS_ARROW: + case SID_DRAWTBX_CS_FLOWCHART: + case SID_DRAWTBX_CS_CALLOUT: + case SID_DRAWTBX_CS_STAR: + getDesignView()->SetMode( DlgEdMode::Insert ); + { + URL aUrl = getURLForId(_nId); + sal_Int32 nIndex = 1; + std::u16string_view sType = o3tl::getToken(aUrl.Complete, 0,'.',nIndex); + if ( nIndex == -1 || sType.empty() ) + { + switch(_nId) + { + case SID_DRAWTBX_CS_SYMBOL: + sType = u"smiley"; + break; + case SID_DRAWTBX_CS_ARROW: + sType = u"left-right-arrow"; + break; + case SID_DRAWTBX_CS_FLOWCHART: + sType = u"flowchart-internal-storage"; + break; + case SID_DRAWTBX_CS_CALLOUT: + sType = u"round-rectangular-callout"; + break; + case SID_DRAWTBX_CS_STAR: + sType = u"star5"; + break; + default: + sType = u"diamond"; + } + } + else + sType = o3tl::getToken(aUrl.Complete, 0,'.',nIndex); + + getDesignView()->SetInsertObj( SdrObjKind::CustomShape, OUString(sType)); + createDefaultControl(aArgs); + } + InvalidateAll(); + break; + case SID_RPT_SHOWREPORTEXPLORER: + if ( isUiVisible() ) + getDesignView()->toggleReportExplorer(); + break; + case SID_FM_ADD_FIELD: + if ( isUiVisible() ) + getDesignView()->toggleAddField(); + break; + case SID_SHOW_PROPERTYBROWSER: + if ( m_bShowProperties ) + m_sLastActivePage = getDesignView()->getCurrentPage(); + else + getDesignView()->setCurrentPage(m_sLastActivePage); + + if ( isUiVisible() ) + { + m_bShowProperties = !m_bShowProperties; + if ( aArgs.getLength() == 1 ) + aArgs[0].Value >>= m_bShowProperties; + + getDesignView()->togglePropertyBrowser(m_bShowProperties); + } + break; + case SID_PROPERTYBROWSER_LAST_PAGE: // nothing to do + m_sLastActivePage = getDesignView()->getCurrentPage(); + break; + case SID_SPLIT_POSITION: + getDesignView()->Resize(); + break; + case SID_PAGEDIALOG: + case SID_ATTR_CHAR_COLOR_BACKGROUND: + { + uno::Reference<report::XSection> xSection; + if (aArgs.getLength() == 1 ) + aArgs[0].Value >>= xSection; + else if (_nId == SID_ATTR_CHAR_COLOR_BACKGROUND) + xSection.set(getDesignView()->getMarkedSection()->getReportSection().getSection()); + openPageDialog(xSection); + bForceBroadcast = true; + } + break; + case SID_SORTINGANDGROUPING: + openSortingAndGroupingDialog(); + break; + case SID_BACKGROUND_COLOR: + { + const util::Color aColor( lcl_extractBackgroundColor( aArgs ) ); + if ( !impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CONTROLBACKGROUND,uno::Any(aColor),aArgs) ) + { + uno::Reference< report::XSection > xSection = getDesignView()->getCurrentSection(); + if ( xSection.is() ) + { + xSection->setBackColor( aColor ); + } + } + bForceBroadcast = true; + } + break; + case SID_ATTR_CHAR_WEIGHT: + case SID_ATTR_CHAR_POSTURE: + case SID_ATTR_CHAR_UNDERLINE: + { + uno::Reference< awt::XWindow> xWindow; + ::std::vector< uno::Reference< uno::XInterface > > aControlsFormats; + lcl_getReportControlFormat( aArgs, getDesignView(), xWindow, aControlsFormats ); + + const OUString sUndoAction(RptResId(RID_STR_UNDO_CHANGEFONT)); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + for (const auto& rxControlFormat : aControlsFormats) + { + uno::Reference< report::XReportControlFormat> xReportControlFormat(rxControlFormat,uno::UNO_QUERY); + lcl_setFontWPU_nothrow(xReportControlFormat,_nId); + } + } + break; + case SID_ATTR_CHAR_COLOR: + case SID_ATTR_CHAR_COLOR2: + case SID_ATTR_CHAR_COLOR_EXT: + { + const SequenceAsHashMap aMap(aArgs); + const util::Color aColor = aMap.getUnpackedValueOrDefault(PROPERTY_FONTCOLOR,util::Color()); + impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARCOLOR,uno::Any(aColor),aArgs); + bForceBroadcast = true; + } + break; + case SID_ATTR_CHAR_FONT: + if ( aArgs.getLength() == 1 ) + { + awt::FontDescriptor aFont; + if ( aArgs[0].Value >>= aFont ) + { + impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARFONTNAME,uno::Any(aFont.Name),aArgs); + } + } + break; + case SID_ATTR_CHAR_FONTHEIGHT: + if ( aArgs.getLength() == 1 ) + { + float fSelVal = 0.0; + if ( aArgs[0].Value >>= fSelVal ) + impl_setPropertyAtControls_throw(RID_STR_UNDO_CHANGEFONT,PROPERTY_CHARHEIGHT,aArgs[0].Value,aArgs); + } + break; + case SID_ATTR_PARA_ADJUST_LEFT: + case SID_ATTR_PARA_ADJUST_CENTER: + case SID_ATTR_PARA_ADJUST_RIGHT: + case SID_ATTR_PARA_ADJUST_BLOCK: + { + style::ParagraphAdjust eParagraphAdjust = style::ParagraphAdjust_LEFT; + switch(_nId) + { + case SID_ATTR_PARA_ADJUST_LEFT: + eParagraphAdjust = style::ParagraphAdjust_LEFT; + break; + case SID_ATTR_PARA_ADJUST_CENTER: + eParagraphAdjust = style::ParagraphAdjust_CENTER; + break; + case SID_ATTR_PARA_ADJUST_RIGHT: + eParagraphAdjust = style::ParagraphAdjust_RIGHT; + break; + case SID_ATTR_PARA_ADJUST_BLOCK: + eParagraphAdjust = style::ParagraphAdjust_BLOCK; + break; + } + impl_setPropertyAtControls_throw(RID_STR_UNDO_ALIGNMENT,PROPERTY_PARAADJUST,uno::Any(static_cast<sal_Int16>(eParagraphAdjust)),aArgs); + + InvalidateFeature(SID_ATTR_PARA_ADJUST_LEFT); + InvalidateFeature(SID_ATTR_PARA_ADJUST_CENTER); + InvalidateFeature(SID_ATTR_PARA_ADJUST_RIGHT); + InvalidateFeature(SID_ATTR_PARA_ADJUST_BLOCK); + } + break; + case SID_CHAR_DLG: + { + uno::Sequence< beans::NamedValue > aSettings; + uno::Reference< awt::XWindow> xWindow; + ::std::vector< uno::Reference< uno::XInterface > > aControlsFormats; + lcl_getReportControlFormat( aArgs, getDesignView(), xWindow, aControlsFormats ); + + if ( !aControlsFormats.empty() ) + { + const OUString sUndoAction( RptResId( RID_STR_UNDO_CHANGEFONT ) ); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + for (const auto& rxControlFormat : aControlsFormats) + { + uno::Reference< report::XReportControlFormat > xFormat( rxControlFormat, uno::UNO_QUERY ); + if ( !xFormat.is() ) + continue; + + if ( !aSettings.hasElements() ) + { + ::rptui::openCharDialog( xFormat, xWindow, aSettings ); + if ( !aSettings.hasElements() ) + break; + } + + applyCharacterSettings( xFormat, aSettings ); + } + + InvalidateAll(); + } + } + break; + case SID_INSERT_GRAPHIC: + insertGraphic(); + break; + case SID_SETCONTROLDEFAULTS: + break; + case SID_CONDITIONALFORMATTING: + { + uno::Reference< report::XFormattedField> xFormattedField(getDesignView()->getCurrentControlModel(),uno::UNO_QUERY); + if ( xFormattedField.is() ) + { + ConditionalFormattingDialog aDlg(getFrameWeld(), xFormattedField, *this); + aDlg.run(); + } + } + break; + case SID_DATETIME: + if ( m_xReportDefinition.is() ) + { + if ( !aArgs.hasElements() ) + { + ODateTimeDialog aDlg(getFrameWeld(), getDesignView()->getCurrentSection(), this); + aDlg.run(); + } + else + createDateTime(aArgs); + } + break; + case SID_INSERT_FLD_PGNUMBER: + if ( m_xReportDefinition.is() ) + { + if ( !aArgs.hasElements() ) + { + OPageNumberDialog aDlg(getFrameWeld(), m_xReportDefinition, this); + aDlg.run(); + } + else + createPageNumber(aArgs); + } + break; + case SID_EXPORTDOC: + case SID_EXPORTDOCASPDF: + case SID_PRINTPREVIEW: + break; + case SID_EDITDOC: + if(isEditable()) + { // the state should be changed to not editable + setModified(false); // and we are not modified yet + } + setEditable(!isEditable()); + InvalidateAll(); + return; + case SID_GROUP: + break; + case SID_ATTR_ZOOM: + if ( !aArgs.hasElements() ) + { + openZoomDialog(); + } + else if ( aArgs.getLength() == 1 && aArgs[0].Name == "Zoom" ) + { + SvxZoomItem aZoomItem; + aZoomItem.PutValue(aArgs[0].Value, 0); + m_nZoomValue = aZoomItem.GetValue(); + m_eZoomType = aZoomItem.GetType(); + impl_zoom_nothrow(); + } + break; + case SID_ATTR_ZOOMSLIDER: + if ( aArgs.getLength() == 1 && aArgs[0].Name == "ZoomSlider" ) + { + SvxZoomSliderItem aZoomSlider; + aZoomSlider.PutValue(aArgs[0].Value, 0); + m_nZoomValue = aZoomSlider.GetValue(); + m_eZoomType = SvxZoomType::PERCENT; + impl_zoom_nothrow(); + } + break; + default: + OReportController_BASE::Execute(_nId,aArgs); + } + InvalidateFeature(_nId,Reference< XStatusListener >(),bForceBroadcast); +} + +void OReportController::impl_initialize( ) +{ + OReportController_BASE::impl_initialize(); + + const ::comphelper::NamedValueCollection& rArguments( getInitParams() ); + + rArguments.get_ensureType( PROPERTY_REPORTNAME, m_sName ); + if ( m_sName.isEmpty() ) + rArguments.get_ensureType( "DocumentTitle", m_sName ); + + try + { + if ( m_xReportDefinition.is() ) + { + getView()->initialize(); // show the windows and fill with our information + + m_aReportModel = reportdesign::OReportDefinition::getSdrModel(m_xReportDefinition); + if ( !m_aReportModel ) + throw RuntimeException(); + m_aReportModel->attachController( *this ); + + clearUndoManager(); + UndoSuppressor aSuppressUndo( getUndoManager() ); + + setMode(::comphelper::NamedValueCollection::getOrDefault(getModel()->getArgs(), u"Mode", OUString("normal"))); + + listen(true); + setEditable( !m_aReportModel->IsReadOnly() ); + m_xFormatter.set(util::NumberFormatter::create(m_xContext), UNO_QUERY_THROW); + m_xFormatter->attachNumberFormatsSupplier(Reference< XNumberFormatsSupplier>(m_xReportDefinition,uno::UNO_QUERY)); + + utl::MediaDescriptor aDescriptor( m_xReportDefinition->getArgs() ); + OUString sHierarchicalDocumentName = aDescriptor.getUnpackedValueOrDefault("HierarchicalDocumentName",OUString()); + + if ( sHierarchicalDocumentName.isEmpty() && getConnection().is() ) + { + uno::Reference<sdbcx::XTablesSupplier> xTablesSup(getConnection(),uno::UNO_QUERY_THROW); + uno::Reference<container::XNameAccess> xTables = xTablesSup->getTables(); + const uno::Sequence< OUString > aNames( xTables->getElementNames() ); + + if ( aNames.hasElements() ) + { + m_xReportDefinition->setCommand(aNames[0]); + m_xReportDefinition->setCommandType(sdb::CommandType::TABLE); + } + } + + m_aVisualAreaSize = m_xReportDefinition->getVisualAreaSize(0); + + } + + // check if chart is supported by the engine + checkChartEnabled(); + // restore the view data + getDesignView()->toggleGrid(m_bGridVisible); + getDesignView()->showRuler(m_bShowRuler); + getDesignView()->togglePropertyBrowser(m_bShowProperties); + getDesignView()->setCurrentPage(m_sLastActivePage); + getDesignView()->unmarkAllObjects(); + + if ( m_nPageNum != -1 ) + { + if ( m_nPageNum < m_aReportModel->GetPageCount() ) + { + const OReportPage* pPage = dynamic_cast<OReportPage*>(m_aReportModel->GetPage(static_cast<sal_uInt16>(m_nPageNum))); + if ( pPage ) + { + executeUnChecked(SID_SELECT,{ comphelper::makePropertyValue("", pPage->getSection() ) }); + } + } + else + m_nPageNum = -1; + } + getDesignView()->collapseSections(m_aCollapsedSections); + impl_zoom_nothrow(); + getDesignView()->Resize(); + getDesignView()->Invalidate(); + InvalidateAll(); + + if ( m_bShowProperties && m_nPageNum == -1 ) + { + m_sLastActivePage = "Data"; + getDesignView()->setCurrentPage(m_sLastActivePage); + executeUnChecked(SID_SELECT_REPORT,{}); + } + + setModified(false); // and we are not modified yet + } + catch(const SQLException&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +IMPL_LINK( OReportController, OnCreateHdl, OAddFieldWindow& ,_rAddFieldDlg, void) +{ + weld::WaitObject aObj(getFrameWeld()); + uno::Sequence< beans::PropertyValue > aArgs = _rAddFieldDlg.getSelectedFieldDescriptors(); + // we use this way to create undo actions + if ( aArgs.hasElements() ) + { + executeChecked(SID_ADD_CONTROL_PAIR,aArgs); + } +} + +bool OReportController::Construct(vcl::Window* pParent) +{ + VclPtrInstance<ODesignView> pMyOwnView( pParent, m_xContext, *this ); + StartListening( *pMyOwnView ); + setView( pMyOwnView ); + + // now that we have a view we can create the clipboard listener + m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() ); + m_aSystemClipboard.StartClipboardListening( ); + m_pClipboardNotifier = new TransferableClipboardListener( LINK( this, OReportController, OnClipboardChanged ) ); + m_pClipboardNotifier->AddListener( getView() ); + + OReportController_BASE::Construct(pParent); + return true; +} + +sal_Bool SAL_CALL OReportController::suspend(sal_Bool /*_bSuspend*/) +{ + if ( getBroadcastHelper().bInDispose || getBroadcastHelper().bDisposed ) + return true; + + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + if ( getView() && getView()->IsInModalMode() ) + return false; + + // this suspend will be handled in the DBAccess interceptor implementation + return true; +} + +void OReportController::describeSupportedFeatures() +{ + DBSubComponentController::describeSupportedFeatures(); + + implDescribeSupportedFeature( ".uno:TextDocument", SID_RPT_TEXTDOCUMENT, CommandGroup::APPLICATION ); + implDescribeSupportedFeature( ".uno:Spreadsheet", SID_RPT_SPREADSHEET, CommandGroup::APPLICATION ); + + implDescribeSupportedFeature( ".uno:Redo", SID_REDO, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:Undo", SID_UNDO, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:SelectAll", SID_SELECTALL, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:SelectAllInSection", SID_SELECTALL_IN_SECTION, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:Delete", SID_DELETE, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:SelectReport", SID_SELECT_REPORT, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:ExecuteReport", SID_EXECUTE_REPORT, CommandGroup::EDIT ); + + implDescribeSupportedFeature( ".uno:GridVisible", SID_GRID_VISIBLE, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:GridUse", SID_GRID_USE, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:HelplinesMove", SID_HELPLINES_MOVE, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:ShowRuler", SID_RULER, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:AddField", SID_FM_ADD_FIELD, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:ReportNavigator", SID_RPT_SHOWREPORTEXPLORER, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:ControlProperties", SID_SHOW_PROPERTYBROWSER, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:DbSortingAndGrouping", SID_SORTINGANDGROUPING, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:PageHeaderFooter", SID_PAGEHEADERFOOTER, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:ReportHeaderFooter", SID_REPORTHEADERFOOTER, CommandGroup::VIEW ); + implDescribeSupportedFeature( ".uno:ZoomSlider", SID_ATTR_ZOOMSLIDER ); + implDescribeSupportedFeature( ".uno:Zoom", SID_ATTR_ZOOM, CommandGroup::VIEW ); + + implDescribeSupportedFeature( ".uno:ConditionalFormatting", SID_CONDITIONALFORMATTING, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:PageDialog", SID_PAGEDIALOG, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:ResetAttributes", SID_SETCONTROLDEFAULTS, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:Bold", SID_ATTR_CHAR_WEIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:Italic", SID_ATTR_CHAR_POSTURE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:Underline", SID_ATTR_CHAR_UNDERLINE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DBBackgroundColor", SID_ATTR_CHAR_COLOR_BACKGROUND, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:BackgroundColor", SID_BACKGROUND_COLOR, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:CharColorExt", SID_ATTR_CHAR_COLOR_EXT); + implDescribeSupportedFeature( ".uno:Color", SID_ATTR_CHAR_COLOR); + implDescribeSupportedFeature( ".uno:FontColor", SID_ATTR_CHAR_COLOR2, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:FontDialog", SID_CHAR_DLG, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:LeftPara", SID_ATTR_PARA_ADJUST_LEFT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:CenterPara", SID_ATTR_PARA_ADJUST_CENTER, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:RightPara", SID_ATTR_PARA_ADJUST_RIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:JustifyPara", SID_ATTR_PARA_ADJUST_BLOCK, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:FontHeight", SID_ATTR_CHAR_FONTHEIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:CharFontName", SID_ATTR_CHAR_FONT, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:ArrangeMenu", SID_ARRANGEMENU, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:BringToFront", SID_FRAME_TO_TOP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:ObjectBackOne", SID_FRAME_DOWN, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:ObjectForwardOne", SID_FRAME_UP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SendToBack", SID_FRAME_TO_BOTTOM, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SetObjectToForeground", SID_OBJECT_HEAVEN, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SetObjectToBackground", SID_OBJECT_HELL, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:ObjectAlign", SID_OBJECT_ALIGN, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:ObjectAlignLeft", SID_OBJECT_ALIGN_LEFT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:AlignCenter", SID_OBJECT_ALIGN_CENTER, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:ObjectAlignRight", SID_OBJECT_ALIGN_RIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:AlignUp", SID_OBJECT_ALIGN_UP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:AlignMiddle", SID_OBJECT_ALIGN_MIDDLE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:AlignDown", SID_OBJECT_ALIGN_DOWN, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:SectionAlign", SID_SECTION_ALIGN ); + implDescribeSupportedFeature( ".uno:SectionAlignLeft", SID_SECTION_ALIGN_LEFT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionAlignCenter", SID_SECTION_ALIGN_CENTER, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionAlignRight", SID_SECTION_ALIGN_RIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionAlignTop", SID_SECTION_ALIGN_UP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionAlignMiddle", SID_SECTION_ALIGN_MIDDLE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionAlignBottom", SID_SECTION_ALIGN_DOWN, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionShrink", SID_SECTION_SHRINK, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionShrinkTop", SID_SECTION_SHRINK_TOP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SectionShrinkBottom", SID_SECTION_SHRINK_BOTTOM, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:ObjectResize", SID_OBJECT_RESIZING, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SmallestWidth", SID_OBJECT_SMALLESTWIDTH, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:SmallestHeight", SID_OBJECT_SMALLESTHEIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:GreatestWidth", SID_OBJECT_GREATESTWIDTH, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:GreatestHeight", SID_OBJECT_GREATESTHEIGHT, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:DistributeSelection", SID_DISTRIBUTE_DLG, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeHorzLeft", SID_DISTRIBUTE_HLEFT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeHorzCenter", SID_DISTRIBUTE_HCENTER, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeHorzDistance", SID_DISTRIBUTE_HDISTANCE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeHorzRight", SID_DISTRIBUTE_HRIGHT, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeVertTop", SID_DISTRIBUTE_VTOP, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeVertCenter", SID_DISTRIBUTE_VCENTER, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeVertDistance", SID_DISTRIBUTE_VDISTANCE, CommandGroup::FORMAT ); + implDescribeSupportedFeature( ".uno:DistributeVertBottom", SID_DISTRIBUTE_VBOTTOM, CommandGroup::FORMAT ); + + implDescribeSupportedFeature( ".uno:ExportTo", SID_EXPORTDOC, CommandGroup::APPLICATION ); + implDescribeSupportedFeature( ".uno:ExportToPDF", SID_EXPORTDOCASPDF, CommandGroup::APPLICATION ); + implDescribeSupportedFeature( ".uno:PrintPreview", SID_PRINTPREVIEW, CommandGroup::APPLICATION ); + + implDescribeSupportedFeature( ".uno:NewDoc", SID_NEWDOC, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:Save", SID_SAVEDOC, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:SaveAs", SID_SAVEASDOC, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:SaveACopy", SID_SAVEACOPY, CommandGroup::DOCUMENT ); + + implDescribeSupportedFeature( ".uno:InsertPageNumberField", SID_INSERT_FLD_PGNUMBER, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:InsertDateTimeField", SID_DATETIME, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:InsertObjectChart", SID_INSERT_DIAGRAM, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:InsertGraphic", SID_INSERT_GRAPHIC, CommandGroup::INSERT ); + // controls + implDescribeSupportedFeature( ".uno:SelectObject", SID_OBJECT_SELECT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Label", SID_FM_FIXEDTEXT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:Edit", SID_FM_EDIT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ImageControl", SID_FM_IMAGECONTROL, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:HFixedLine", SID_INSERT_HFIXEDLINE, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:VFixedLine", SID_INSERT_VFIXEDLINE, CommandGroup::INSERT ); + + // shapes + implDescribeSupportedFeature( ".uno:BasicShapes", SID_DRAWTBX_CS_BASIC, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.rectangle", SID_DRAWTBX_CS_BASIC1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.round-rectangle",SID_DRAWTBX_CS_BASIC2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.quadrat", SID_DRAWTBX_CS_BASIC3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.round-quadrat", SID_DRAWTBX_CS_BASIC4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.circle", SID_DRAWTBX_CS_BASIC5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.ellipse", SID_DRAWTBX_CS_BASIC6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.circle-pie", SID_DRAWTBX_CS_BASIC7, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.isosceles-triangle",SID_DRAWTBX_CS_BASIC8, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.right-triangle",SID_DRAWTBX_CS_BASIC9, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.trapezoid", SID_DRAWTBX_CS_BASIC10, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.diamond", SID_DRAWTBX_CS_BASIC11, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.parallelogram", SID_DRAWTBX_CS_BASIC12, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.pentagon", SID_DRAWTBX_CS_BASIC13, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.hexagon", SID_DRAWTBX_CS_BASIC14, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.octagon", SID_DRAWTBX_CS_BASIC15, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.cross", SID_DRAWTBX_CS_BASIC16, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.ring", SID_DRAWTBX_CS_BASIC17, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.block-arc", SID_DRAWTBX_CS_BASIC18, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.can", SID_DRAWTBX_CS_BASIC19, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.cube", SID_DRAWTBX_CS_BASIC20, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.paper", SID_DRAWTBX_CS_BASIC21, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:BasicShapes.frame", SID_DRAWTBX_CS_BASIC22, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:SymbolShapes", SID_DRAWTBX_CS_SYMBOL, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:SymbolShapes.smiley" , SID_DRAWTBX_CS_SYMBOL1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.sun" , SID_DRAWTBX_CS_SYMBOL2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.moon" , SID_DRAWTBX_CS_SYMBOL3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.lightning" , SID_DRAWTBX_CS_SYMBOL4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.heart" , SID_DRAWTBX_CS_SYMBOL5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.flower" , SID_DRAWTBX_CS_SYMBOL6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.cloud" , SID_DRAWTBX_CS_SYMBOL7, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.forbidden" , SID_DRAWTBX_CS_SYMBOL8, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.puzzle" , SID_DRAWTBX_CS_SYMBOL9, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.bracket-pair" ,SID_DRAWTBX_CS_SYMBOL10, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.left-bracket" ,SID_DRAWTBX_CS_SYMBOL11, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.right-bracket",SID_DRAWTBX_CS_SYMBOL12, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.brace-pair" , SID_DRAWTBX_CS_SYMBOL13, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.left-brace" , SID_DRAWTBX_CS_SYMBOL14, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.right-brace" , SID_DRAWTBX_CS_SYMBOL15, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.quad-bevel" , SID_DRAWTBX_CS_SYMBOL16, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.octagon-bevel",SID_DRAWTBX_CS_SYMBOL17, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:SymbolShapes.diamond-bevel",SID_DRAWTBX_CS_SYMBOL18, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:ArrowShapes.left-arrow" , SID_DRAWTBX_CS_ARROW1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.right-arrow" , SID_DRAWTBX_CS_ARROW2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-arrow" , SID_DRAWTBX_CS_ARROW3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.down-arrow" , SID_DRAWTBX_CS_ARROW4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.left-right-arrow" , SID_DRAWTBX_CS_ARROW5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-down-arrow" , SID_DRAWTBX_CS_ARROW6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-arrow" , SID_DRAWTBX_CS_ARROW7, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-down-arrow" , SID_DRAWTBX_CS_ARROW8, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.quad-arrow" , SID_DRAWTBX_CS_ARROW9, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.corner-right-arrow" , SID_DRAWTBX_CS_ARROW10, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.split-arrow" , SID_DRAWTBX_CS_ARROW11, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.striped-right-arrow" , SID_DRAWTBX_CS_ARROW12, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.notched-right-arrow" , SID_DRAWTBX_CS_ARROW13, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.pentagon-right" , SID_DRAWTBX_CS_ARROW14, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.chevron" , SID_DRAWTBX_CS_ARROW15, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.right-arrow-callout" , SID_DRAWTBX_CS_ARROW16, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.left-arrow-callout" , SID_DRAWTBX_CS_ARROW17, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-arrow-callout" , SID_DRAWTBX_CS_ARROW18, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.down-arrow-callout" , SID_DRAWTBX_CS_ARROW19, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.left-right-arrow-callout",SID_DRAWTBX_CS_ARROW20, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-down-arrow-callout" ,SID_DRAWTBX_CS_ARROW21, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.up-right-arrow-callout",SID_DRAWTBX_CS_ARROW22, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.quad-arrow-callout" , SID_DRAWTBX_CS_ARROW23, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.circular-arrow" , SID_DRAWTBX_CS_ARROW24, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.split-round-arrow" , SID_DRAWTBX_CS_ARROW25, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:ArrowShapes.s-sharped-arrow" , SID_DRAWTBX_CS_ARROW26, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:StarShapes.bang" , SID_DRAWTBX_CS_STAR1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star4" , SID_DRAWTBX_CS_STAR2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star5" , SID_DRAWTBX_CS_STAR3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star6" , SID_DRAWTBX_CS_STAR4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star8" , SID_DRAWTBX_CS_STAR5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star12" , SID_DRAWTBX_CS_STAR6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.star24" , SID_DRAWTBX_CS_STAR7, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.concave-star6" , SID_DRAWTBX_CS_STAR8, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.vertical-scroll" , SID_DRAWTBX_CS_STAR9, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.horizontal-scroll" , SID_DRAWTBX_CS_STAR10, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.signet" , SID_DRAWTBX_CS_STAR11, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes.doorplate" , SID_DRAWTBX_CS_STAR12, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-process" , SID_DRAWTBX_CS_FLOWCHART1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-alternate-process" , SID_DRAWTBX_CS_FLOWCHART2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-decision" , SID_DRAWTBX_CS_FLOWCHART3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-data" , SID_DRAWTBX_CS_FLOWCHART4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-predefined-process" , SID_DRAWTBX_CS_FLOWCHART5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-internal-storage" , SID_DRAWTBX_CS_FLOWCHART6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-document" , SID_DRAWTBX_CS_FLOWCHART7, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-multidocument" , SID_DRAWTBX_CS_FLOWCHART8, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-terminator" , SID_DRAWTBX_CS_FLOWCHART9, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-preparation" , SID_DRAWTBX_CS_FLOWCHART10, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-manual-input" , SID_DRAWTBX_CS_FLOWCHART11, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-manual-operation" , SID_DRAWTBX_CS_FLOWCHART12, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-connector" , SID_DRAWTBX_CS_FLOWCHART13, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-off-page-connector" , SID_DRAWTBX_CS_FLOWCHART14, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-card" , SID_DRAWTBX_CS_FLOWCHART15, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-punched-tape" , SID_DRAWTBX_CS_FLOWCHART16, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-summing-junction" , SID_DRAWTBX_CS_FLOWCHART17, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-or" , SID_DRAWTBX_CS_FLOWCHART18, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-collate" , SID_DRAWTBX_CS_FLOWCHART19, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-sort" , SID_DRAWTBX_CS_FLOWCHART20, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-extract" , SID_DRAWTBX_CS_FLOWCHART21, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-merge" , SID_DRAWTBX_CS_FLOWCHART22, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-stored-data" , SID_DRAWTBX_CS_FLOWCHART23, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-delay" , SID_DRAWTBX_CS_FLOWCHART24, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-sequential-access" , SID_DRAWTBX_CS_FLOWCHART25, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-magnetic-disk" , SID_DRAWTBX_CS_FLOWCHART26, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-direct-access-storage",SID_DRAWTBX_CS_FLOWCHART27, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:FlowChartShapes.flowchart-display" , SID_DRAWTBX_CS_FLOWCHART28, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:CalloutShapes.rectangular-callout" , SID_DRAWTBX_CS_CALLOUT1, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.round-rectangular-callout" , SID_DRAWTBX_CS_CALLOUT2, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.round-callout" , SID_DRAWTBX_CS_CALLOUT3, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.cloud-callout" , SID_DRAWTBX_CS_CALLOUT4, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-1" , SID_DRAWTBX_CS_CALLOUT5, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-2" , SID_DRAWTBX_CS_CALLOUT6, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes.line-callout-3" , SID_DRAWTBX_CS_CALLOUT7, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:ArrowShapes", SID_DRAWTBX_CS_ARROW, CommandGroup::INSERT ); + + implDescribeSupportedFeature( ".uno:FlowChartShapes", SID_DRAWTBX_CS_FLOWCHART, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:CalloutShapes", SID_DRAWTBX_CS_CALLOUT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:StarShapes", SID_DRAWTBX_CS_STAR, CommandGroup::INSERT ); + + + // keys + implDescribeSupportedFeature( ".uno:Escape", SID_ESCAPE); + + // internal one + implDescribeSupportedFeature( ".uno:RPT_RPTHEADER_UNDO", SID_REPORTHEADER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:RPT_RPTFOOTER_UNDO", SID_REPORTFOOTER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:RPT_PGHEADER_UNDO", SID_PAGEHEADER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:RPT_PGFOOTER_UNDO", SID_PAGEFOOTER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:SID_GROUPHEADER", SID_GROUPHEADER); + implDescribeSupportedFeature( ".uno:SID_GROUPHEADER_WITHOUT_UNDO", SID_GROUPHEADER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:SID_GROUPFOOTER", SID_GROUPFOOTER); + implDescribeSupportedFeature( ".uno:SID_GROUPFOOTER_WITHOUT_UNDO", SID_GROUPFOOTER_WITHOUT_UNDO); + implDescribeSupportedFeature( ".uno:SID_GROUP_REMOVE", SID_GROUP_REMOVE); + implDescribeSupportedFeature( ".uno:SID_GROUP_APPEND", SID_GROUP_APPEND); + implDescribeSupportedFeature( ".uno:SID_ADD_CONTROL_PAIR", SID_ADD_CONTROL_PAIR); + implDescribeSupportedFeature( ".uno:SplitPosition", SID_SPLIT_POSITION); + implDescribeSupportedFeature( ".uno:LastPropertyBrowserPage", SID_PROPERTYBROWSER_LAST_PAGE); + implDescribeSupportedFeature( ".uno:Select", SID_SELECT); + implDescribeSupportedFeature( ".uno:InsertFunction", SID_RPT_NEW_FUNCTION); + implDescribeSupportedFeature( ".uno:NextMark", SID_NEXT_MARK); + implDescribeSupportedFeature( ".uno:PrevMark", SID_PREV_MARK); + implDescribeSupportedFeature( ".uno:TerminateInplaceActivation", SID_TERMINATE_INPLACEACTIVATION); + implDescribeSupportedFeature( ".uno:SelectAllLabels", SID_SELECT_ALL_LABELS); + implDescribeSupportedFeature( ".uno:SelectAllEdits", SID_SELECT_ALL_EDITS); + implDescribeSupportedFeature( ".uno:CollapseSection", SID_COLLAPSE_SECTION); + implDescribeSupportedFeature( ".uno:ExpandSection", SID_EXPAND_SECTION); + implDescribeSupportedFeature( ".uno:GetUndoStrings", SID_GETUNDOSTRINGS); + implDescribeSupportedFeature( ".uno:GetRedoStrings", SID_GETREDOSTRINGS); +} + +void OReportController::impl_onModifyChanged() +{ + try + { + if ( m_xReportDefinition.is() ) + m_xReportDefinition->setModified( impl_isModified() ); + DBSubComponentController::impl_onModifyChanged(); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void OReportController::onLoadedMenu(const Reference< frame::XLayoutManager >& _xLayoutManager) +{ + if ( !_xLayoutManager.is() ) + return; + + static const std::u16string_view s_sMenu[] = { + u"private:resource/statusbar/statusbar" + ,u"private:resource/toolbar/reportcontrols" + ,u"private:resource/toolbar/drawbar" + ,u"private:resource/toolbar/Formatting" + ,u"private:resource/toolbar/alignmentbar" + ,u"private:resource/toolbar/sectionalignmentbar" + ,u"private:resource/toolbar/resizebar" + ,u"private:resource/toolbar/sectionshrinkbar" + }; + for (const auto & i : s_sMenu) + { + _xLayoutManager->createElement( OUString(i) ); + _xLayoutManager->requestElement( OUString(i) ); + } +} + +void OReportController::notifyGroupSections(const ContainerEvent& _rEvent,bool _bShow) +{ + uno::Reference< report::XGroup> xGroup(_rEvent.Element,uno::UNO_QUERY); + if ( !xGroup.is() ) + return; + + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + sal_Int32 nGroupPos = 0; + _rEvent.Accessor >>= nGroupPos; + + if ( _bShow ) + { + xGroup->addPropertyChangeListener(PROPERTY_HEADERON, static_cast<XPropertyChangeListener*>(this)); + xGroup->addPropertyChangeListener(PROPERTY_FOOTERON, static_cast<XPropertyChangeListener*>(this)); + } + else + { + xGroup->removePropertyChangeListener(PROPERTY_HEADERON, static_cast<XPropertyChangeListener*>(this)); + xGroup->removePropertyChangeListener(PROPERTY_FOOTERON, static_cast<XPropertyChangeListener*>(this)); + } + + if ( xGroup->getHeaderOn() ) + { + groupChange(xGroup,PROPERTY_HEADERON,nGroupPos,_bShow); + if (_bShow) + { + m_pReportControllerObserver->AddSection(xGroup->getHeader()); + } + else + { + m_pReportControllerObserver->RemoveSection(xGroup->getHeader()); + } + } + if ( xGroup->getFooterOn() ) + { + groupChange(xGroup,PROPERTY_FOOTERON,nGroupPos,_bShow); + if (_bShow) + { + m_pReportControllerObserver->AddSection(xGroup->getFooter()); + } + else + { + m_pReportControllerObserver->RemoveSection(xGroup->getFooter()); + } + } +} + +// ::container::XContainerListener +void SAL_CALL OReportController::elementInserted( const ContainerEvent& _rEvent ) +{ + notifyGroupSections(_rEvent,true); +} + +void SAL_CALL OReportController::elementRemoved( const ContainerEvent& _rEvent ) +{ + notifyGroupSections(_rEvent,false); +} + +void SAL_CALL OReportController::elementReplaced( const ContainerEvent& /*_rEvent*/ ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + OSL_FAIL("Not yet implemented!"); +} + +void SAL_CALL OReportController::propertyChange( const beans::PropertyChangeEvent& evt ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + try + { + bool bShow = false; + evt.NewValue >>= bShow; + if ( evt.Source == m_xReportDefinition ) + { + if ( evt.PropertyName == PROPERTY_REPORTHEADERON ) + { + const sal_uInt16 nPosition = m_xReportDefinition->getPageHeaderOn() ? 1 : 0; + if ( bShow ) + { + getDesignView()->addSection(m_xReportDefinition->getReportHeader(),DBREPORTHEADER,nPosition); + m_pReportControllerObserver->AddSection(m_xReportDefinition->getReportHeader()); + } + else + { + getDesignView()->removeSection(nPosition); + } + } + else if ( evt.PropertyName == PROPERTY_REPORTFOOTERON ) + { + sal_uInt16 nPosition = getDesignView()->getSectionCount(); + if ( m_xReportDefinition->getPageFooterOn() ) + --nPosition; + if ( bShow ) + { + getDesignView()->addSection(m_xReportDefinition->getReportFooter(),DBREPORTFOOTER,nPosition); + m_pReportControllerObserver->AddSection(m_xReportDefinition->getReportFooter()); + } + else + { + getDesignView()->removeSection(nPosition - 1); + } + } + else if ( evt.PropertyName == PROPERTY_PAGEHEADERON ) + { + if ( bShow ) + { + getDesignView()->addSection(m_xReportDefinition->getPageHeader(),DBPAGEHEADER,0); + m_pReportControllerObserver->AddSection(m_xReportDefinition->getPageHeader()); + } + else + { + getDesignView()->removeSection(sal_uInt16(0)); + } + } + else if ( evt.PropertyName == PROPERTY_PAGEFOOTERON ) + { + if ( bShow ) + { + getDesignView()->addSection(m_xReportDefinition->getPageFooter(),DBPAGEFOOTER); + m_pReportControllerObserver->AddSection(m_xReportDefinition->getPageFooter()); + } + else + { + getDesignView()->removeSection(getDesignView()->getSectionCount() - 1); + } + } + else if ( evt.PropertyName == PROPERTY_COMMAND + || evt.PropertyName == PROPERTY_COMMANDTYPE + || evt.PropertyName == PROPERTY_ESCAPEPROCESSING + || evt.PropertyName == PROPERTY_FILTER + ) + { + m_xColumns.clear(); + m_xHoldAlive.clear(); + InvalidateFeature(SID_FM_ADD_FIELD); + if ( !getDesignView()->isAddFieldVisible() && isUiVisible() ) + getDesignView()->toggleAddField(); + } + /// TODO: check what we need to notify here TitleHelper + /*else if ( evt.PropertyName.equals( PROPERTY_CAPTION ) ) + updateTitle();*/ + } + else + { + uno::Reference< report::XGroup> xGroup(evt.Source,uno::UNO_QUERY); + if ( xGroup.is() ) + { + sal_Int32 nGroupPos = getGroupPosition(xGroup); + + groupChange(xGroup,evt.PropertyName,nGroupPos,bShow); + } + } + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void SAL_CALL OReportController::disposing( const lang::EventObject& Source ) +{ + // simply disambiguate + OReportController_BASE::disposing(Source); +} + + +static sal_uInt16 lcl_getNonVisibleGroupsBefore( const uno::Reference< report::XGroups>& _xGroups + ,sal_Int32 _nGroupPos + ,::std::function<bool(OGroupHelper *)> const & _pGroupMemberFunction) +{ + uno::Reference< report::XGroup> xGroup; + sal_uInt16 nNonVisibleGroups = 0; + sal_Int32 nCount = _xGroups->getCount(); + for( sal_Int32 i = 0; i < _nGroupPos && i < nCount; ++i) + { + xGroup.set(_xGroups->getByIndex(i),uno::UNO_QUERY); + OSL_ENSURE(xGroup.is(),"Group is NULL! -> GPF"); + OGroupHelper aGroupHelper(xGroup); + if ( !_pGroupMemberFunction(&aGroupHelper) ) + ++nNonVisibleGroups; + } + return nNonVisibleGroups; +} + +void OReportController::groupChange( const uno::Reference< report::XGroup>& _xGroup,std::u16string_view _sPropName,sal_Int32 _nGroupPos,bool _bShow) +{ + ::std::function<bool(OGroupHelper *)> pMemFun = ::std::mem_fn(&OGroupHelper::getHeaderOn); + ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader); + OUString sColor(DBGROUPHEADER); + sal_uInt16 nPosition = 0; + bool bHandle = false; + if ( _sPropName == PROPERTY_HEADERON ) + { + nPosition = m_xReportDefinition->getPageHeaderOn() ? (m_xReportDefinition->getReportHeaderOn() ? 2 : 1) : (m_xReportDefinition->getReportHeaderOn() ? 1 : 0); + nPosition += (static_cast<sal_uInt16>(_nGroupPos) - lcl_getNonVisibleGroupsBefore(m_xReportDefinition->getGroups(),_nGroupPos,pMemFun)); + bHandle = true; + } + else if ( _sPropName == PROPERTY_FOOTERON ) + { + pMemFun = ::std::mem_fn(&OGroupHelper::getFooterOn); + pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter); + nPosition = getDesignView()->getSectionCount(); + + if ( m_xReportDefinition->getPageFooterOn() ) + --nPosition; + if ( m_xReportDefinition->getReportFooterOn() ) + --nPosition; + sColor = DBGROUPFOOTER; + nPosition -= (static_cast<sal_uInt16>(_nGroupPos) - lcl_getNonVisibleGroupsBefore(m_xReportDefinition->getGroups(),_nGroupPos,pMemFun)); + if ( !_bShow ) + --nPosition; + bHandle = true; + } + if ( bHandle ) + { + if ( _bShow ) + { + OGroupHelper aGroupHelper(_xGroup); + getDesignView()->addSection(pMemFunSection(&aGroupHelper),sColor,nPosition); + } + else + { + getDesignView()->removeSection(nPosition); + } + } +} + +IMPL_LINK_NOARG(OReportController, OnClipboardChanged, TransferableDataHelper*, void) +{ + OnInvalidateClipboard(); +} + +void OReportController::OnInvalidateClipboard() +{ + InvalidateFeature(SID_CUT); + InvalidateFeature(SID_COPY); + InvalidateFeature(SID_PASTE); +} + +void OReportController::openPageDialog(const uno::Reference<report::XSection>& _xSection) +{ + if ( !m_xReportDefinition.is() ) + return; + + // UNO->ItemSet + static SfxItemInfo aItemInfos[] = + { + { SID_ATTR_LRSPACE, true }, + { SID_ATTR_ULSPACE, true }, + { SID_ATTR_PAGE, true }, + { SID_ATTR_PAGE_SIZE, true }, + { SID_ENUM_PAGE_MODE, true }, + { SID_PAPER_START, true }, + { SID_PAPER_END, true }, + { SID_ATTR_BRUSH, true }, + { 0, true }, // XATTR_FILLSTYLE + { 0, true }, // XATTR_FILLCOLOR + { 0, true }, // XATTR_FILLGRADIENT + { 0, true }, // XATTR_FILLHATCH + { 0, true }, // XATTR_FILLBITMAP + { 0, true }, // XATTR_FILLTRANSPARENCE + { 0, true }, // XATTR_GRADIENTSTEPCOUNT + { 0, true }, // XATTR_FILLBMP_TILE + { 0, true }, // XATTR_FILLBMP_POS + { 0, true }, // XATTR_FILLBMP_SIZEX + { 0, true }, // XATTR_FILLBMP_SIZEY + { 0, true }, // XATTR_FILLFLOATTRANSPARENCE + { 0, true }, // XATTR_SECONDARYFILLCOLOR + { 0, true }, // XATTR_FILLBMP_SIZELOG + { 0, true }, // XATTR_FILLBMP_TILEOFFSETX + { 0, true }, // XATTR_FILLBMP_TILEOFFSETY + { 0, true }, // XATTR_FILLBMP_STRETCH + { 0, true }, // XATTR_FILLBMP_POSOFFSETX + { 0, true }, // XATTR_FILLBMP_POSOFFSETY + { 0, true }, // XATTR_FILLBACKGROUND + { SID_ATTR_METRIC, true } + }; + + MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum(); + FieldUnit eUserMetric = MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH; + static const WhichRangesContainer pRanges(svl::Items< + RPTUI_ID_LRSPACE, XATTR_FILL_LAST, + SID_ATTR_METRIC,SID_ATTR_METRIC + >); + rtl::Reference<SfxItemPool> pPool( new SfxItemPool("ReportPageProperties", RPTUI_ID_LRSPACE, RPTUI_ID_METRIC, aItemInfos ) ); + + const Graphic aNullGraphic; + const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color + const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color + const XGradient aNullGrad(COL_BLACK, COL_WHITE); + const XHatch aNullHatch(aNullLineCol); + + std::vector<SfxPoolItem*> pDefaults + { + new SvxLRSpaceItem(RPTUI_ID_LRSPACE), + new SvxULSpaceItem(RPTUI_ID_ULSPACE), + new SvxPageItem(RPTUI_ID_PAGE), + new SvxSizeItem(RPTUI_ID_SIZE), + new SfxUInt16Item(RPTUI_ID_PAGE_MODE,SVX_PAGE_MODE_STANDARD), + new SfxUInt16Item(RPTUI_ID_START,PAPER_A4), + new SfxUInt16Item(RPTUI_ID_END,PAPER_E), + new SvxBrushItem(RPTUI_ID_BRUSH), + new XFillStyleItem, + new XFillColorItem("", aNullFillCol), + new XFillGradientItem(aNullGrad), + new XFillHatchItem(aNullHatch), + new XFillBitmapItem(aNullGraphic), + new XFillTransparenceItem, + new XGradientStepCountItem, + new XFillBmpTileItem, + new XFillBmpPosItem, + new XFillBmpSizeXItem, + new XFillBmpSizeYItem, + new XFillFloatTransparenceItem(aNullGrad, false), + new XSecondaryFillColorItem("", aNullFillCol), + new XFillBmpSizeLogItem, + new XFillBmpTileOffsetXItem, + new XFillBmpTileOffsetYItem, + new XFillBmpStretchItem, + new XFillBmpPosOffsetXItem, + new XFillBmpPosOffsetYItem, + new XFillBackgroundItem, + new SfxUInt16Item(RPTUI_ID_METRIC,static_cast<sal_uInt16>(eUserMetric)) + }; + + pPool->SetDefaults(&pDefaults); + + + pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why + pPool->FreezeIdRanges(); // the same + + try + { + SfxItemSet aDescriptor(*pPool, pRanges); + // fill it + if ( _xSection.is() ) + aDescriptor.Put(SvxBrushItem(::Color(ColorTransparency, _xSection->getBackColor()),RPTUI_ID_BRUSH)); + else + { + aDescriptor.Put(SvxSizeItem(RPTUI_ID_SIZE,VCLSize(getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE)))); + aDescriptor.Put(SvxLRSpaceItem(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN) + ,getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN),0,0,RPTUI_ID_LRSPACE)); + aDescriptor.Put(SvxULSpaceItem(static_cast<sal_uInt16>(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_TOPMARGIN)) + ,static_cast<sal_uInt16>(getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_BOTTOMMARGIN)),RPTUI_ID_ULSPACE)); + aDescriptor.Put(SfxUInt16Item(SID_ATTR_METRIC,static_cast<sal_uInt16>(eUserMetric))); + + uno::Reference< style::XStyle> xPageStyle(getUsedStyle(m_xReportDefinition)); + if ( xPageStyle.is() ) + { + SvxPageItem aPageItem(RPTUI_ID_PAGE); + aPageItem.SetDescName(xPageStyle->getName()); + uno::Reference<beans::XPropertySet> xProp(xPageStyle,uno::UNO_QUERY_THROW); + aPageItem.PutValue(xProp->getPropertyValue(PROPERTY_PAGESTYLELAYOUT),MID_PAGE_LAYOUT); + aPageItem.SetLandscape(getStyleProperty<bool>(m_xReportDefinition,PROPERTY_ISLANDSCAPE)); + aPageItem.SetNumType(static_cast<SvxNumType>(getStyleProperty<sal_Int16>(m_xReportDefinition,PROPERTY_NUMBERINGTYPE))); + aDescriptor.Put(aPageItem); + aDescriptor.Put(SvxBrushItem(::Color(ColorTransparency, getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_BACKCOLOR)),RPTUI_ID_BRUSH)); + } + } + + { // want the dialog to be destroyed before our set + ORptPageDialog aDlg( + getFrameWeld(), &aDescriptor,_xSection.is() + ? OUString("BackgroundDialog") + : OUString("PageDialog")); + if (aDlg.run() == RET_OK) + { + + // ItemSet->UNO + // UNO-properties + const SfxItemSet* pSet = aDlg.GetOutputItemSet(); + if ( _xSection.is() ) + { + if ( const SvxBrushItem* pBrushItem = pSet->GetItemIfSet( RPTUI_ID_BRUSH )) + _xSection->setBackColor(sal_Int32(pBrushItem->GetColor())); + } + else + { + uno::Reference< beans::XPropertySet> xProp(getUsedStyle(m_xReportDefinition),uno::UNO_QUERY_THROW); + const OUString sUndoAction(RptResId(RID_STR_UNDO_CHANGEPAGE)); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + if ( const SvxSizeItem* pSizeItem = pSet->GetItemIfSet( RPTUI_ID_SIZE )) + { + uno::Any aValue; + pSizeItem->QueryValue(aValue); + xProp->setPropertyValue(PROPERTY_PAPERSIZE,aValue); + resetZoomType(); + } + + if ( const SvxLRSpaceItem* pSpaceItem = pSet->GetItemIfSet( RPTUI_ID_LRSPACE )) + { + Any aValue; + pSpaceItem->QueryValue(aValue,MID_L_MARGIN); + xProp->setPropertyValue(PROPERTY_LEFTMARGIN,aValue); + pSpaceItem->QueryValue(aValue,MID_R_MARGIN); + xProp->setPropertyValue(PROPERTY_RIGHTMARGIN,aValue); + } + if ( const SvxULSpaceItem* pSpaceItem = pSet->GetItemIfSet( RPTUI_ID_ULSPACE )) + { + xProp->setPropertyValue(PROPERTY_TOPMARGIN,uno::Any(pSpaceItem->GetUpper())); + xProp->setPropertyValue(PROPERTY_BOTTOMMARGIN,uno::Any(pSpaceItem->GetLower())); + } + if ( const SvxPageItem* pPageItem = pSet->GetItemIfSet( RPTUI_ID_PAGE )) + { + xProp->setPropertyValue(PROPERTY_ISLANDSCAPE,uno::Any(pPageItem->IsLandscape())); + xProp->setPropertyValue(PROPERTY_NUMBERINGTYPE,uno::Any(static_cast<sal_Int16>(pPageItem->GetNumType()))); + uno::Any aValue; + pPageItem->QueryValue(aValue,MID_PAGE_LAYOUT); + xProp->setPropertyValue(PROPERTY_PAGESTYLELAYOUT,aValue); + resetZoomType(); + } + if ( const SvxBrushItem* pBrushItem = pSet->GetItemIfSet( RPTUI_ID_BRUSH )) + { + ::Color aBackColor = pBrushItem->GetColor(); + xProp->setPropertyValue(PROPERTY_BACKTRANSPARENT,uno::Any(aBackColor == COL_TRANSPARENT)); + xProp->setPropertyValue(PROPERTY_BACKCOLOR,uno::Any(aBackColor)); + } + } + } + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + pPool.clear(); + + for (SfxPoolItem* pDefault : pDefaults) + delete pDefault; + +} + + +sal_Bool SAL_CALL OReportController::attachModel(const uno::Reference< frame::XModel > & xModel) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + uno::Reference< report::XReportDefinition > xReportDefinition( xModel, UNO_QUERY ); + if ( !xReportDefinition.is() ) + return false; + + uno::Reference< document::XUndoManagerSupplier > xTestSuppUndo( xModel, UNO_QUERY ); + if ( !xTestSuppUndo.is() ) + return false; + + m_xReportDefinition = xReportDefinition; + return true; +} + + +void OReportController::openSortingAndGroupingDialog() +{ + if ( !m_xReportDefinition.is() ) + return; + if (!m_xGroupsFloater) + { + m_xGroupsFloater = std::make_shared<OGroupsSortingDialog>(getFrameWeld(), !isEditable(), this); + SvtViewOptions aDlgOpt(EViewType::Window, OStringToOUString(m_xGroupsFloater->get_help_id(), RTL_TEXTENCODING_UTF8)); + if ( aDlgOpt.Exists() ) + m_xGroupsFloater->getDialog()->set_window_state(OUStringToOString(aDlgOpt.GetWindowState(), RTL_TEXTENCODING_ASCII_US)); + } + if (isUiVisible()) + { + if (!m_xGroupsFloater->getDialog()->get_visible()) + weld::DialogController::runAsync(m_xGroupsFloater, [this](sal_Int32 /*nResult*/) { m_xGroupsFloater.reset(); }); + else + m_xGroupsFloater->response(RET_CANCEL); + } +} + +sal_Int32 OReportController::getGroupPosition(const uno::Reference< report::XGroup >& _xGroup) +{ + return rptui::getPositionInIndexAccess(m_xReportDefinition->getGroups(),_xGroup); +} + + +void OReportController::Notify(SfxBroadcaster & /* _rBc */, SfxHint const & _rHint) +{ + const DlgEdHint* pDlgEdHint = dynamic_cast<const DlgEdHint*>(&_rHint); + if (!(pDlgEdHint && pDlgEdHint->GetKind() == RPTUI_HINT_SELECTIONCHANGED)) + return; + + const sal_Int32 nSelectionCount = getDesignView()->getMarkedObjectCount(); + if ( m_nSelectionCount != nSelectionCount ) + { + m_nSelectionCount = nSelectionCount; + InvalidateAll(); + } + lang::EventObject aEvent(*this); + m_aSelectionListeners.forEach( + [&aEvent] (uno::Reference<view::XSelectionChangeListener> const& xListener) { + return xListener->selectionChanged(aEvent); + }); +} + +void OReportController::executeMethodWithUndo(TranslateId pUndoStrId,const ::std::function<void(ODesignView *)>& _pMemfun) +{ + const OUString sUndoAction = RptResId(pUndoStrId); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + _pMemfun( getDesignView() ); + InvalidateFeature( SID_UNDO ); +} + +void OReportController::alignControlsWithUndo(TranslateId pUndoStrId, ControlModification _nControlModification, bool _bAlignAtSection) +{ + const OUString sUndoAction = RptResId(pUndoStrId); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + getDesignView()->alignMarkedObjects(_nControlModification,_bAlignAtSection); + InvalidateFeature( SID_UNDO ); +} + +void OReportController::shrinkSectionBottom(const uno::Reference<report::XSection>& _xSection) +{ + const sal_Int32 nElements = _xSection->getCount(); + if (nElements == 0) + { + // there are no elements + return; + } + const sal_Int32 nSectionHeight = _xSection->getHeight(); + sal_Int32 nMaxPositionY = 0; + uno::Reference< report::XReportComponent> xReportComponent; + + // for every component get its Y-position and compare it to the current Y-position + for (int i=0;i<nElements;i++) + { + xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY); + const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY(); + const sal_Int32 nReportComponentHeight = xReportComponent->getHeight(); + const sal_Int32 nReportComponentPositionYAndHeight = nReportComponentPositionY + nReportComponentHeight; + nMaxPositionY = std::max(nReportComponentPositionYAndHeight, nMaxPositionY); + } + // now we know the minimal Y-Position and maximal Y-Position + + if (nMaxPositionY > (nSectionHeight - 7) ) // Magic Number, we use a little bit less heights for right positioning + { + // the lowest position is already 0 + return; + } + _xSection->setHeight(nMaxPositionY); +} + +void OReportController::shrinkSectionTop(const uno::Reference<report::XSection>& _xSection) +{ + const sal_Int32 nElements = _xSection->getCount(); + if (nElements == 0) + { + // there are no elements + return; + } + + const sal_Int32 nSectionHeight = _xSection->getHeight(); + sal_Int32 nMinPositionY = nSectionHeight; + uno::Reference< report::XReportComponent> xReportComponent; + + // for every component get its Y-position and compare it to the current Y-position + for (int i=0;i<nElements;i++) + { + xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY); + const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY(); + nMinPositionY = std::min(nReportComponentPositionY, nMinPositionY); + } + // now we know the minimal Y-Position and maximal Y-Position + if (nMinPositionY == 0) + { + // the lowest position is already 0 + return; + } + for (int i=0;i<nElements;i++) + { + xReportComponent.set(_xSection->getByIndex(i), uno::UNO_QUERY); + const sal_Int32 nReportComponentPositionY = xReportComponent->getPositionY(); + const sal_Int32 nNewPositionY = nReportComponentPositionY - nMinPositionY; + xReportComponent->setPositionY(nNewPositionY); + } + const sal_Int32 nNewSectionHeight = nSectionHeight - nMinPositionY; + _xSection->setHeight(nNewSectionHeight); +} + +void OReportController::shrinkSection(TranslateId pUndoStrId, const uno::Reference<report::XSection>& _xSection, sal_Int32 _nSid) +{ + if ( _xSection.is() ) + { + const OUString sUndoAction = RptResId(pUndoStrId); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + if (_nSid == SID_SECTION_SHRINK) + { + shrinkSectionTop(_xSection); + shrinkSectionBottom(_xSection); + } + else if (_nSid == SID_SECTION_SHRINK_TOP) + { + shrinkSectionTop(_xSection); + } + else if (_nSid == SID_SECTION_SHRINK_BOTTOM) + { + shrinkSectionBottom(_xSection); + } + } + + InvalidateFeature( SID_UNDO ); +} + + +uno::Any SAL_CALL OReportController::getViewData() +{ + ::osl::MutexGuard aGuard( getMutex() ); + + const sal_Int32 nCommandIDs[] = + { + SID_GRID_VISIBLE, + SID_GRID_USE, + SID_HELPLINES_MOVE, + SID_RULER, + SID_SHOW_PROPERTYBROWSER, + SID_PROPERTYBROWSER_LAST_PAGE, + SID_SPLIT_POSITION + }; + + ::comphelper::NamedValueCollection aCommandProperties; + for (sal_Int32 nCommandID : nCommandIDs) + { + const FeatureState aFeatureState = GetState( nCommandID ); + + OUString sCommandURL( getURLForId( nCommandID ).Main ); + OSL_ENSURE( sCommandURL.startsWith( ".uno:" ), "OReportController::getViewData: illegal command URL!" ); + sCommandURL = sCommandURL.copy( 5 ); + + Any aCommandState; + if ( !!aFeatureState.bChecked ) + aCommandState <<= *aFeatureState.bChecked; + else if ( aFeatureState.aValue.hasValue() ) + aCommandState = aFeatureState.aValue; + + aCommandProperties.put( sCommandURL, aCommandState ); + } + + ::comphelper::NamedValueCollection aViewData; + aViewData.put( "CommandProperties", aCommandProperties.getPropertyValues() ); + + if ( getDesignView() ) + { + ::std::vector<sal_uInt16> aCollapsedPositions; + getDesignView()->fillCollapsedSections(aCollapsedPositions); + if ( !aCollapsedPositions.empty() ) + { + uno::Sequence<beans::PropertyValue> aCollapsedSections(aCollapsedPositions.size()); + beans::PropertyValue* pCollapsedIter = aCollapsedSections.getArray(); + sal_Int32 i = 1; + for (const auto& rPos : aCollapsedPositions) + { + pCollapsedIter->Name = PROPERTY_SECTION + OUString::number(i); + pCollapsedIter->Value <<= static_cast<sal_Int32>(rPos); + ++pCollapsedIter; + ++i; + } + + aViewData.put( "CollapsedSections", aCollapsedSections ); + } + + OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection(); + if ( pSectionWindow ) + { + aViewData.put( "MarkedSection", static_cast<sal_Int32>(pSectionWindow->getReportSection().getPage()->GetPageNum()) ); + } + } + + aViewData.put( "ZoomFactor", m_nZoomValue ); + return uno::Any( aViewData.getPropertyValues() ); +} + +void SAL_CALL OReportController::restoreViewData(const uno::Any& i_data) +{ + ::osl::MutexGuard aGuard( getMutex() ); + + try + { + const ::comphelper::NamedValueCollection aViewData( i_data ); + + m_aCollapsedSections = aViewData.getOrDefault( "CollapsedSections", m_aCollapsedSections ); + m_nPageNum = aViewData.getOrDefault( "MarkedSection", m_nPageNum ); + m_nZoomValue = aViewData.getOrDefault( "ZoomFactor", m_nZoomValue ); + // TODO: setting those 3 members is not enough - in theory, restoreViewData can be called when the + // view is fully alive, so we need to reflect those 3 values in the view. + // (At the moment, the method is called only during construction phase) + + + ::comphelper::NamedValueCollection aCommandProperties( aViewData.get( "CommandProperties" ) ); + const ::std::vector< OUString > aCommandNames( aCommandProperties.getNames() ); + + for ( const auto& rCommandName : aCommandNames ) + { + const Any& rCommandValue = aCommandProperties.get( rCommandName ); + if ( !rCommandValue.hasValue() ) + continue; + + if ( getView() ) + { + util::URL aCommand; + aCommand.Complete = ".uno:" + rCommandName; + + executeUnChecked( aCommand, { comphelper::makePropertyValue("Value", rCommandValue) } ); + } + else + { + if ( rCommandName == "ShowRuler" ) + OSL_VERIFY( rCommandValue >>= m_bShowRuler ); + else if ( rCommandName == "HelplinesMove" ) + OSL_VERIFY( rCommandValue >>= m_bHelplinesMove ); + else if ( rCommandName == "GridVisible" ) + OSL_VERIFY( rCommandValue >>= m_bGridVisible ); + else if ( rCommandName == "GridUse" ) + OSL_VERIFY( rCommandValue >>= m_bGridUse ); + else if ( rCommandName == "ControlProperties" ) + OSL_VERIFY( rCommandValue >>= m_bShowProperties ); + else if ( rCommandName == "LastPropertyBrowserPage" ) + OSL_VERIFY( rCommandValue >>= m_sLastActivePage ); + else if ( rCommandName == "SplitPosition" ) + OSL_VERIFY( rCommandValue >>= m_nSplitPos ); + } + } + } + catch(const IllegalArgumentException&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +Reference<XFrame> OReportController::getXFrame() +{ + if ( !m_xFrameLoader.is() ) + { + m_xFrameLoader.set( frame::Desktop::create(m_xContext) ); + } + const sal_Int32 nFrameSearchFlag = frame::FrameSearchFlag::TASKS | frame::FrameSearchFlag::CREATE; + Reference<XFrame> xFrame = m_xFrameLoader->findFrame("_blank",nFrameSearchFlag); + return xFrame; +} + + +uno::Reference<frame::XModel> OReportController::executeReport() +{ + OSL_ENSURE(m_xReportDefinition.is(),"Where is my report?"); + + uno::Reference<frame::XModel> xModel; + if ( m_xReportDefinition.is() ) + { + TranslateId pErrorId = RID_ERR_NO_COMMAND; + bool bEnabled = !m_xReportDefinition->getCommand().isEmpty(); + if ( bEnabled ) + { + bEnabled = false; + const sal_uInt16 nCount = m_aReportModel->GetPageCount(); + sal_uInt16 i = 0; + for (; i < nCount && !bEnabled ; ++i) + { + const SdrPage* pPage = m_aReportModel->GetPage(i); + bEnabled = pPage->GetObjCount() != 0; + } + if ( !bEnabled ) + pErrorId = RID_ERR_NO_OBJECTS; + } + + dbtools::SQLExceptionInfo aInfo; + if ( !bEnabled ) + { + sdb::SQLContext aFirstMessage; + OUString sInfo = RptResId( pErrorId ); + aFirstMessage.Message = sInfo; + aInfo = aFirstMessage; + if ( isEditable() ) + { + sal_uInt16 nCommand = 0; + if (pErrorId != RID_ERR_NO_COMMAND) + { + if ( !m_bShowProperties ) + executeUnChecked(SID_SHOW_PROPERTYBROWSER, {}); + + m_sLastActivePage = "Data"; + getDesignView()->setCurrentPage(m_sLastActivePage); + nCommand = SID_SELECT_REPORT; + } + else if ( getDesignView() && !getDesignView()->isAddFieldVisible() ) + { + nCommand = SID_FM_ADD_FIELD; + } + if ( nCommand ) + { + executeUnChecked(nCommand, {}); + } + } + } + else + { + m_bInGeneratePreview = true; + try + { + weld::WaitObject aWait(getFrameWeld()); // cursor + if ( !m_xReportEngine.is() ) + m_xReportEngine.set( report::ReportEngine::create(m_xContext) ); + m_xReportEngine->setReportDefinition(m_xReportDefinition); + m_xReportEngine->setActiveConnection(getConnection()); + Reference<XFrame> xFrame = getXFrame(); + xModel = m_xReportEngine->createDocumentAlive(xFrame); + } + catch(const sdbc::SQLException&) + { // SQLExceptions and derived exceptions must not be translated + aInfo = ::cppu::getCaughtException(); + } + catch(const uno::Exception& e) + { + uno::Any aCaughtException( ::cppu::getCaughtException() ); + + // our first message says: we caught an exception + sdb::SQLContext aFirstMessage; + OUString sInfo(RptResId(RID_STR_CAUGHT_FOREIGN_EXCEPTION)); + sInfo = sInfo.replaceAll("$type$", aCaughtException.getValueTypeName()); + aFirstMessage.Message = sInfo; + + // our second message: the message of the exception we caught + sdbc::SQLException aSecondMessage; + aSecondMessage.Message = e.Message; + aSecondMessage.Context = e.Context; + + // maybe our third message: the message which is wrapped in the exception we caught + sdbc::SQLException aThirdMessage; + lang::WrappedTargetException aWrapped; + if ( aCaughtException >>= aWrapped ) + { + aThirdMessage.Message = aWrapped.Message; + aThirdMessage.Context = aWrapped.Context; + } + + if ( !aThirdMessage.Message.isEmpty() ) + aSecondMessage.NextException <<= aThirdMessage; + aFirstMessage.NextException <<= aSecondMessage; + + aInfo = aFirstMessage; + } + if (aInfo.isValid()) + { + const OUString suSQLContext = RptResId( RID_STR_COULD_NOT_CREATE_REPORT ); + aInfo.prepend(suSQLContext); + } + m_bInGeneratePreview = false; + } + + if (aInfo.isValid()) + { + showError(aInfo); + } + } + return xModel; +} + +uno::Reference< frame::XModel > SAL_CALL OReportController::getModel() +{ + return m_xReportDefinition; +} + +uno::Reference< sdbc::XRowSet > const & OReportController::getRowSet() +{ + OSL_PRECOND( m_xReportDefinition.is(), "OReportController::getRowSet: no report definition?!" ); + + if ( m_xRowSet.is() || !m_xReportDefinition.is() ) + return m_xRowSet; + + try + { + uno::Reference< sdbc::XRowSet > xRowSet( + getORB()->getServiceManager()->createInstanceWithContext("com.sun.star.sdb.RowSet", getORB()), + uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet> xRowSetProp( xRowSet, uno::UNO_QUERY_THROW ); + + xRowSetProp->setPropertyValue( PROPERTY_ACTIVECONNECTION, uno::Any( getConnection() ) ); + xRowSetProp->setPropertyValue( PROPERTY_APPLYFILTER, uno::Any( true ) ); + + auto aNoConverter = std::make_shared<AnyConverter>(); + TPropertyNamePair aPropertyMediation; + aPropertyMediation.emplace( PROPERTY_COMMAND, TPropertyConverter(PROPERTY_COMMAND,aNoConverter) ); + aPropertyMediation.emplace( PROPERTY_COMMANDTYPE, TPropertyConverter(PROPERTY_COMMANDTYPE,aNoConverter) ); + aPropertyMediation.emplace( PROPERTY_ESCAPEPROCESSING, TPropertyConverter(PROPERTY_ESCAPEPROCESSING,aNoConverter) ); + aPropertyMediation.emplace( PROPERTY_FILTER, TPropertyConverter(PROPERTY_FILTER,aNoConverter) ); + + m_xRowSetMediator = new OPropertyMediator( m_xReportDefinition, xRowSetProp, std::move(aPropertyMediation) ); + m_xRowSet = xRowSet; + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + + return m_xRowSet; +} + +void OReportController::insertGraphic() +{ + const OUString sTitle(RptResId(RID_STR_IMPORT_GRAPHIC)); + // build some arguments for the upcoming dialog + try + { + uno::Reference< report::XSection> xSection = getDesignView()->getCurrentSection(); + ::sfx2::FileDialogHelper aDialog(ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW, FileDialogFlags::Graphic, getFrameWeld()); + aDialog.SetContext(sfx2::FileDialogHelper::ReportInsertImage); + aDialog.SetTitle( sTitle ); + + uno::Reference< ui::dialogs::XFilePickerControlAccess > xController(aDialog.GetFilePicker(), UNO_QUERY_THROW); + xController->setValue(ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, css::uno::Any(true)); + xController->enableControl(ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, false/*sal_True*/); + xController->setValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, css::uno::Any(true) ); + + if ( ERRCODE_NONE == aDialog.Execute() ) + { + bool bLink = true; + xController->getValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bLink; + uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({ + { PROPERTY_IMAGEURL, Any(aDialog.GetPath()) }, + { PROPERTY_PRESERVEIRI, Any(bLink) } + })); + createControl(aArgs,xSection,OUString(),SdrObjKind::ReportDesignImageControl); + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +sal_Bool SAL_CALL OReportController::select( const Any& aSelection ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + if ( !getDesignView() ) + return true; + + getDesignView()->unmarkAllObjects(); + getDesignView()->SetMode(DlgEdMode::Select); + + uno::Sequence< uno::Reference<report::XReportComponent> > aElements; + if ( aSelection >>= aElements ) + { + if ( aElements.hasElements() ) + getDesignView()->showProperties(uno::Reference<uno::XInterface>(aElements[0],uno::UNO_QUERY)); + getDesignView()->setMarked(aElements, true); + } + else + { + uno::Reference<uno::XInterface> xObject(aSelection,uno::UNO_QUERY); + uno::Reference<report::XReportComponent> xProp(xObject,uno::UNO_QUERY); + if ( xProp.is() ) + { + getDesignView()->showProperties(xObject); + aElements = { xProp }; + getDesignView()->setMarked(aElements, true); + } + else + { + uno::Reference<report::XSection> xSection(aSelection,uno::UNO_QUERY); + if ( !xSection.is() && xObject.is() ) + getDesignView()->showProperties(xObject); + getDesignView()->setMarked(xSection,xSection.is()); + } + } + InvalidateAll(); + return true; +} + +Any SAL_CALL OReportController::getSelection( ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + Any aRet; + if ( getDesignView() ) + { + aRet = getDesignView()->getCurrentlyShownProperty(); + if ( !aRet.hasValue() ) + aRet <<= getDesignView()->getCurrentSection(); + } + return aRet; +} + +void SAL_CALL OReportController::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener ) +{ + m_aSelectionListeners.addInterface( Listener ); +} + +void SAL_CALL OReportController::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener ) +{ + m_aSelectionListeners.removeInterface( Listener ); +} + +void OReportController::createNewFunction(const uno::Any& _aValue) +{ + uno::Reference< container::XIndexContainer> xFunctions(_aValue,uno::UNO_QUERY_THROW); + const OUString sNewName = RptResId(RID_STR_FUNCTION); + uno::Reference< report::XFunction> xFunction(report::Function::create(m_xContext)); + xFunction->setName(sNewName); + // the call below will also create an undo action -> listener + xFunctions->insertByIndex(xFunctions->getCount(),uno::Any(xFunction)); +} + +IMPL_LINK_NOARG( OReportController, OnExecuteReport, void*, void ) +{ + executeReport(); +} + +void OReportController::createControl(const Sequence< PropertyValue >& _aArgs,const uno::Reference< report::XSection>& _xSection,const OUString& _sFunction,SdrObjKind _nObjectId) +{ + SequenceAsHashMap aMap(_aArgs); + getDesignView()->setMarked(_xSection, true); + OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection(); + if ( !pSectionWindow ) + return; + + OSL_ENSURE(pSectionWindow->getReportSection().getSection() == _xSection,"Invalid section after marking the correct one."); + + sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN); + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN); + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE).Width - nRightMargin; + awt::Point aPos = aMap.getUnpackedValueOrDefault(PROPERTY_POSITION,awt::Point(nLeftMargin,0)); + if ( aPos.X < nLeftMargin ) + aPos.X = nLeftMargin; + + SdrObject* pNewControl = nullptr; + uno::Reference< report::XReportComponent> xShapeProp; + if ( _nObjectId == SdrObjKind::CustomShape ) + { + pNewControl = SdrObjFactory::MakeNewObject( + *m_aReportModel, + SdrInventor::ReportDesign, + _nObjectId); + xShapeProp.set(pNewControl->getUnoShape(),uno::UNO_QUERY); + OUString sCustomShapeType = getDesignView()->GetInsertObjString(); + if ( sCustomShapeType.isEmpty() ) + sCustomShapeType = "diamond"; + OReportSection::createDefault(sCustomShapeType,pNewControl); + pNewControl->SetLogicRect(tools::Rectangle(3000,500,6000,3500)); // switch height and width + } + else if ( _nObjectId == SdrObjKind::OLE2 || SdrObjKind::ReportDesignSubReport == _nObjectId ) + { + pNewControl = SdrObjFactory::MakeNewObject( + *m_aReportModel, + SdrInventor::ReportDesign, + _nObjectId); + + pNewControl->SetLogicRect(tools::Rectangle(3000,500,8000,5500)); // switch height and width + xShapeProp.set(pNewControl->getUnoShape(),uno::UNO_QUERY_THROW); + OOle2Obj* pObj = dynamic_cast<OOle2Obj*>(pNewControl); + if ( pObj && !pObj->IsEmpty() ) + { + pObj->initializeChart(getModel()); + } + } + else + { + std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pLabel; + std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl; + + FmFormView::createControlLabelPair( + getDesignView()->GetOutDev(), + nLeftMargin, + 0, + nullptr, + nullptr, + _nObjectId, + SdrInventor::ReportDesign, + SdrObjKind::ReportDesignFixedText, + + // tdf#118963 Need a SdrModel for SdrObject creation. Dereferencing + // m_aReportModel seems pretty safe, it's done in other places, initialized + // in impl_initialize and throws a RuntimeException if not existing. + *m_aReportModel, + + pLabel, + pControl); + + pLabel.reset(); + + pNewControl = pControl.release(); + OUnoObject* pObj = dynamic_cast<OUnoObject*>(pNewControl); + assert(pObj); + if(pObj) + { + uno::Reference<beans::XPropertySet> xUnoProp(pObj->GetUnoControlModel(),uno::UNO_QUERY); + xShapeProp.set(pObj->getUnoShape(),uno::UNO_QUERY); + uno::Reference<beans::XPropertySetInfo> xShapeInfo = xShapeProp->getPropertySetInfo(); + uno::Reference<beans::XPropertySetInfo> xInfo = xUnoProp->getPropertySetInfo(); + + const OUString sProps[] = { OUString(PROPERTY_NAME) + ,OUString(PROPERTY_FONTDESCRIPTOR) + ,OUString(PROPERTY_FONTDESCRIPTORASIAN) + ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX) + ,OUString(PROPERTY_ORIENTATION) + ,OUString(PROPERTY_BORDER) + ,OUString(PROPERTY_FORMATSSUPPLIER) + ,OUString(PROPERTY_BACKGROUNDCOLOR) + }; + for(const auto & sProp : sProps) + { + if ( xInfo->hasPropertyByName(sProp) && xShapeInfo->hasPropertyByName(sProp) ) + xUnoProp->setPropertyValue(sProp,xShapeProp->getPropertyValue(sProp)); + } + + if ( xInfo->hasPropertyByName(PROPERTY_BORDER) && xShapeInfo->hasPropertyByName(PROPERTY_CONTROLBORDER) ) + xUnoProp->setPropertyValue(PROPERTY_BORDER,xShapeProp->getPropertyValue(PROPERTY_CONTROLBORDER)); + + + if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) && !_sFunction.isEmpty() ) + { + ReportFormula aFunctionFormula( ReportFormula::Expression, _sFunction ); + xUnoProp->setPropertyValue( PROPERTY_DATAFIELD, uno::Any( aFunctionFormula.getCompleteFormula() ) ); + } + + sal_Int32 nFormatKey = aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEY,sal_Int32(0)); + if ( nFormatKey && xInfo->hasPropertyByName(PROPERTY_FORMATKEY) ) + xUnoProp->setPropertyValue( PROPERTY_FORMATKEY, uno::Any( nFormatKey ) ); + + OUString sUrl = aMap.getUnpackedValueOrDefault(PROPERTY_IMAGEURL,OUString()); + if ( !sUrl.isEmpty() && xInfo->hasPropertyByName(PROPERTY_IMAGEURL) ) + xUnoProp->setPropertyValue( PROPERTY_IMAGEURL, uno::Any( sUrl ) ); + + pObj->CreateMediator(true); + + if ( _nObjectId == SdrObjKind::ReportDesignFixedText ) // special case for fixed text + xUnoProp->setPropertyValue(PROPERTY_LABEL,uno::Any(OUnoObject::GetDefaultName(pObj))); + else if ( _nObjectId == SdrObjKind::ReportDesignVerticalFixedLine ) + { + awt::Size aOlSize = xShapeProp->getSize(); + xShapeProp->setSize(awt::Size(aOlSize.Height,aOlSize.Width)); // switch height and width + } + } + } + + const sal_Int32 nShapeWidth = aMap.getUnpackedValueOrDefault(PROPERTY_WIDTH,xShapeProp->getWidth()); + if ( nShapeWidth != xShapeProp->getWidth() ) + xShapeProp->setWidth( nShapeWidth ); + + const bool bChangedPos = (aPos.X + nShapeWidth) > nPaperWidth; + if ( bChangedPos ) + aPos.X = nPaperWidth - nShapeWidth; + xShapeProp->setPosition(aPos); + + correctOverlapping(pNewControl,pSectionWindow->getReportSection()); +} + +void OReportController::createDateTime(const Sequence< PropertyValue >& _aArgs) +{ + getDesignView()->unmarkAllObjects(); + + const OUString sUndoAction(RptResId(RID_STR_UNDO_INSERT_CONTROL)); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + SequenceAsHashMap aMap(_aArgs); + aMap.createItemIfMissing(PROPERTY_FORMATKEY,aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEYDATE,sal_Int32(0))); + + uno::Reference< report::XSection> xSection = aMap.getUnpackedValueOrDefault(PROPERTY_SECTION,uno::Reference< report::XSection>()); + OUString sFunction; + + bool bDate = aMap.getUnpackedValueOrDefault(PROPERTY_DATE_STATE, false); + if ( bDate ) + { + sFunction = "TODAY()"; + createControl(aMap.getAsConstPropertyValueList(),xSection,sFunction); + } + bool bTime = aMap.getUnpackedValueOrDefault(PROPERTY_TIME_STATE, false); + if ( bTime ) + { + sFunction = "TIMEVALUE(NOW())"; + aMap[PROPERTY_FORMATKEY] <<= aMap.getUnpackedValueOrDefault(PROPERTY_FORMATKEYTIME,sal_Int32(0)); + createControl(aMap.getAsConstPropertyValueList(),xSection,sFunction); + } +} + +void OReportController::createPageNumber(const Sequence< PropertyValue >& _aArgs) +{ + getDesignView()->unmarkAllObjects(); + + const OUString sUndoAction(RptResId(RID_STR_UNDO_INSERT_CONTROL)); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + if ( !m_xReportDefinition->getPageHeaderOn() ) + { + uno::Sequence< beans::PropertyValue > aArgs; + executeChecked(SID_PAGEHEADERFOOTER,aArgs); + } + + SequenceAsHashMap aMap(_aArgs); + bool bStateOfPage = aMap.getUnpackedValueOrDefault(PROPERTY_STATE, false); + + OUString sFunction( RptResId(STR_RPT_PN_PAGE) ); + sFunction = sFunction.replaceFirst("#PAGENUMBER#", "PageNumber()"); + + if ( bStateOfPage ) + { + sFunction += RptResId(STR_RPT_PN_PAGE_OF); + sFunction = sFunction.replaceFirst("#PAGECOUNT#", "PageCount()"); + } + + bool bInPageHeader = aMap.getUnpackedValueOrDefault(PROPERTY_PAGEHEADERON, true); + createControl(_aArgs,bInPageHeader ? m_xReportDefinition->getPageHeader() : m_xReportDefinition->getPageFooter(),sFunction); +} + + +void OReportController::addPairControls(const Sequence< PropertyValue >& aArgs) +{ + getDesignView()->unmarkAllObjects(); + + // the FormatKey determines which field is required + OSectionWindow* pSectionWindow[2]; + pSectionWindow[0] = getDesignView()->getMarkedSection(); + + if ( !pSectionWindow[0] ) + { + select(uno::Any(m_xReportDefinition->getDetail())); + pSectionWindow[0] = getDesignView()->getMarkedSection(); + if ( !pSectionWindow[0] ) + return; + } + + uno::Reference<report::XSection> xCurrentSection = getDesignView()->getCurrentSection(); + UndoContext aUndoContext(getUndoManager(), RptResId(RID_STR_UNDO_INSERT_CONTROL)); + + try + { + bool bHandleOnlyOne = false; + for(const PropertyValue& rArg : aArgs) + { + if (bHandleOnlyOne) + break; + Sequence< PropertyValue > aValue; + if ( !(rArg.Value >>= aValue) ) + { // the sequence has only one element which already contains the descriptor + bHandleOnlyOne = true; + aValue = aArgs; + } + svx::ODataAccessDescriptor aDescriptor(aValue); + SequenceAsHashMap aMap(aValue); + uno::Reference<report::XSection> xSection = aMap.getUnpackedValueOrDefault("Section",xCurrentSection); + uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + + getDesignView()->setMarked(xSection, true); + pSectionWindow[0] = getDesignView()->getMarkedSection(); + + sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_LEFTMARGIN); + awt::Point aPos = aMap.getUnpackedValueOrDefault(PROPERTY_POSITION,awt::Point(nLeftMargin,0)); + if ( aPos.X < nLeftMargin ) + aPos.X = nLeftMargin; + + // LLA: new feature, add the Label in dependency of the given DND_ACTION one section up, normal or one section down + sal_Int8 nDNDAction = aMap.getUnpackedValueOrDefault("DNDAction", sal_Int8(0)); + pSectionWindow[1] = pSectionWindow[0]; + bool bLabelAboveTextField = nDNDAction == DND_ACTION_COPY; + if ( bLabelAboveTextField || nDNDAction == DND_ACTION_LINK ) + { + // Add the Label one Section up + pSectionWindow[1] = getDesignView()->getMarkedSection(bLabelAboveTextField ? PREVIOUS : POST); + if (!pSectionWindow[1]) + { + // maybe out of bounds + pSectionWindow[1] = pSectionWindow[0]; + } + } + // clear all selections + getDesignView()->unmarkAllObjects(); + + uno::Reference< beans::XPropertySet > xField( aDescriptor[ svx::DataAccessDescriptorProperty::ColumnObject ], uno::UNO_QUERY ); + uno::Reference< lang::XComponent > xHoldAlive; + if ( !xField.is() ) + { + OUString sCommand; + OUString sColumnName; + sal_Int32 nCommandType( -1 ); + OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::Command ] >>= sCommand ); + OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::ColumnName ] >>= sColumnName ); + OSL_VERIFY( aDescriptor[ svx::DataAccessDescriptorProperty::CommandType ] >>= nCommandType ); + + uno::Reference< container::XNameAccess > xColumns; + uno::Reference< sdbc::XConnection > xConnection( getConnection() ); + if ( !sCommand.isEmpty() && nCommandType != -1 && !sColumnName.isEmpty() && xConnection.is() ) + { + if ( xReportDefinition->getCommand().isEmpty() ) + { + xReportDefinition->setCommand(sCommand); + xReportDefinition->setCommandType(nCommandType); + } + + xColumns = dbtools::getFieldsByCommandDescriptor(xConnection,nCommandType,sCommand,xHoldAlive); + if ( xColumns.is() && xColumns->hasByName(sColumnName) ) + xField.set( xColumns->getByName( sColumnName ), uno::UNO_QUERY ); + } + + if ( !xField.is() ) + { + #if OSL_DEBUG_LEVEL > 0 + try + { + uno::Reference< beans::XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW ); + OUString sRowSetCommand; + sal_Int32 nRowSetCommandType( -1 ); + OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMAND ) >>= sRowSetCommand ); + OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nRowSetCommandType ); + OSL_ENSURE( ( sRowSetCommand == sCommand ) && ( nCommandType == nRowSetCommandType ), + "OReportController::addPairControls: this only works for a data source which equals our current settings!" ); + // if this asserts, then either our row set and our report definition are not in sync, or somebody + // requested the creation of a control/pair for another data source than what our report + // definition is bound to - which is not supported for the parameters case, since we + // can retrieve parameters from the RowSet only. + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + #endif + + // no column name - perhaps a parameter name? + uno::Reference< sdb::XParametersSupplier > xSuppParam( getRowSet(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xParams( xSuppParam->getParameters(), uno::UNO_SET_THROW ); + sal_Int32 nParamCount( xParams->getCount() ); + for ( sal_Int32 i=0; i<nParamCount; ++i) + { + uno::Reference< beans::XPropertySet > xParamCol( xParams->getByIndex(i), uno::UNO_QUERY_THROW ); + OUString sParamName; + OSL_VERIFY( xParamCol->getPropertyValue("Name") >>= sParamName ); + if ( sParamName == sColumnName ) + { + xField = xParamCol; + break; + } + } + } + } + if ( !xField.is() ) + continue; + + SdrObjKind nOBJID = SdrObjKind::NONE; + sal_Int32 nDataType = sdbc::DataType::BINARY; + xField->getPropertyValue(PROPERTY_TYPE) >>= nDataType; + switch ( nDataType ) + { + case sdbc::DataType::BINARY: + case sdbc::DataType::VARBINARY: + case sdbc::DataType::LONGVARBINARY: + nOBJID = SdrObjKind::ReportDesignImageControl; + break; + default: + nOBJID = SdrObjKind::ReportDesignFormattedField; + break; + } + + if ( nOBJID == SdrObjKind::NONE ) + continue; + + Reference< util::XNumberFormatsSupplier > xSupplier = getReportNumberFormatter()->getNumberFormatsSupplier(); + if ( !xSupplier.is() ) + continue; + + Reference< XNumberFormats > xNumberFormats(xSupplier->getNumberFormats()); + std::unique_ptr<SdrUnoObj, SdrObjectFreeOp> pControl[2]; + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(m_xReportDefinition,PROPERTY_RIGHTMARGIN); + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_xReportDefinition,PROPERTY_PAPERSIZE).Width - nRightMargin; + OSectionView* pSectionViews[2]; + pSectionViews[0] = &pSectionWindow[1]->getReportSection().getSectionView(); + pSectionViews[1] = &pSectionWindow[0]->getReportSection().getSectionView(); + + // find this in svx + FmFormView::createControlLabelPair( + getDesignView()->GetOutDev(), + nLeftMargin, + 0, + xField, + xNumberFormats, + nOBJID, + SdrInventor::ReportDesign, + SdrObjKind::ReportDesignFixedText, + + // tdf#118963 Need a SdrModel for SdrObject creation. Dereferencing + // m_aReportModel seems pretty safe, it's done in other places, initialized + // in impl_initialize and throws a RuntimeException if not existing. + *m_aReportModel, + + pControl[0], + pControl[1]); + + if ( pControl[0] && pControl[1] ) + { + SdrPageView* pPgViews[2]; + pPgViews[0] = pSectionViews[0]->GetSdrPageView(); + pPgViews[1] = pSectionViews[1]->GetSdrPageView(); + if ( pPgViews[0] && pPgViews[1] ) + { + OUString sDefaultName; + size_t i = 0; + OUnoObject* pObjs[2]; + for(i = 0; i < SAL_N_ELEMENTS(pControl); ++i) + { + pObjs[i] = dynamic_cast<OUnoObject*>(pControl[i].get()); + assert(pObjs[i]); + uno::Reference<beans::XPropertySet> xUnoProp(pObjs[i]->GetUnoControlModel(),uno::UNO_QUERY_THROW); + uno::Reference< report::XReportComponent> xShapeProp(pObjs[i]->getUnoShape(),uno::UNO_QUERY_THROW); + xUnoProp->setPropertyValue(PROPERTY_NAME,xShapeProp->getPropertyValue(PROPERTY_NAME)); + + uno::Reference<beans::XPropertySetInfo> xShapeInfo = xShapeProp->getPropertySetInfo(); + uno::Reference<beans::XPropertySetInfo> xInfo = xUnoProp->getPropertySetInfo(); + const OUString sProps[] = { OUString(PROPERTY_FONTDESCRIPTOR) + ,OUString(PROPERTY_FONTDESCRIPTORASIAN) + ,OUString(PROPERTY_FONTDESCRIPTORCOMPLEX) + ,OUString(PROPERTY_BORDER) + ,OUString(PROPERTY_BACKGROUNDCOLOR) + }; + for(const auto & sProp : sProps) + { + if ( xInfo->hasPropertyByName(sProp) && xShapeInfo->hasPropertyByName(sProp) ) + xUnoProp->setPropertyValue(sProp,xShapeProp->getPropertyValue(sProp)); + } + if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) ) + { + OUString sName; + xUnoProp->getPropertyValue(PROPERTY_DATAFIELD) >>= sName; + sDefaultName = sName; + xUnoProp->setPropertyValue(PROPERTY_NAME,uno::Any(sDefaultName)); + + ReportFormula aFormula( ReportFormula::Field, sName ); + xUnoProp->setPropertyValue( PROPERTY_DATAFIELD, uno::Any( aFormula.getCompleteFormula() ) ); + } + + if ( xInfo->hasPropertyByName(PROPERTY_BORDER) && xShapeInfo->hasPropertyByName(PROPERTY_CONTROLBORDER) ) + xUnoProp->setPropertyValue(PROPERTY_BORDER,xShapeProp->getPropertyValue(PROPERTY_CONTROLBORDER)); + + pObjs[i]->CreateMediator(true); + + const sal_Int32 nShapeWidth = xShapeProp->getWidth(); + const bool bChangedPos = (aPos.X + nShapeWidth) > nPaperWidth; + if ( bChangedPos ) + aPos.X = nPaperWidth - nShapeWidth; + xShapeProp->setPosition(aPos); + if ( bChangedPos ) + aPos.Y += xShapeProp->getHeight(); + aPos.X += nShapeWidth; + } + OUString sLabel; + if ( xField->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xField->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + + if (pSectionViews[0] != pSectionViews[1] && + nOBJID == SdrObjKind::ReportDesignFormattedField) // we want this nice feature only at FORMATTEDFIELD + { + uno::Reference< report::XReportComponent> xShapePropLabel(pObjs[0]->getUnoShape(),uno::UNO_QUERY_THROW); + uno::Reference< report::XReportComponent> xShapePropTextField(pObjs[1]->getUnoShape(),uno::UNO_QUERY_THROW); + if ( !sLabel.isEmpty() ) + xShapePropTextField->setName(sLabel); + awt::Point aPosLabel = xShapePropLabel->getPosition(); + awt::Point aPosTextField = xShapePropTextField->getPosition(); + aPosTextField.X = aPosLabel.X; + xShapePropTextField->setPosition(aPosTextField); + if (bLabelAboveTextField) + { + // move the label down near the splitter + const uno::Reference<report::XSection> xLabelSection = pSectionWindow[1]->getReportSection().getSection(); + aPosLabel.Y = xLabelSection->getHeight() - xShapePropLabel->getHeight(); + } + else + { + // move the label up to the splitter + aPosLabel.Y = 0; + } + xShapePropLabel->setPosition(aPosLabel); + } + OUnoObject* pObj = dynamic_cast<OUnoObject*>(pControl[0].get()); + assert(pObj); + uno::Reference< report::XFixedText> xShapeProp(pObj->getUnoShape(),uno::UNO_QUERY_THROW); + xShapeProp->setName(xShapeProp->getName() + sDefaultName ); + + for(i = 0; i < SAL_N_ELEMENTS(pControl); ++i) // insert controls + { + correctOverlapping(pControl[i].get(), pSectionWindow[1-i]->getReportSection()); + } + + if (!bLabelAboveTextField ) + { + if ( pSectionViews[0] == pSectionViews[1] ) + { + tools::Rectangle aLabel = getRectangleFromControl(pControl[0].get()); + tools::Rectangle aTextfield = getRectangleFromControl(pControl[1].get()); + + // create a Union of the given Label and Textfield + tools::Rectangle aLabelAndTextfield( aLabel ); + aLabelAndTextfield.Union(aTextfield); + + // check if there exists other fields and if yes, move down + bool bOverlapping = true; + bool bHasToMove = false; + while ( bOverlapping ) + { + const SdrObject* pOverlappedObj = isOver(aLabelAndTextfield, *pSectionWindow[0]->getReportSection().getPage(), *pSectionViews[0], true, pControl, 2); + bOverlapping = pOverlappedObj != nullptr; + if ( bOverlapping ) + { + const tools::Rectangle& aLogicRect = pOverlappedObj->GetLogicRect(); + aLabelAndTextfield.Move(0,aLogicRect.Top() + aLogicRect.getHeight() - aLabelAndTextfield.Top()); + bHasToMove = true; + } + } + + if (bHasToMove) + { + // There was a move down, we need to move the Label and the Textfield down + aLabel.Move(0, aLabelAndTextfield.Top() - aLabel.Top()); + aTextfield.Move(0, aLabelAndTextfield.Top() - aTextfield.Top()); + + uno::Reference< report::XReportComponent> xLabel(pControl[0]->getUnoShape(),uno::UNO_QUERY_THROW); + xLabel->setPositionY(aLabel.Top()); + + uno::Reference< report::XReportComponent> xTextfield(pControl[1]->getUnoShape(),uno::UNO_QUERY_THROW); + xTextfield->setPositionY(aTextfield.Top()); + } + } + } + } + // not sure where the ownership of these passes too... + pControl[0].release(); + pControl[1].release(); + } + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +OSectionView* OReportController::getCurrentSectionView() const +{ + OSectionView* pSectionView = nullptr; + OSectionWindow* pSectionWindow = getDesignView()->getMarkedSection(); + if ( pSectionWindow ) + pSectionView = &pSectionWindow->getReportSection().getSectionView(); + return pSectionView; +} + +void OReportController::changeZOrder(sal_Int32 _nId) +{ + OSectionView* pSectionView = getCurrentSectionView(); + if ( !pSectionView ) + return; + + switch(_nId) + { + case SID_FRAME_TO_BOTTOM: + pSectionView->PutMarkedToBtm(); + break; + case SID_FRAME_TO_TOP: + pSectionView->PutMarkedToTop(); + break; + case SID_FRAME_DOWN: + pSectionView->MovMarkedToBtm(); + break; + case SID_FRAME_UP: + pSectionView->MovMarkedToTop(); + break; + + case SID_OBJECT_HEAVEN: + pSectionView->SetMarkedToLayer( RPT_LAYER_FRONT ); + break; + case SID_OBJECT_HELL: + pSectionView->SetMarkedToLayer( RPT_LAYER_BACK ); + break; + } +} + +void OReportController::listen(const bool _bAdd) +{ + const OUString aProps [] = { OUString(PROPERTY_REPORTHEADERON),OUString(PROPERTY_REPORTFOOTERON) + ,OUString(PROPERTY_PAGEHEADERON),OUString(PROPERTY_PAGEFOOTERON) + ,OUString(PROPERTY_COMMAND), OUString(PROPERTY_COMMANDTYPE),OUString(PROPERTY_CAPTION) + }; + + void (SAL_CALL XPropertySet::*pPropertyListenerAction)( const OUString&, const uno::Reference< XPropertyChangeListener >& ) = + _bAdd ? &XPropertySet::addPropertyChangeListener : &XPropertySet::removePropertyChangeListener; + + for (const auto & aProp : aProps) + (m_xReportDefinition.get()->*pPropertyListenerAction)( aProp, static_cast< XPropertyChangeListener* >( this ) ); + + OXUndoEnvironment& rUndoEnv = m_aReportModel->GetUndoEnv(); + uno::Reference< XPropertyChangeListener > xUndo = &rUndoEnv; + const uno::Sequence< beans::Property> aSeq = m_xReportDefinition->getPropertySetInfo()->getProperties(); + const OUString* pPropsBegin = &aProps[0]; + const OUString* pPropsEnd = pPropsBegin + SAL_N_ELEMENTS(aProps) - 3; + for(const beans::Property& rProp : aSeq) + { + if ( ::std::find(pPropsBegin,pPropsEnd,rProp.Name) == pPropsEnd ) + (m_xReportDefinition.get()->*pPropertyListenerAction)( rProp.Name, xUndo ); + } + + // Add Listeners to UndoEnvironment + void (OXUndoEnvironment::*pElementUndoFunction)( const uno::Reference< uno::XInterface >& ) = + _bAdd ? &OXUndoEnvironment::AddElement : &OXUndoEnvironment::RemoveElement; + + (rUndoEnv.*pElementUndoFunction)( m_xReportDefinition->getStyleFamilies() ); + (rUndoEnv.*pElementUndoFunction)( m_xReportDefinition->getFunctions() ); + + // Add Listeners to ReportControllerObserver + OXReportControllerObserver& rObserver = *m_pReportControllerObserver; + + if ( m_xReportDefinition->getPageHeaderOn() && _bAdd ) + { + getDesignView()->addSection(m_xReportDefinition->getPageHeader(),DBPAGEHEADER); + rObserver.AddSection(m_xReportDefinition->getPageHeader()); + } + if ( m_xReportDefinition->getReportHeaderOn() && _bAdd ) + { + getDesignView()->addSection(m_xReportDefinition->getReportHeader(),DBREPORTHEADER); + rObserver.AddSection(m_xReportDefinition->getReportHeader()); + } + + uno::Reference< report::XGroups > xGroups = m_xReportDefinition->getGroups(); + const sal_Int32 nCount = xGroups->getCount(); + _bAdd ? xGroups->addContainerListener(&rUndoEnv) : xGroups->removeContainerListener(&rUndoEnv); + _bAdd ? xGroups->addContainerListener(&rObserver) : xGroups->removeContainerListener(&rObserver); + + for (sal_Int32 i=0;i<nCount ; ++i) + { + uno::Reference< report::XGroup > xGroup(xGroups->getByIndex(i),uno::UNO_QUERY); + (xGroup.get()->*pPropertyListenerAction)( OUString(PROPERTY_HEADERON), static_cast< XPropertyChangeListener* >( this ) ); + (xGroup.get()->*pPropertyListenerAction)( OUString(PROPERTY_FOOTERON), static_cast< XPropertyChangeListener* >( this ) ); + + (rUndoEnv.*pElementUndoFunction)( xGroup ); + (rUndoEnv.*pElementUndoFunction)( xGroup->getFunctions() ); + if ( xGroup->getHeaderOn() && _bAdd ) + { + getDesignView()->addSection(xGroup->getHeader(),DBGROUPHEADER); + rObserver.AddSection(xGroup->getHeader()); + } + } + + if ( _bAdd ) + { + getDesignView()->addSection(m_xReportDefinition->getDetail(),DBDETAIL); + rObserver.AddSection(m_xReportDefinition->getDetail()); + + for (sal_Int32 i=nCount;i > 0 ; --i) + { + uno::Reference< report::XGroup > xGroup(xGroups->getByIndex(i-1),uno::UNO_QUERY); + if ( xGroup->getFooterOn() ) + { + getDesignView()->addSection(xGroup->getFooter(),DBGROUPFOOTER); + rObserver.AddSection(xGroup->getFooter()); + } + } + if ( m_xReportDefinition->getReportFooterOn() ) + { + getDesignView()->addSection(m_xReportDefinition->getReportFooter(),DBREPORTFOOTER); + rObserver.AddSection(m_xReportDefinition->getReportFooter()); + } + if ( m_xReportDefinition->getPageFooterOn()) + { + getDesignView()->addSection(m_xReportDefinition->getPageFooter(),DBPAGEFOOTER); + rObserver.AddSection(m_xReportDefinition->getPageFooter()); + } + + xGroups->addContainerListener(static_cast<XContainerListener*>(this)); + m_xReportDefinition->addModifyListener(static_cast<XModifyListener*>(this)); + } + else /* ! _bAdd */ + { + rObserver.RemoveSection(m_xReportDefinition->getDetail()); + xGroups->removeContainerListener(static_cast<XContainerListener*>(this)); + m_xReportDefinition->removeModifyListener(static_cast<XModifyListener*>(this)); + m_aReportModel->detachController(); + } +} + +void OReportController::switchReportSection(const sal_Int16 _nId) +{ + OSL_ENSURE(_nId == SID_REPORTHEADER_WITHOUT_UNDO || _nId == SID_REPORTFOOTER_WITHOUT_UNDO || _nId == SID_REPORTHEADERFOOTER ,"Illegal id given!"); + + if ( !m_xReportDefinition.is() ) + return; + + const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() ); + const bool bSwitchOn = !m_xReportDefinition->getReportHeaderOn(); + + std::unique_ptr< UndoContext > pUndoContext; + if ( SID_REPORTHEADERFOOTER == _nId ) + { + const OUString sUndoAction(RptResId(bSwitchOn ? RID_STR_UNDO_ADD_REPORTHEADERFOOTER : RID_STR_UNDO_REMOVE_REPORTHEADERFOOTER)); + pUndoContext.reset( new UndoContext( getUndoManager(), sUndoAction ) ); + + addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel,SID_REPORTHEADER_WITHOUT_UNDO + ,::std::mem_fn(&OReportHelper::getReportHeader) + ,m_xReportDefinition + ,bSwitchOn ? Inserted : Removed + )); + + addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel,SID_REPORTFOOTER_WITHOUT_UNDO + ,::std::mem_fn(&OReportHelper::getReportFooter) + ,m_xReportDefinition + ,bSwitchOn ? Inserted : Removed + )); + } + + switch( _nId ) + { + case SID_REPORTHEADER_WITHOUT_UNDO: + m_xReportDefinition->setReportHeaderOn( bSwitchOn ); + break; + case SID_REPORTFOOTER_WITHOUT_UNDO: + m_xReportDefinition->setReportFooterOn( !m_xReportDefinition->getReportFooterOn() ); + break; + case SID_REPORTHEADERFOOTER: + m_xReportDefinition->setReportHeaderOn( bSwitchOn ); + m_xReportDefinition->setReportFooterOn( bSwitchOn ); + break; + } + + if ( SID_REPORTHEADERFOOTER == _nId ) + pUndoContext.reset(); + getView()->Resize(); +} + +void OReportController::switchPageSection(const sal_Int16 _nId) +{ + OSL_ENSURE(_nId == SID_PAGEHEADERFOOTER || _nId == SID_PAGEHEADER_WITHOUT_UNDO || _nId == SID_PAGEFOOTER_WITHOUT_UNDO ,"Illegal id given!"); + if ( !m_xReportDefinition.is() ) + return; + + const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() ); + const bool bSwitchOn = !m_xReportDefinition->getPageHeaderOn(); + + std::unique_ptr< UndoContext > pUndoContext; + if ( SID_PAGEHEADERFOOTER == _nId ) + { + const OUString sUndoAction(RptResId(bSwitchOn ? RID_STR_UNDO_ADD_REPORTHEADERFOOTER : RID_STR_UNDO_REMOVE_REPORTHEADERFOOTER)); + pUndoContext.reset( new UndoContext( getUndoManager(), sUndoAction ) ); + + addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel + ,SID_PAGEHEADER_WITHOUT_UNDO + ,::std::mem_fn(&OReportHelper::getPageHeader) + ,m_xReportDefinition + ,bSwitchOn ? Inserted : Removed + )); + + addUndoAction(std::make_unique<OReportSectionUndo>(*m_aReportModel + ,SID_PAGEFOOTER_WITHOUT_UNDO + ,::std::mem_fn(&OReportHelper::getPageFooter) + ,m_xReportDefinition + ,bSwitchOn ? Inserted : Removed + )); + } + switch( _nId ) + { + case SID_PAGEHEADER_WITHOUT_UNDO: + m_xReportDefinition->setPageHeaderOn( bSwitchOn ); + break; + case SID_PAGEFOOTER_WITHOUT_UNDO: + m_xReportDefinition->setPageFooterOn( !m_xReportDefinition->getPageFooterOn() ); + break; + case SID_PAGEHEADERFOOTER: + m_xReportDefinition->setPageHeaderOn( bSwitchOn ); + m_xReportDefinition->setPageFooterOn( bSwitchOn ); + break; + } + if ( SID_PAGEHEADERFOOTER == _nId ) + pUndoContext.reset(); + getView()->Resize(); +} + +void OReportController::modifyGroup(const bool _bAppend, const Sequence< PropertyValue >& _aArgs) +{ + if ( !m_xReportDefinition.is() ) + return; + + try + { + const SequenceAsHashMap aMap( _aArgs ); + uno::Reference< report::XGroup > xGroup = aMap.getUnpackedValueOrDefault( PROPERTY_GROUP, uno::Reference< report::XGroup >() ); + if ( !xGroup.is() ) + return; + + OXUndoEnvironment& rUndoEnv = m_aReportModel->GetUndoEnv(); + uno::Reference< report::XGroups > xGroups = m_xReportDefinition->getGroups(); + if ( _bAppend ) + { + const sal_Int32 nPos = aMap.getUnpackedValueOrDefault( PROPERTY_POSITIONY, xGroups->getCount() ); + xGroups->insertByIndex( nPos, uno::Any( xGroup ) ); + rUndoEnv.AddElement( xGroup->getFunctions() ); + } + + addUndoAction( std::make_unique<OGroupUndo>( + *m_aReportModel, + _bAppend ? RID_STR_UNDO_APPEND_GROUP : RID_STR_UNDO_REMOVE_GROUP, + _bAppend ? Inserted : Removed, + xGroup, + m_xReportDefinition + ) ); + + if ( !_bAppend ) + { + rUndoEnv.RemoveElement( xGroup->getFunctions() ); + const sal_Int32 nPos = getGroupPosition( xGroup ); + const OXUndoEnvironment::OUndoEnvLock aLock( m_aReportModel->GetUndoEnv() ); + xGroups->removeByIndex( nPos ); + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OReportController::createGroupSection(const bool _bUndo,const bool _bHeader, const Sequence< PropertyValue >& _aArgs) +{ + if ( !m_xReportDefinition.is() ) + return; + + const SequenceAsHashMap aMap(_aArgs); + const bool bSwitchOn = aMap.getUnpackedValueOrDefault(_bHeader ? OUString(PROPERTY_HEADERON) : OUString(PROPERTY_FOOTERON), false); + uno::Reference< report::XGroup> xGroup = aMap.getUnpackedValueOrDefault(PROPERTY_GROUP,uno::Reference< report::XGroup>()); + if ( !xGroup.is() ) + return; + + const OXUndoEnvironment::OUndoEnvLock aLock(m_aReportModel->GetUndoEnv()); + if ( _bUndo ) + addUndoAction(std::make_unique<OGroupSectionUndo>(*m_aReportModel + ,_bHeader ? SID_GROUPHEADER_WITHOUT_UNDO : SID_GROUPFOOTER_WITHOUT_UNDO + ,_bHeader ? ::std::mem_fn(&OGroupHelper::getHeader) : ::std::mem_fn(&OGroupHelper::getFooter) + ,xGroup + ,bSwitchOn ? Inserted : Removed + , ( _bHeader ? + (bSwitchOn ? RID_STR_UNDO_ADD_GROUP_HEADER : RID_STR_UNDO_REMOVE_GROUP_HEADER) + :(bSwitchOn ? RID_STR_UNDO_ADD_GROUP_FOOTER : RID_STR_UNDO_REMOVE_GROUP_FOOTER) + ) + )); + + if ( _bHeader ) + xGroup->setHeaderOn( bSwitchOn ); + else + xGroup->setFooterOn( bSwitchOn ); +} + +void OReportController::collapseSection(const bool _bCollapse) +{ + OSectionWindow *pSection = getDesignView()->getMarkedSection(); + if ( pSection ) + { + pSection->setCollapsed(_bCollapse); + } +} + +void OReportController::markSection(const bool _bNext) +{ + OSectionWindow *pSection = getDesignView()->getMarkedSection(); + if ( pSection ) + { + OSectionWindow *pPrevSection = getDesignView()->getMarkedSection(_bNext ? POST : PREVIOUS); + if ( pPrevSection != pSection && pPrevSection ) + select(uno::Any(pPrevSection->getReportSection().getSection())); + else + select(uno::Any(m_xReportDefinition)); + } + else + { + getDesignView()->markSection(_bNext ? 0 : getDesignView()->getSectionCount() - 1); + pSection = getDesignView()->getMarkedSection(); + if ( pSection ) + select(uno::Any(pSection->getReportSection().getSection())); + } +} + +void OReportController::createDefaultControl(const uno::Sequence< beans::PropertyValue>& _aArgs) +{ + uno::Reference< report::XSection > xSection = getDesignView()->getCurrentSection(); + if ( !xSection.is() ) + xSection = m_xReportDefinition->getDetail(); + + if ( !xSection.is() ) + return; + + const beans::PropertyValue* pIter = _aArgs.getConstArray(); + const beans::PropertyValue* pEnd = pIter + _aArgs.getLength(); + const beans::PropertyValue* pKeyModifier = ::std::find_if(pIter, pEnd, + [] (const beans::PropertyValue& x) -> bool { + return x.Name == "KeyModifier"; + }); + sal_Int16 nKeyModifier = 0; + if ( pKeyModifier == pEnd || ((pKeyModifier->Value >>= nKeyModifier) && nKeyModifier == KEY_MOD1) ) + { + Sequence< PropertyValue > aCreateArgs; + getDesignView()->unmarkAllObjects(); + createControl(aCreateArgs,xSection,OUString(),getDesignView()->GetInsertObj()); + } +} + + +void OReportController::checkChartEnabled() +{ + if ( m_bChartEnabledAsked ) + return; + + m_bChartEnabledAsked = true; + + try + { + ::utl::OConfigurationTreeRoot aConfiguration( + ::utl::OConfigurationTreeRoot::createWithComponentContext( m_xContext, "/org.openoffice.Office.ReportDesign" ) ); + + bool bChartEnabled = false; + static const OUStringLiteral sPropertyName( u"UserData/Chart" ); + if ( aConfiguration.hasByHierarchicalName(sPropertyName) ) + aConfiguration.getNodeValue( sPropertyName ) >>= bChartEnabled; + m_bChartEnabled = bChartEnabled; + } + catch(const Exception&) + { + } +} + + +// css.frame.XTitle +OUString SAL_CALL OReportController::getTitle() +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + + uno::Reference< frame::XTitle> xTitle(m_xReportDefinition,uno::UNO_QUERY_THROW); + + return xTitle->getTitle (); +} + +void OReportController::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const +{ + _rDefault <<= sal_Int16(100); +} + +// comphelper::OPropertyArrayUsageHelper +::cppu::IPropertyArrayHelper* OReportController::createArrayHelper( ) const +{ + Sequence< Property > aProps; + describeProperties(aProps); + return new ::cppu::OPropertyArrayHelper(aProps); +} + + +// cppu::OPropertySetHelper +::cppu::IPropertyArrayHelper& SAL_CALL OReportController::getInfoHelper() +{ + return *::comphelper::OPropertyArrayUsageHelper<OReportController_BASE>::getArrayHelper(); +} + +void SAL_CALL OReportController::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle,const Any& _aValue) +{ + if ( _nHandle == PROPERTY_ID_ZOOMVALUE ) + { + _aValue >>= m_nZoomValue; + impl_zoom_nothrow(); + } +} +void SAL_CALL OReportController::setMode( const OUString& aMode ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + m_sMode = aMode; +} +OUString SAL_CALL OReportController::getMode( ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return m_sMode; +} +css::uno::Sequence< OUString > SAL_CALL OReportController::getSupportedModes( ) +{ + return uno::Sequence< OUString> { OUString("remote"), OUString("normal") }; +} +sal_Bool SAL_CALL OReportController::supportsMode( const OUString& aMode ) +{ + uno::Sequence< OUString> aModes = getSupportedModes(); + return comphelper::findValue(aModes, aMode) != -1; +} + +bool OReportController::isUiVisible() const +{ + return m_sMode != "remote"; +} + +void OReportController::impl_fillState_nothrow(const OUString& _sProperty,dbaui::FeatureState& _rState) const +{ + _rState.bEnabled = isEditable(); + if ( !_rState.bEnabled ) + return; + + ::std::vector< uno::Reference< uno::XInterface > > aSelection; + getDesignView()->fillControlModelSelection(aSelection); + _rState.bEnabled = !aSelection.empty(); + if ( !_rState.bEnabled ) + return; + + uno::Any aTemp; + ::std::vector< uno::Reference< uno::XInterface > >::const_iterator aIter = aSelection.begin(); + for(; aIter != aSelection.end() && _rState.bEnabled ;++aIter) + { + uno::Reference< beans::XPropertySet> xProp(*aIter,uno::UNO_QUERY); + try + { + uno::Any aTemp2 = xProp->getPropertyValue(_sProperty); + if ( aIter == aSelection.begin() ) + { + aTemp = aTemp2; + } + else if ( aTemp != aTemp2 ) + break; + } + catch(const beans::UnknownPropertyException&) + { + _rState.bEnabled = false; + } + } + if ( aIter == aSelection.end() ) + _rState.aValue = aTemp; +} + +void OReportController::impl_zoom_nothrow() +{ + Fraction aZoom(m_nZoomValue,100); + setZoomFactor( aZoom, *getDesignView() ); + getDesignView()->zoom(aZoom); + InvalidateFeature(SID_ATTR_ZOOM,Reference< XStatusListener >(), true); + InvalidateFeature(SID_ATTR_ZOOMSLIDER,Reference< XStatusListener >(), true); +} + +bool OReportController::isFormatCommandEnabled(sal_uInt16 _nCommand,const uno::Reference< report::XReportControlFormat>& _xReportControlFormat) +{ + bool bRet = false; + if ( _xReportControlFormat.is() && !uno::Reference< report::XFixedLine>(_xReportControlFormat,uno::UNO_QUERY).is() ) // this command is really often called so we need a short cut here + { + try + { + const awt::FontDescriptor aFontDescriptor = _xReportControlFormat->getFontDescriptor(); + + switch(_nCommand) + { + case SID_ATTR_CHAR_WEIGHT: + bRet = awt::FontWeight::BOLD == aFontDescriptor.Weight; + break; + case SID_ATTR_CHAR_POSTURE: + bRet = awt::FontSlant_ITALIC == aFontDescriptor.Slant; + break; + case SID_ATTR_CHAR_UNDERLINE: + bRet = awt::FontUnderline::SINGLE == aFontDescriptor.Underline; + break; + default: + ; + } + } + catch(const uno::Exception&) + { + } + } + return bRet; +} + +bool OReportController::impl_setPropertyAtControls_throw(TranslateId pUndoResId,const OUString& _sProperty,const uno::Any& _aValue,const Sequence< PropertyValue >& _aArgs) +{ + ::std::vector< uno::Reference< uno::XInterface > > aSelection; + uno::Reference< awt::XWindow> xWindow; + lcl_getReportControlFormat( _aArgs, getDesignView(), xWindow, aSelection ); + + const OUString sUndoAction = RptResId( pUndoResId ); + UndoContext aUndoContext( getUndoManager(), sUndoAction ); + + for (const auto& rxInterface : aSelection) + { + const uno::Reference< beans::XPropertySet > xControlModel(rxInterface,uno::UNO_QUERY); + if ( xControlModel.is() ) + // tdf#117795: some elements may have not some property + // eg class "OFixedLine" doesn't have property "CharFontName" + // so in this case, instead of crashing when selecting all and changing font + // just display a warning + try + { + xControlModel->setPropertyValue(_sProperty,_aValue); + } + catch(const UnknownPropertyException&) + { + TOOLS_WARN_EXCEPTION("reportdesign", ""); + } + } + + return !aSelection.empty(); +} + +void OReportController::impl_fillCustomShapeState_nothrow(const char* _pCustomShapeType,dbaui::FeatureState& _rState) const +{ + _rState.bEnabled = isEditable(); + _rState.bChecked = getDesignView()->GetInsertObj() == SdrObjKind::CustomShape && getDesignView()->GetInsertObjString().equalsAscii(_pCustomShapeType); +} + + +OSectionWindow* OReportController::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const +{ + if ( getDesignView() ) + { + return getDesignView()->getSectionWindow(_xSection); + } + + // throw NullPointerException? + return nullptr; +} + + +void OReportController::openZoomDialog() +{ + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + + static SfxItemInfo aItemInfos[] = + { + { SID_ATTR_ZOOM, true } + }; + std::vector<SfxPoolItem*> pDefaults + { + new SvxZoomItem() + }; + rtl::Reference<SfxItemPool> pPool( new SfxItemPool("ZoomProperties", SID_ATTR_ZOOM,SID_ATTR_ZOOM, aItemInfos, &pDefaults) ); + pPool->SetDefaultMetric( MapUnit::Map100thMM ); // ripped, don't understand why + pPool->FreezeIdRanges(); // the same + try + { + SfxItemSetFixed<SID_ATTR_ZOOM,SID_ATTR_ZOOM> aDescriptor(*pPool); + // fill it + SvxZoomItem aZoomItem( m_eZoomType, m_nZoomValue, SID_ATTR_ZOOM ); + aZoomItem.SetValueSet(SvxZoomEnableFlags::N100|SvxZoomEnableFlags::WHOLEPAGE|SvxZoomEnableFlags::PAGEWIDTH); + aDescriptor.Put(aZoomItem); + + ScopedVclPtr<AbstractSvxZoomDialog> pDlg(pFact->CreateSvxZoomDialog(nullptr, aDescriptor)); + pDlg->SetLimits( 20, 400 ); + bool bCancel = ( RET_CANCEL == pDlg->Execute() ); + + if ( !bCancel ) + { + const SvxZoomItem& rZoomItem = pDlg->GetOutputItemSet()->Get( SID_ATTR_ZOOM ); + m_eZoomType = rZoomItem.GetType(); + m_nZoomValue = rZoomItem.GetValue(); + if ( m_eZoomType != SvxZoomType::PERCENT ) + m_nZoomValue = getDesignView()->getZoomFactor( m_eZoomType ); + + impl_zoom_nothrow(); + } + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + pPool.clear(); + + for (SfxPoolItem* pDefault : pDefaults) + delete pDefault; +} + + +// XVisualObject +void SAL_CALL OReportController::setVisualAreaSize( ::sal_Int64 _nAspect, const awt::Size& _aSize ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + bool bChanged = + (m_aVisualAreaSize.Width != _aSize.Width || + m_aVisualAreaSize.Height != _aSize.Height); + m_aVisualAreaSize = _aSize; + if( bChanged ) + setModified( true ); + m_nAspect = _nAspect; +} + +awt::Size SAL_CALL OReportController::getVisualAreaSize( ::sal_Int64 /*nAspect*/ ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return m_aVisualAreaSize; +} + +embed::VisualRepresentation SAL_CALL OReportController::getPreferredVisualRepresentation( ::sal_Int64 _nAspect ) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( getMutex() ); + embed::VisualRepresentation aResult; + if ( !m_bInGeneratePreview ) + { + m_bInGeneratePreview = true; + try + { + if ( !m_xReportEngine.is() ) + m_xReportEngine.set( report::ReportEngine::create(m_xContext) ); + const sal_Int32 nOldMaxRows = m_xReportEngine->getMaxRows(); + m_xReportEngine->setMaxRows(MAX_ROWS_FOR_PREVIEW); + m_xReportEngine->setReportDefinition(m_xReportDefinition); + m_xReportEngine->setActiveConnection(getConnection()); + try + { + Reference<embed::XVisualObject> xTransfer(m_xReportEngine->createDocumentModel(),UNO_QUERY); + if ( xTransfer.is() ) + { + xTransfer->setVisualAreaSize(m_nAspect,m_aVisualAreaSize); + aResult = xTransfer->getPreferredVisualRepresentation( _nAspect ); + } + } + catch(const uno::Exception&) + { + } + m_xReportEngine->setMaxRows(nOldMaxRows); + } + catch(const uno::Exception&) + { + } + m_bInGeneratePreview = false; + } + return aResult; +} + +::sal_Int32 SAL_CALL OReportController::getMapUnit( ::sal_Int64 /*nAspect*/ ) +{ + return embed::EmbedMapUnits::ONE_100TH_MM; +} + +uno::Reference< container::XNameAccess > const & OReportController::getColumns() const +{ + if ( !m_xColumns.is() && m_xReportDefinition.is() && !m_xReportDefinition->getCommand().isEmpty() ) + { + m_xColumns = dbtools::getFieldsByCommandDescriptor(getConnection(),m_xReportDefinition->getCommandType(),m_xReportDefinition->getCommand(),m_xHoldAlive); + } + return m_xColumns; +} + +OUString OReportController::getColumnLabel_throw(const OUString& i_sColumnName) const +{ + OUString sLabel; + uno::Reference< container::XNameAccess > xColumns = getColumns(); + if ( xColumns.is() && xColumns->hasByName(i_sColumnName) ) + { + uno::Reference< beans::XPropertySet> xColumn(xColumns->getByName(i_sColumnName),uno::UNO_QUERY_THROW); + if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_LABEL) ) + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + } + return sLabel; +} + + +SfxUndoManager& OReportController::getUndoManager() const +{ + DBG_TESTSOLARMUTEX(); + // this is expected to be called during UI actions, so the SM is assumed to be locked + + std::shared_ptr< OReportModel > pReportModel( getSdrModel() ); + ENSURE_OR_THROW( !!pReportModel, "no access to our model" ); + + SfxUndoManager* pUndoManager( pReportModel->GetSdrUndoManager() ); + ENSURE_OR_THROW( pUndoManager != nullptr, "no access to our model's UndoManager" ); + + return *pUndoManager; +} + + +void OReportController::clearUndoManager() const +{ + getUndoManager().Clear(); +} + + +void OReportController::addUndoAction( std::unique_ptr<SfxUndoAction> i_pAction ) +{ + getUndoManager().AddUndoAction( std::move(i_pAction) ); + + InvalidateFeature( SID_UNDO ); + InvalidateFeature( SID_REDO ); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +reportdesign_OReportController_get_implementation( + css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&) +{ + return cppu::acquire(new OReportController(context)); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ReportControllerObserver.cxx b/reportdesign/source/ui/report/ReportControllerObserver.cxx new file mode 100644 index 000000000..514624388 --- /dev/null +++ b/reportdesign/source/ui/report/ReportControllerObserver.cxx @@ -0,0 +1,342 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/config.h> + +#include <map> + +#include <ReportControllerObserver.hxx> +#include <ReportController.hxx> +#include <osl/mutex.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +#include <FormattedFieldBeautifier.hxx> + +// DBG_UNHANDLED_EXCEPTION +#include <tools/diagnose_ex.h> + +namespace rptui +{ + + using namespace ::com::sun::star; + +typedef std::map<OUString, bool> AllProperties; +typedef std::map<uno::Reference< beans::XPropertySet >, AllProperties> PropertySetInfoCache; + +class OXReportControllerObserverImpl +{ +public: + ::std::vector< uno::Reference< container::XChild> > m_aSections; + ::osl::Mutex m_aMutex; + oslInterlockedCount m_nLocks; + + explicit OXReportControllerObserverImpl(); + OXReportControllerObserverImpl(const OXReportControllerObserverImpl&) = delete; + OXReportControllerObserverImpl& operator=(const OXReportControllerObserverImpl&) = delete; +}; + + + OXReportControllerObserverImpl::OXReportControllerObserverImpl() + :m_nLocks(0) + { + } + + + OXReportControllerObserver::OXReportControllerObserver(const OReportController& _rController) + :m_pImpl(new OXReportControllerObserverImpl ) + ,m_aFormattedFieldBeautifier(_rController) + ,m_aFixedTextColor(_rController) + { + + Application::AddEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) ); + } + + OXReportControllerObserver::~OXReportControllerObserver() + { + Application::RemoveEventListener(LINK( this, OXReportControllerObserver, SettingsChanged ) ); + } + + + IMPL_LINK(OXReportControllerObserver, SettingsChanged, VclSimpleEvent&, _rEvt, void) + { + VclEventId nEvent = _rEvt.GetId(); + + if (nEvent != VclEventId::ApplicationDataChanged ) + return; + + DataChangedEvent* pData = static_cast<DataChangedEvent*>(static_cast<VclWindowEvent&>(_rEvt).GetData()); + if ( !(pData && ((( pData->GetType() == DataChangedEventType::SETTINGS ) || + ( pData->GetType() == DataChangedEventType::DISPLAY )) && + ( pData->GetFlags() & AllSettingsFlags::STYLE )))) + return; + + OEnvLock aLock(*this); + + // send all Section Objects a 'tingle' + // maybe they need a change in format, color, etc + for (const uno::Reference<container::XChild>& xChild : m_pImpl->m_aSections) + { + if (xChild.is()) + { + uno::Reference<report::XSection> xSection(xChild, uno::UNO_QUERY); + if (xSection.is()) + { + const sal_Int32 nCount = xSection->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + const uno::Any aObj = xSection->getByIndex(i); + uno::Reference < report::XReportComponent > xReportComponent(aObj, uno::UNO_QUERY); + if (xReportComponent.is()) + { + m_aFormattedFieldBeautifier.handle(xReportComponent); + m_aFixedTextColor.handle(xReportComponent); + } + } + } + } + } + } + + // XEventListener + void SAL_CALL OXReportControllerObserver::disposing(const lang::EventObject& e) + { + // check if it's an object we have cached information about + uno::Reference< beans::XPropertySet > xSourceSet(e.Source, uno::UNO_QUERY); + if ( xSourceSet.is() ) + { + uno::Reference< report::XSection> xSection(xSourceSet,uno::UNO_QUERY); + if ( xSection.is() ) + RemoveSection(xSection); + else + RemoveElement(xSourceSet); + } + } + + void OXReportControllerObserver::Clear() + { + OEnvLock aLock(*this); + m_pImpl->m_aSections.clear(); + } + + // XPropertyChangeListener + void SAL_CALL OXReportControllerObserver::propertyChange(const beans::PropertyChangeEvent& _rEvent) + { + osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + if ( m_pImpl->m_nLocks != 0 ) + return; + + m_aFormattedFieldBeautifier.notifyPropertyChange(_rEvent); + m_aFixedTextColor.notifyPropertyChange(_rEvent); + } + + +void OXReportControllerObserver::Lock() +{ + OSL_ENSURE(m_refCount,"Illegal call to dead object!"); + osl_atomic_increment( &m_pImpl->m_nLocks ); +} + +void OXReportControllerObserver::UnLock() +{ + OSL_ENSURE(m_refCount,"Illegal call to dead object!"); + + osl_atomic_decrement( &m_pImpl->m_nLocks ); +} + +void OXReportControllerObserver::AddSection(const uno::Reference< report::XSection > & _xSection) +{ + OEnvLock aLock(*this); + try + { + uno::Reference<container::XChild> xChild = _xSection; + m_pImpl->m_aSections.push_back(xChild); + uno::Reference< uno::XInterface > xInt(_xSection); + AddElement(xInt); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OXReportControllerObserver::RemoveSection(const uno::Reference< report::XSection > & _xSection) +{ + OEnvLock aLock(*this); + try + { + uno::Reference<container::XChild> xChild(_xSection); + m_pImpl->m_aSections.erase(::std::remove(m_pImpl->m_aSections.begin(),m_pImpl->m_aSections.end(), + xChild), m_pImpl->m_aSections.end()); + uno::Reference< uno::XInterface > xInt(_xSection); + RemoveElement(xInt); + } + catch(uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OXReportControllerObserver::switchListening( const uno::Reference< container::XIndexAccess >& _rxContainer, bool _bStartListening ) +{ + OSL_PRECOND( _rxContainer.is(), "OXReportControllerObserver::switchListening: invalid container!" ); + if ( !_rxContainer.is() ) + return; + + try + { + // also handle all children of this element + uno::Reference< uno::XInterface > xInterface; + sal_Int32 nCount = _rxContainer->getCount(); + for(sal_Int32 i = 0;i != nCount;++i) + { + xInterface.set(_rxContainer->getByIndex( i ),uno::UNO_QUERY); + if ( _bStartListening ) + AddElement( xInterface ); + else + RemoveElement( xInterface ); + } + + // be notified of any changes in the container elements + uno::Reference< container::XContainer > xSimpleContainer( _rxContainer, uno::UNO_QUERY ); + if ( xSimpleContainer.is() ) + { + if ( _bStartListening ) + xSimpleContainer->addContainerListener( this ); + else + xSimpleContainer->removeContainerListener( this ); + } + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void OXReportControllerObserver::switchListening( const uno::Reference< uno::XInterface >& _rxObject, bool _bStartListening ) +{ + OSL_PRECOND( _rxObject.is(), "OXReportControllerObserver::switchListening: how should I listen at a NULL object?" ); + + try + { + uno::Reference< beans::XPropertySet > xProps( _rxObject, uno::UNO_QUERY ); + if ( xProps.is() ) + { + if ( _bStartListening ) + xProps->addPropertyChangeListener( OUString(), this ); + else + xProps->removePropertyChangeListener( OUString(), this ); + } + + uno::Reference< util::XModifyBroadcaster > xBroadcaster( _rxObject, uno::UNO_QUERY ); + if ( xBroadcaster.is() ) + { + if ( _bStartListening ) + xBroadcaster->addModifyListener( this ); + else + xBroadcaster->removeModifyListener( this ); + } + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + + +void SAL_CALL OXReportControllerObserver::modified( const lang::EventObject& /*aEvent*/ ) +{ +} + + +void OXReportControllerObserver::AddElement(const uno::Reference< uno::XInterface >& _rxElement ) +{ + m_aFormattedFieldBeautifier.notifyElementInserted(_rxElement); + m_aFixedTextColor.notifyElementInserted(_rxElement); + + // if it's a container, start listening at all elements + uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY ); + if ( xContainer.is() ) + switchListening( xContainer, true ); + + switchListening( _rxElement, true ); +} + + +void OXReportControllerObserver::RemoveElement(const uno::Reference< uno::XInterface >& _rxElement) +{ + switchListening( _rxElement, false ); + + uno::Reference< container::XIndexAccess > xContainer( _rxElement, uno::UNO_QUERY ); + if ( xContainer.is() ) + switchListening( xContainer, false ); +} + + +// XContainerListener + +void SAL_CALL OXReportControllerObserver::elementInserted(const container::ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + // new listener object + uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY ); + if ( xIface.is() ) + { + AddElement(xIface); + } +} + + +void SAL_CALL OXReportControllerObserver::elementReplaced(const container::ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + uno::Reference< uno::XInterface > xIface(evt.ReplacedElement,uno::UNO_QUERY); + OSL_ENSURE(xIface.is(), "OXReportControllerObserver::elementReplaced: invalid container notification!"); + RemoveElement(xIface); + + xIface.set(evt.Element,uno::UNO_QUERY); + AddElement(xIface); +} + + +void SAL_CALL OXReportControllerObserver::elementRemoved(const container::ContainerEvent& evt) +{ + SolarMutexGuard aSolarGuard; + ::osl::MutexGuard aGuard( m_pImpl->m_aMutex ); + + uno::Reference< uno::XInterface > xIface( evt.Element, uno::UNO_QUERY ); + if ( xIface.is() ) + { + RemoveElement(xIface); + } +} + + +} // namespace rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ReportSection.cxx b/reportdesign/source/ui/report/ReportSection.cxx new file mode 100644 index 000000000..95d063c1d --- /dev/null +++ b/reportdesign/source/ui/report/ReportSection.cxx @@ -0,0 +1,805 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <memory> +#include <ReportSection.hxx> +#include <ReportWindow.hxx> +#include <DesignView.hxx> +#include <strings.hxx> +#include <RptObject.hxx> +#include <RptModel.hxx> +#include <SectionView.hxx> +#include <RptPage.hxx> +#include <ReportController.hxx> +#include <UITools.hxx> +#include <ViewsWindow.hxx> + +#include <svx/svdpagv.hxx> +#include <editeng/adjustitem.hxx> +#include <editeng/eeitem.hxx> +#include <svx/sdrpaintwindow.hxx> +#include <svx/gallery.hxx> +#include <svx/svxids.hrc> +#include <svx/svditer.hxx> +#include <svx/dbaexchange.hxx> +#include <svx/sdtagitm.hxx> + +#include <com/sun/star/awt/PopupMenuDirection.hpp> +#include <com/sun/star/frame/XPopupMenuController.hpp> +#include <comphelper/propertyvalue.hxx> +#include <toolkit/helper/convert.hxx> +#include <tools/diagnose_ex.h> +#include <RptDef.hxx> +#include <SectionWindow.hxx> +#include <helpids.h> +#include <dlgedclip.hxx> +#include <rptui_slotid.hrc> + +#include <vcl/commandevent.hxx> +#include <o3tl/safeint.hxx> + +#include <svl/itempool.hxx> +#include <svtools/extcolorcfg.hxx> + + +namespace rptui +{ + +using namespace ::com::sun::star; + + +static Color lcl_getOverlappedControlColor(/*const uno::Reference <lang::XMultiServiceFactory> _rxFactory*/) +{ + svtools::ExtendedColorConfig aConfig; + return aConfig.GetColorValue(CFG_REPORTDESIGNER, DBOVERLAPPEDCONTROL).getColor(); +} + +OReportSection::OReportSection(OSectionWindow* _pParent,const uno::Reference< report::XSection >& _xSection) + : Window(_pParent,WB_DIALOGCONTROL) + , ::comphelper::OPropertyChangeListener(m_aMutex) + , DropTargetHelper(this) + , m_pPage(nullptr) + , m_pView(nullptr) + , m_pParent(_pParent) + , m_xSection(_xSection) + , m_nPaintEntranceCount(0) + , m_eMode(DlgEdMode::Select) +{ + //EnableChildTransparentMode(); + SetHelpId(HID_REPORTSECTION); + SetMapMode(MapMode(MapUnit::Map100thMM)); + SetParentClipMode(ParentClipMode::Clip); + EnableChildTransparentMode( false ); + SetPaintTransparent( false ); + + try + { + fill(); + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", ""); + } + + m_pFunc.reset(new DlgEdFuncSelect( this )); + m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor() ); +} + +OReportSection::~OReportSection() +{ + disposeOnce(); +} + +void OReportSection::dispose() +{ + m_pPage = nullptr; + if ( m_pMulti.is() ) + m_pMulti->dispose(); + m_pMulti.clear(); + + if ( m_pReportListener.is() ) + m_pReportListener->dispose(); + m_pReportListener.clear(); + m_pFunc.reset(); + + { + if ( m_pView ) + m_pView->EndListening( *m_pModel ); + delete m_pView; + m_pView = nullptr; + } + m_pParent.clear(); + vcl::Window::dispose(); +} + +void OReportSection::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) +{ + Window::Paint(rRenderContext, rRect); + + if ( !(m_pView && m_nPaintEntranceCount == 0)) + return; + + ++m_nPaintEntranceCount; + // repaint, get PageView and prepare Region + SdrPageView* pPgView = m_pView->GetSdrPageView(); + const vcl::Region aPaintRectRegion(rRect); + + // #i74769# + SdrPaintWindow* pTargetPaintWindow = nullptr; + + // mark repaint start + if (pPgView) + { + pTargetPaintWindow = pPgView->GetView().BeginDrawLayers(GetOutDev(), aPaintRectRegion); + OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)"); + // draw background self using wallpaper + OutputDevice& rTargetOutDev = pTargetPaintWindow->GetTargetOutputDevice(); + rTargetOutDev.DrawWallpaper(rRect, Wallpaper(pPgView->GetApplicationDocumentColor())); + + // do paint (unbuffered) and mark repaint end + pPgView->DrawLayer(RPT_LAYER_FRONT, &rRenderContext); + pPgView->GetView().EndDrawLayers(*pTargetPaintWindow, true); + } + + m_pView->CompleteRedraw(&rRenderContext, aPaintRectRegion); + --m_nPaintEntranceCount; +} + +void OReportSection::fill() +{ + if ( !m_xSection.is() ) + return; + + m_pMulti = new comphelper::OPropertyChangeMultiplexer(this,m_xSection); + m_pMulti->addProperty(PROPERTY_BACKCOLOR); + + m_pReportListener = addStyleListener(m_xSection->getReportDefinition(),this); + + m_pModel = m_pParent->getViewsWindow()->getView()->getReportView()->getController().getSdrModel(); + m_pPage = m_pModel->getPage(m_xSection); + + m_pView = new OSectionView( + *m_pModel, + this, + m_pParent->getViewsWindow()->getView()); + + // #i93597# tell SdrPage that only left and right page border is defined + // instead of the full rectangle definition + m_pPage->setPageBorderOnlyLeftRight(true); + + // without the following call, no grid is painted + m_pView->ShowSdrPage( m_pPage ); + + m_pView->SetMoveSnapOnlyTopLeft( true ); + ODesignView* pDesignView = m_pParent->getViewsWindow()->getView()->getReportView(); + + // #i93595# Adapted grid to a more coarse grid and subdivisions for better visualisation. This + // is only for visualisation and has nothing to do with the actual snap + const Size aGridSizeCoarse(pDesignView->getGridSizeCoarse()); + const Size aGridSizeFine(pDesignView->getGridSizeFine()); + m_pView->SetGridCoarse(aGridSizeCoarse); + m_pView->SetGridFine(aGridSizeFine); + + // #i93595# set snap grid width to snap to all existing subdivisions + const Fraction aX(aGridSizeFine.Width()); + const Fraction aY(aGridSizeFine.Height()); + m_pView->SetSnapGridWidth(aX, aY); + + m_pView->SetGridSnap( true ); + m_pView->SetGridFront( false ); + m_pView->SetDragStripes( true ); + m_pView->SetPageVisible(); + sal_Int32 nColor = m_xSection->getBackColor(); + if ( nColor == static_cast<sal_Int32>(COL_TRANSPARENT) ) + nColor = getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR); + m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor)); + + uno::Reference<report::XReportDefinition> xReportDefinition = m_xSection->getReportDefinition(); + const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN); + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN); + m_pPage->SetLeftBorder(nLeftMargin); + m_pPage->SetRightBorder(nRightMargin); + +// LLA: TODO +// m_pPage->SetUpperBorder(-10000); + + m_pView->SetDesignMode(); + + m_pPage->SetSize( Size( getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width,5*m_xSection->getHeight()) ); + const Size aPageSize = m_pPage->GetSize(); + m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) ); +} + +void OReportSection::Paste(const uno::Sequence< beans::NamedValue >& _aAllreadyCopiedObjects,bool _bForce) +{ + OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!"); + if ( !(m_xSection.is() && _aAllreadyCopiedObjects.hasElements()) ) + return; + + // stop all drawing actions + m_pView->BrkAction(); + + // unmark all objects + m_pView->UnmarkAll(); + const OUString sSectionName = m_xSection->getName(); + for(const beans::NamedValue& rObject : _aAllreadyCopiedObjects) + { + if ( _bForce || rObject.Name == sSectionName) + { + try + { + uno::Sequence< uno::Reference<report::XReportComponent> > aCopies; + rObject.Value >>= aCopies; + for (const uno::Reference<report::XReportComponent>& rCopy : std::as_const(aCopies)) + { + SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rCopy ); + if ( pObject ) + { + // Clone to target SdrModel + SdrObject* pNewObj(pObject->CloneSdrObject(*m_pModel)); + m_pPage->InsertObject(pNewObj, SAL_MAX_SIZE); + tools::Rectangle aRet(VCLPoint(rCopy->getPosition()),VCLSize(rCopy->getSize())); + aRet.setHeight(aRet.getHeight() + 1); + aRet.setWidth(aRet.getWidth() + 1); + bool bOverlapping = true; + while ( bOverlapping ) + { + bOverlapping = isOver(aRet,*m_pPage,*m_pView,true,pNewObj) != nullptr; + if ( bOverlapping ) + { + aRet.Move(0,aRet.getHeight()+1); + pNewObj->SetLogicRect(aRet); + } + } + m_pView->AddUndo( m_pView->GetModel()->GetSdrUndoFactory().CreateUndoNewObject( *pNewObj ) ); + m_pView->MarkObj( pNewObj, m_pView->GetSdrPageView() ); + if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getHeight() + aRet.Top()) > m_xSection->getHeight()) ) + m_xSection->setHeight(aRet.getHeight() + aRet.Top()); + } + } + } + catch(uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while pasting a new object!"); + } + if ( !_bForce ) + break; + } + } +} + +void OReportSection::Delete() +{ + if( !m_pView->AreObjectsMarked() ) + return; + + m_pView->BrkAction(); + m_pView->DeleteMarked(); +} + +void OReportSection::SetMode( DlgEdMode eNewMode ) +{ + if ( eNewMode == m_eMode ) + return; + + if ( eNewMode == DlgEdMode::Insert ) + { + m_pFunc.reset(new DlgEdFuncInsert( this )); + } + else + { + m_pFunc.reset(new DlgEdFuncSelect( this )); + } + m_pFunc->setOverlappedControlColor(lcl_getOverlappedControlColor( ) ); + m_pModel->SetReadOnly(false); + m_eMode = eNewMode; +} + +void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects) +{ + Copy(_rAllreadyCopiedObjects,false); +} + +void OReportSection::Copy(uno::Sequence< beans::NamedValue >& _rAllreadyCopiedObjects,bool _bEraseAnddNoClone) +{ + OSL_ENSURE(m_xSection.is(),"Why is the section here NULL!"); + if( !m_pView->AreObjectsMarked() || !m_xSection.is() ) + return; + + // insert control models of marked objects into clipboard dialog model + const SdrMarkList& rMarkedList = m_pView->GetMarkedObjectList(); + const size_t nMark = rMarkedList.GetMarkCount(); + + ::std::vector< uno::Reference<report::XReportComponent> > aCopies; + aCopies.reserve(nMark); + + SdrUndoFactory& rUndo = m_pView->GetModel()->GetSdrUndoFactory(); + + for( size_t i = nMark; i > 0; ) + { + --i; + SdrObject* pSdrObject = rMarkedList.GetMark(i)->GetMarkedSdrObj(); + OObjectBase* pObj = dynamic_cast<OObjectBase*>(pSdrObject); + if ( pObj ) + { + try + { + SdrObject* pNewObj(pSdrObject->CloneSdrObject(pSdrObject->getSdrModelFromSdrObject())); + aCopies.emplace_back(pNewObj->getUnoShape(),uno::UNO_QUERY); + if ( _bEraseAnddNoClone ) + { + m_pView->AddUndo( rUndo.CreateUndoDeleteObject( *pSdrObject ) ); + m_pPage->RemoveObject(pSdrObject->GetOrdNum()); + } + + } + catch(uno::Exception&) + { + OSL_FAIL("Can't copy report elements!"); + } + } + } + + if ( !aCopies.empty() ) + { + ::std::reverse(aCopies.begin(),aCopies.end()); + const sal_Int32 nLength = _rAllreadyCopiedObjects.getLength(); + _rAllreadyCopiedObjects.realloc( nLength + 1); + beans::NamedValue* pNewValue = _rAllreadyCopiedObjects.getArray() + nLength; + pNewValue->Name = m_xSection->getName(); + pNewValue->Value <<= uno::Sequence< uno::Reference<report::XReportComponent> >(&(*aCopies.begin()),aCopies.size()); + } +} + +void OReportSection::MouseButtonDown( const MouseEvent& rMEvt ) +{ + m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true); // mark the section in which is clicked + m_pFunc->MouseButtonDown( rMEvt ); + Window::MouseButtonDown(rMEvt); +} + +void OReportSection::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( !m_pFunc->MouseButtonUp( rMEvt ) ) + m_pParent->getViewsWindow()->getView()->getReportView()->getController().executeUnChecked(SID_OBJECT_SELECT,uno::Sequence< beans::PropertyValue>()); +} + + +void OReportSection::MouseMove( const MouseEvent& rMEvt ) +{ + m_pFunc->MouseMove( rMEvt ); + +} + +void OReportSection::SetGridVisible(bool _bVisible) +{ + m_pView->SetGridVisible( _bVisible ); +} + +void OReportSection::SelectAll(const SdrObjKind _nObjectType) +{ + if ( !m_pView ) + return; + + if ( _nObjectType == SdrObjKind::NONE ) + m_pView->MarkAllObj(); + else + { + m_pView->UnmarkAll(); + SdrObjListIter aIter(m_pPage,SdrIterMode::DeepNoGroups); + SdrObject* pObjIter = nullptr; + while( (pObjIter = aIter.Next()) != nullptr ) + { + if ( pObjIter->GetObjIdentifier() == _nObjectType ) + m_pView->MarkObj( pObjIter, m_pView->GetSdrPageView() ); + } + } +} + +void OReportSection::Command( const CommandEvent& _rCEvt ) +{ + Window::Command(_rCEvt); + if (_rCEvt.GetCommand() != CommandEventId::ContextMenu) + return; + + OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController(); + uno::Reference<frame::XFrame> xFrame = rController.getFrame(); + css::uno::Sequence<css::uno::Any> aArgs { + css::uno::Any(comphelper::makePropertyValue("Value", OUString("report"))), + css::uno::Any(comphelper::makePropertyValue("Frame", xFrame)), + css::uno::Any(comphelper::makePropertyValue("IsContextMenu", true)) + }; + + css::uno::Reference<css::uno::XComponentContext> xContext(rController.getORB()); + css::uno::Reference<css::frame::XPopupMenuController> xMenuController( + xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.comp.framework.ResourceMenuController", aArgs, xContext), css::uno::UNO_QUERY); + + if (!xMenuController.is()) + return; + + css::uno::Reference<css::awt::XPopupMenu> xPopupMenu( + xContext->getServiceManager()->createInstanceWithContext( + "com.sun.star.awt.PopupMenu", xContext), css::uno::UNO_QUERY); + + if (!xPopupMenu.is()) + return; + + xMenuController->setPopupMenu(xPopupMenu); + + Point aPos = _rCEvt.GetMousePosPixel(); + m_pView->EndAction(); + + xPopupMenu->execute(GetComponentInterface(), + css::awt::Rectangle(aPos.X(), aPos.Y(), 1, 1), + css::awt::PopupMenuDirection::EXECUTE_DOWN); + + css::uno::Reference<css::lang::XComponent> xComponent(xMenuController, css::uno::UNO_QUERY); + xComponent->dispose(); +} + +void OReportSection::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) +{ + if ( !m_xSection.is() ) + return; + + if ( _rEvent.Source == m_xSection || PROPERTY_BACKCOLOR == _rEvent.PropertyName ) + { + sal_Int32 nColor = m_xSection->getBackColor(); + if ( nColor == static_cast<sal_Int32>(COL_TRANSPARENT) ) + nColor = getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_BACKCOLOR); + m_pView->SetApplicationDocumentColor(Color(ColorTransparency, nColor)); + Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::NoErase); + } + else + { + uno::Reference<report::XReportDefinition> xReportDefinition = m_xSection->getReportDefinition(); + const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN); + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN); + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width; + + if ( _rEvent.PropertyName == PROPERTY_LEFTMARGIN ) + { + m_pPage->SetLeftBorder(nLeftMargin); + } + else if ( _rEvent.PropertyName == PROPERTY_RIGHTMARGIN ) + { + m_pPage->SetRightBorder(nRightMargin); + } + const Size aOldPageSize = m_pPage->GetSize(); + sal_Int32 nNewHeight = 5*m_xSection->getHeight(); + if ( aOldPageSize.Height() != nNewHeight || nPaperWidth != aOldPageSize.Width() ) + { + m_pPage->SetSize( Size( nPaperWidth,nNewHeight) ); + const Size aPageSize = m_pPage->GetSize(); + m_pView->SetWorkArea( tools::Rectangle( Point( nLeftMargin, 0), Size(aPageSize.Width() - nLeftMargin - nRightMargin,aPageSize.Height()) ) ); + } + impl_adjustObjectSizePosition(nPaperWidth,nLeftMargin,nRightMargin); + m_pParent->Invalidate(InvalidateFlags::Update | InvalidateFlags::Transparent); + } +} +void OReportSection::impl_adjustObjectSizePosition(sal_Int32 i_nPaperWidth,sal_Int32 i_nLeftMargin,sal_Int32 i_nRightMargin) +{ + try + { + sal_Int32 nRightBorder = i_nPaperWidth - i_nRightMargin; + const sal_Int32 nCount = m_xSection->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference< report::XReportComponent> xReportComponent(m_xSection->getByIndex(i),uno::UNO_QUERY_THROW); + awt::Point aPos = xReportComponent->getPosition(); + awt::Size aSize = xReportComponent->getSize(); + SdrObject* pObject = SdrObject::getSdrObjectFromXShape( xReportComponent ); + if ( pObject ) + { + bool bChanged = false; + + OObjectBase& rBase = dynamic_cast<OObjectBase&>(*pObject); + rBase.EndListening(); + if ( aPos.X < i_nLeftMargin ) + { + aPos.X = i_nLeftMargin; + bChanged = true; + } + if ( (aPos.X + aSize.Width) > nRightBorder ) + { + aPos.X = nRightBorder - aSize.Width; + if ( aPos.X < i_nLeftMargin ) + { + aSize.Width += aPos.X - i_nLeftMargin; + aPos.X = i_nLeftMargin; + // add listener around + rBase.StartListening(); + xReportComponent->setSize(aSize); + rBase.EndListening(); + } + bChanged = true; + } + if ( aPos.Y < 0 ) + aPos.Y = 0; + if ( bChanged ) + { + xReportComponent->setPosition(aPos); + correctOverlapping(pObject,*this,false); + tools::Rectangle aRet(VCLPoint(xReportComponent->getPosition()),VCLSize(xReportComponent->getSize())); + aRet.setHeight(aRet.getHeight() + 1); + aRet.setWidth(aRet.getWidth() + 1); + if ( m_xSection.is() && (o3tl::make_unsigned(aRet.getHeight() + aRet.Top()) > m_xSection->getHeight()) ) + m_xSection->setHeight(aRet.getHeight() + aRet.Top()); + + pObject->RecalcBoundRect(); + } + rBase.StartListening(); + } + } + } + catch(const uno::Exception &) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "OReportSection::impl_adjustObjectSizePosition()"); + } +} + +bool OReportSection::handleKeyEvent(const KeyEvent& _rEvent) +{ + return m_pFunc && m_pFunc->handleKeyEvent(_rEvent); +} + +void OReportSection::deactivateOle() +{ + if (m_pFunc) + m_pFunc->deactivateOle(true); +} + +void OReportSection::createDefault(const OUString& _sType) +{ + SdrObject* pObj = m_pView->GetCreateObj(); + if ( !pObj ) + return; + createDefault(_sType,pObj); +} + +void OReportSection::createDefault(const OUString& _sType,SdrObject* _pObj) +{ + bool bAttributesAppliedFromGallery = false; + + if ( GalleryExplorer::GetSdrObjCount( GALLERY_THEME_POWERPOINT ) ) + { + std::vector< OUString > aObjList; + if ( GalleryExplorer::FillObjListTitle( GALLERY_THEME_POWERPOINT, aObjList ) ) + { + auto aIter = std::find_if(aObjList.begin(), aObjList.end(), + [&_sType](const OUString& rObj) { return rObj.equalsIgnoreAsciiCase(_sType); }); + if (aIter != aObjList.end()) + { + auto i = static_cast<sal_uInt32>(std::distance(aObjList.begin(), aIter)); + OReportModel aReportModel(nullptr); + SfxItemPool& rPool = aReportModel.GetItemPool(); + rPool.FreezeIdRanges(); + if ( GalleryExplorer::GetSdrObj( GALLERY_THEME_POWERPOINT, i, &aReportModel ) ) + { + const SdrObject* pSourceObj = aReportModel.GetPage( 0 )->GetObj( 0 ); + if( pSourceObj ) + { + const SfxItemSet& rSource = pSourceObj->GetMergedItemSet(); + SfxItemSetFixed< + // Ranges from SdrAttrObj: + SDRATTR_START, SDRATTR_SHADOW_LAST, + SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, + SDRATTR_TEXTDIRECTION, + SDRATTR_TEXTDIRECTION, + // Graphic attributes, 3D properties, + // CustomShape properties: + SDRATTR_GRAF_FIRST, + SDRATTR_CUSTOMSHAPE_LAST, + // Range from SdrTextObj: + EE_ITEMS_START, EE_ITEMS_END> + aDest( _pObj->getSdrModelFromSdrObject().GetItemPool() ); + aDest.Set( rSource ); + _pObj->SetMergedItemSet( aDest ); + Degree100 nAngle = pSourceObj->GetRotateAngle(); + if ( nAngle ) + _pObj->NbcRotate( _pObj->GetSnapRect().Center(), nAngle ); + bAttributesAppliedFromGallery = true; + } + } + } + } + } + if ( !bAttributesAppliedFromGallery ) + { + _pObj->SetMergedItem( SvxAdjustItem( SvxAdjust::Center, EE_PARA_JUST) ); + _pObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); + _pObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) ); + _pObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( false ) ); + static_cast<SdrObjCustomShape*>(_pObj)->MergeDefaultAttributes( &_sType ); + } +} + +uno::Reference< report::XReportComponent > OReportSection::getCurrentControlModel() const +{ + uno::Reference< report::XReportComponent > xModel; + if ( m_pView ) + { + const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList(); + + if ( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pDlgEdObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); + OObjectBase* pObj = dynamic_cast<OObjectBase*>(pDlgEdObj); + if ( pObj ) + xModel = pObj->getReportComponent().get(); + } + } + return xModel; +} + +void OReportSection::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const +{ + if ( !m_pView ) + return; + + const SdrMarkList& rMarkList = m_pView->GetMarkedObjectList(); + const size_t nMarkCount = rMarkList.GetMarkCount(); + + for (size_t i=0; i < nMarkCount; ++i) + { + const SdrObject* pDlgEdObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); + const OObjectBase* pObj = dynamic_cast<const OObjectBase*>(pDlgEdObj); + if ( pObj ) + { + uno::Reference<uno::XInterface> xInterface(pObj->getReportComponent()); + _rSelection.push_back(xInterface); + } + } +} + +sal_Int8 OReportSection::AcceptDrop( const AcceptDropEvent& _rEvt ) +{ + ::Point aDropPos(_rEvt.maPosPixel); + const MouseEvent aMouseEvt(aDropPos); + if ( m_pFunc->isOverlapping(aMouseEvt) ) + return DND_ACTION_NONE; + + if ( _rEvt.mnAction == DND_ACTION_COPY || + _rEvt.mnAction == DND_ACTION_LINK + ) + { + if (!m_pParent) return DND_ACTION_NONE; + sal_uInt16 nCurrentPosition = m_pParent->getViewsWindow()->getPosition(m_pParent); + if (_rEvt.mnAction == DND_ACTION_COPY ) + { + // we must assure, we can't drop in the top section + if (nCurrentPosition < 1) + { + return DND_ACTION_NONE; + } + return DND_ACTION_LINK; + } + if (_rEvt.mnAction == DND_ACTION_LINK) + { + // we must assure, we can't drop in the bottom section + if (m_pParent->getViewsWindow()->getSectionCount() > (nCurrentPosition + 1) ) + { + return DND_ACTION_COPY; + } + return DND_ACTION_NONE; + } + } + else + { + const DataFlavorExVector& rFlavors = GetDataFlavorExVector(); + if ( svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors) + || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) ) + return _rEvt.mnAction; + + const sal_Int8 nDropOption = ( OReportExchange::canExtract(rFlavors) ) ? DND_ACTION_COPYMOVE : DND_ACTION_NONE; + + return nDropOption; + } + return DND_ACTION_NONE; +} + + +sal_Int8 OReportSection::ExecuteDrop( const ExecuteDropEvent& _rEvt ) +{ + ::Point aDropPos(PixelToLogic(_rEvt.maPosPixel)); + const MouseEvent aMouseEvt(aDropPos); + if ( m_pFunc->isOverlapping(aMouseEvt) ) + return DND_ACTION_NONE; + + sal_Int8 nDropOption = DND_ACTION_NONE; + const TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable); + const DataFlavorExVector& rFlavors = aDropped.GetDataFlavorExVector(); + bool bMultipleFormat = svx::OMultiColumnTransferable::canExtractDescriptor(rFlavors); + if ( OReportExchange::canExtract(rFlavors) ) + { + OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aDropped); + Paste(aCopies,true); + nDropOption = DND_ACTION_COPYMOVE; + m_pParent->getViewsWindow()->BrkAction(); + m_pParent->getViewsWindow()->unmarkAllObjects(m_pView); + } + else if ( bMultipleFormat + || svx::OColumnTransferable::canExtractColumnDescriptor(rFlavors, ColumnTransferFormatFlags::FIELD_DESCRIPTOR | ColumnTransferFormatFlags::CONTROL_EXCHANGE | ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) ) + { + m_pParent->getViewsWindow()->getView()->setMarked(m_pView, true); + m_pView->UnmarkAll(); + const tools::Rectangle& rRect = m_pView->GetWorkArea(); + if ( aDropPos.X() < rRect.Left() ) + aDropPos.setX( rRect.Left() ); + else if ( aDropPos.X() > rRect.Right() ) + aDropPos.setX( rRect.Right() ); + + if ( aDropPos.Y() > rRect.Bottom() ) + aDropPos.setY( rRect.Bottom() ); + + uno::Sequence<beans::PropertyValue> aValues; + if ( !bMultipleFormat ) + { + svx::ODataAccessDescriptor aDescriptor = svx::OColumnTransferable::extractColumnDescriptor(aDropped); + + aValues.realloc(1); + aValues.getArray()[0].Value <<= aDescriptor.createPropertyValueSequence(); + } + else + aValues = svx::OMultiColumnTransferable::extractDescriptor(aDropped); + + for(beans::PropertyValue & propVal : asNonConstRange(aValues)) + { + uno::Sequence<beans::PropertyValue> aCurrent; + propVal.Value >>= aCurrent; + sal_Int32 nLength = aCurrent.getLength(); + if ( nLength ) + { + aCurrent.realloc(nLength + 3); + auto pCurrent = aCurrent.getArray(); + pCurrent[nLength].Name = PROPERTY_POSITION; + pCurrent[nLength++].Value <<= AWTPoint(aDropPos); + // give also the DND Action (Shift|Ctrl) Key to really say what we want + pCurrent[nLength].Name = "DNDAction"; + pCurrent[nLength++].Value <<= _rEvt.mnAction; + + pCurrent[nLength].Name = "Section"; + pCurrent[nLength++].Value <<= getSection(); + propVal.Value <<= aCurrent; + } + } + + // we use this way to create undo actions + OReportController& rController = m_pParent->getViewsWindow()->getView()->getReportView()->getController(); + rController.executeChecked(SID_ADD_CONTROL_PAIR,aValues); + nDropOption = DND_ACTION_COPY; + } + return nDropOption; +} + +void OReportSection::stopScrollTimer() +{ + m_pFunc->stopScrollTimer(); +} + +bool OReportSection::isUiActive() const +{ + return m_pFunc->isUiActive(); +} + + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ReportWindow.cxx b/reportdesign/source/ui/report/ReportWindow.cxx new file mode 100644 index 000000000..8da0855f6 --- /dev/null +++ b/reportdesign/source/ui/report/ReportWindow.cxx @@ -0,0 +1,433 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ReportWindow.hxx> +#include <ReportSection.hxx> +#include <SectionView.hxx> +#include <ViewsWindow.hxx> +#include <DesignView.hxx> +#include <UITools.hxx> + +#include <unotools/syslocale.hxx> +#include <unotools/localedatawrapper.hxx> + +#include <vcl/settings.hxx> + +#include <RptDef.hxx> +#include <strings.hxx> +#include <ReportController.hxx> +#include <ScrollHelper.hxx> + +#include <helpids.h> +#include <dlgedfac.hxx> + + +#define SECTION_OFFSET 3 +namespace rptui +{ +using namespace ::com::sun::star; +using namespace ::comphelper; + + + +OReportWindow::OReportWindow(OScrollWindowHelper* _pParent,ODesignView* _pView) +: Window(_pParent,WB_DIALOGCONTROL) +, ::comphelper::OPropertyChangeListener(m_aMutex) +,m_aHRuler(VclPtr<Ruler>::Create(this)) +,m_pView(_pView) +,m_pParent(_pParent) +,m_aViewsWindow(VclPtr<rptui::OViewsWindow>::Create(this)) +,m_pObjFac( new DlgEdFactory() ) +{ + SetHelpId(UID_RPT_REPORTWINDOW); + SetMapMode( MapMode( MapUnit::Map100thMM ) ); + + m_aViewsWindow->Show(); + + m_aHRuler->Show(); + m_aHRuler->Activate(); + m_aHRuler->SetPagePos(); + m_aHRuler->SetBorders(); + m_aHRuler->SetIndents(); + m_aHRuler->SetMargin1(); + m_aHRuler->SetMargin2(); + const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum(); + m_aHRuler->SetUnit(MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH); + + ImplInitSettings(); + m_pReportListener = addStyleListener(_pView->getController().getReportDefinition(),this); +} + +OReportWindow::~OReportWindow() +{ + disposeOnce(); +} + +void OReportWindow::dispose() +{ + if ( m_pReportListener.is() ) + m_pReportListener->dispose(); + m_aHRuler.disposeAndClear(); + m_aViewsWindow.disposeAndClear(); + m_pView.clear(); + m_pParent.clear(); + vcl::Window::dispose(); +} + +void OReportWindow::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType ) +{ + m_aViewsWindow->SetInsertObj( eObj,_sShapeType); +} + +OUString const & OReportWindow::GetInsertObjString() const +{ + return m_aViewsWindow->GetInsertObjString(); +} + +void OReportWindow::SetMode( DlgEdMode eNewMode ) +{ + m_aViewsWindow->SetMode(eNewMode); +} + +void OReportWindow::removeSection(sal_uInt16 _nPosition) +{ + m_aViewsWindow->removeSection(_nPosition); + m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight()); + m_aViewsWindow->Invalidate(InvalidateFlags::Transparent); +} + +void OReportWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition) +{ + if ( !_xSection.is() ) + return; + + m_aViewsWindow->addSection(_xSection,_sColorEntry,_nPosition); + + m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight()); +} + +void OReportWindow::toggleGrid(bool _bVisible) +{ + m_aViewsWindow->toggleGrid(_bVisible); +} + +void OReportWindow::showRuler(bool _bShow) +{ + m_aHRuler->Show(_bShow); + + m_aViewsWindow->showRuler(_bShow); +} + +sal_Int32 OReportWindow::getMaxMarkerWidth() const +{ + Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH)); + aStartWidth *= m_aViewsWindow->GetMapMode().GetScaleX(); + return sal_Int32(static_cast<tools::Long>(aStartWidth)); +} + +sal_Int32 OReportWindow::GetTotalWidth() const +{ + sal_Int32 nWidth = 0; + if ( !m_aViewsWindow->empty() ) + { + Fraction aStartWidth(tools::Long(REPORT_ENDMARKER_WIDTH + REPORT_STARTMARKER_WIDTH )); + const Fraction aZoom(m_pView->getController().getZoomValue(),100); + aStartWidth *= aZoom; + sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_pView->getController().getReportDefinition(),PROPERTY_PAPERSIZE).Width; + nPaperWidth = tools::Long(nPaperWidth * aZoom); + const Size aPageSize = LogicToPixel(Size(nPaperWidth,0)); + nWidth = aPageSize.Width() + tools::Long(aStartWidth); + } + return nWidth; +} + +void OReportWindow::Resize() +{ + Window::Resize(); + if ( m_aViewsWindow->empty() ) + return; + + const Size aTotalOutputSize = GetOutputSizePixel(); + Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH)*m_pView->getController().getZoomValue(),100); + + const Point aOffset = LogicToPixel(Point(SECTION_OFFSET, 0), MapMode(MapUnit::MapAppFont)); + Point aStartPoint(static_cast<tools::Long>(aStartWidth) + aOffset.X(),0); + uno::Reference<report::XReportDefinition> xReportDefinition = getReportView()->getController().getReportDefinition(); + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width; + sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN); + sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN); + Size aPageSize = m_aViewsWindow->LogicToPixel(Size(nPaperWidth ,0)); + nLeftMargin = m_aViewsWindow->LogicToPixel(Size(nLeftMargin,0)).Width(); + nRightMargin = m_aViewsWindow->LogicToPixel(Size(nRightMargin,0)).Width(); + + aPageSize.setHeight( m_aHRuler->GetSizePixel().Height() ); + + const tools::Long nTermp(m_aViewsWindow->getTotalHeight() + aPageSize.Height()); + tools::Long nSectionsHeight = ::std::max<tools::Long>(nTermp,aTotalOutputSize.Height()); + + m_aHRuler->SetPosSizePixel(aStartPoint,aPageSize); + m_aHRuler->SetNullOffset(nLeftMargin); + m_aHRuler->SetMargin1(0); + m_aHRuler->SetMargin2(aPageSize.Width() - nLeftMargin - nRightMargin); + + aStartPoint.AdjustY(aPageSize.Height() ); + nSectionsHeight -= aStartPoint.Y(); + + aStartPoint.setX( aOffset.X() ); + + m_aViewsWindow->SetPosSizePixel(aStartPoint,Size(aTotalOutputSize.Width(),nSectionsHeight)); +} + +Point OReportWindow::getThumbPos() const +{ + return m_pParent->getThumbPos(); +} + +void OReportWindow::ImplInitSettings() +{ + SetBackground( ); +} + +void OReportWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +sal_Int32 OReportWindow::GetTotalHeight() const +{ + return m_aViewsWindow->getTotalHeight(); +} + +void OReportWindow::ScrollChildren(const Point& _aThumbPos) +{ + MapMode aMap = m_aHRuler->GetMapMode(); + Point aOrg( aMap.GetOrigin() ); + if ( aOrg.X() != (-_aThumbPos.X()) ) + { + aMap.SetOrigin( Point(- _aThumbPos.X(), aOrg.Y())); + m_aHRuler->SetMapMode( aMap ); + m_aHRuler->Scroll(-(aOrg.X() + _aThumbPos.X()),0); + } + + m_aViewsWindow->scrollChildren(_aThumbPos); +} + +sal_uInt16 OReportWindow::getSectionCount() const +{ + return m_aViewsWindow->getSectionCount(); +} + +void OReportWindow::notifySizeChanged() +{ + m_pParent->setTotalSize(GetTotalWidth(),GetTotalHeight()); +} + +bool OReportWindow::HasSelection() const +{ + return m_aViewsWindow->HasSelection(); +} + +void OReportWindow::Delete() +{ + + m_aViewsWindow->Delete(); +} + +void OReportWindow::Copy() +{ + + m_aViewsWindow->Copy(); +} + +void OReportWindow::Paste() +{ + + m_aViewsWindow->Paste(); +} + +bool OReportWindow::IsPasteAllowed() const +{ + return m_aViewsWindow->IsPasteAllowed(); +} + +void OReportWindow::SelectAll(const SdrObjKind _nObjectType) +{ + + m_aViewsWindow->SelectAll(_nObjectType); +} + +void OReportWindow::unmarkAllObjects() +{ + + m_aViewsWindow->unmarkAllObjects(nullptr); +} + +void OReportWindow::showProperties(const uno::Reference< report::XSection>& _xReportComponent) +{ + OSectionWindow* pSectionWindow = m_aViewsWindow->getSectionWindow( _xReportComponent ); + m_pView->UpdatePropertyBrowserDelayed(pSectionWindow->getReportSection().getSectionView()); +} + +bool OReportWindow::handleKeyEvent(const KeyEvent& _rEvent) +{ + return m_aViewsWindow->handleKeyEvent(_rEvent); +} + +void OReportWindow::setMarked(OSectionView const * _pSectionView, bool _bMark) +{ + if ( _pSectionView ) + m_aViewsWindow->setMarked(_pSectionView,_bMark); +} + +void OReportWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark) +{ + + m_aViewsWindow->setMarked(_xSection,_bMark); +} + +void OReportWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _xShape, bool _bMark) +{ + + m_aViewsWindow->setMarked(_xShape,_bMark); +} + +OSectionWindow* OReportWindow::getMarkedSection(NearSectionAccess nsa) const +{ + return m_aViewsWindow->getMarkedSection(nsa); +} + +OSectionWindow* OReportWindow::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const +{ + return m_aViewsWindow->getSectionWindow(_xSection); +} + +void OReportWindow::markSection(const sal_uInt16 _nPos) +{ + + m_aViewsWindow->markSection(_nPos); +} + +void OReportWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const +{ + + m_aViewsWindow->fillCollapsedSections(_rCollapsedPositions); +} + +void OReportWindow::collapseSections(const uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections) +{ + + m_aViewsWindow->collapseSections(_aCollapsedSections); +} + +void OReportWindow::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection) +{ + m_aViewsWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection); +} + +void OReportWindow::setGridSnap(bool bOn) +{ + + m_aViewsWindow->setGridSnap(bOn); +} + +void OReportWindow::setDragStripes(bool bOn) +{ + m_aViewsWindow->setDragStripes(bOn); +} + +sal_uInt32 OReportWindow::getMarkedObjectCount() const +{ + return m_aViewsWindow->getMarkedObjectCount(); +} + +void OReportWindow::zoom(const Fraction& _aZoom) +{ + m_aHRuler->SetZoom(_aZoom); + m_aHRuler->Invalidate(); + + m_aViewsWindow->zoom(_aZoom); + + notifySizeChanged(); + const Point aNewThumbPos( m_pParent->getThumbPos() ); + + ScrollChildren( aNewThumbPos ); + Resize(); + + Invalidate(InvalidateFlags::NoErase | InvalidateFlags::NoChildren | InvalidateFlags::Transparent); +} + +void OReportWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const +{ + m_aViewsWindow->fillControlModelSelection(_rSelection); +} + +sal_Int32 OReportWindow::impl_getRealPixelWidth() const +{ + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(m_pView->getController().getReportDefinition(),PROPERTY_PAPERSIZE).Width; + MapMode aMap( MapUnit::Map100thMM ); + const Size aPageSize = LogicToPixel(Size(nPaperWidth,0),aMap); + return aPageSize.Width() + REPORT_ENDMARKER_WIDTH + REPORT_STARTMARKER_WIDTH + SECTION_OFFSET; +} + +sal_uInt16 OReportWindow::getZoomFactor(SvxZoomType _eType) const +{ + sal_uInt16 nZoom(100); + const Size aSize( GetSizePixel() ); + switch( _eType) + { + case SvxZoomType::PERCENT: + nZoom = m_pView->getController().getZoomValue(); + break; + case SvxZoomType::OPTIMAL: + break; + case SvxZoomType::WHOLEPAGE: + { + nZoom = static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Width()*100,impl_getRealPixelWidth()))); + MapMode aMap( MapUnit::Map100thMM ); + const Size aHeight = m_aViewsWindow->LogicToPixel(m_aViewsWindow->PixelToLogic(Size(0,GetTotalHeight() + m_aHRuler->GetSizePixel().Height())),aMap); + nZoom = ::std::min(nZoom,static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Height()*100,aHeight.Height())))); + } + break; + case SvxZoomType::PAGEWIDTH: + nZoom = static_cast<sal_uInt16>(static_cast<tools::Long>(Fraction(aSize.Width()*100,impl_getRealPixelWidth()))); + break; + default: + break; + } + + return nZoom; +} + +void OReportWindow::_propertyChanged(const beans::PropertyChangeEvent&) +{ + Resize(); + m_aViewsWindow->Resize(); + Invalidate(InvalidateFlags::Transparent); +} + +} //rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ScrollHelper.cxx b/reportdesign/source/ui/report/ScrollHelper.cxx new file mode 100644 index 000000000..bf5f261cf --- /dev/null +++ b/reportdesign/source/ui/report/ScrollHelper.cxx @@ -0,0 +1,412 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <ScrollHelper.hxx> +#include <DesignView.hxx> +#include <ReportController.hxx> +#include <ReportWindow.hxx> +#include <UITools.hxx> +#include <com/sun/star/accessibility/AccessibleRole.hpp> + +#include <vcl/commandevent.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> + +namespace rptui +{ +#define SECTION_OFFSET 3 +#define SCR_LINE_SIZE 10 +using namespace ::com::sun::star; + + +static void lcl_setScrollBar(sal_Int32 _nNewValue,const Point& _aPos,const Size& _aSize,ScrollBar& _rScrollBar) +{ + _rScrollBar.SetPosSizePixel(_aPos,_aSize); + _rScrollBar.SetPageSize( _nNewValue ); + _rScrollBar.SetVisibleSize( _nNewValue ); +} + + +OScrollWindowHelper::OScrollWindowHelper( ODesignView* _pDesignView) + : OScrollWindowHelper_BASE( _pDesignView,WB_DIALOGCONTROL) + ,OPropertyChangeListener(m_aMutex) + ,m_aHScroll( VclPtr<ScrollBar>::Create(this, WB_HSCROLL|WB_REPEAT|WB_DRAG) ) + ,m_aVScroll( VclPtr<ScrollBar>::Create(this, WB_VSCROLL|WB_REPEAT|WB_DRAG) ) + ,m_aCornerWin( VclPtr<ScrollBarBox>::Create(this) ) + ,m_pParent(_pDesignView) + ,m_aReportWindow(VclPtr<rptui::OReportWindow>::Create(this,m_pParent)) +{ + SetMapMode( MapMode( MapUnit::Map100thMM ) ); + + impl_initScrollBar( *m_aHScroll ); + impl_initScrollBar( *m_aVScroll ); + + m_aReportWindow->SetMapMode( MapMode( MapUnit::Map100thMM ) ); + m_aReportWindow->Show(); + + // normally we should be SCROLL_PANE + SetAccessibleRole(css::accessibility::AccessibleRole::SCROLL_PANE); + ImplInitSettings(); +} + + +OScrollWindowHelper::~OScrollWindowHelper() +{ + disposeOnce(); +} + +void OScrollWindowHelper::dispose() +{ + if ( m_pReportDefinitionMultiPlexer.is() ) + m_pReportDefinitionMultiPlexer->dispose(); + + m_aHScroll.disposeAndClear(); + m_aVScroll.disposeAndClear(); + m_aCornerWin.disposeAndClear(); + m_aReportWindow.disposeAndClear(); + m_pParent.clear(); + OScrollWindowHelper_BASE::dispose(); +} + + +void OScrollWindowHelper::impl_initScrollBar( ScrollBar& _rScrollBar ) const +{ + AllSettings aSettings( _rScrollBar.GetSettings() ); + StyleSettings aStyle( aSettings.GetStyleSettings() ); + aStyle.SetDragFullOptions( aStyle.GetDragFullOptions() | DragFullOptions::Scroll ); // live scrolling + aSettings.SetStyleSettings( aStyle ); + _rScrollBar.SetSettings( aSettings ); + + _rScrollBar.SetScrollHdl( LINK( const_cast<OScrollWindowHelper*>(this), OScrollWindowHelper, ScrollHdl ) ); + _rScrollBar.SetLineSize( SCR_LINE_SIZE ); +} + + +void OScrollWindowHelper::initialize() +{ + uno::Reference<report::XReportDefinition> xReportDefinition = m_pParent->getController().getReportDefinition(); + m_pReportDefinitionMultiPlexer = addStyleListener(xReportDefinition,this); +} + +void OScrollWindowHelper::setTotalSize(sal_Int32 _nWidth ,sal_Int32 _nHeight) +{ + m_aTotalPixelSize.setWidth( _nWidth ); + m_aTotalPixelSize.setHeight( _nHeight ); + + // now set the ranges without start marker + Fraction aStartWidth(REPORT_STARTMARKER_WIDTH * m_pParent->getController().getZoomValue(),100); + tools::Long nWidth = tools::Long(_nWidth - static_cast<double>(aStartWidth)); + m_aHScroll->SetRangeMax( nWidth ); + m_aVScroll->SetRangeMax( m_aTotalPixelSize.Height() ); + + Resize(); +} + +Size OScrollWindowHelper::ResizeScrollBars() +{ + // get the new output-size in pixel + Size aOutPixSz = GetOutputSizePixel(); + if ( aOutPixSz.IsEmpty() ) + return aOutPixSz; + + aOutPixSz.AdjustHeight( -(m_aReportWindow->getRulerHeight()) ); + // determine the size of the output-area and if we need scrollbars + const tools::Long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + bool bVVisible = false; // by default no vertical-ScrollBar + bool bHVisible = false; // by default no horizontal-ScrollBar + bool bChanged; // determines if a visiblility was changed + do + { + bChanged = false; + + // does we need a vertical ScrollBar + if ( aOutPixSz.Width() < m_aTotalPixelSize.Width() && !bHVisible ) + { + bHVisible = true; + aOutPixSz.AdjustHeight( -nScrSize ); + bChanged = true; + } + + // does we need a horizontal ScrollBar + if ( aOutPixSz.Height() < m_aTotalPixelSize.Height() && !bVVisible ) + { + bVVisible = true; + aOutPixSz.AdjustWidth( -nScrSize ); + bChanged = true; + } + + } + while ( bChanged ); // until no visibility has changed + + aOutPixSz.AdjustHeight(m_aReportWindow->getRulerHeight() ); + + // show or hide scrollbars + m_aVScroll->Show( bVVisible ); + m_aHScroll->Show( bHVisible ); + + // disable painting in the corner between the scrollbars + if ( bVVisible && bHVisible ) + { + m_aCornerWin->SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()), Size(nScrSize, nScrSize) ); + m_aCornerWin->Show(); + } + else + m_aCornerWin->Hide(); + + const Point aOffset = LogicToPixel(Point(SECTION_OFFSET, SECTION_OFFSET), MapMode(MapUnit::MapAppFont)); + // resize scrollbars and set their ranges + { + Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH*m_pParent->getController().getZoomValue()),100); + const sal_Int32 nNewWidth = aOutPixSz.Width() - aOffset.X() - static_cast<tools::Long>(aStartWidth); + lcl_setScrollBar(nNewWidth,Point( static_cast<tools::Long>(aStartWidth) + aOffset.X(), aOutPixSz.Height() ), Size( nNewWidth, nScrSize ), *m_aHScroll); + } + { + const sal_Int32 nNewHeight = aOutPixSz.Height() - m_aReportWindow->getRulerHeight(); + lcl_setScrollBar(nNewHeight,Point( aOutPixSz.Width(), m_aReportWindow->getRulerHeight() ), Size( nScrSize,nNewHeight), *m_aVScroll); + } + + return aOutPixSz; +} + +void OScrollWindowHelper::Resize() +{ + OScrollWindowHelper_BASE::Resize(); + const Size aTotalOutputSize = ResizeScrollBars(); + + m_aReportWindow->SetPosSizePixel(Point( 0, 0 ),aTotalOutputSize); +} + +IMPL_LINK( OScrollWindowHelper, ScrollHdl, ScrollBar*, /*pScroll*/, void ) +{ + m_aReportWindow->ScrollChildren( getThumbPos() ); +} + +void OScrollWindowHelper::addSection(const uno::Reference< report::XSection >& _xSection + ,const OUString& _sColorEntry + ,sal_uInt16 _nPosition) +{ + m_aReportWindow->addSection(_xSection,_sColorEntry,_nPosition); +} + +void OScrollWindowHelper::removeSection(sal_uInt16 _nPosition) +{ + m_aReportWindow->removeSection(_nPosition); +} + +void OScrollWindowHelper::toggleGrid(bool _bVisible) +{ + m_aReportWindow->toggleGrid(_bVisible); +} + +sal_uInt16 OScrollWindowHelper::getSectionCount() const +{ + return m_aReportWindow->getSectionCount(); +} + +void OScrollWindowHelper::SetInsertObj(SdrObjKind eObj, const OUString& _sShapeType) +{ + m_aReportWindow->SetInsertObj(eObj,_sShapeType); +} + +OUString const & OScrollWindowHelper::GetInsertObjString() const +{ + return m_aReportWindow->GetInsertObjString(); +} + +void OScrollWindowHelper::SetMode( DlgEdMode _eNewMode ) +{ + m_aReportWindow->SetMode(_eNewMode); +} + +bool OScrollWindowHelper::HasSelection() const +{ + return m_aReportWindow->HasSelection(); +} + +void OScrollWindowHelper::Delete() +{ + m_aReportWindow->Delete(); +} + +void OScrollWindowHelper::Copy() +{ + m_aReportWindow->Copy(); +} + +void OScrollWindowHelper::Paste() +{ + m_aReportWindow->Paste(); +} + +bool OScrollWindowHelper::IsPasteAllowed() const +{ + return m_aReportWindow->IsPasteAllowed(); +} + +void OScrollWindowHelper::SelectAll(const SdrObjKind _nObjectType) +{ + m_aReportWindow->SelectAll(_nObjectType); +} + +void OScrollWindowHelper::unmarkAllObjects() +{ + m_aReportWindow->unmarkAllObjects(); +} + +sal_Int32 OScrollWindowHelper::getMaxMarkerWidth() const +{ + return m_aReportWindow->getMaxMarkerWidth(); +} + +void OScrollWindowHelper::showRuler(bool _bShow) +{ + m_aReportWindow->showRuler(_bShow); +} + +bool OScrollWindowHelper::handleKeyEvent(const KeyEvent& _rEvent) +{ + return m_aReportWindow->handleKeyEvent(_rEvent); +} + +void OScrollWindowHelper::setMarked(OSectionView const * _pSectionView, bool _bMark) +{ + m_aReportWindow->setMarked(_pSectionView,_bMark); +} + +void OScrollWindowHelper::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark) +{ + m_aReportWindow->setMarked(_xSection,_bMark); +} + +void OScrollWindowHelper::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _xShape, bool _bMark) +{ + m_aReportWindow->setMarked(_xShape,_bMark); +} + +OSectionWindow* OScrollWindowHelper::getMarkedSection(NearSectionAccess nsa) const +{ + return m_aReportWindow->getMarkedSection(nsa); +} + +OSectionWindow* OScrollWindowHelper::getSectionWindow(const css::uno::Reference< css::report::XSection>& _xSection) const +{ + return m_aReportWindow->getSectionWindow(_xSection); +} + +void OScrollWindowHelper::markSection(const sal_uInt16 _nPos) +{ + m_aReportWindow->markSection(_nPos); +} + +void OScrollWindowHelper::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const +{ + m_aReportWindow->fillCollapsedSections(_rCollapsedPositions); +} + +void OScrollWindowHelper::collapseSections(const uno::Sequence< css::beans::PropertyValue>& _aCollapsedSections) +{ + m_aReportWindow->collapseSections(_aCollapsedSections); +} + +bool OScrollWindowHelper::EventNotify( NotifyEvent& rNEvt ) +{ + const CommandEvent* pCommandEvent = rNEvt.GetCommandEvent(); + if ( pCommandEvent && + ((pCommandEvent->GetCommand() == CommandEventId::Wheel) || + (pCommandEvent->GetCommand() == CommandEventId::StartAutoScroll) || + (pCommandEvent->GetCommand() == CommandEventId::AutoScroll)) ) + { + ScrollBar* pHScrBar = nullptr; + ScrollBar* pVScrBar = nullptr; + if ( m_aHScroll->IsVisible() ) + pHScrBar = m_aHScroll.get(); + + if ( m_aVScroll->IsVisible() ) + pVScrBar = m_aVScroll.get(); + + if ( HandleScrollCommand( *pCommandEvent, pHScrBar, pVScrBar ) ) + return true; + } + return OScrollWindowHelper_BASE::EventNotify(rNEvt); +} + +void OScrollWindowHelper::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection) +{ + m_aReportWindow->alignMarkedObjects(_nControlModification, _bAlignAtSection); +} + +void OScrollWindowHelper::ImplInitSettings() +{ + SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() )); + GetOutDev()->SetFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); + SetTextFillColor( Application::GetSettings().GetStyleSettings().GetFaceColor() ); +} + +void OScrollWindowHelper::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void OScrollWindowHelper::_propertyChanged(const beans::PropertyChangeEvent& /*_rEvent*/) +{ + m_aReportWindow->notifySizeChanged(); +} + +void OScrollWindowHelper::setGridSnap(bool bOn) +{ + m_aReportWindow->setGridSnap(bOn); +} + +void OScrollWindowHelper::setDragStripes(bool bOn) +{ + m_aReportWindow->setDragStripes(bOn); +} + +sal_uInt32 OScrollWindowHelper::getMarkedObjectCount() const +{ + return m_aReportWindow->getMarkedObjectCount(); +} + +void OScrollWindowHelper::zoom(const Fraction& _aZoom) +{ + m_aReportWindow->zoom(_aZoom); + Resize(); + Invalidate(InvalidateFlags::NoChildren|InvalidateFlags::Transparent); +} + +void OScrollWindowHelper::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const +{ + m_aReportWindow->fillControlModelSelection(_rSelection); +} + +sal_uInt16 OScrollWindowHelper::getZoomFactor(SvxZoomType _eType) const +{ + return m_aReportWindow->getZoomFactor(_eType); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/SectionView.cxx b/reportdesign/source/ui/report/SectionView.cxx new file mode 100644 index 000000000..f0da7c2e1 --- /dev/null +++ b/reportdesign/source/ui/report/SectionView.cxx @@ -0,0 +1,250 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <SectionView.hxx> +#include <DesignView.hxx> +#include <RptPage.hxx> +#include <RptObject.hxx> +#include <RptDef.hxx> +#include <svx/svddrgmt.hxx> +#include <ReportSection.hxx> +#include <ReportWindow.hxx> +#include <strings.hxx> +#include <tools/diagnose_ex.h> + +namespace rptui +{ + using namespace ::com::sun::star; + +OSectionView::OSectionView( + SdrModel& rSdrModel, + OReportSection* _pSectionWindow, + OReportWindow* pEditor) +: SdrView(rSdrModel, _pSectionWindow->GetOutDev()) + ,m_pReportWindow( pEditor ) + ,m_pSectionWindow(_pSectionWindow) +{ + // SetPagePaintingAllowed(false); + SetBufferedOutputAllowed(true); + SetBufferedOverlayAllowed(true); + SetPageBorderVisible(false); + SetBordVisible(); + SetQuickTextEditMode(false); +} + + +OSectionView::~OSectionView() +{ +} + + +void OSectionView::MarkListHasChanged() +{ + SdrView::MarkListHasChanged(); + + if ( m_pReportWindow && m_pSectionWindow && !m_pSectionWindow->getPage()->getSpecialMode() ) + { + DlgEdHint aHint( RPTUI_HINT_SELECTIONCHANGED ); + m_pReportWindow->getReportView()->Broadcast( aHint ); + m_pReportWindow->getReportView()->UpdatePropertyBrowserDelayed(*this); + } +} + + +void OSectionView::MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin ) +{ + // visible area + MapMode aMap( rWin.GetMapMode() ); + const Point aOrg( aMap.GetOrigin() ); + const Size aVisSize( rWin.GetOutDev()->GetOutputSize() ); + const tools::Rectangle aVisRect( Point(-aOrg.X(),-aOrg.Y()), aVisSize ); + + // check, if rectangle is inside visible area + if ( !aVisRect.Contains( rRect ) ) + { + // calculate scroll distance; the rectangle must be inside the visible area + sal_Int32 nScrollX = 0, nScrollY = 0; + + const sal_Int32 nVisLeft = aVisRect.Left(); + const sal_Int32 nVisRight = aVisRect.Right(); + const sal_Int32 nVisTop = aVisRect.Top(); + const sal_Int32 nVisBottom = aVisRect.Bottom(); + + // don't scroll beyond the page size + Size aPageSize = m_pSectionWindow->getPage()->GetSize(); + const sal_Int32 nPageWidth = aPageSize.Width(); + const sal_Int32 nPageHeight = aPageSize.Height(); + + if ( nVisRight + nScrollX > nPageWidth ) + nScrollX = nPageWidth - nVisRight; + + if ( nVisLeft + nScrollX < 0 ) + nScrollX = -nVisLeft; + + if ( nVisBottom + nScrollY > nPageHeight ) + nScrollY = nPageHeight - nVisBottom; + + if ( nVisTop + nScrollY < 0 ) + nScrollY = -nVisTop; + + // scroll window + rWin.PaintImmediately(); + rWin.Scroll( -nScrollX, -nScrollY ); + aMap.SetOrigin( Point( aOrg.X() - nScrollX, aOrg.Y() - nScrollY ) ); + rWin.SetMapMode( aMap ); + rWin.Invalidate(); + + if ( m_pReportWindow ) + { + const DlgEdHint aHint( RPTUI_HINT_WINDOWSCROLLED ); + m_pReportWindow->getReportView()->Broadcast( aHint ); + } + } + else + { + rWin.Invalidate(InvalidateFlags::NoErase); + } +} + +void OSectionView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + SdrView::Notify(rBC,rHint); + if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint) + return; + const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint); + const SdrObject* pObj = pSdrHint->GetObject(); + const SdrHintKind eKind = pSdrHint->GetKind(); + // check for change of selected object + if(SdrHintKind::ObjectChange == eKind && pObj && IsObjMarked(pObj)) + AdjustMarkHdl(); + else if ( eKind == SdrHintKind::ObjectRemoved ) + ObjectRemovedInAliveMode(pObj); +} + + +void OSectionView::ObjectRemovedInAliveMode( const SdrObject* _pObject ) +{ + const SdrMarkList& rMarkedList = GetMarkedObjectList(); + const size_t nMark = rMarkedList.GetMarkCount(); + + for( size_t i = 0; i < nMark; ++i ) + { + SdrObject* pSdrObj = rMarkedList.GetMark(i)->GetMarkedSdrObj(); + if (_pObject == pSdrObj) + { + SdrPageView* pPgView = GetSdrPageView(); + BrkAction(); + MarkObj( pSdrObj, pPgView, true ); + break; + } + } +} + + +void OSectionView::SetMarkedToLayer( SdrLayerID _nLayerNo ) +{ + if (!AreObjectsMarked()) + return; + + // #i11702# use SdrUndoObjectLayerChange for undo + // STR_UNDO_SELATTR is "Attributes" - should use a different text later + BegUndo( ); + + const SdrMarkList& rMark = GetMarkedObjectList(); + const size_t nCount = rMark.GetMarkCount(); + for (size_t i = 0; i<nCount; ++i) + { + SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj(); + if ( dynamic_cast< const OCustomShape *>( pObj ) != nullptr ) + { + AddUndo( std::make_unique<SdrUndoObjectLayerChange>( *pObj, pObj->GetLayer(), _nLayerNo) ); + pObj->SetLayer( _nLayerNo ); + OObjectBase& rBaseObj = dynamic_cast<OObjectBase&>(*pObj); + try + { + rBaseObj.getReportComponent()->setPropertyValue(PROPERTY_OPAQUE,uno::Any(_nLayerNo == RPT_LAYER_FRONT)); + } + catch(const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } + } + } + + EndUndo(); + + // check mark list now instead of later in a timer + CheckMarked(); + MarkListHasChanged(); +} + +bool OSectionView::OnlyShapesMarked() const +{ + const SdrMarkList& rMark = GetMarkedObjectList(); + const size_t nCount = rMark.GetMarkCount(); + if ( !nCount ) + return false; + for (size_t i = 0; i<nCount; ++i) + { + SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj(); + if ( dynamic_cast< const OCustomShape *>( pObj ) == nullptr ) + { + return false; + } + } + return true; +} + +bool OSectionView::IsDragResize() const +{ + const SdrDragMethod* pDragMethod = GetDragMethod(); + if (pDragMethod) + { + bool bMoveOnly = pDragMethod->getMoveOnly(); + if (!bMoveOnly) + { + // current marked components will be resized + return true; + } + } + return false; +} + + +SdrLayerID OSectionView::GetLayerIdOfMarkedObjects() const +{ + SdrLayerID nRet = SDRLAYER_NOTFOUND; + const SdrMarkList &rMrkList = GetMarkedObjectList(); + for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i ) + { + const SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); + if ( nRet == SDRLAYER_NOTFOUND ) + nRet = pObj->GetLayer(); + else if ( nRet != pObj->GetLayer() ) + { + break; + } + } + return nRet; +} + + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/SectionWindow.cxx b/reportdesign/source/ui/report/SectionWindow.cxx new file mode 100644 index 000000000..60d5235f8 --- /dev/null +++ b/reportdesign/source/ui/report/SectionWindow.cxx @@ -0,0 +1,391 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <SectionWindow.hxx> +#include <ReportWindow.hxx> +#include <UITools.hxx> +#include <ReportController.hxx> +#include <ReportSection.hxx> +#include <DesignView.hxx> +#include <strings.hxx> +#include <core_resource.hxx> +#include <strings.hrc> +#include <StartMarker.hxx> +#include <EndMarker.hxx> +#include <ViewsWindow.hxx> + +#include <functional> +#include <algorithm> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +namespace rptui +{ +using namespace ::com::sun::star; +using namespace ::comphelper; + +OSectionWindow::OSectionWindow( OViewsWindow* _pParent,const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry) +: Window( _pParent,WB_DIALOGCONTROL) +,OPropertyChangeListener(m_aMutex) +,m_pParent(_pParent) +,m_aStartMarker( VclPtr<rptui::OStartMarker>::Create(this,_sColorEntry)) +,m_aReportSection( VclPtr<rptui::OReportSection>::Create(this,_xSection)) +,m_aSplitter(VclPtr<Splitter>::Create(this)) +,m_aEndMarker( VclPtr<rptui::OEndMarker>::Create(this,_sColorEntry)) +{ + const MapMode& rMapMode = _pParent->GetMapMode(); + SetMapMode( rMapMode ); + ImplInitSettings(); + // TRY + m_aSplitter->SetMapMode( MapMode( MapUnit::Map100thMM ) ); + m_aSplitter->SetStartSplitHdl(LINK(this, OSectionWindow,StartSplitHdl)); + m_aSplitter->SetSplitHdl(LINK(this, OSectionWindow,SplitHdl)); + m_aSplitter->SetEndSplitHdl(LINK(this, OSectionWindow,EndSplitHdl)); + m_aSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetFaceColor() )); + m_aSplitter->SetSplitPosPixel(m_aSplitter->LogicToPixel(Size(0,_xSection->getHeight())).Height()); + + + m_aStartMarker->setCollapsedHdl(LINK(this,OSectionWindow,Collapsed)); + + m_aStartMarker->zoom(rMapMode.GetScaleX()); + setZoomFactor(rMapMode.GetScaleX(), *m_aReportSection); + setZoomFactor(rMapMode.GetScaleX(), *m_aSplitter); + setZoomFactor(rMapMode.GetScaleX(), *m_aEndMarker); + + m_aSplitter->Show(); + m_aStartMarker->Show(); + m_aReportSection->Show(); + m_aEndMarker->Show(); + Show(); + + m_pSectionMulti = new OPropertyChangeMultiplexer(this,_xSection); + m_pSectionMulti->addProperty(PROPERTY_NAME); + m_pSectionMulti->addProperty(PROPERTY_HEIGHT); + + beans::PropertyChangeEvent aEvent; + aEvent.Source = _xSection; + aEvent.PropertyName = PROPERTY_NAME; + uno::Reference< report::XGroup > xGroup(_xSection->getGroup()); + if ( xGroup.is() ) + { + m_pGroupMulti = new OPropertyChangeMultiplexer(this,xGroup); + m_pGroupMulti->addProperty(PROPERTY_EXPRESSION); + aEvent.Source = xGroup; + aEvent.PropertyName = PROPERTY_EXPRESSION; + } + + _propertyChanged(aEvent); +} + +OSectionWindow::~OSectionWindow() +{ + disposeOnce(); +} + +void OSectionWindow::dispose() +{ + try + { + if ( m_pSectionMulti.is() ) + m_pSectionMulti->dispose(); + m_pSectionMulti.clear(); + if ( m_pGroupMulti.is() ) + m_pGroupMulti->dispose(); + m_pGroupMulti.clear(); + } + catch (uno::Exception&) + { + } + m_aStartMarker.disposeAndClear(); + m_aReportSection.disposeAndClear(); + m_aSplitter.disposeAndClear(); + m_aEndMarker.disposeAndClear(); + m_pParent.clear(); + vcl::Window::dispose(); +} + +void OSectionWindow::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) +{ + SolarMutexGuard g; + const uno::Reference< report::XSection > xSection(_rEvent.Source,uno::UNO_QUERY); + if ( xSection.is() ) + { + if ( _rEvent.PropertyName == PROPERTY_HEIGHT ) + { + m_pParent->getView()->SetUpdateMode(false); + //Resize(); + m_pParent->getView()->notifySizeChanged(); + m_pParent->resize(*this); + m_pParent->getView()->SetUpdateMode(true); + // getViewsWindow()->getView()->getReportView()->getController().resetZoomType(); + } + else if ( _rEvent.PropertyName == PROPERTY_NAME && !xSection->getGroup().is() ) + { + uno::Reference< report::XReportDefinition > xReport = xSection->getReportDefinition(); + if ( setReportSectionTitle(xReport,RID_STR_REPORT_HEADER,::std::mem_fn(&OReportHelper::getReportHeader),::std::mem_fn(&OReportHelper::getReportHeaderOn)) + || setReportSectionTitle(xReport,RID_STR_REPORT_FOOTER,::std::mem_fn(&OReportHelper::getReportFooter),::std::mem_fn(&OReportHelper::getReportFooterOn)) + || setReportSectionTitle(xReport,RID_STR_PAGE_HEADER,::std::mem_fn(&OReportHelper::getPageHeader),::std::mem_fn(&OReportHelper::getPageHeaderOn)) + || setReportSectionTitle(xReport,RID_STR_PAGE_FOOTER,::std::mem_fn(&OReportHelper::getPageFooter),::std::mem_fn(&OReportHelper::getPageFooterOn)) ) + { + m_aStartMarker->Invalidate(InvalidateFlags::NoErase); + } + else + { + OUString sTitle = RptResId(RID_STR_DETAIL); + m_aStartMarker->setTitle(sTitle); + m_aStartMarker->Invalidate(InvalidateFlags::Children); + } + } + } + else if ( _rEvent.PropertyName == PROPERTY_EXPRESSION ) + { + uno::Reference< report::XGroup > xGroup(_rEvent.Source,uno::UNO_QUERY); + if ( xGroup.is() && !setGroupSectionTitle(xGroup,RID_STR_HEADER,::std::mem_fn(&OGroupHelper::getHeader),::std::mem_fn(&OGroupHelper::getHeaderOn))) + { + setGroupSectionTitle(xGroup,RID_STR_FOOTER,::std::mem_fn(&OGroupHelper::getFooter),::std::mem_fn(&OGroupHelper::getFooterOn)); + } + } +} + +bool OSectionWindow::setReportSectionTitle( + const uno::Reference<report::XReportDefinition>& _xReport, TranslateId pResId, + const ::std::function<uno::Reference<report::XSection>(OReportHelper*)>& _pGetSection, + const ::std::function<bool(OReportHelper*)>& _pIsSectionOn) +{ + OReportHelper aReportHelper(_xReport); + const bool bRet = _pIsSectionOn(&aReportHelper) && _pGetSection(&aReportHelper) == m_aReportSection->getSection(); + if ( bRet ) + { + OUString sTitle = RptResId(pResId); + m_aStartMarker->setTitle(sTitle); + m_aStartMarker->Invalidate(InvalidateFlags::Children); + } + return bRet; +} + +bool OSectionWindow::setGroupSectionTitle( + const uno::Reference<report::XGroup>& _xGroup, TranslateId pResId, + const ::std::function<uno::Reference<report::XSection>(OGroupHelper*)>& _pGetSection, + const ::std::function<bool(OGroupHelper*)>& _pIsSectionOn) +{ + OGroupHelper aGroupHelper(_xGroup); + const bool bRet = _pIsSectionOn(&aGroupHelper) && _pGetSection(&aGroupHelper) == m_aReportSection->getSection() ; + if ( bRet ) + { + OUString sExpression = _xGroup->getExpression(); + OUString sLabel = getViewsWindow()->getView()->getReportView()->getController().getColumnLabel_throw(sExpression); + if ( !sLabel.isEmpty() ) + { + sExpression = sLabel; + } + + OUString sTitle(RptResId(pResId)); + sTitle = sTitle.replaceFirst("#", sExpression); + m_aStartMarker->setTitle( sTitle ); + m_aStartMarker->Invalidate(InvalidateFlags::Children); + } + return bRet; +} + +void OSectionWindow::ImplInitSettings() +{ + EnableChildTransparentMode(); + SetParentClipMode( ParentClipMode::NoClip ); + SetPaintTransparent( true ); + SetBackground( ); +} + +void OSectionWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void OSectionWindow::Resize() +{ + Window::Resize(); + + Size aOutputSize = GetOutputSizePixel(); + tools::Long nEndWidth = tools::Long(REPORT_ENDMARKER_WIDTH * GetMapMode().GetScaleX()); + + const Point aThumbPos = m_pParent->getView()->getThumbPos(); + aOutputSize.AdjustWidth( -(aThumbPos.X()) ); + aOutputSize.AdjustHeight( -m_aSplitter->GetSizePixel().Height() ); + + if ( m_aStartMarker->isCollapsed() ) + { + Point aPos(0,0); + m_aStartMarker->SetPosSizePixel(aPos,aOutputSize); + } + else + { + const bool bShowEndMarker = m_pParent->getView()->GetTotalWidth() <= (aThumbPos.X() + aOutputSize.Width() ); + + tools::Long nStartWidth = tools::Long(REPORT_STARTMARKER_WIDTH * GetMapMode().GetScaleX()); + + // set start marker + m_aStartMarker->SetPosSizePixel(Point(0,0),Size(nStartWidth,aOutputSize.Height())); + + // set report section + const uno::Reference< report::XSection> xSection = m_aReportSection->getSection(); + Size aSectionSize = LogicToPixel( Size( 0,xSection->getHeight() ) ); + Point aReportPos(nStartWidth,0); + aSectionSize.setWidth( aOutputSize.Width() - nStartWidth ); + if ( bShowEndMarker ) + aSectionSize.AdjustWidth( -nEndWidth ); + + m_aReportSection->SetPosSizePixel(aReportPos,aSectionSize); + + // set splitter + aReportPos.AdjustY(aSectionSize.Height() ); + m_aSplitter->SetPosSizePixel(aReportPos,Size(aSectionSize.Width(),m_aSplitter->GetSizePixel().Height())); + aSectionSize.setHeight( static_cast<tools::Long>(1000 * static_cast<double>(GetMapMode().GetScaleY())) ); + m_aSplitter->SetDragRectPixel( tools::Rectangle(Point(nStartWidth,0),aSectionSize)); + + // set end marker + aReportPos.AdjustX(aSectionSize.Width() ); + aReportPos.setY( 0 ); + m_aEndMarker->Show(bShowEndMarker); + m_aEndMarker->SetPosSizePixel(aReportPos,Size(nEndWidth,aOutputSize.Height())); + } +} + +void OSectionWindow::setCollapsed(bool _bCollapsed) +{ + if ( m_aStartMarker->isCollapsed() != _bCollapsed ) + { + m_aStartMarker->setCollapsed(_bCollapsed); + } +} + +void OSectionWindow::showProperties() +{ + m_pParent->getView()->showProperties( m_aReportSection->getSection() ); +} + +void OSectionWindow::setMarked(bool _bMark) +{ + m_aStartMarker->setMarked(_bMark); + m_aEndMarker->setMarked(_bMark); +} + +IMPL_LINK( OSectionWindow, Collapsed, OColorListener&, _rMarker, void ) +{ + bool bShow = !_rMarker.isCollapsed(); + m_aReportSection->Show(bShow); + m_aEndMarker->Show(bShow); + m_aSplitter->Show(bShow); + + m_pParent->resize(*this); +} + +void OSectionWindow::zoom(const Fraction& _aZoom) +{ + setZoomFactor(_aZoom,*this); + m_aStartMarker->zoom(_aZoom); + + setZoomFactor(_aZoom, *m_aReportSection); + setZoomFactor(_aZoom, *m_aSplitter); + setZoomFactor(_aZoom, *m_aEndMarker); + Invalidate(); +} + +IMPL_LINK_NOARG( OSectionWindow, StartSplitHdl, Splitter*, void) +{ + const OUString sUndoAction( RptResId( RID_STR_UNDO_CHANGE_SIZE ) ); + getViewsWindow()->getView()->getReportView()->getController().getUndoManager().EnterListAction( sUndoAction, OUString(), 0, ViewShellId(-1) ); +} + +IMPL_LINK_NOARG( OSectionWindow, EndSplitHdl, Splitter*, void ) +{ + getViewsWindow()->getView()->getReportView()->getController().getUndoManager().LeaveListAction(); +} + +IMPL_LINK( OSectionWindow, SplitHdl, Splitter*, _pSplitter, void ) +{ + if ( !getViewsWindow()->getView()->getReportView()->getController().isEditable() ) + { + return; + } + + sal_Int32 nSplitPos = _pSplitter->GetSplitPosPixel(); + + const uno::Reference< report::XSection> xSection = m_aReportSection->getSection(); + nSplitPos = m_aSplitter->PixelToLogic(Size(0,nSplitPos)).Height(); + + const sal_Int32 nCount = xSection->getCount(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + uno::Reference<report::XReportComponent> xReportComponent(xSection->getByIndex(i),uno::UNO_QUERY); + if ( xReportComponent.is() ) + { + nSplitPos = ::std::max(nSplitPos,xReportComponent->getPositionY() + xReportComponent->getHeight()); + } + } + + if ( nSplitPos < 0 ) + nSplitPos = 0; + + xSection->setHeight(nSplitPos); + m_aSplitter->SetSplitPosPixel(m_aSplitter->LogicToPixel(Size(0,nSplitPos)).Height()); +} + +static void lcl_scroll(vcl::Window& _rWindow,const Point& _aDelta) +{ + _rWindow.Scroll(-_aDelta.X(),-_aDelta.Y()); + _rWindow.Invalidate(InvalidateFlags::Transparent); +} + +static void lcl_setOrigin(vcl::Window& _rWindow,tools::Long _nX, tools::Long _nY) +{ + MapMode aMap = _rWindow.GetMapMode(); + aMap.SetOrigin( Point(- _nX, - _nY)); + _rWindow.SetMapMode( aMap ); +} + +void OSectionWindow::scrollChildren(tools::Long _nX) +{ + const Point aDelta( _nX,0 ); + + MapMode aMapMode( m_aReportSection->GetMapMode() ); + const Point aOld = aMapMode.GetOrigin(); + lcl_setOrigin(*m_aReportSection, aDelta.X(), 0); + + aMapMode = m_aReportSection->GetMapMode(); + const Point aNew = aMapMode.GetOrigin(); + const Point aDiff = aOld - aNew; + { + lcl_scroll(*m_aReportSection, aDiff); + } + + lcl_scroll(*m_aEndMarker, m_aEndMarker->PixelToLogic(Point(_nX,0))); + + lcl_setOrigin(*m_aSplitter,_nX, 0); + lcl_scroll(*m_aSplitter,aDiff); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/StartMarker.cxx b/reportdesign/source/ui/report/StartMarker.cxx new file mode 100644 index 000000000..3d05f2910 --- /dev/null +++ b/reportdesign/source/ui/report/StartMarker.cxx @@ -0,0 +1,304 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <StartMarker.hxx> +#include <UITools.hxx> +#include <vcl/image.hxx> +#include <vcl/svapp.hxx> +#include <bitmaps.hlst> +#include <ColorChanger.hxx> +#include <ReportDefines.hxx> +#include <SectionWindow.hxx> +#include <vcl/event.hxx> +#include <vcl/help.hxx> +#include <vcl/gradient.hxx> +#include <vcl/lineinfo.hxx> +#include <vcl/settings.hxx> + +#include <unotools/syslocale.hxx> +#include <unotools/localedatawrapper.hxx> + +#define CORNER_SPACE 5 + + +namespace rptui +{ + + +Image* OStartMarker::s_pDefCollapsed = nullptr; +Image* OStartMarker::s_pDefExpanded = nullptr; +oslInterlockedCount OStartMarker::s_nImageRefCount = 0; + + +OStartMarker::OStartMarker(OSectionWindow* _pParent,const OUString& _sColorEntry) + : OColorListener(_pParent,_sColorEntry) + , m_aVRuler(VclPtr<Ruler>::Create(this,WB_VERT)) + , m_pParent(_pParent) + , m_bShowRuler(true) +{ + osl_atomic_increment(&s_nImageRefCount); + initDefaultNodeImages(); + ImplInitSettings(); + m_aVRuler->Show(); + m_aVRuler->Activate(); + m_aVRuler->SetPagePos(); + m_aVRuler->SetBorders(); + m_aVRuler->SetIndents(); + m_aVRuler->SetMargin1(); + m_aVRuler->SetMargin2(); + const MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum(); + m_aVRuler->SetUnit(MeasurementSystem::Metric == eSystem ? FieldUnit::CM : FieldUnit::INCH); + EnableChildTransparentMode(); + SetParentClipMode( ParentClipMode::NoClip ); + SetPaintTransparent( true ); +} + +OStartMarker::~OStartMarker() +{ + disposeOnce(); +} + +void OStartMarker::dispose() +{ + if ( osl_atomic_decrement(&s_nImageRefCount) == 0 ) + { + delete s_pDefCollapsed; + s_pDefCollapsed = nullptr; + delete s_pDefExpanded; + s_pDefExpanded = nullptr; + } + m_aVRuler.disposeAndClear(); + m_pParent.clear(); + OColorListener::dispose(); +} + +sal_Int32 OStartMarker::getMinHeight() const +{ + Fraction aExtraWidth(tools::Long(2 * REPORT_EXTRA_SPACE)); + aExtraWidth *= GetMapMode().GetScaleX(); + return LogicToPixel(Size(0, GetTextHeight())).Height() + tools::Long(aExtraWidth); +} + +void OStartMarker::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) +{ + rRenderContext.Push(vcl::PushFlags::TEXTCOLOR); + + Size aSize(GetOutputSizePixel()); + const tools::Long nCornerWidth = tools::Long(CORNER_SPACE * double(GetMapMode().GetScaleX())); + + if (isCollapsed()) + { + rRenderContext.SetClipRegion(); + } + else + { + const tools::Long nVRulerWidth = m_aVRuler->GetSizePixel().Width(); + tools::Long nSize = aSize.Width() - nVRulerWidth; + aSize.AdjustWidth(nCornerWidth ); + rRenderContext.SetClipRegion(vcl::Region(rRenderContext.PixelToLogic(tools::Rectangle(Point(), + Size(nSize, aSize.Height()))))); + } + + tools::Rectangle aWholeRect(Point(), aSize); + { + const ColorChanger aColors(&rRenderContext, m_nTextBoundaries, m_nColor); + tools::PolyPolygon aPoly; + aPoly.Insert( tools::Polygon(aWholeRect,nCornerWidth,nCornerWidth)); + + Color aStartColor(m_nColor); + aStartColor.IncreaseLuminance(10); + sal_uInt16 nHue = 0; + sal_uInt16 nSat = 0; + sal_uInt16 nBri = 0; + aStartColor.RGBtoHSB(nHue, nSat, nBri); + nSat += 40; + Color aEndColor(Color::HSBtoRGB(nHue, nSat, nBri)); + Gradient aGradient(GradientStyle::Linear,aStartColor,aEndColor); + aGradient.SetSteps(static_cast<sal_uInt16>(aSize.Height())); + + rRenderContext.DrawGradient(PixelToLogic(aPoly) ,aGradient); + } + + rRenderContext.Push(vcl::PushFlags::MAPMODE); + rRenderContext.SetMapMode(); + + rRenderContext.DrawImage(m_aImageRect.TopLeft(), m_aImageRect.GetSize(), m_aImage); + + const Color aColor(m_nColor); + Color aTextColor = GetTextColor(); + if (aColor.GetLuminance() < 128) + aTextColor = COL_WHITE; + rRenderContext.SetTextColor(aTextColor); + + rRenderContext.DrawText(m_aTextRect, m_aText, DrawTextFlags::MultiLine | DrawTextFlags::WordBreakHyphenation); + + rRenderContext.Pop(); + + if (m_bMarked) + { + const tools::Long nCornerHeight = tools::Long(CORNER_SPACE * double(GetMapMode().GetScaleY())); + tools::Rectangle aRect(Point(nCornerWidth, nCornerHeight), + Size(aSize.Width() - nCornerWidth - nCornerWidth, + aSize.Height() - nCornerHeight - nCornerHeight)); + ColorChanger aColors(&rRenderContext, COL_WHITE, COL_WHITE); + rRenderContext.DrawPolyLine( tools::Polygon(rRenderContext.PixelToLogic(aRect)), + LineInfo(LineStyle::Solid, 2)); + } + + rRenderContext.Pop(); +} + +void OStartMarker::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( !rMEvt.IsLeft() ) + return; + + Point aPos( rMEvt.GetPosPixel()); + + const Size aOutputSize = GetOutputSizePixel(); + if( aPos.X() > aOutputSize.Width() || aPos.Y() > aOutputSize.Height() ) + return; + if ( rMEvt.GetClicks() == 2 || m_aImageRect.Contains( aPos ) ) + { + m_bCollapsed = !m_bCollapsed; + + changeImage(); + + m_aVRuler->Show(!m_bCollapsed && m_bShowRuler); + m_aCollapsedLink.Call(*this); + } + + m_pParent->showProperties(); +} + +void OStartMarker::changeImage() +{ + m_aImage = m_bCollapsed ? *s_pDefCollapsed : *s_pDefExpanded; +} + +void OStartMarker::initDefaultNodeImages() +{ + if ( !s_pDefCollapsed ) + { + s_pDefCollapsed = new Image(StockImage::Yes, RID_BMP_TREENODE_COLLAPSED); + s_pDefExpanded = new Image(StockImage::Yes, RID_BMP_TREENODE_EXPANDED); + } + + m_aImage = m_bCollapsed ? *s_pDefCollapsed : *s_pDefExpanded; +} + +void OStartMarker::ApplySettings(vcl::RenderContext& rRenderContext) +{ + rRenderContext.SetBackground(); + rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor()); +} + +void OStartMarker::ImplInitSettings() +{ + ApplySettings(*GetOutDev()); +} + +void OStartMarker::Resize() +{ + const Size aOutputSize( GetOutputSizePixel() ); + const tools::Long nOutputWidth = aOutputSize.Width(); + const tools::Long nOutputHeight = aOutputSize.Height(); + + const tools::Long nVRulerWidth = m_aVRuler->GetSizePixel().Width(); + const Point aRulerPos(nOutputWidth - nVRulerWidth,0); + m_aVRuler->SetPosSizePixel(aRulerPos,Size(nVRulerWidth,nOutputHeight)); + + Size aImageSize = m_aImage.GetSizePixel(); + const MapMode& rMapMode = GetMapMode(); + aImageSize.setWidth( tools::Long(aImageSize.Width() * static_cast<double>(rMapMode.GetScaleX())) ); + aImageSize.setHeight( tools::Long(aImageSize.Height() * static_cast<double>(rMapMode.GetScaleY())) ); + + tools::Long nExtraWidth = tools::Long(REPORT_EXTRA_SPACE * rMapMode.GetScaleX()); + + Point aPos(aImageSize.Width() + (nExtraWidth * 2), nExtraWidth); + const tools::Long nHeight = ::std::max<sal_Int32>(nOutputHeight - 2*aPos.Y(),LogicToPixel(Size(0, GetTextHeight())).Height()); + m_aTextRect = tools::Rectangle(aPos, Size(aRulerPos.X() - aPos.X(),nHeight)); + + aPos.setX( nExtraWidth ); + aPos.AdjustY(static_cast<sal_Int32>((LogicToPixel(Size(0, GetTextHeight())).Height() - aImageSize.Height()) * 0.5) ) ; + m_aImageRect = tools::Rectangle(aPos, aImageSize); + + OColorListener::Resize(); +} + +void OStartMarker::setTitle(const OUString& rTitle) +{ + if (m_aText != rTitle) + { + m_aText = rTitle; + Invalidate(); + } +} + +void OStartMarker::Notify(SfxBroadcaster & rBc, SfxHint const & rHint) +{ + OColorListener::Notify(rBc, rHint); + if (rHint.GetId() == SfxHintId::ColorsChanged) + { + Invalidate(InvalidateFlags::Children); + } +} + +void OStartMarker::showRuler(bool _bShow) +{ + m_bShowRuler = _bShow; + m_aVRuler->Show(!m_bCollapsed && m_bShowRuler); +} + +void OStartMarker::RequestHelp( const HelpEvent& rHEvt ) +{ + if (m_aText.isEmpty()) + return; + + // show help + tools::Rectangle aItemRect(rHEvt.GetMousePosPixel(),Size(GetSizePixel().Width(),getMinHeight())); + Point aPt = OutputToScreenPixel( aItemRect.TopLeft() ); + aItemRect.SetLeft( aPt.X() ); + aItemRect.SetTop( aPt.Y() ); + aPt = OutputToScreenPixel( aItemRect.BottomRight() ); + aItemRect.SetRight( aPt.X() ); + aItemRect.SetBottom( aPt.Y() ); + if( rHEvt.GetMode() == HelpEventMode::BALLOON ) + Help::ShowBalloon( this, aItemRect.Center(), aItemRect, m_aText); + else + Help::ShowQuickHelp( this, aItemRect, m_aText ); +} + +void OStartMarker::setCollapsed(bool _bCollapsed) +{ + OColorListener::setCollapsed(_bCollapsed); + showRuler(_bCollapsed); + changeImage(); +} + +void OStartMarker::zoom(const Fraction& _aZoom) +{ + setZoomFactor(_aZoom, *this); + m_aVRuler->SetZoom(_aZoom); + Resize(); + Invalidate(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/ViewsWindow.cxx b/reportdesign/source/ui/report/ViewsWindow.cxx new file mode 100644 index 000000000..b5ce7a48f --- /dev/null +++ b/reportdesign/source/ui/report/ViewsWindow.cxx @@ -0,0 +1,1673 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <ViewsWindow.hxx> +#include <ScrollHelper.hxx> +#include <UndoActions.hxx> +#include <ReportWindow.hxx> +#include <DesignView.hxx> +#include <svtools/colorcfg.hxx> +#include <ReportController.hxx> +#include <UITools.hxx> +#include <RptDef.hxx> +#include <strings.hrc> +#include <SectionView.hxx> +#include <ReportSection.hxx> +#include <strings.hxx> +#include <rptui_slotid.hrc> +#include <dlgedclip.hxx> +#include <RptObject.hxx> +#include <EndMarker.hxx> +#include <sal/log.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <core_resource.hxx> +#include <svx/svdundo.hxx> +#include <toolkit/helper/convert.hxx> +#include <algorithm> +#include <cstdlib> +#include <numeric> + +namespace rptui +{ +#define DEFAUL_MOVE_SIZE 100 + +using namespace ::com::sun::star; +using namespace ::comphelper; + +static bool lcl_getNewRectSize(const tools::Rectangle& _aObjRect,tools::Long& _nXMov, tools::Long& _nYMov,SdrObject const * _pObj,SdrView const * _pView, ControlModification _nControlModification) +{ + bool bMoveAllowed = _nXMov != 0 || _nYMov != 0; + if ( bMoveAllowed ) + { + tools::Rectangle aNewRect = _aObjRect; + SdrObject* pOverlappedObj = nullptr; + do + { + aNewRect = _aObjRect; + switch(_nControlModification) + { + case ControlModification::HEIGHT_GREATEST: + case ControlModification::WIDTH_GREATEST: + aNewRect.setWidth(_nXMov); + aNewRect.setHeight(_nYMov); + break; + default: + aNewRect.Move(_nXMov,_nYMov); + break; + } + if (dynamic_cast<OUnoObject const *>(_pObj) != nullptr || dynamic_cast<OOle2Obj const *>(_pObj) != nullptr) + { + pOverlappedObj = isOver(aNewRect,*_pObj->getSdrPageFromSdrObject(),*_pView,true,_pObj); + if ( pOverlappedObj && _pObj != pOverlappedObj ) + { + tools::Rectangle aOverlappingRect = pOverlappedObj->GetSnapRect(); + sal_Int32 nXTemp = _nXMov; + sal_Int32 nYTemp = _nYMov; + switch(_nControlModification) + { + case ControlModification::LEFT: + nXTemp += aOverlappingRect.Right() - aNewRect.Left(); + bMoveAllowed = _nXMov != nXTemp; + break; + case ControlModification::RIGHT: + nXTemp += aOverlappingRect.Left() - aNewRect.Right(); + bMoveAllowed = _nXMov != nXTemp; + break; + case ControlModification::TOP: + nYTemp += aOverlappingRect.Bottom() - aNewRect.Top(); + bMoveAllowed = _nYMov != nYTemp; + break; + case ControlModification::BOTTOM: + nYTemp += aOverlappingRect.Top() - aNewRect.Bottom(); + bMoveAllowed = _nYMov != nYTemp; + break; + case ControlModification::CENTER_HORIZONTAL: + if ( _aObjRect.Left() < aOverlappingRect.Left() ) + nXTemp += aOverlappingRect.Left() - aNewRect.Left() - aNewRect.getWidth(); + else + nXTemp += aOverlappingRect.Right() - aNewRect.Left(); + bMoveAllowed = _nXMov != nXTemp; + break; + case ControlModification::CENTER_VERTICAL: + if ( _aObjRect.Top() < aOverlappingRect.Top() ) + nYTemp += aOverlappingRect.Top() - aNewRect.Top() - aNewRect.getHeight(); + else + nYTemp += aOverlappingRect.Bottom() - aNewRect.Top(); + bMoveAllowed = _nYMov != nYTemp; + break; + case ControlModification::HEIGHT_GREATEST: + case ControlModification::WIDTH_GREATEST: + { + tools::Rectangle aIntersectionRect = aNewRect.GetIntersection(aOverlappingRect); + if ( !aIntersectionRect.IsEmpty() ) + { + if ( _nControlModification == ControlModification::WIDTH_GREATEST ) + { + if ( aNewRect.Left() < aIntersectionRect.Left() ) + { + aNewRect.SetRight( aIntersectionRect.Left() ); + } + else if ( aNewRect.Left() < aIntersectionRect.Right() ) + { + aNewRect.SetLeft( aIntersectionRect.Right() ); + } + } + else if ( _nControlModification == ControlModification::HEIGHT_GREATEST ) + { + if ( aNewRect.Top() < aIntersectionRect.Top() ) + { + aNewRect.SetBottom( aIntersectionRect.Top() ); + } + else if ( aNewRect.Top() < aIntersectionRect.Bottom() ) + { + aNewRect.SetTop( aIntersectionRect.Bottom() ); + } + } + nYTemp = aNewRect.getHeight(); + bMoveAllowed = _nYMov != nYTemp; + nXTemp = aNewRect.getWidth(); + bMoveAllowed = bMoveAllowed && _nXMov != nXTemp; + } + } + break; + default: + break; + } + + _nXMov = nXTemp; + _nYMov = nYTemp; + } + else + pOverlappedObj = nullptr; + } + } + while ( pOverlappedObj && bMoveAllowed ); + } + return bMoveAllowed; +} + +OViewsWindow::OViewsWindow( OReportWindow* _pReportWindow) + : Window( _pReportWindow,WB_DIALOGCONTROL) + , m_pParent(_pReportWindow) + , m_bInUnmark(false) +{ + SetPaintTransparent(true); + SetMapMode(MapMode(MapUnit::Map100thMM)); + m_aColorConfig.AddListener(this); + ImplInitSettings(); +} + +OViewsWindow::~OViewsWindow() +{ + disposeOnce(); +} + +void OViewsWindow::dispose() +{ + m_aColorConfig.RemoveListener(this); + for (auto& rxSection : m_aSections) + rxSection.disposeAndClear(); + m_aSections.clear(); + m_pParent.clear(); + vcl::Window::dispose(); +} + +void OViewsWindow::impl_resizeSectionWindow(OSectionWindow& _rSectionWindow,Point& _rStartPoint,bool _bSet) +{ + const uno::Reference< report::XSection> xSection = _rSectionWindow.getReportSection().getSection(); + + Size aSectionSize = _rSectionWindow.LogicToPixel( Size( 0,xSection->getHeight() ) ); + aSectionSize.setWidth( getView()->GetTotalWidth() ); + + const sal_Int32 nMinHeight = _rSectionWindow.getStartMarker().getMinHeight(); + if ( _rSectionWindow.getStartMarker().isCollapsed() || nMinHeight > aSectionSize.Height() ) + { + aSectionSize.setHeight( nMinHeight ); + } + aSectionSize.AdjustHeight(static_cast<tools::Long>(StyleSettings::GetSplitSize() * static_cast<double>(_rSectionWindow.GetMapMode().GetScaleY())) ); + + if ( _bSet ) + _rSectionWindow.SetPosSizePixel(_rStartPoint,aSectionSize); + + _rStartPoint.AdjustY(aSectionSize.Height() ); +} + + +void OViewsWindow::resize(const OSectionWindow& _rSectionWindow) +{ + bool bSet = false; + Point aStartPoint; + for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections) + { + if ( pSectionWindow == &_rSectionWindow ) + { + aStartPoint = pSectionWindow->GetPosPixel(); + bSet = true; + } + + if ( bSet ) + { + impl_resizeSectionWindow(*pSectionWindow,aStartPoint,bSet); + static const InvalidateFlags nIn = InvalidateFlags::Update | InvalidateFlags::Transparent; + pSectionWindow->getStartMarker().Invalidate( nIn ); // InvalidateFlags::NoErase |InvalidateFlags::NoChildren| InvalidateFlags::Transparent + pSectionWindow->getEndMarker().Invalidate( nIn ); + } + } + m_pParent->notifySizeChanged(); +} + +void OViewsWindow::Resize() +{ + Window::Resize(); + if ( !m_aSections.empty() ) + { + const Point aOffset(m_pParent->getThumbPos()); + Point aStartPoint(0,-aOffset.Y()); + for (VclPtr<OSectionWindow> const & pSectionWindow : m_aSections) + { + impl_resizeSectionWindow(*pSectionWindow,aStartPoint,true); + } + } +} + +void OViewsWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + Window::Paint(rRenderContext, rRect); + + rRenderContext.SetBackground(); + rRenderContext.SetFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor()); + rRenderContext.SetTextFillColor(Application::GetSettings().GetStyleSettings().GetDialogColor()); + + Size aOut(GetOutputSizePixel()); + tools::Long nStartWidth = tools::Long(REPORT_STARTMARKER_WIDTH * rRenderContext.GetMapMode().GetScaleX()); + + aOut.AdjustWidth( -nStartWidth ); + aOut = rRenderContext.PixelToLogic(aOut); + + tools::Rectangle aRect(rRenderContext.PixelToLogic(Point(nStartWidth,0)), aOut); + Wallpaper aWall(m_aColorConfig.GetColorValue(::svtools::APPBACKGROUND).nColor); + rRenderContext.DrawWallpaper(aRect, aWall); +} + +void OViewsWindow::ImplInitSettings() +{ + EnableChildTransparentMode(); +} + +void OViewsWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && + (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + ImplInitSettings(); + Invalidate(); + } +} + +void OViewsWindow::addSection(const uno::Reference< report::XSection >& _xSection,const OUString& _sColorEntry,sal_uInt16 _nPosition) +{ + VclPtrInstance<OSectionWindow> pSectionWindow(this,_xSection,_sColorEntry); + m_aSections.insert(getIteratorAtPos(_nPosition) , TSectionsMap::value_type(pSectionWindow)); + m_pParent->setMarked(&pSectionWindow->getReportSection().getSectionView(),m_aSections.size() == 1); + Resize(); +} + +void OViewsWindow::removeSection(sal_uInt16 _nPosition) +{ + if ( _nPosition < m_aSections.size() ) + { + TSectionsMap::iterator aPos = getIteratorAtPos(_nPosition); + TSectionsMap::const_iterator aNew = getIteratorAtPos(_nPosition == 0 ? _nPosition+1: _nPosition - 1); + + m_pParent->getReportView()->UpdatePropertyBrowserDelayed((*aNew)->getReportSection().getSectionView()); + + aPos->disposeAndClear(); + m_aSections.erase(aPos); + Resize(); + } +} + +void OViewsWindow::toggleGrid(bool _bVisible) +{ + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [_bVisible] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().SetGridVisible(_bVisible); + }); + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().Window::Invalidate(InvalidateFlags::NoErase); + }); +} + +sal_Int32 OViewsWindow::getTotalHeight() const +{ + return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_Int32(0), + [](const sal_Int32 nHeight, const VclPtr<OSectionWindow>& rxSection) { return nHeight + rxSection->GetSizePixel().Height(); }); +} + +sal_uInt16 OViewsWindow::getSectionCount() const +{ + return static_cast<sal_uInt16>(m_aSections.size()); +} + +void OViewsWindow::SetInsertObj( SdrObjKind eObj,const OUString& _sShapeType ) +{ + for (const auto& rxSection : m_aSections) + rxSection->getReportSection().getSectionView().SetCurrentObj( eObj, SdrInventor::ReportDesign ); + + m_sShapeType = _sShapeType; +} + + +void OViewsWindow::SetMode( DlgEdMode eNewMode ) +{ + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [&eNewMode] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().SetMode(eNewMode); + }); +} + +bool OViewsWindow::HasSelection() const +{ + return std::any_of(m_aSections.begin(), m_aSections.end(), + [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().AreObjectsMarked(); }); +} + +void OViewsWindow::Delete() +{ + m_bInUnmark = true; + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().Delete(); + }); + m_bInUnmark = false; +} + +void OViewsWindow::Copy() +{ + uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects; + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [&aAllreadyCopiedObjects] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().Copy(aAllreadyCopiedObjects); + }); + + rtl::Reference<OReportExchange> pCopy = new OReportExchange(aAllreadyCopiedObjects); + pCopy->CopyToClipboard(this); +} + +void OViewsWindow::Paste() +{ + TransferableDataHelper aTransferData(TransferableDataHelper::CreateFromSystemClipboard(this)); + OReportExchange::TSectionElements aCopies = OReportExchange::extractCopies(aTransferData); + if ( aCopies.getLength() > 1 ) + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [&aCopies] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().Paste(aCopies); + }); + else + { + OSectionWindow* pMarkedSection = getMarkedSection(); + if ( pMarkedSection ) + pMarkedSection->getReportSection().Paste(aCopies,true); + } +} + +OSectionWindow* OViewsWindow::getSectionWindow(const uno::Reference< report::XSection>& _xSection) const +{ + OSL_ENSURE(_xSection.is(),"Section is NULL!"); + + OSectionWindow* pSectionWindow = nullptr; + for (VclPtr<OSectionWindow> const & p : m_aSections) + { + if (p->getReportSection().getSection() == _xSection) + { + pSectionWindow = p.get(); + break; + } + } + + return pSectionWindow; +} + + +OSectionWindow* OViewsWindow::getMarkedSection(NearSectionAccess nsa) const +{ + OSectionWindow* pRet = nullptr; + TSectionsMap::const_iterator aIter = m_aSections.begin(); + TSectionsMap::const_iterator aEnd = m_aSections.end(); + sal_uInt32 nCurrentPosition = 0; + for (; aIter != aEnd ; ++aIter) + { + if ( (*aIter)->getStartMarker().isMarked() ) + { + if (nsa == CURRENT) + { + pRet = aIter->get(); + break; + } + else if ( nsa == PREVIOUS ) + { + if (nCurrentPosition > 0) + { + pRet = (--aIter)->get(); + if (pRet == nullptr) + { + pRet = m_aSections.begin()->get(); + } + } + else + { + // if we are out of bounds return the first one + pRet = m_aSections.begin()->get(); + } + break; + } + else if ( nsa == POST ) + { + sal_uInt32 nSize = m_aSections.size(); + if ((nCurrentPosition + 1) < nSize) + { + pRet = (++aIter)->get(); + if (pRet == nullptr) + { + pRet = (--aEnd)->get(); + } + } + else + { + // if we are out of bounds return the last one + pRet = (--aEnd)->get(); + } + break; + } + } + ++nCurrentPosition; + } + + return pRet; +} + +void OViewsWindow::markSection(const sal_uInt16 _nPos) +{ + if ( _nPos < m_aSections.size() ) + m_pParent->setMarked(m_aSections[_nPos]->getReportSection().getSection(),true); +} + +bool OViewsWindow::IsPasteAllowed() const +{ + TransferableDataHelper aTransferData( TransferableDataHelper::CreateFromSystemClipboard( const_cast< OViewsWindow* >( this ) ) ); + return aTransferData.HasFormat(OReportExchange::getDescriptorFormatId()); +} + +void OViewsWindow::SelectAll(const SdrObjKind _nObjectType) +{ + m_bInUnmark = true; + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [&_nObjectType] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().SelectAll(_nObjectType); + }); + m_bInUnmark = false; +} + +void OViewsWindow::unmarkAllObjects(OSectionView const * _pSectionView) +{ + if ( m_bInUnmark ) + return; + + m_bInUnmark = true; + for (const auto& rxSection : m_aSections) + { + if ( &rxSection->getReportSection().getSectionView() != _pSectionView ) + { + rxSection->getReportSection().deactivateOle(); + rxSection->getReportSection().getSectionView().UnmarkAllObj(); + } + } + m_bInUnmark = false; +} + +void OViewsWindow::ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints) +{ + ImplInitSettings(); + Invalidate(); +} + +void OViewsWindow::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( rMEvt.IsLeft() ) + { + GrabFocus(); + const uno::Sequence< beans::PropertyValue> aArgs; + getView()->getReportView()->getController().executeChecked(SID_SELECT_REPORT,aArgs); + } + Window::MouseButtonDown(rMEvt); +} + +void OViewsWindow::showRuler(bool _bShow) +{ + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [_bShow] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getStartMarker().showRuler(_bShow); + }); + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getStartMarker().Window::Invalidate(InvalidateFlags::NoErase); + }); +} + +void OViewsWindow::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( !rMEvt.IsLeft() ) + return; + + auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(), + [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().AreObjectsMarked(); }); + if (aIter != m_aSections.end()) + { + (*aIter)->getReportSection().MouseButtonUp(rMEvt); + } + + // remove special insert mode + for (const auto& rxSection : m_aSections) + { + rxSection->getReportSection().getPage()->resetSpecialMode(); + } +} + +bool OViewsWindow::handleKeyEvent(const KeyEvent& _rEvent) +{ + bool bRet = false; + for (const auto& rxSection : m_aSections) + { + if ( rxSection->getStartMarker().isMarked() ) + { + bRet = rxSection->getReportSection().handleKeyEvent(_rEvent); + } + } + return bRet; +} + +OViewsWindow::TSectionsMap::iterator OViewsWindow::getIteratorAtPos(sal_uInt16 _nPos) +{ + TSectionsMap::iterator aRet = m_aSections.end(); + if ( _nPos < m_aSections.size() ) + aRet = m_aSections.begin() + _nPos; + return aRet; +} + +void OViewsWindow::setMarked(OSectionView const * _pSectionView, bool _bMark) +{ + OSL_ENSURE(_pSectionView != nullptr,"SectionView is NULL!"); + if ( _pSectionView ) + setMarked(_pSectionView->getReportSection()->getSection(),_bMark); +} + +void OViewsWindow::setMarked(const uno::Reference< report::XSection>& _xSection, bool _bMark) +{ + for (const auto& rxSection : m_aSections) + { + if ( rxSection->getReportSection().getSection() != _xSection ) + { + rxSection->setMarked(false); + } + else if ( rxSection->getStartMarker().isMarked() != _bMark ) + { + rxSection->setMarked(_bMark); + } + } +} + +void OViewsWindow::setMarked(const uno::Sequence< uno::Reference< report::XReportComponent> >& _aShapes, bool _bMark) +{ + bool bFirst = true; + for(const uno::Reference< report::XReportComponent>& rShape : _aShapes) + { + const uno::Reference< report::XSection> xSection = rShape->getSection(); + if ( xSection.is() ) + { + if ( bFirst ) + { + bFirst = false; + m_pParent->setMarked(xSection,_bMark); + } + OSectionWindow* pSectionWindow = getSectionWindow(xSection); + if ( pSectionWindow ) + { + SdrObject* pObject = SdrObject::getSdrObjectFromXShape( rShape ); + OSL_ENSURE( pObject, "OViewsWindow::setMarked: no SdrObject for the shape!" ); + if ( pObject ) + pSectionWindow->getReportSection().getSectionView().MarkObj( pObject, pSectionWindow->getReportSection().getSectionView().GetSdrPageView(), !_bMark ); + } + } + } +} + +void OViewsWindow::collectRectangles(TRectangleMap& _rSortRectangles) +{ + for (const auto& rxSection : m_aSections) + { + OSectionView& rView = rxSection->getReportSection().getSectionView(); + if ( rView.AreObjectsMarked() ) + { + rView.SortMarkedObjects(); + const size_t nCount = rView.GetMarkedObjectCount(); + for (size_t i=0; i < nCount; ++i) + { + const SdrMark* pM = rView.GetSdrMarkByIndex(i); + SdrObject* pObj = pM->GetMarkedSdrObj(); + tools::Rectangle aObjRect(pObj->GetSnapRect()); + _rSortRectangles.emplace(aObjRect,TRectangleMap::mapped_type(pObj,&rView)); + } + } + } +} + +void OViewsWindow::collectBoundResizeRect(const TRectangleMap& _rSortRectangles, ControlModification _nControlModification,bool _bAlignAtSection, tools::Rectangle& _rBound, tools::Rectangle& _rResize) +{ + bool bOnlyOnce = false; + for (const auto& [aObjRect, rObjViewPair] : _rSortRectangles) + { + if ( _rResize.IsEmpty() ) + _rResize = aObjRect; + switch(_nControlModification) + { + case ControlModification::WIDTH_SMALLEST: + if ( _rResize.getWidth() > aObjRect.getWidth() ) + _rResize = aObjRect; + break; + case ControlModification::HEIGHT_SMALLEST: + if ( _rResize.getHeight() > aObjRect.getHeight() ) + _rResize = aObjRect; + break; + case ControlModification::WIDTH_GREATEST: + if ( _rResize.getWidth() < aObjRect.getWidth() ) + _rResize = aObjRect; + break; + case ControlModification::HEIGHT_GREATEST: + if ( _rResize.getHeight() < aObjRect.getHeight() ) + _rResize = aObjRect; + break; + default: break; + } + + SdrObjTransformInfoRec aInfo; + const SdrObject* pObj = rObjViewPair.first; + pObj->TakeObjInfo(aInfo); + bool bHasFixed = !aInfo.bMoveAllowed || pObj->IsMoveProtect(); + if ( bHasFixed ) + _rBound.Union(aObjRect); + else + { + if ( _bAlignAtSection || _rSortRectangles.size() == 1 ) + { // align single object at the page + if ( ! bOnlyOnce ) + { + bOnlyOnce = true; + OReportSection* pReportSection = rObjViewPair.second->getReportSection(); + const uno::Reference< report::XSection>& xSection = pReportSection->getSection(); + try + { + uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + _rBound.Union(tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0, + getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN), + xSection->getHeight())); + } + catch(const uno::Exception &){} + } + } + else + { + _rBound.Union(rObjViewPair.second->GetMarkedObjRect()); + } + } + } +} + +void OViewsWindow::alignMarkedObjects(ControlModification _nControlModification, bool _bAlignAtSection) +{ + if ( _nControlModification == ControlModification::NONE ) + return; + + Point aRefPoint; + RectangleLess::CompareMode eCompareMode = RectangleLess::POS_LEFT; + switch (_nControlModification) + { + case ControlModification::TOP : eCompareMode = RectangleLess::POS_UPPER; break; + case ControlModification::BOTTOM: eCompareMode = RectangleLess::POS_DOWN; break; + case ControlModification::LEFT : eCompareMode = RectangleLess::POS_LEFT; break; + case ControlModification::RIGHT : eCompareMode = RectangleLess::POS_RIGHT; break; + case ControlModification::CENTER_HORIZONTAL : + case ControlModification::CENTER_VERTICAL : + { + eCompareMode = (ControlModification::CENTER_VERTICAL == _nControlModification) ? RectangleLess::POS_CENTER_VERTICAL : RectangleLess::POS_CENTER_HORIZONTAL; + uno::Reference<report::XSection> xSection = (*m_aSections.begin())->getReportSection().getSection(); + uno::Reference<report::XReportDefinition> xReportDefinition = xSection->getReportDefinition(); + aRefPoint = tools::Rectangle(getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN),0, + getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width - getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN), + xSection->getHeight()).Center(); + } + break; + default: break; + } + RectangleLess aCompare(eCompareMode,aRefPoint); + TRectangleMap aSortRectangles(aCompare); + collectRectangles(aSortRectangles); + + tools::Rectangle aBound; + tools::Rectangle aResize; + collectBoundResizeRect(aSortRectangles,_nControlModification,_bAlignAtSection,aBound,aResize); + + bool bMove = true; + + auto aGetFun = ::std::mem_fn(&tools::Rectangle::Bottom); + auto aSetFun = ::std::mem_fn(&tools::Rectangle::SetBottom); + auto aRefFun = ::std::mem_fn(&tools::Rectangle::Top); + TRectangleMap::const_iterator aRectIter = aSortRectangles.begin(); + TRectangleMap::const_iterator aRectEnd = aSortRectangles.end(); + for (;aRectIter != aRectEnd ; ++aRectIter) + { + tools::Rectangle aObjRect = aRectIter->first; + SdrObject* pObj = aRectIter->second.first; + SdrView* pView = aRectIter->second.second; + Point aCenter(aBound.Center()); + SdrObjTransformInfoRec aInfo; + pObj->TakeObjInfo(aInfo); + if (aInfo.bMoveAllowed && !pObj->IsMoveProtect()) + { + tools::Long nXMov = 0; + tools::Long nYMov = 0; + tools::Long* pValue = &nXMov; + switch(_nControlModification) + { + case ControlModification::TOP : + aGetFun = ::std::mem_fn(&tools::Rectangle::Top); + aSetFun = ::std::mem_fn(&tools::Rectangle::SetTop); + aRefFun = ::std::mem_fn(&tools::Rectangle::Bottom); + pValue = &nYMov; + break; + case ControlModification::BOTTOM: + // defaults are already set + pValue = &nYMov; + break; + case ControlModification::CENTER_VERTICAL: + nYMov = aCenter.Y() - aObjRect.Center().Y(); + pValue = &nYMov; + bMove = false; + break; + case ControlModification::RIGHT : + aGetFun = ::std::mem_fn(&tools::Rectangle::Right); + aSetFun = ::std::mem_fn(&tools::Rectangle::SetRight); + aRefFun = ::std::mem_fn(&tools::Rectangle::Left); + break; + case ControlModification::CENTER_HORIZONTAL: + nXMov = aCenter.X() - aObjRect.Center().X(); + bMove = false; + break; + case ControlModification::LEFT : + aGetFun = ::std::mem_fn(&tools::Rectangle::Left); + aSetFun = ::std::mem_fn(&tools::Rectangle::SetLeft); + aRefFun = ::std::mem_fn(&tools::Rectangle::Right); + break; + default: + bMove = false; + break; + } + if ( bMove ) + { + tools::Rectangle aTest = aObjRect; + aSetFun(&aTest, aGetFun(&aBound)); + TRectangleMap::const_iterator aInterSectRectIter = aSortRectangles.begin(); + for (; aInterSectRectIter != aRectIter; ++aInterSectRectIter) + { + if ( pView == aInterSectRectIter->second.second && (dynamic_cast<OUnoObject*>(aInterSectRectIter->second.first) || dynamic_cast<OOle2Obj*>(aInterSectRectIter->second.first))) + { + SdrObject* pPreviousObj = aInterSectRectIter->second.first; + tools::Rectangle aIntersectRect = aTest.GetIntersection( pPreviousObj->GetSnapRect()); + if ( !aIntersectRect.IsEmpty() && (aIntersectRect.Left() != aIntersectRect.Right() && aIntersectRect.Top() != aIntersectRect.Bottom() ) ) + { + *pValue = aRefFun(&aIntersectRect) - aGetFun(&aObjRect); + break; + } + } + } + if ( aInterSectRectIter == aRectIter ) + *pValue = aGetFun(&aBound) - aGetFun(&aObjRect); + } + + if ( lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification) ) + { + const Size aSize(nXMov,nYMov); + pView->AddUndo(pView->GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,aSize)); + pObj->Move(aSize); + aObjRect = pObj->GetSnapRect(); + } + + // resizing control + if ( !aResize.IsEmpty() && aObjRect != aResize ) + { + nXMov = aResize.getWidth(); + nYMov = aResize.getHeight(); + switch(_nControlModification) + { + case ControlModification::WIDTH_GREATEST: + case ControlModification::HEIGHT_GREATEST: + if ( _nControlModification == ControlModification::HEIGHT_GREATEST ) + nXMov = aObjRect.getWidth(); + else if ( _nControlModification == ControlModification::WIDTH_GREATEST ) + nYMov = aObjRect.getHeight(); + lcl_getNewRectSize(aObjRect,nXMov,nYMov,pObj,pView,_nControlModification); + [[fallthrough]]; + case ControlModification::WIDTH_SMALLEST: + case ControlModification::HEIGHT_SMALLEST: + pView->AddUndo( pView->GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); + { + OObjectBase* pObjBase = dynamic_cast<OObjectBase*>(pObj); + OSL_ENSURE(pObjBase,"Where comes this object from?"); + if ( pObjBase ) + { + if ( _nControlModification == ControlModification::WIDTH_SMALLEST || _nControlModification == ControlModification::WIDTH_GREATEST ) + pObjBase->getReportComponent()->setSize(awt::Size(nXMov,aObjRect.getHeight())); + else if ( _nControlModification == ControlModification::HEIGHT_GREATEST || _nControlModification == ControlModification::HEIGHT_SMALLEST ) + pObjBase->getReportComponent()->setSize(awt::Size(aObjRect.getWidth(),nYMov)); + } + } + break; + default: + break; + } + } + } + pView->AdjustMarkHdl(); + } +} + +void OViewsWindow::createDefault() +{ + OSectionWindow* pMarkedSection = getMarkedSection(); + if ( pMarkedSection ) + pMarkedSection->getReportSection().createDefault(m_sShapeType); +} + +void OViewsWindow::setGridSnap(bool bOn) +{ + for (const auto& rxSection : m_aSections) + { + rxSection->getReportSection().getSectionView().SetGridSnap(bOn); + rxSection->getReportSection().Invalidate(); + } +} + +void OViewsWindow::setDragStripes(bool bOn) +{ + for (const auto& rxSection : m_aSections) + rxSection->getReportSection().getSectionView().SetDragStripes(bOn); +} + +sal_uInt16 OViewsWindow::getPosition(const OSectionWindow* _pSectionWindow) const +{ + auto aIter = std::find_if(m_aSections.begin(), m_aSections.end(), + [&_pSectionWindow](const VclPtr<OSectionWindow>& rxSection) { return _pSectionWindow == rxSection.get(); }); + return static_cast<sal_uInt16>(std::distance(m_aSections.begin(), aIter)); +} + +OSectionWindow* OViewsWindow::getSectionWindow(const sal_uInt16 _nPos) const +{ + OSectionWindow* aReturn = nullptr; + + if ( _nPos < m_aSections.size() ) + aReturn = m_aSections[_nPos].get(); + + return aReturn; +} + +namespace +{ + enum SectionViewAction + { + eEndDragObj, + eEndAction, + eForceToAnotherPage, + eBreakAction + }; + class ApplySectionViewAction + { + private: + SectionViewAction m_eAction; + + public: + explicit ApplySectionViewAction() + : m_eAction(eEndDragObj) + { + } + + explicit ApplySectionViewAction(SectionViewAction _eAction) + : m_eAction(_eAction) + { + } + + void operator() ( const OViewsWindow::TSectionsMap::value_type& _rhs ) + { + OSectionView& rView( _rhs->getReportSection().getSectionView() ); + switch ( m_eAction ) + { + case eEndDragObj: + rView.EndDragObj(); + break; + case eEndAction: + if ( rView.IsAction() ) + rView.EndAction ( ); + break; + case eForceToAnotherPage: + rView.ForceMarkedToAnotherPage(); + break; + case eBreakAction: + if ( rView.IsAction() ) + rView.BrkAction ( ); + break; + // default: + + } + } + }; +} + +void OViewsWindow::BrkAction() +{ + EndDragObj_removeInvisibleObjects(); + ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eBreakAction) ); +} + +void OViewsWindow::BegDragObj_createInvisibleObjectAtPosition(const tools::Rectangle& _aRect, const OSectionView& _rSection) +{ + Point aNewPos(0,0); + + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + rReportSection.getPage()->setSpecialMode(); + OSectionView& rView = rReportSection.getSectionView(); + + if ( &rView != &_rSection ) + { + SdrObject *pNewObj = new SdrUnoObj( + rView.getSdrModelFromSdrView(), + "com.sun.star.form.component.FixedText"); + + pNewObj->SetLogicRect(_aRect); + pNewObj->Move(Size(0, aNewPos.Y())); + bool bChanged = rView.GetModel()->IsChanged(); + rReportSection.getPage()->InsertObject(pNewObj); + rView.GetModel()->SetChanged(bChanged); + m_aBegDragTempList.push_back(pNewObj); + + rView.MarkObj( pNewObj, rView.GetSdrPageView() ); + } + const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aNewPos.AdjustY( -nSectionHeight ); + } +} + +void OViewsWindow::BegDragObj(const Point& _aPnt, SdrHdl* _pHdl,const OSectionView* _pSection) +{ + SAL_INFO( + "reportdesign", "Clickpoint X:" << _aPnt.X() << " Y:" << _aPnt.Y()); + + m_aBegDragTempList.clear(); + + // Calculate the absolute clickpoint in the views + Point aAbsolutePnt = _aPnt; + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + OSectionView* pView = &rReportSection.getSectionView(); + if (pView == _pSection) + break; + const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aAbsolutePnt.AdjustY(nSectionHeight ); + } + m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32); + SAL_INFO( + "reportdesign", + "Absolute X:" << aAbsolutePnt.X() << " Y:" << aAbsolutePnt.Y()); + + // Create drag lines over all viewable Views + // Therefore we need to identify the marked objects + // and create temporary objects on all other views at the same position + // relative to its occurrence. + + int nViewCount = 0; + Point aNewObjPos(0,0); + Point aLeftTop(SAL_MAX_INT32, SAL_MAX_INT32); + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + + OSectionView& rView = rReportSection.getSectionView(); + + if ( rView.AreObjectsMarked() ) + { + const size_t nCount = rView.GetMarkedObjectCount(); + for (size_t i=0; i < nCount; ++i) + { + const SdrMark* pM = rView.GetSdrMarkByIndex(i); + SdrObject* pObj = pM->GetMarkedSdrObj(); + if (::std::find(m_aBegDragTempList.begin(),m_aBegDragTempList.end(),pObj) == m_aBegDragTempList.end()) + { + tools::Rectangle aRect( pObj->GetCurrentBoundRect() ); + aRect.Move(0, aNewObjPos.Y()); + + aLeftTop.setX( ::std::min( aRect.Left(), aLeftTop.X() ) ); + aLeftTop.setY( ::std::min( aRect.Top(), aLeftTop.Y() ) ); + + SAL_INFO( + "reportdesign", + "createInvisible X:" << aRect.Left() << " Y:" + << aRect.Top() << " on View #" << nViewCount); + + BegDragObj_createInvisibleObjectAtPosition(aRect, rView); + } + } + } + ++nViewCount; + tools::Rectangle aClipRect = rView.GetWorkArea(); + aClipRect.SetTop( -aNewObjPos.Y() ); + rView.SetWorkArea( aClipRect ); + + const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aNewObjPos.AdjustY(nSectionHeight ); + } + + const sal_Int32 nDeltaX = std::abs(aLeftTop.X() - aAbsolutePnt.X()); + const sal_Int32 nDeltaY = std::abs(aLeftTop.Y() - aAbsolutePnt.Y()); + m_aDragDelta.setX( nDeltaX ); + m_aDragDelta.setY( nDeltaY ); + + Point aNewPos = aAbsolutePnt; + + const short nDrgLog = static_cast<short>(PixelToLogic(Size(3,0)).Width()); + nViewCount = 0; + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + + SdrHdl* pHdl = _pHdl; + if ( pHdl ) + { + if ( &rReportSection.getSectionView() != _pSection ) + { + const SdrHdlList& rHdlList = rReportSection.getSectionView().GetHdlList(); + pHdl = rHdlList.GetHdl(_pHdl->GetKind()); + } + } + SAL_INFO( + "reportdesign", + "X:" << aNewPos.X() << " Y:" << aNewPos.Y() << " on View#" + << nViewCount++); + rReportSection.getSectionView().BegDragObj(aNewPos, nullptr, pHdl, nDrgLog); + + const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aNewPos.AdjustY( -nSectionHeight ); + } +} + + +void OViewsWindow::ForceMarkedToAnotherPage() +{ + ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eForceToAnotherPage ) ); +} + +void OViewsWindow::BegMarkObj(const Point& _aPnt,const OSectionView* _pSection) +{ + bool bAdd = true; + Point aNewPos = _aPnt; + + tools::Long nLastSectionHeight = 0; + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + if ( &rReportSection.getSectionView() == _pSection ) + { + bAdd = false; + aNewPos = _aPnt; // 2,2 + } + else if ( bAdd ) + { + const tools::Long nSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aNewPos.AdjustY(nSectionHeight ); + } + else + { + aNewPos.AdjustY( -nLastSectionHeight ); + } + rReportSection.getSectionView().BegMarkObj ( aNewPos ); + nLastSectionHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + } +} + +OSectionView* OViewsWindow::getSectionRelativeToPosition(const OSectionView* _pSection,Point& _rPnt) +{ + OSectionView* pSection = nullptr; + TSectionsMap::const_iterator aIter = m_aSections.begin(); + const TSectionsMap::const_iterator aEnd = m_aSections.end(); + aIter = std::find_if(aIter, aEnd, [&_pSection](const VclPtr<OSectionWindow>& rxSection) { + return &rxSection->getReportSection().getSectionView() == _pSection; }); + sal_Int32 nCount = static_cast<sal_Int32>(std::distance(m_aSections.cbegin(), aIter)); + OSL_ENSURE(aIter != aEnd,"This can never happen!"); + if ( _rPnt.Y() < 0 ) + { + if ( nCount ) + --aIter; + for (; nCount && (_rPnt.Y() < 0); --nCount) + { + OReportSection& rReportSection = (*aIter)->getReportSection(); + const sal_Int32 nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + _rPnt.AdjustY(nHeight ); + if ( (nCount -1) > 0 && (_rPnt.Y() < 0) ) + --aIter; + } + if ( nCount == 0 ) + pSection = &(*m_aSections.begin())->getReportSection().getSectionView(); + else + pSection = &(*aIter)->getReportSection().getSectionView(); + } + else + { + for (; aIter != aEnd; ++aIter) + { + OReportSection& rReportSection = (*aIter)->getReportSection(); + const tools::Long nHeight = rReportSection.PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + if ( (_rPnt.Y() - nHeight) < 0 ) + break; + _rPnt.AdjustY( -nHeight ); + } + if ( aIter != aEnd ) + pSection = &(*aIter)->getReportSection().getSectionView(); + else + pSection = &(*(aEnd-1))->getReportSection().getSectionView(); + } + + return pSection; +} + +void OViewsWindow::EndDragObj_removeInvisibleObjects() +{ + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + rReportSection.getPage()->resetSpecialMode(); + } +} + +void OViewsWindow::EndDragObj(bool _bControlKeyPressed, const OSectionView* _pSection, const Point& _aPnt) +{ + const OUString sUndoAction = RptResId(RID_STR_UNDO_CHANGEPOSITION); + const UndoContext aUndoContext( getView()->getReportView()->getController().getUndoManager(), sUndoAction ); + + Point aNewPos = _aPnt; + OSectionView* pInSection = getSectionRelativeToPosition(_pSection, aNewPos); + if (!_bControlKeyPressed && + _pSection && !_pSection->IsDragResize() && /* Not in resize mode */ + _pSection != pInSection) + { + EndDragObj_removeInvisibleObjects(); + + // we need to manipulate the current clickpoint, we subtract the old delta from BeginDrag + aNewPos -= m_aDragDelta; + + uno::Sequence< beans::NamedValue > aAllreadyCopiedObjects; + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + if ( pInSection != &rReportSection.getSectionView() ) + { + rReportSection.getSectionView().BrkAction(); + rReportSection.Copy(aAllreadyCopiedObjects,true); + } + else + pInSection->EndDragObj(); + } + + if ( aAllreadyCopiedObjects.hasElements() ) + { + try + { + uno::Reference<report::XReportDefinition> xReportDefinition = getView()->getReportView()->getController().getReportDefinition(); + const sal_Int32 nLeftMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_LEFTMARGIN); + const sal_Int32 nRightMargin = getStyleProperty<sal_Int32>(xReportDefinition,PROPERTY_RIGHTMARGIN); + const sal_Int32 nPaperWidth = getStyleProperty<awt::Size>(xReportDefinition,PROPERTY_PAPERSIZE).Width; + + if ( aNewPos.X() < nLeftMargin ) + aNewPos.setX( nLeftMargin ); + if ( aNewPos.Y() < 0 ) + aNewPos.setY( 0 ); + + Point aPrevious; + for (beans::NamedValue const & namedVal : std::as_const(aAllreadyCopiedObjects)) + { + uno::Sequence< uno::Reference<report::XReportComponent> > aClones; + namedVal.Value >>= aClones; + uno::Reference<report::XReportComponent>* pColIter = aClones.getArray(); + const uno::Reference<report::XReportComponent>* pColEnd = pColIter + aClones.getLength(); + + // move the cloned Components to new positions + for (; pColIter != pColEnd; ++pColIter) + { + uno::Reference< report::XReportComponent> xRC(*pColIter); + aPrevious = VCLPoint(xRC->getPosition()); + awt::Size aSize = xRC->getSize(); + + if ( aNewPos.X() < nLeftMargin ) + { + aNewPos.setX( nLeftMargin ); + } + else if ( (aNewPos.X() + aSize.Width) > (nPaperWidth - nRightMargin) ) + { + aNewPos.setX( nPaperWidth - nRightMargin - aSize.Width ); + } + if ( aNewPos.Y() < 0 ) + { + aNewPos.setY( 0 ); + } + if ( aNewPos.X() < 0 ) + { + aSize.Width += aNewPos.X(); + aNewPos.setX( 0 ); + xRC->setSize(aSize); + } + xRC->setPosition(AWTPoint(aNewPos)); + if ( (pColIter+1) != pColEnd ) + { + // bring aNewPos to the position of the next object + uno::Reference< report::XReportComponent> xRCNext = *(pColIter + 1); + Point aNextPosition = VCLPoint(xRCNext->getPosition()); + aNewPos += aNextPosition - aPrevious; + } + } + } + } + catch(uno::Exception&) + { + } + pInSection->getReportSection()->Paste(aAllreadyCopiedObjects,true); + } + } + else + { + ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction() ); + EndDragObj_removeInvisibleObjects(); + } + m_aDragDelta = Point(SAL_MAX_INT32, SAL_MAX_INT32); +} + +void OViewsWindow::EndAction() +{ + ::std::for_each( m_aSections.begin(), m_aSections.end(), ApplySectionViewAction(eEndAction) ); +} + +void OViewsWindow::MovAction(const Point& _aPnt,const OSectionView* _pSection, bool _bControlKeySet) +{ + Point aRealMousePos = _aPnt; + Point aCurrentSectionPos; + SAL_INFO( + "reportdesign", + "X:" << aRealMousePos.X() << " Y:" << aRealMousePos.Y()); + + Point aHdlPos; + SdrHdl* pHdl = _pSection->GetDragHdl(); + if ( pHdl ) + { + aHdlPos = pHdl->GetPos(); + } + + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + if ( &rReportSection.getSectionView() == _pSection ) + break; + const tools::Long nSectionHeight = rxSection->PixelToLogic(rReportSection.GetOutputSizePixel()).Height(); + aCurrentSectionPos.AdjustY(nSectionHeight ); + } + aRealMousePos += aCurrentSectionPos; + + // If control key is pressed the work area is limited to the section with the current selection. + Point aPosForWorkArea(0,0); + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + OSectionView& rView = rReportSection.getSectionView(); + const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height(); + + if (_bControlKeySet) + { + tools::Rectangle aClipRect = rView.GetWorkArea(); + aClipRect.SetTop( aCurrentSectionPos.Y() - aPosForWorkArea.Y() ); + aClipRect.SetBottom( aClipRect.Top() + nSectionHeight ); + rView.SetWorkArea( aClipRect ); + } + else + { + tools::Rectangle aClipRect = rView.GetWorkArea(); + aClipRect.SetTop( -aPosForWorkArea.Y() ); + rView.SetWorkArea( aClipRect ); + } + aPosForWorkArea.AdjustY(nSectionHeight ); + } + + + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + SdrHdl* pCurrentHdl = rReportSection.getSectionView().GetDragHdl(); + if ( pCurrentHdl && aRealMousePos.Y() > 0 ) + aRealMousePos = _aPnt + pCurrentHdl->GetPos() - aHdlPos; + rReportSection.getSectionView().MovAction ( aRealMousePos ); + const tools::Long nSectionHeight = rxSection->PixelToLogic(rxSection->GetOutputSizePixel()).Height(); + aRealMousePos.AdjustY( -nSectionHeight ); + } +} + +bool OViewsWindow::IsAction() const +{ + return std::any_of(m_aSections.begin(), m_aSections.end(), + [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); }); +} + +bool OViewsWindow::IsDragObj() const +{ + return std::any_of(m_aSections.begin(), m_aSections.end(), + [](const VclPtr<OSectionWindow>& rxSection) { return rxSection->getReportSection().getSectionView().IsAction(); }); +} + +sal_uInt32 OViewsWindow::getMarkedObjectCount() const +{ + return std::accumulate(m_aSections.begin(), m_aSections.end(), sal_uInt32(0), + [](const sal_uInt32 nCount, const VclPtr<OSectionWindow>& rxSection) { + return nCount + static_cast<sal_uInt32>(rxSection->getReportSection().getSectionView().GetMarkedObjectCount()); }); +} + +void OViewsWindow::handleKey(const vcl::KeyCode& _rCode) +{ + const sal_uInt16 nCode = _rCode.GetCode(); + if ( _rCode.IsMod1() ) + { + // scroll page + OScrollWindowHelper* pScrollWindow = getView()->getScrollWindow(); + ScrollBar& rScrollBar = ( nCode == KEY_LEFT || nCode == KEY_RIGHT ) ? pScrollWindow->GetHScroll() : pScrollWindow->GetVScroll(); + if ( rScrollBar.IsVisible() ) + rScrollBar.DoScrollAction(( nCode == KEY_RIGHT || nCode == KEY_UP ) ? ScrollType::LineUp : ScrollType::LineDown ); + return; + } + + for (const auto& rxSection : m_aSections) + { + OReportSection& rReportSection = rxSection->getReportSection(); + tools::Long nX = 0; + tools::Long nY = 0; + + if ( nCode == KEY_UP ) + nY = -1; + else if ( nCode == KEY_DOWN ) + nY = 1; + else if ( nCode == KEY_LEFT ) + nX = -1; + else if ( nCode == KEY_RIGHT ) + nX = 1; + + if ( rReportSection.getSectionView().AreObjectsMarked() ) + { + if ( _rCode.IsMod2() ) + { + // move in 1 pixel distance + const Size aPixelSize = rReportSection.PixelToLogic( Size( 1, 1 ) ); + nX *= aPixelSize.Width(); + nY *= aPixelSize.Height(); + } + else + { + // move in 1 mm distance + nX *= DEFAUL_MOVE_SIZE; + nY *= DEFAUL_MOVE_SIZE; + } + + OSectionView& rView = rReportSection.getSectionView(); + const SdrHdlList& rHdlList = rView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + + if ( pHdl == nullptr ) + { + // no handle selected + if ( rView.IsMoveAllowed() ) + { + // restrict movement to work area + tools::Rectangle rWorkArea = rView.GetWorkArea(); + rWorkArea.AdjustRight( 1 ); + + if ( !rWorkArea.IsEmpty() ) + { + if ( rWorkArea.Top() < 0 ) + rWorkArea.SetTop( 0 ); + tools::Rectangle aMarkRect( rView.GetMarkedObjRect() ); + aMarkRect.Move( nX, nY ); + + if ( !rWorkArea.Contains( aMarkRect ) ) + { + if ( aMarkRect.Left() < rWorkArea.Left() ) + nX += rWorkArea.Left() - aMarkRect.Left(); + + if ( aMarkRect.Right() > rWorkArea.Right() ) + nX -= aMarkRect.Right() - rWorkArea.Right(); + + if ( aMarkRect.Top() < rWorkArea.Top() ) + nY += rWorkArea.Top() - aMarkRect.Top(); + + if ( aMarkRect.Bottom() > rWorkArea.Bottom() ) + nY -= aMarkRect.Bottom() - rWorkArea.Bottom(); + } + bool bCheck = false; + const SdrMarkList& rMarkList = rView.GetMarkedObjectList(); + for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i ) + { + SdrMark* pMark = rMarkList.GetMark(i); + bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr|| dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()); + } + + + if ( bCheck ) + { + SdrObject* pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView); + if ( pOverlapped ) + { + do + { + tools::Rectangle aOver = pOverlapped->GetLastBoundRect(); + Point aPos; + if ( nCode == KEY_UP ) + { + aPos.setX( aMarkRect.Left() ); + aPos.setY( aOver.Top() - aMarkRect.getHeight() ); + nY += (aPos.Y() - aMarkRect.Top()); + } + else if ( nCode == KEY_DOWN ) + { + aPos.setX( aMarkRect.Left() ); + aPos.setY( aOver.Bottom() ); + nY += (aPos.Y() - aMarkRect.Top()); + } + else if ( nCode == KEY_LEFT ) + { + aPos.setX( aOver.Left() - aMarkRect.getWidth() ); + aPos.setY( aMarkRect.Top() ); + nX += (aPos.X() - aMarkRect.Left()); + } + else if ( nCode == KEY_RIGHT ) + { + aPos.setX( aOver.Right() ); + aPos.setY( aMarkRect.Top() ); + nX += (aPos.X() - aMarkRect.Left()); + } + + aMarkRect.SetPos(aPos); + if ( !rWorkArea.Contains( aMarkRect ) ) + { + break; + } + pOverlapped = isOver(aMarkRect,*rReportSection.getPage(),rView); + } + while(pOverlapped != nullptr); + if (pOverlapped != nullptr) + break; + } + } + } + + if ( nX != 0 || nY != 0 ) + { + rView.MoveAllMarked( Size( nX, nY ) ); + rView.MakeVisible( rView.GetAllMarkedRect(), rReportSection); + } + } + } + else // pHdl != nullptr + { + // move the handle + if (nX || nY) + { + const Point aStartPoint( pHdl->GetPos() ); + const Point aEndPoint( pHdl->GetPos() + Point( nX, nY ) ); + const SdrDragStat& rDragStat = rView.GetDragStat(); + + // start dragging + rView.BegDragObj( aStartPoint, nullptr, pHdl, 0 ); + + if ( rView.IsDragObj() ) + { + const bool bWasNoSnap = rDragStat.IsNoSnap(); + const bool bWasSnapEnabled = rView.IsSnapEnabled(); + + // switch snapping off + if ( !bWasNoSnap ) + const_cast<SdrDragStat&>(rDragStat).SetNoSnap(); + if ( bWasSnapEnabled ) + rView.SetSnapEnabled( false ); + + tools::Rectangle aNewRect; + bool bCheck = false; + const SdrMarkList& rMarkList = rView.GetMarkedObjectList(); + for (size_t i = 0; !bCheck && i < rMarkList.GetMarkCount(); ++i ) + { + SdrMark* pMark = rMarkList.GetMark(i); + bCheck = dynamic_cast<OUnoObject*>(pMark->GetMarkedSdrObj()) != nullptr || dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()) != nullptr; + if ( bCheck ) + aNewRect.Union(pMark->GetMarkedSdrObj()->GetLastBoundRect()); + } + + switch(pHdl->GetKind()) + { + case SdrHdlKind::Left: + case SdrHdlKind::UpperLeft: + case SdrHdlKind::LowerLeft: + case SdrHdlKind::Upper: + aNewRect.AdjustLeft(nX ); + aNewRect.AdjustTop(nY ); + break; + case SdrHdlKind::UpperRight: + case SdrHdlKind::Right: + case SdrHdlKind::LowerRight: + case SdrHdlKind::Lower: + aNewRect.setWidth(aNewRect.getWidth() + nX); + aNewRect.setHeight(aNewRect.getHeight() + nY); + break; + default: + break; + } + if ( !(bCheck && isOver(aNewRect,*rReportSection.getPage(),rView)) ) + rView.MovAction(aEndPoint); + rView.EndDragObj(); + + // restore snap + if ( !bWasNoSnap ) + const_cast<SdrDragStat&>(rDragStat).SetNoSnap( bWasNoSnap ); + if ( bWasSnapEnabled ) + rView.SetSnapEnabled( bWasSnapEnabled ); + } + + // make moved handle visible + const tools::Rectangle aVisRect( aEndPoint - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) ); + rView.MakeVisible( aVisRect, rReportSection); + } + } + rView.AdjustMarkHdl(); + } + } +} + +void OViewsWindow::stopScrollTimer() +{ + ::std::for_each(m_aSections.begin(),m_aSections.end(), + [] (const TSectionsMap::value_type& sectionPtr) { + sectionPtr->getReportSection().stopScrollTimer(); + }); +} + +void OViewsWindow::fillCollapsedSections(::std::vector<sal_uInt16>& _rCollapsedPositions) const +{ + sal_uInt16 i = 0; + for (const auto& rxSection : m_aSections) + { + if ( rxSection->getStartMarker().isCollapsed() ) + _rCollapsedPositions.push_back(i); + ++i; + } +} + +void OViewsWindow::collapseSections(const uno::Sequence< beans::PropertyValue>& _aCollapsedSections) +{ + for (const beans::PropertyValue& rSection : _aCollapsedSections) + { + sal_uInt16 nPos = sal_uInt16(-1); + if ( (rSection.Value >>= nPos) && nPos < m_aSections.size() ) + { + m_aSections[nPos]->setCollapsed(true); + } + } +} + +void OViewsWindow::zoom(const Fraction& _aZoom) +{ + const MapMode& aMapMode = GetMapMode(); + + Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH)); + if ( _aZoom < aMapMode.GetScaleX() ) + aStartWidth *= aMapMode.GetScaleX(); + else + aStartWidth *= _aZoom; + + setZoomFactor(_aZoom,*this); + + for (const auto& rxSection : m_aSections) + { + rxSection->zoom(_aZoom); + } + + Resize(); + + Size aOut = GetOutputSizePixel(); + aOut.setWidth( tools::Long(aStartWidth) ); + aOut = PixelToLogic(aOut); + + tools::Rectangle aRect(PixelToLogic(Point(0,0)),aOut); + Invalidate(aRect, InvalidateFlags::NoChildren); +} + +void OViewsWindow::scrollChildren(const Point& _aThumbPos) +{ + const Point aPos(PixelToLogic(_aThumbPos)); + { + MapMode aMapMode = GetMapMode(); + const Point aOld = aMapMode.GetOrigin(); + aMapMode.SetOrigin(m_pParent->GetMapMode().GetOrigin()); + + const Point aPosY(m_pParent->PixelToLogic(_aThumbPos,aMapMode)); + + aMapMode.SetOrigin( Point(aOld.X() , - aPosY.Y())); + SetMapMode( aMapMode ); + Scroll(0, -( aOld.Y() + aPosY.Y()),ScrollFlags::Children); + } + + for (const auto& rxSection : m_aSections) + { + rxSection->scrollChildren(aPos.X()); + } +} + +void OViewsWindow::fillControlModelSelection(::std::vector< uno::Reference< uno::XInterface > >& _rSelection) const +{ + for (const auto& rxSection : m_aSections) + { + rxSection->getReportSection().fillControlModelSelection(_rSelection); + } +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/dlgedclip.cxx b/reportdesign/source/ui/report/dlgedclip.cxx new file mode 100644 index 000000000..1f36563fe --- /dev/null +++ b/reportdesign/source/ui/report/dlgedclip.cxx @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <dlgedclip.hxx> +#include <osl/diagnose.h> +#include <sot/exchange.hxx> + +namespace rptui +{ + +using namespace ::com::sun::star; + + +// OReportExchange + + +OReportExchange::OReportExchange(const TSectionElements& _rCopyElements ) +: m_aCopyElements(_rCopyElements) +{ +} + +SotClipboardFormatId OReportExchange::getDescriptorFormatId() +{ + static SotClipboardFormatId s_nFormat = static_cast<SotClipboardFormatId>(-1); + if (static_cast<SotClipboardFormatId>(-1) == s_nFormat) + { + s_nFormat = SotExchange::RegisterFormatName("application/x-openoffice;windows_formatname=\"report.ReportObjectsTransfer\""); + OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nFormat, "OReportExchange::getDescriptorFormatId: bad exchange id!"); + } + return s_nFormat; +} + +void OReportExchange::AddSupportedFormats() +{ + AddFormat(getDescriptorFormatId()); +} + +bool OReportExchange::GetData( const datatransfer::DataFlavor& _rFlavor, const OUString& /*rDestDoc*/ ) +{ + const SotClipboardFormatId nFormatId = SotExchange::GetFormat(_rFlavor); + return (nFormatId == getDescriptorFormatId()) && SetAny( uno::Any(m_aCopyElements) ); +} + +bool OReportExchange::canExtract(const DataFlavorExVector& _rFlavor) +{ + return IsFormatSupported(_rFlavor,getDescriptorFormatId()); +} + +OReportExchange::TSectionElements OReportExchange::extractCopies(const TransferableDataHelper& _rData) +{ + SotClipboardFormatId nKnownFormatId = getDescriptorFormatId(); + if ( _rData.HasFormat( nKnownFormatId ) ) + { + // extract the any from the transferable + datatransfer::DataFlavor aFlavor; + bool bSuccess = + SotExchange::GetFormatDataFlavor(nKnownFormatId, aFlavor); + OSL_ENSURE(bSuccess, "OReportExchange::extractCopies: invalid data format (no flavor)!"); + + uno::Any aDescriptor = _rData.GetAny(aFlavor, OUString()); + + TSectionElements aCopies; + bSuccess = aDescriptor >>= aCopies; + OSL_ENSURE(bSuccess, "OReportExchange::extractCopies: invalid clipboard format!"); + + // build the real descriptor + return aCopies; + } + + return TSectionElements(); +} + +} // rptui + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/dlgedfac.cxx b/reportdesign/source/ui/report/dlgedfac.cxx new file mode 100644 index 000000000..7429d5517 --- /dev/null +++ b/reportdesign/source/ui/report/dlgedfac.cxx @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <dlgedfac.hxx> +#include <strings.hxx> +#include <RptObject.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <osl/diagnose.h> + +namespace rptui +{ +using namespace ::com::sun::star; + + +DlgEdFactory::DlgEdFactory() +{ + SdrObjFactory::InsertMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) ); +} + + +DlgEdFactory::~DlgEdFactory() COVERITY_NOEXCEPT_FALSE +{ + SdrObjFactory::RemoveMakeObjectHdl( LINK(this, DlgEdFactory, MakeObject) ); +} + + +IMPL_STATIC_LINK( + DlgEdFactory, MakeObject, SdrObjCreatorParams, aParams, SdrObject* ) +{ + SdrObject* pNewObj = nullptr; + + if ( aParams.nInventor == SdrInventor::ReportDesign ) + { + switch( aParams.nObjIdentifier ) + { + case SdrObjKind::ReportDesignFixedText: + pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_FIXEDTEXT + ,OUString("com.sun.star.form.component.FixedText") + ,SdrObjKind::ReportDesignFixedText); + break; + case SdrObjKind::ReportDesignImageControl: + pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_IMAGECONTROL + ,OUString("com.sun.star.form.component.DatabaseImageControl") + ,SdrObjKind::ReportDesignImageControl); + break; + case SdrObjKind::ReportDesignFormattedField: + pNewObj = new OUnoObject(aParams.rSdrModel, SERVICE_FORMATTEDFIELD + ,OUString("com.sun.star.form.component.FormattedField") + ,SdrObjKind::ReportDesignFormattedField); + break; + case SdrObjKind::ReportDesignVerticalFixedLine: + case SdrObjKind::ReportDesignHorizontalFixedLine: + { + OUnoObject* pObj = new OUnoObject(aParams.rSdrModel, SERVICE_FIXEDLINE + ,OUString("com.sun.star.awt.UnoControlFixedLineModel") + ,aParams.nObjIdentifier); + pNewObj = pObj; + if ( aParams.nObjIdentifier == SdrObjKind::ReportDesignHorizontalFixedLine ) + { + uno::Reference<beans::XPropertySet> xProp = pObj->getAwtComponent(); + xProp->setPropertyValue( PROPERTY_ORIENTATION, uno::Any(sal_Int32(0)) ); + } + } + break; + case SdrObjKind::CustomShape: + pNewObj = new OCustomShape(aParams.rSdrModel, SERVICE_SHAPE); + break; + case SdrObjKind::ReportDesignSubReport: + pNewObj = new OOle2Obj(aParams.rSdrModel, SERVICE_REPORTDEFINITION, SdrObjKind::ReportDesignSubReport); + break; + case SdrObjKind::OLE2: + pNewObj = new OOle2Obj(aParams.rSdrModel, "com.sun.star.chart2.ChartDocument", SdrObjKind::OLE2); + break; + default: + OSL_FAIL("Unknown object id"); + break; + } + } + return pNewObj; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/dlgedfunc.cxx b/reportdesign/source/ui/report/dlgedfunc.cxx new file mode 100644 index 000000000..8a84093cd --- /dev/null +++ b/reportdesign/source/ui/report/dlgedfunc.cxx @@ -0,0 +1,894 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <vcl/scrbar.hxx> +#include <vcl/seleng.hxx> +#include <vcl/ptrstyle.hxx> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <svx/svdview.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdetc.hxx> +#include <svx/svddrgmt.hxx> +#include <svx/svdoashp.hxx> +#include <svx/svxids.hrc> +#include <svx/svditer.hxx> + +#include <toolkit/helper/vclunohelper.hxx> + +#include <dlgedfunc.hxx> +#include <ReportSection.hxx> +#include <DesignView.hxx> +#include <ReportController.hxx> +#include <SectionView.hxx> +#include <ViewsWindow.hxx> +#include <ReportWindow.hxx> +#include <RptObject.hxx> +#include <ScrollHelper.hxx> +#include <UITools.hxx> + +#include <strings.hxx> +#include <UndoEnv.hxx> +#include <RptModel.hxx> +#include <comphelper/propertysequence.hxx> +#include <tools/diagnose_ex.h> + +#define DEFAUL_MOVE_SIZE 100 +namespace rptui +{ +using namespace ::com::sun::star; + + +IMPL_LINK_NOARG( DlgEdFunc, ScrollTimeout, Timer *, void ) +{ + ForceScroll( m_pParent->PixelToLogic( m_pParent->GetPointerPosPixel() ) ); +} + + +void DlgEdFunc::ForceScroll( const Point& rPos ) +{ + aScrollTimer.Stop(); + + OReportWindow* pReportWindow = m_pParent->getSectionWindow()->getViewsWindow()->getView(); + OScrollWindowHelper* pScrollWindow = pReportWindow->getScrollWindow(); + + Size aOut = pReportWindow->GetOutputSizePixel(); + Fraction aStartWidth(tools::Long(REPORT_STARTMARKER_WIDTH)); + aStartWidth *= m_pParent->GetMapMode().GetScaleX(); + + aOut.AdjustWidth( -static_cast<tools::Long>(aStartWidth) ); + aOut.setHeight( m_pParent->GetOutputSizePixel().Height() ); + + Point aPos = pScrollWindow->getThumbPos(); + aPos.setX( aPos.X() * 0.5 ); + aPos.setY( aPos.Y() * 0.5 ); + tools::Rectangle aOutRect( aPos, aOut ); + aOutRect = m_pParent->PixelToLogic( aOutRect ); + tools::Rectangle aWorkArea(Point(), pScrollWindow->getTotalSize()); + aWorkArea.AdjustRight( -static_cast<tools::Long>(aStartWidth) ); + aWorkArea = pScrollWindow->PixelToLogic( aWorkArea ); + if( !aOutRect.Contains( rPos ) && aWorkArea.Contains( rPos ) ) + { + ScrollBar& rHScroll = pScrollWindow->GetHScroll(); + ScrollBar& rVScroll = pScrollWindow->GetVScroll(); + ScrollType eH = ScrollType::LineDown,eV = ScrollType::LineDown; + if( rPos.X() < aOutRect.Left() ) + eH = ScrollType::LineUp; + else if( rPos.X() <= aOutRect.Right() ) + eH = ScrollType::DontKnow; + + if( rPos.Y() < aOutRect.Top() ) + eV = ScrollType::LineUp; + else if( rPos.Y() <= aOutRect.Bottom() ) + eV = ScrollType::DontKnow; + + rHScroll.DoScrollAction(eH); + rVScroll.DoScrollAction(eV); + } + + aScrollTimer.Start(); +} + +DlgEdFunc::DlgEdFunc( OReportSection* _pParent ) + : m_pParent(_pParent) + , m_rView(_pParent->getSectionView()) + , aScrollTimer("reportdesign DlgEdFunc aScrollTimer") + , m_pOverlappingObj(nullptr) + , m_nOverlappedControlColor(0) + , m_nOldColor(0) + , m_bSelectionMode(false) + , m_bUiActive(false) + , m_bShowPropertyBrowser(false) +{ + aScrollTimer.SetInvokeHandler( LINK( this, DlgEdFunc, ScrollTimeout ) ); + m_rView.SetActualWin( m_pParent->GetOutDev() ); + aScrollTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL ); +} + +void DlgEdFunc::setOverlappedControlColor(Color _nColor) +{ + m_nOverlappedControlColor = _nColor; +} + +static Color lcl_setColorOfObject(const uno::Reference< uno::XInterface >& _xObj, Color _nColorTRGB) +{ + Color nBackColor; + try + { + uno::Reference<report::XReportComponent> xComponent(_xObj, uno::UNO_QUERY_THROW); + uno::Reference< beans::XPropertySet > xProp(xComponent, uno::UNO_QUERY_THROW); + uno::Any aAny = xProp->getPropertyValue(PROPERTY_CONTROLBACKGROUND); + if (aAny.hasValue()) + { + aAny >>= nBackColor; + // try to set background color at the ReportComponent + uno::Any aBlackColorAny(_nColorTRGB); + xProp->setPropertyValue(PROPERTY_CONTROLBACKGROUND, aBlackColorAny); + } + } + catch(uno::Exception&) + { + } + return nBackColor; +} + +DlgEdFunc::~DlgEdFunc() +{ + unColorizeOverlappedObj(); + aScrollTimer.Stop(); +} + + +bool DlgEdFunc::MouseButtonDown( const MouseEvent& rMEvt ) +{ + m_aMDPos = m_pParent->PixelToLogic( rMEvt.GetPosPixel() ); + m_pParent->GrabFocus(); + bool bHandled = false; + if ( rMEvt.IsLeft() ) + { + if ( rMEvt.GetClicks() > 1 ) + { + // show property browser + uno::Sequence<beans::PropertyValue> aArgs( comphelper::InitPropertySequence({ + { "ShowProperties", uno::Any(true) } + })); + m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController().executeUnChecked(SID_SHOW_PROPERTYBROWSER,aArgs); + m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView); + // TODO character in shapes + // SdrViewEvent aVEvt; + // m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + // if ( aVEvt.mpRootObj && aVEvt.pRootObj->ISA(SdrTextObj) ) + // SetInEditMode(static_cast<SdrTextObj *>(aVEvt.mpRootObj),rMEvt, sal_False); + bHandled = true; + } + else + { + SdrHdl* pHdl = m_rView.PickHandle(m_aMDPos); + + // if selected object was hit, drag object + if ( pHdl!=nullptr || m_rView.IsMarkedHit(m_aMDPos) ) + { + bHandled = true; + m_pParent->CaptureMouse(); + m_pParent->getSectionWindow()->getViewsWindow()->BegDragObj(m_aMDPos, pHdl,&m_rView); + } + } + } + else if ( rMEvt.IsRight() && !rMEvt.IsLeft() && rMEvt.GetClicks() == 1 ) // mark object when context menu was selected + { + SdrPageView* pPV = m_rView.GetSdrPageView(); + SdrViewEvent aVEvt; + if ( m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt) != SdrHitKind::MarkedObject && !rMEvt.IsShift() ) + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr); + if ( aVEvt.mpRootObj ) + m_rView.MarkObj(aVEvt.mpRootObj, pPV); + else + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr); + + bHandled = true; + } + else if( !rMEvt.IsLeft() ) + bHandled = true; + if ( !bHandled ) + m_pParent->CaptureMouse(); + return bHandled; +} + + +bool DlgEdFunc::MouseButtonUp( const MouseEvent& /*rMEvt*/ ) +{ + m_pParent->getSectionWindow()->getViewsWindow()->stopScrollTimer(); + return false; +} + +void DlgEdFunc::checkTwoClicks(const MouseEvent& rMEvt) +{ + deactivateOle(); + + const sal_uInt16 nClicks = rMEvt.GetClicks(); + if ( !(nClicks == 2 && rMEvt.IsLeft()) ) + return; + + if ( m_rView.AreObjectsMarked() ) + { + const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList(); + if (rMarkList.GetMarkCount() == 1) + { + const SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + activateOle(pObj); + } + } +} + +void DlgEdFunc::stopScrollTimer() +{ + unColorizeOverlappedObj(); + aScrollTimer.Stop(); + if ( m_pParent->IsMouseCaptured() ) + m_pParent->ReleaseMouse(); +} + + +bool DlgEdFunc::MouseMove( const MouseEvent& /*rMEvt*/ ) +{ + return false; +} + +bool DlgEdFunc::handleKeyEvent(const KeyEvent& _rEvent) +{ + bool bReturn = false; + + if ( !m_bUiActive ) + { + const vcl::KeyCode& rCode = _rEvent.GetKeyCode(); + sal_uInt16 nCode = rCode.GetCode(); + + switch ( nCode ) + { + case KEY_ESCAPE: + { + if ( m_pParent->getSectionWindow()->getViewsWindow()->IsAction() ) + { + m_pParent->getSectionWindow()->getViewsWindow()->BrkAction(); + bReturn = true; + } + else if ( m_rView.IsTextEdit() ) + { + m_rView.SdrEndTextEdit(); + bReturn = true; + } + else if ( m_rView.AreObjectsMarked() ) + { + const SdrHdlList& rHdlList = m_rView.GetHdlList(); + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + if ( pHdl ) + const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl(); + else + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr); + + deactivateOle(true); + bReturn = false; + } + else + { + deactivateOle(true); + } + } + break; + case KEY_TAB: + { + if ( !rCode.IsMod1() && !rCode.IsMod2() ) + { + // mark next object + if ( !m_rView.MarkNextObj( !rCode.IsShift() ) ) + { + // if no next object, mark first/last + m_rView.UnmarkAllObj(); + m_rView.MarkNextObj( !rCode.IsShift() ); + } + + if ( m_rView.AreObjectsMarked() ) + m_rView.MakeVisible( m_rView.GetAllMarkedRect(), *m_pParent); + + bReturn = true; + } + else if ( rCode.IsMod1() && rCode.IsMod2()) + { + // selected handle + const SdrHdlList& rHdlList = m_rView.GetHdlList(); + const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl( !rCode.IsShift() ); + + // guarantee visibility of focused handle + SdrHdl* pHdl = rHdlList.GetFocusHdl(); + if ( pHdl ) + { + Point aHdlPosition( pHdl->GetPos() ); + tools::Rectangle aVisRect( aHdlPosition - Point( DEFAUL_MOVE_SIZE, DEFAUL_MOVE_SIZE ), Size( 200, 200 ) ); + m_rView.MakeVisible( aVisRect, *m_pParent); + } + + bReturn = true; + } + } + break; + case KEY_UP: + case KEY_DOWN: + case KEY_LEFT: + case KEY_RIGHT: + { + m_pParent->getSectionWindow()->getViewsWindow()->handleKey(rCode); + bReturn = true; + } + break; + case KEY_RETURN: + if ( !rCode.IsMod1() ) + { + const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList(); + if ( rMarkList.GetMarkCount() == 1 ) + { + SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); + activateOle(pObj); + } + } + break; + case KEY_DELETE: + if ( !rCode.IsMod1() && !rCode.IsMod2() ) + { + bReturn = true; + break; + } + [[fallthrough]]; + default: + { + bReturn = m_rView.KeyInput(_rEvent, m_pParent); + } + break; + } + } + + if ( bReturn && m_pParent->IsMouseCaptured() ) + m_pParent->ReleaseMouse(); + + return bReturn; +} + +void DlgEdFunc::activateOle(SdrObject* _pObj) +{ + if ( !_pObj ) + return; + + const SdrObjKind nSdrObjKind = _pObj->GetObjIdentifier(); + + // OLE: activate + + if (nSdrObjKind != SdrObjKind::OLE2) + return; + + SdrOle2Obj* pOleObj = dynamic_cast<SdrOle2Obj*>(_pObj); + if (!(pOleObj && pOleObj->GetObjRef().is())) + return; + + if (m_rView.IsTextEdit()) + { + m_rView.SdrEndTextEdit(); + } + + pOleObj->AddOwnLightClient(); + pOleObj->SetWindow(VCLUnoHelper::GetInterface(m_pParent)); + try + { + pOleObj->GetObjRef()->changeState( embed::EmbedStates::UI_ACTIVE ); + m_bUiActive = true; + OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController(); + m_bShowPropertyBrowser = rController.isCommandChecked(SID_SHOW_PROPERTYBROWSER); + if ( m_bShowPropertyBrowser ) + rController.executeChecked(SID_SHOW_PROPERTYBROWSER,uno::Sequence< beans::PropertyValue >()); + } + catch( uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + } +} + +void DlgEdFunc::deactivateOle(bool _bSelect) +{ + OLEObjCache& rObjCache = GetSdrGlobalData().GetOLEObjCache(); + OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController(); + const size_t nCount = rObjCache.size(); + for(size_t i = 0 ; i < nCount;++i) + { + SdrOle2Obj* pObj = rObjCache[i]; + if ( m_pParent->getPage() == pObj->getSdrPageFromSdrObject() ) + { + uno::Reference< embed::XEmbeddedObject > xObj = pObj->GetObjRef(); + if ( xObj.is() && xObj->getCurrentState() == embed::EmbedStates::UI_ACTIVE ) + { + xObj->changeState( embed::EmbedStates::RUNNING ); + m_bUiActive = false; + if ( m_bShowPropertyBrowser ) + { + rController.executeChecked(SID_SHOW_PROPERTYBROWSER,uno::Sequence< beans::PropertyValue >()); + } + + if ( _bSelect ) + { + SdrPageView* pPV = m_rView.GetSdrPageView(); + m_rView.MarkObj(pObj, pPV); + } + } + } + } +} + +void DlgEdFunc::colorizeOverlappedObject(SdrObject* _pOverlappedObj) +{ + OObjectBase* pObj = dynamic_cast<OObjectBase*>(_pOverlappedObj); + if ( !pObj ) + return; + + const uno::Reference<report::XReportComponent>& xComponent = pObj->getReportComponent(); + if (xComponent.is() && xComponent != m_xOverlappingObj) + { + OReportModel& rRptModel(static_cast< OReportModel& >(_pOverlappedObj->getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + // uncolorize an old object, if there is one + unColorizeOverlappedObj(); + + m_nOldColor = lcl_setColorOfObject(xComponent, m_nOverlappedControlColor); + m_xOverlappingObj = xComponent; + m_pOverlappingObj = _pOverlappedObj; + } +} + +void DlgEdFunc::unColorizeOverlappedObj() +{ + // uncolorize an old object, if there is one + if (m_xOverlappingObj.is()) + { + OReportModel& rRptModel(static_cast< OReportModel& >(m_pOverlappingObj->getSdrModelFromSdrObject())); + OXUndoEnvironment::OUndoEnvLock aLock(rRptModel.GetUndoEnv()); + + lcl_setColorOfObject(m_xOverlappingObj, m_nOldColor); + m_xOverlappingObj = nullptr; + m_pOverlappingObj = nullptr; + } +} + +bool DlgEdFunc::isOverlapping(const MouseEvent& rMEvt) +{ + SdrViewEvent aVEvt; + bool bOverlapping = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aVEvt) != SdrHitKind::NONE; + if (bOverlapping && aVEvt.mpObj) + { + colorizeOverlappedObject(aVEvt.mpObj); + } + else + { + unColorizeOverlappedObj(); + } + + return bOverlapping; +} + +void DlgEdFunc::checkMovementAllowed(const MouseEvent& rMEvt) +{ + if ( m_pParent->getSectionWindow()->getViewsWindow()->IsDragObj() ) + { + if ( isRectangleHit(rMEvt) ) + { + // there is another component under use, break action + m_pParent->getSectionWindow()->getViewsWindow()->BrkAction(); + } + // object was dragged + Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) ); + if (m_bSelectionMode) + { + m_pParent->getSectionWindow()->getViewsWindow()->EndAction(); + } + else + { + bool bControlKeyPressed = rMEvt.IsMod1(); + // Don't allow points smaller 0 + if (bControlKeyPressed && (aPnt.Y() < 0)) + { + aPnt.setY( 0 ); + } + if (m_rView.IsDragResize()) + { + // we resize the object don't resize to above sections + if ( aPnt.Y() < 0 ) + { + aPnt.setY( 0 ); + } + } + m_pParent->getSectionWindow()->getViewsWindow()->EndDragObj( bControlKeyPressed, &m_rView, aPnt ); + } + m_pParent->getSectionWindow()->getViewsWindow()->ForceMarkedToAnotherPage(); + m_pParent->Invalidate(InvalidateFlags::Children); + } + else + m_pParent->getSectionWindow()->getViewsWindow()->EndAction(); +} + +bool DlgEdFunc::isOnlyCustomShapeMarked() const +{ + bool bReturn = true; + const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList(); + for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i ) + { + SdrMark* pMark = rMarkList.GetMark(i); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + if (pObj->GetObjIdentifier() != SdrObjKind::CustomShape) + { + // we found an object in the marked objects, which is not a custom shape. + bReturn = false; + break; + } + } + return bReturn; +} + +bool DlgEdFunc::isRectangleHit(const MouseEvent& rMEvt) +{ + if (isOnlyCustomShapeMarked()) + { + return false; + } + + SdrViewEvent aVEvt; + const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::MOVE, aVEvt); + bool bIsSetPoint = (eHit == SdrHitKind::UnmarkedObject); + if ( !bIsSetPoint ) + { + // no drag rect, we have to check every single select rect + const SdrDragStat& rDragStat = m_rView.GetDragStat(); + if (rDragStat.GetDragMethod() != nullptr) + { + SdrObjListIter aIter(m_pParent->getPage(),SdrIterMode::DeepNoGroups); + // loop through all marked objects and check if there new rect overlapps an old one. + for (;;) + { + SdrObject* pObjIter = aIter.Next(); + if( !pObjIter || bIsSetPoint) + break; + if ( m_rView.IsObjMarked(pObjIter) + && (dynamic_cast<OUnoObject*>(pObjIter) != nullptr || dynamic_cast<OOle2Obj*>(pObjIter) != nullptr) ) + { + tools::Rectangle aNewRect = pObjIter->GetLastBoundRect(); + tools::Long nDx = rDragStat.IsHorFixed() ? 0 : rDragStat.GetDX(); + tools::Long nDy = rDragStat.IsVerFixed() ? 0 : rDragStat.GetDY(); + if ( (nDx + aNewRect.Left()) < 0 ) + nDx = -aNewRect.Left(); + if ( (nDy + aNewRect.Top()) < 0 ) + nDy = -aNewRect.Top(); + + if ( rDragStat.GetDragMethod()->getMoveOnly() ) + aNewRect.Move(nDx,nDy); + else + ::ResizeRect(aNewRect,rDragStat.GetRef1(),rDragStat.GetXFact(),rDragStat.GetYFact()); + + + SdrObject* pObjOverlapped = isOver(aNewRect,*m_pParent->getPage(),m_rView,false,pObjIter, ISOVER_IGNORE_CUSTOMSHAPES); + bIsSetPoint = pObjOverlapped != nullptr; + if (pObjOverlapped && !m_bSelectionMode) + { + colorizeOverlappedObject(pObjOverlapped); + } + } + } + } + } + else if (aVEvt.mpObj && (aVEvt.mpObj->GetObjIdentifier() != SdrObjKind::CustomShape) && !m_bSelectionMode) + { + colorizeOverlappedObject(aVEvt.mpObj); + } + else + bIsSetPoint = false; + return bIsSetPoint; +} + +bool DlgEdFunc::setMovementPointer(const MouseEvent& rMEvt) +{ + bool bIsSetPoint = isRectangleHit(rMEvt); + if ( bIsSetPoint ) + m_pParent->SetPointer( PointerStyle::NotAllowed ); + else + { + bool bCtrlKey = rMEvt.IsMod1(); + if (bCtrlKey) + { + m_pParent->SetPointer( PointerStyle::MoveDataLink ); + bIsSetPoint = true; + } + } + return bIsSetPoint; +} + + +DlgEdFuncInsert::DlgEdFuncInsert( OReportSection* _pParent ) : + DlgEdFunc( _pParent ) +{ + m_rView.SetCreateMode(); +} + + +DlgEdFuncInsert::~DlgEdFuncInsert() +{ + m_rView.SetEditMode(); +} + + +bool DlgEdFuncInsert::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if ( DlgEdFunc::MouseButtonDown(rMEvt) ) + return true; + + SdrViewEvent aVEvt; + SdrObjKind nId = m_rView.GetCurrentObjIdentifier(); + + const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + + if (eHit == SdrHitKind::UnmarkedObject && nId != SdrObjKind::CustomShape) + { + // there is an object under the mouse cursor, but not a customshape + m_pParent->getSectionWindow()->getViewsWindow()->BrkAction(); + return false; + } + + // if no action, create object + if (!m_pParent->getSectionWindow()->getViewsWindow()->IsAction()) + { + deactivateOle(true); + if ( m_pParent->getSectionWindow()->getViewsWindow()->HasSelection() ) + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(&m_rView); + m_rView.BegCreateObj(m_aMDPos); + m_pParent->getSectionWindow()->getViewsWindow()->createDefault(); + } + + return true; +} + + +bool DlgEdFuncInsert::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( DlgEdFunc::MouseButtonUp( rMEvt ) ) + return true; + + const Point aPos( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) ); + const sal_uInt16 nHitLog = sal_uInt16 ( m_pParent->PixelToLogic(Size(3,0)).Width() ); + + bool bReturn = true; + // object creation active? + if ( m_rView.IsCreateObj() ) + { + if ( isOver(m_rView.GetCreateObj(),*m_pParent->getPage(),m_rView) ) + { + m_pParent->getSectionWindow()->getViewsWindow()->BrkAction(); + // BrkAction disables the create mode + m_rView.SetCreateMode(); + return true; + } + + m_rView.EndCreateObj(SdrCreateCmd::ForceEnd); + + if ( !m_rView.AreObjectsMarked() ) + { + m_rView.MarkObj(aPos, nHitLog); + } + + bReturn = m_rView.AreObjectsMarked(); + if ( bReturn ) + { + OReportController& rController = m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->getController(); + const SdrMarkList& rMarkList = m_rView.GetMarkedObjectList(); + for (size_t i = 0; i < rMarkList.GetMarkCount(); ++i ) + { + SdrMark* pMark = rMarkList.GetMark(i); + OOle2Obj* pObj = dynamic_cast<OOle2Obj*>(pMark->GetMarkedSdrObj()); + if ( pObj && !pObj->IsEmpty() ) + { + pObj->initializeChart(rController.getModel()); + } + } + } + } + else + checkMovementAllowed(rMEvt); + + if ( !m_rView.AreObjectsMarked() && + std::abs(m_aMDPos.X() - aPos.X()) < nHitLog && + std::abs(m_aMDPos.Y() - aPos.Y()) < nHitLog && + !rMEvt.IsShift() && !rMEvt.IsMod2() ) + { + SdrPageView* pPV = m_rView.GetSdrPageView(); + SdrViewEvent aVEvt; + m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + m_rView.MarkObj(aVEvt.mpRootObj, pPV); + } + checkTwoClicks(rMEvt); + m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView); + return bReturn; +} + + +bool DlgEdFuncInsert::MouseMove( const MouseEvent& rMEvt ) +{ + if ( DlgEdFunc::MouseMove(rMEvt ) ) + return true; + Point aPos( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) ); + + if ( m_rView.IsCreateObj() ) + { + m_rView.SetOrtho(SdrObjCustomShape::doConstructOrthogonal(m_rView.getReportSection()->getSectionWindow()->getViewsWindow()->getShapeType()) ? !rMEvt.IsShift() : rMEvt.IsShift()); + m_rView.SetAngleSnapEnabled(rMEvt.IsShift()); + } + + bool bIsSetPoint = false; + if ( m_rView.IsAction() ) + { + if ( m_rView.IsDragResize() ) + { + // we resize the object don't resize to above sections + if ( aPos.Y() < 0 ) + { + aPos.setY( 0 ); + } + } + bIsSetPoint = setMovementPointer(rMEvt); + ForceScroll(aPos); + m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPos,&m_rView, false); + } + + if ( !bIsSetPoint ) + m_pParent->SetPointer( m_rView.GetPreferredPointer( aPos, m_pParent->GetOutDev()) ); + + return true; +} + + +DlgEdFuncSelect::DlgEdFuncSelect( OReportSection* _pParent ) : + DlgEdFunc( _pParent ) +{ +} + + +DlgEdFuncSelect::~DlgEdFuncSelect() +{ +} + + +bool DlgEdFuncSelect::MouseButtonDown( const MouseEvent& rMEvt ) +{ + m_bSelectionMode = false; + if ( DlgEdFunc::MouseButtonDown(rMEvt) ) + return true; + + SdrViewEvent aVEvt; + const SdrHitKind eHit = m_rView.PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); + if( eHit == SdrHitKind::UnmarkedObject ) + { + // if not multi selection, unmark all + if ( !rMEvt.IsShift() ) + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr); + + if ( m_rView.MarkObj(m_aMDPos) && rMEvt.IsLeft() ) + { + // drag object + m_pParent->getSectionWindow()->getViewsWindow()->BegDragObj(m_aMDPos, m_rView.PickHandle(m_aMDPos), &m_rView); + } + else + { + // select object + m_pParent->getSectionWindow()->getViewsWindow()->BegMarkObj(m_aMDPos,&m_rView); + } + } + else + { + if( !rMEvt.IsShift() ) + m_pParent->getSectionWindow()->getViewsWindow()->unmarkAllObjects(nullptr); + + if ( rMEvt.GetClicks() == 1 ) + { + m_bSelectionMode = true; + m_pParent->getSectionWindow()->getViewsWindow()->BegMarkObj( m_aMDPos ,&m_rView); + } + else + { + m_rView.SdrBeginTextEdit( aVEvt.mpRootObj,m_rView.GetSdrPageView(),m_pParent ); + } + } + + return true; +} + + +bool DlgEdFuncSelect::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if ( DlgEdFunc::MouseButtonUp( rMEvt ) ) + return true; + + // get view from parent + const Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) ); + + if ( rMEvt.IsLeft() ) // left mousebutton pressed + checkMovementAllowed(rMEvt); + + m_pParent->getSectionWindow()->getViewsWindow()->EndAction(); + checkTwoClicks(rMEvt); + + m_pParent->SetPointer( m_rView.GetPreferredPointer( aPnt, m_pParent->GetOutDev() ) ); + + if ( !m_bUiActive ) + m_pParent->getSectionWindow()->getViewsWindow()->getView()->getReportView()->UpdatePropertyBrowserDelayed(m_rView); + m_bSelectionMode = false; + return true; +} + + +bool DlgEdFuncSelect::MouseMove( const MouseEvent& rMEvt ) +{ + if ( DlgEdFunc::MouseMove(rMEvt ) ) + return true; + + Point aPnt( m_pParent->PixelToLogic( rMEvt.GetPosPixel() ) ); + bool bIsSetPoint = false; + + if ( m_rView.IsAction() ) // Drag Mode + { + bIsSetPoint = setMovementPointer(rMEvt); + ForceScroll(aPnt); + if (m_rView.GetDragMethod()==nullptr) + { + // create a selection + m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPnt, &m_rView, false); + } + else + { + if ( m_rView.IsDragResize() ) + { + // we resize the object don't resize to above sections + if ( aPnt.Y() < 0 ) + { + aPnt.setY( 0 ); + } + } + // drag or resize an object + bool bControlKey = rMEvt.IsMod1(); + m_pParent->getSectionWindow()->getViewsWindow()->MovAction(aPnt, &m_rView, bControlKey); + } + } + + if ( !bIsSetPoint ) + { + m_pParent->SetPointer( m_rView.GetPreferredPointer( aPnt, m_pParent->GetOutDev() ) ); + + // restore color + unColorizeOverlappedObj(); + } + + return true; +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/reportdesign/source/ui/report/propbrw.cxx b/reportdesign/source/ui/report/propbrw.cxx new file mode 100644 index 000000000..4254dcf3e --- /dev/null +++ b/reportdesign/source/ui/report/propbrw.cxx @@ -0,0 +1,528 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#include <memory> +#include <propbrw.hxx> +#include <RptObject.hxx> +#include <ReportController.hxx> +#include <cppuhelper/component_context.hxx> +#include <strings.hrc> +#include <rptui_slotid.hrc> +#include <tools/diagnose_ex.h> +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/frame/Frame.hpp> +#include <com/sun/star/inspection/ObjectInspector.hpp> +#include <com/sun/star/inspection/DefaultHelpProvider.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/report/inspection/DefaultComponentInspectorModel.hpp> +#include <vcl/stdtext.hxx> +#include <vcl/weld.hxx> +#include <svx/svditer.hxx> + +#include <toolkit/helper/vclunohelper.hxx> +#include <comphelper/namecontainer.hxx> +#include <comphelper/types.hxx> +#include <comphelper/sequence.hxx> +#include <core_resource.hxx> +#include <SectionView.hxx> +#include <ReportSection.hxx> +#include <strings.hxx> +#include <DesignView.hxx> +#include <ViewsWindow.hxx> +#include <UITools.hxx> +#include <unotools/confignode.hxx> + +namespace rptui +{ +#define STD_WIN_SIZE_X 300 +#define STD_WIN_SIZE_Y 350 + +using namespace ::com::sun::star; +using namespace uno; +using namespace lang; +using namespace frame; +using namespace beans; +using namespace container; +using namespace ::comphelper; + + +namespace +{ + bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext ) + { + ::utl::OConfigurationTreeRoot aConfiguration( + ::utl::OConfigurationTreeRoot::createWithComponentContext( + _rxContext, "/org.openoffice.Office.ReportDesign/PropertyBrowser/" ) ); + + bool bEnabled = false; + OSL_VERIFY( aConfiguration.getNodeValue( "DirectHelp" ) >>= bEnabled ); + return bEnabled; + } +} + + +// PropBrw + + +PropBrw::PropBrw(const Reference< XComponentContext >& _xORB, vcl::Window* pParent, ODesignView* _pDesignView) + : DockingWindow(pParent,WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK)) + , m_xContentArea(VclPtr<VclVBox>::Create(this)) + , m_xORB(_xORB) + , m_pDesignView(_pDesignView) + , m_pView( nullptr ) + , m_bInitialStateChange(true) +{ + + Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y); + SetOutputSizePixel(aPropWinSize); + + // turn off WB_CLIPCHILDREN otherwise the bg won't extend "under" + // transparent children of the widget + m_xContentArea->SetControlBackground(m_xContentArea->GetSettings().GetStyleSettings().GetWindowColor()); + m_xContentArea->SetBackground(m_xContentArea->GetControlBackground()); + m_xContentArea->SetStyle(m_xContentArea->GetStyle() & ~WB_CLIPCHILDREN); + m_xContentArea->Show(); + + try + { + // create a frame wrapper for myself + m_xMeAsFrame = Frame::create( m_xORB ); + m_xMeAsFrame->initialize(VCLUnoHelper::GetInterface(m_xContentArea)); + m_xMeAsFrame->setName("report property browser"); // change name! + } + catch (Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + OSL_FAIL("PropBrw::PropBrw: could not create/initialize my frame!"); + m_xMeAsFrame.clear(); + } + + if (m_xMeAsFrame.is()) + { + try + { + ::cppu::ContextEntry_Init aHandlerContextInfo[] = + { + ::cppu::ContextEntry_Init( "ContextDocument", Any( m_pDesignView->getController().getModel() )), + ::cppu::ContextEntry_Init( "DialogParentWindow", Any( VCLUnoHelper::GetInterface ( this ) )), + ::cppu::ContextEntry_Init( "ActiveConnection", Any( m_pDesignView->getController().getConnection() ) ), + }; + m_xInspectorContext.set( + ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ), + m_xORB ) ); + // create a property browser controller + bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB ); + Reference< inspection::XObjectInspectorModel> xInspectorModel( bEnableHelpSection + ? report::inspection::DefaultComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 8 ) + : report::inspection::DefaultComponentInspectorModel::createDefault( m_xInspectorContext ) ); + + m_xBrowserController = inspection::ObjectInspector::createWithModel(m_xInspectorContext, xInspectorModel); + if ( !m_xBrowserController.is() ) + { + ShowServiceNotAvailableError(pParent ? pParent->GetFrameWeld() : nullptr, u"com.sun.star.inspection.ObjectInspector", true); + } + else + { + m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame, UNO_QUERY_THROW)); + if ( bEnableHelpSection ) + { + uno::Reference< inspection::XObjectInspector > xInspector( m_xBrowserController, uno::UNO_SET_THROW ); + uno::Reference< inspection::XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() ); + inspection::DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI ); + } + } + } + catch (Exception&) + { + DBG_UNHANDLED_EXCEPTION("reportdesign"); + OSL_FAIL("PropBrw::PropBrw: could not create/initialize the browser controller!"); + try + { + ::comphelper::disposeComponent(m_xBrowserController); + } + catch(Exception&) { } + m_xBrowserController.clear(); + } + } + + VclContainer::setLayoutAllocation(*m_xContentArea, Point(0, 0), aPropWinSize); + m_xContentArea->Show(); + + ::rptui::notifySystemWindow(pParent,this,::comphelper::mem_fun(&TaskPaneList::AddWindow)); +} + + +PropBrw::~PropBrw() +{ + disposeOnce(); +} + +void PropBrw::dispose() +{ + if (m_xBrowserController.is()) + implDetachController(); + + try + { + uno::Reference<container::XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY); + if ( xName.is() ) + { + const OUString pProps[] = { OUString( "ContextDocument" ) + , OUString( "DialogParentWindow" ) + , OUString( "ActiveConnection" )}; + for (const auto & i : pProps) + xName->removeByName(i); + } + } + catch(Exception&) + {} + + ::rptui::notifySystemWindow(this,this,::comphelper::mem_fun(&TaskPaneList::RemoveWindow)); + m_pDesignView.clear(); + m_xContentArea.disposeAndClear(); + DockingWindow::dispose(); +} + +void PropBrw::setCurrentPage(const OUString& _sLastActivePage) +{ + m_sLastActivePage = _sLastActivePage; +} + + +void PropBrw::implDetachController() +{ + m_sLastActivePage = getCurrentPage(); + implSetNewObject( ); + + if ( m_xMeAsFrame.is() ) + m_xMeAsFrame->setComponent( nullptr, nullptr ); + + if ( m_xBrowserController.is() ) + m_xBrowserController->attachFrame( nullptr ); + + m_xMeAsFrame.clear(); + m_xBrowserController.clear(); +} + +OUString PropBrw::getCurrentPage() const +{ + OUString sCurrentPage; + try + { + if ( m_xBrowserController.is() ) + { + OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage ); + } + + if ( sCurrentPage.isEmpty() ) + sCurrentPage = m_sLastActivePage; + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::getCurrentPage: caught an exception while retrieving the current page!" ); + } + return sCurrentPage; +} + +bool PropBrw::Close() +{ + m_xLastSection.clear(); + // suspend the controller (it is allowed to veto) + if ( m_xMeAsFrame.is() ) + { + try + { + Reference< XController > xController( m_xMeAsFrame->getController() ); + if ( xController.is() && !xController->suspend( true ) ) + return false; + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::Close: caught an exception while asking the controller!" ); + } + } + implDetachController(); + + m_pDesignView->getController().executeUnChecked(SID_PROPERTYBROWSER_LAST_PAGE,uno::Sequence< beans::PropertyValue>()); + + return true; +} + +uno::Sequence< Reference<uno::XInterface> > PropBrw::CreateCompPropSet(const SdrMarkList& _rMarkList) +{ + const size_t nMarkCount = _rMarkList.GetMarkCount(); + ::std::vector< uno::Reference< uno::XInterface> > aSets; + aSets.reserve(nMarkCount); + + for(size_t i=0; i<nMarkCount; ++i) + { + SdrObject* pCurrent = _rMarkList.GetMark(i)->GetMarkedSdrObj(); + + ::std::unique_ptr<SdrObjListIter> pGroupIterator; + if (pCurrent->IsGroupObject()) + { + pGroupIterator.reset(new SdrObjListIter(pCurrent->GetSubList())); + pCurrent = pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr; + } + + while (pCurrent) + { + OObjectBase* pObj = dynamic_cast<OObjectBase*>(pCurrent); + if ( pObj ) + aSets.push_back(CreateComponentPair(pObj)); + + // next element + pCurrent = pGroupIterator && pGroupIterator->IsMore() ? pGroupIterator->Next() : nullptr; + } + } + return uno::Sequence< Reference<uno::XInterface> >(aSets.data(), aSets.size()); +} + +void PropBrw::implSetNewObject( const uno::Sequence< Reference<uno::XInterface> >& _aObjects ) +{ + if ( m_xBrowserController.is() ) + { + try + { + m_xBrowserController->inspect(uno::Sequence< Reference<uno::XInterface> >()); + m_xBrowserController->inspect(_aObjects); + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" ); + } + } + SetText( GetHeadlineName(_aObjects) ); +} + + +OUString PropBrw::GetHeadlineName( const uno::Sequence< Reference<uno::XInterface> >& _aObjects ) +{ + OUString aName; + if ( !_aObjects.hasElements() ) + { + aName = RptResId(RID_STR_BRWTITLE_NO_PROPERTIES); + } + else if ( _aObjects.getLength() == 1 ) // single selection + { + aName = RptResId(RID_STR_BRWTITLE_PROPERTIES); + + uno::Reference< container::XNameContainer > xNameCont(_aObjects[0],uno::UNO_QUERY); + Reference< lang::XServiceInfo > xServiceInfo( xNameCont->getByName("ReportComponent"), UNO_QUERY ); + if ( xServiceInfo.is() ) + { + TranslateId pResId; + if ( xServiceInfo->supportsService( SERVICE_FIXEDTEXT ) ) + { + pResId = RID_STR_PROPTITLE_FIXEDTEXT; + } + else if ( xServiceInfo->supportsService( SERVICE_IMAGECONTROL ) ) + { + pResId = RID_STR_PROPTITLE_IMAGECONTROL; + } + else if ( xServiceInfo->supportsService( SERVICE_FORMATTEDFIELD ) ) + { + pResId = RID_STR_PROPTITLE_FORMATTED; + } + else if ( xServiceInfo->supportsService( SERVICE_SHAPE ) ) + { + pResId = RID_STR_PROPTITLE_SHAPE; + } + else if ( xServiceInfo->supportsService( SERVICE_REPORTDEFINITION ) ) + { + pResId = RID_STR_PROPTITLE_REPORT; + } + else if ( xServiceInfo->supportsService( SERVICE_SECTION ) ) + { + pResId = RID_STR_PROPTITLE_SECTION; + } + else if ( xServiceInfo->supportsService( SERVICE_FUNCTION ) ) + { + pResId = RID_STR_PROPTITLE_FUNCTION; + } + else if ( xServiceInfo->supportsService( SERVICE_GROUP ) ) + { + pResId = RID_STR_PROPTITLE_GROUP; + } + else if ( xServiceInfo->supportsService( SERVICE_FIXEDLINE ) ) + { + pResId = RID_STR_PROPTITLE_FIXEDLINE; + } + else + { + OSL_FAIL("Unknown service name!"); + aName += RID_STR_CLASS_FORMATTEDFIELD; + return aName; + } + + aName += RptResId(pResId); + } + } + else // multiselection + { + aName = RptResId(RID_STR_BRWTITLE_PROPERTIES) + + RptResId(RID_STR_BRWTITLE_MULTISELECT); + } + + return aName; +} + +uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(OObjectBase* _pObj) +{ + _pObj->initializeOle(); + return CreateComponentPair(_pObj->getAwtComponent(),_pObj->getReportComponent()); +} + +uno::Reference< uno::XInterface> PropBrw::CreateComponentPair(const uno::Reference< uno::XInterface>& _xFormComponent + ,const uno::Reference< uno::XInterface>& _xReportComponent) +{ + uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get()); + xNameCont->insertByName("FormComponent",uno::Any(_xFormComponent)); + xNameCont->insertByName("ReportComponent",uno::Any(_xReportComponent)); + xNameCont->insertByName("RowSet",uno::Any(uno::Reference< uno::XInterface>(m_pDesignView->getController().getRowSet()))); + + return xNameCont; +} + +::Size PropBrw::getMinimumSize() const +{ + ::Size aSize; + Reference< awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY ); + if( xLayoutConstrains.is() ) + { + awt::Size aMinSize = xLayoutConstrains->getMinimumSize(); + aMinSize.Height += 4; + aMinSize.Width += 4; + aSize.setHeight( aMinSize.Height ); + aSize.setWidth( aMinSize.Width ); + } + return aSize; +} + +void PropBrw::Update( OSectionView* pNewView ) +{ + try + { + if ( m_pView ) + { + EndListening( *(m_pView->GetModel()) ); + m_pView = nullptr; + } + + // set focus on initialization + if ( m_bInitialStateChange ) + { + // if we're just newly created, we want to have the focus + PostUserEvent( LINK( this, PropBrw, OnAsyncGetFocus ), nullptr, true ); + m_bInitialStateChange = false; + // and additionally, we want to show the page which was active during + // our previous incarnation + if ( !m_sLastActivePage.isEmpty() && m_xBrowserController.is() ) + { + try + { + m_xBrowserController->restoreViewData( Any( m_sLastActivePage ) ); + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "FmPropBrw::StateChanged: caught an exception while setting the initial page!" ); + } + } + } + + if ( !pNewView ) + return; + else + m_pView = pNewView; + + uno::Sequence< Reference<uno::XInterface> > aMarkedObjects; + OViewsWindow* pViews = m_pView->getReportSection()->getSectionWindow()->getViewsWindow(); + const sal_uInt16 nSectionCount = pViews->getSectionCount(); + for (sal_uInt16 i = 0; i < nSectionCount; ++i) + { + OSectionWindow* pSectionWindow = pViews->getSectionWindow(i); + if ( pSectionWindow ) + { + const SdrMarkList& rMarkList = pSectionWindow->getReportSection().getSectionView().GetMarkedObjectList(); + aMarkedObjects = ::comphelper::concatSequences(aMarkedObjects,CreateCompPropSet( rMarkList )); + } + } + + if ( aMarkedObjects.hasElements() ) // multiple selection + { + m_xLastSection.clear(); + implSetNewObject( aMarkedObjects ); + } + else if ( m_xLastSection != m_pView->getReportSection()->getSection() ) + { + uno::Reference< uno::XInterface> xTemp(m_pView->getReportSection()->getSection()); + m_xLastSection = xTemp; + uno::Reference< container::XNameContainer > xNameCont = ::comphelper::NameContainer_createInstance(cppu::UnoType<XInterface>::get() ); + xNameCont->insertByName("ReportComponent",uno::Any(xTemp)); + xTemp = xNameCont; + + implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) ); + } + + StartListening( *(m_pView->GetModel()) ); + } + catch ( Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update" ); + } +} + +void PropBrw::Update( const uno::Reference< uno::XInterface>& _xReportComponent) +{ + if ( m_xLastSection == _xReportComponent ) + return; + + m_xLastSection = _xReportComponent; + try + { + if ( m_pView ) + { + EndListening( *(m_pView->GetModel()) ); + m_pView = nullptr; + } + + uno::Reference< uno::XInterface> xTemp(CreateComponentPair(_xReportComponent,_xReportComponent)); + implSetNewObject( uno::Sequence< uno::Reference< uno::XInterface> >(&xTemp,1) ); + } + catch ( Exception& ) + { + TOOLS_WARN_EXCEPTION( "reportdesign", "PropBrw::Update: Exception occurred!" ); + } +} + +IMPL_LINK_NOARG( PropBrw, OnAsyncGetFocus, void*, void ) +{ + m_xContentArea->GrabFocus(); +} + +void PropBrw::LoseFocus() +{ + DockingWindow::LoseFocus(); + if (m_pDesignView) + m_pDesignView->getController().InvalidateAll(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |