diff options
Diffstat (limited to '')
-rw-r--r-- | reportdesign/source/ui/misc/RptUndo.cxx | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/reportdesign/source/ui/misc/RptUndo.cxx b/reportdesign/source/ui/misc/RptUndo.cxx new file mode 100644 index 000000000..5ac23ff0c --- /dev/null +++ b/reportdesign/source/ui/misc/RptUndo.cxx @@ -0,0 +1,386 @@ +/* -*- 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/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&) + { + OSL_FAIL("lcl_insertElements:Exception caught!"); + } + } + } + + 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&) + { + OSL_FAIL("lcl_setValues:Exception caught!"); + } + } + } +} + + +OSectionUndo::OSectionUndo(OReportModel& _rMod + ,sal_uInt16 _nSlot + ,Action _eAction + ,const char* 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::getUnoTunnelImplementation<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 &) + { + OSL_FAIL("Exception caught!"); + } + } +} + +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, nullptr) + , 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, const char* 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( ) +{ + uno::Sequence< beans::PropertyValue > aArgs(2); + + aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUStringLiteral(PROPERTY_HEADERON) : OUStringLiteral(PROPERTY_FOOTERON); + aArgs[0].Value <<= true; + aArgs[1].Name = PROPERTY_GROUP; + aArgs[1].Value <<= 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)); + + uno::Sequence< beans::PropertyValue > aArgs(2); + + aArgs[0].Name = SID_GROUPHEADER_WITHOUT_UNDO == m_nSlot? OUStringLiteral(PROPERTY_HEADERON) : OUStringLiteral(PROPERTY_FOOTERON); + aArgs[0].Value <<= false; + aArgs[1].Name = PROPERTY_GROUP; + aArgs[1].Value <<= m_aGroupHelper.getGroup(); + + m_pController->executeChecked(m_nSlot,aArgs); + m_bInserted = false; +} + + +OGroupUndo::OGroupUndo(OReportModel& _rMod + ,const char* 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().get(),m_xGroup); +} + +void OGroupUndo::implReInsert( ) +{ + try + { + m_xReportDefinition->getGroups()->insertByIndex(m_nLastPosition,uno::makeAny(m_xGroup)); + } + catch(uno::Exception&) + { + OSL_FAIL("Exception caught while undoing remove group"); + } +} + +void OGroupUndo::implReRemove( ) +{ + try + { + m_xReportDefinition->getGroups()->removeByIndex(m_nLastPosition); + } + catch(uno::Exception&) + { + OSL_FAIL("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: */ |