merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / tools / ImplUndoManager.cxx
blobf2309a90c808a2c2bff6020998d6501462eab9fb
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ImplUndoManager.cxx,v $
10 * $Revision: 1.7.16.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "ImplUndoManager.hxx"
35 #include "DisposeHelper.hxx"
36 #include "CommonFunctors.hxx"
37 #include "ControllerLockGuard.hxx"
38 #include "PropertyHelper.hxx"
39 #include "DataSourceHelper.hxx"
40 #include "ChartModelHelper.hxx"
42 #include <com/sun/star/chart/XChartDataArray.hpp>
43 #include <com/sun/star/chart2/XChartDocument.hpp>
44 #include <com/sun/star/chart2/XInternalDataProvider.hpp>
45 #include <com/sun/star/chart2/XTitled.hpp>
46 #include <com/sun/star/util/XCloneable.hpp>
47 #include <com/sun/star/util/XModifiable.hpp>
48 #include <com/sun/star/view/XSelectionSupplier.hpp>
50 #include <boost/bind.hpp>
51 #include <algorithm>
53 using namespace ::com::sun::star;
55 using ::com::sun::star::uno::Reference;
56 using ::com::sun::star::uno::Sequence;
57 using ::rtl::OUString;
58 using ::com::sun::star::chart::XChartDataArray;
60 namespace chart
62 namespace impl
65 void ImplApplyDataToModel(
66 Reference< frame::XModel > & xInOutModelToChange,
67 const Reference< chart2::XInternalDataProvider > & xData )
69 Reference< chart2::XChartDocument > xDoc( xInOutModelToChange, uno::UNO_QUERY );
70 OSL_ASSERT( xDoc.is() && xDoc->hasInternalDataProvider());
72 // copy data from stored internal data provider
73 if( xDoc.is() && xDoc->hasInternalDataProvider())
75 Reference< XChartDataArray > xCurrentData( xDoc->getDataProvider(), uno::UNO_QUERY );
76 Reference< XChartDataArray > xSavedData( xData, uno::UNO_QUERY );
77 if( xCurrentData.is() && xSavedData.is())
79 xCurrentData->setData( xSavedData->getData());
80 xCurrentData->setRowDescriptions( xSavedData->getRowDescriptions());
81 xCurrentData->setColumnDescriptions( xSavedData->getColumnDescriptions());
86 // ----------------------------------------
88 UndoElement::UndoElement(
89 const OUString & rActionString,
90 const Reference< frame::XModel > & xModel ) :
91 m_aActionString( rActionString )
93 initialize( xModel );
96 UndoElement::UndoElement(
97 const Reference< frame::XModel > & xModel )
99 initialize( xModel );
102 UndoElement::UndoElement( const UndoElement & rOther ) :
103 m_aActionString( rOther.m_aActionString )
105 initialize( rOther.m_xModel );
108 UndoElement::~UndoElement()
111 void UndoElement::initialize( const Reference< frame::XModel > & xModel )
113 m_xModel.set( UndoElement::cloneModel( xModel ));
116 void UndoElement::dispose()
118 Reference< lang::XComponent > xComp( m_xModel, uno::UNO_QUERY );
119 if( xComp.is())
120 xComp->dispose();
121 m_xModel.set( 0 );
124 void UndoElement::applyToModel(
125 Reference< frame::XModel > & xInOutModelToChange )
127 UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel );
130 UndoElement * UndoElement::createFromModel(
131 const Reference< frame::XModel > & xModel )
133 return new UndoElement( getActionString(), xModel );
136 void UndoElement::setActionString( const ::rtl::OUString & rActionString )
138 m_aActionString = rActionString;
141 OUString UndoElement::getActionString() const
143 return m_aActionString;
146 // static
147 Reference< frame::XModel > UndoElement::cloneModel( const Reference< frame::XModel > & xModel )
149 Reference< frame::XModel > xResult;
150 uno::Reference< util::XCloneable > xCloneable( xModel, uno::UNO_QUERY );
151 OSL_ENSURE( xCloneable.is(), "Cannot clone model" );
152 if( xCloneable.is())
153 xResult.set( xCloneable->createClone(), uno::UNO_QUERY );
155 return xResult;
158 // static
159 void UndoElement::applyModelContentToModel(
160 Reference< frame::XModel > & xInOutModelToChange,
161 const Reference< frame::XModel > & xModelToCopyFrom,
162 const Reference< chart2::XInternalDataProvider > & xData /* = 0 */ )
165 if( xModelToCopyFrom.is() && xInOutModelToChange.is())
169 // /-- loccked controllers of destination
170 ControllerLockGuard aLockedControllers( xInOutModelToChange );
171 Reference< chart2::XChartDocument > xSource( xModelToCopyFrom, uno::UNO_QUERY_THROW );
172 Reference< chart2::XChartDocument > xDestination( xInOutModelToChange, uno::UNO_QUERY_THROW );
174 // propagate the correct flag for plotting of hidden values to the data provider and all used sequences
175 ChartModelHelper::setIncludeHiddenCells( ChartModelHelper::isIncludeHiddenCells( xModelToCopyFrom ) , xInOutModelToChange );
177 // diagram
178 xDestination->setFirstDiagram( xSource->getFirstDiagram());
180 // main title
181 Reference< chart2::XTitled > xDestinationTitled( xDestination, uno::UNO_QUERY_THROW );
182 Reference< chart2::XTitled > xSourceTitled( xSource, uno::UNO_QUERY_THROW );
183 xDestinationTitled->setTitleObject( xSourceTitled->getTitleObject());
185 // page background
186 comphelper::copyProperties(
187 xSource->getPageBackground(),
188 xDestination->getPageBackground() );
190 // apply data (not applied in standard Undo)
191 if( xData.is())
192 ImplApplyDataToModel( xInOutModelToChange, xData );
194 // register all sequences at the internal data provider to get adapted
195 // indexes when columns are added/removed
196 if( xDestination->hasInternalDataProvider())
198 Reference< chart2::XInternalDataProvider > xNewDataProvider( xDestination->getDataProvider(), uno::UNO_QUERY );
199 Reference< chart2::data::XDataSource > xUsedData( DataSourceHelper::getUsedData( xInOutModelToChange ));
200 if( xUsedData.is() && xNewDataProvider.is())
202 Sequence< Reference< chart2::data::XLabeledDataSequence > > aData( xUsedData->getDataSequences());
203 for( sal_Int32 i=0; i<aData.getLength(); ++i )
205 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getValues());
206 xNewDataProvider->registerDataSequenceForChanges( aData[i]->getLabel());
211 // restore modify status
212 Reference< util::XModifiable > xSourceMod( xSource, uno::UNO_QUERY );
213 Reference< util::XModifiable > xDestMod( xDestination, uno::UNO_QUERY );
214 if( xSourceMod.is() && xDestMod.is() &&
215 ! xSourceMod->isModified() )
217 xDestMod->setModified( sal_False );
219 // \-- loccked controllers of destination
221 catch( uno::Exception & )
227 // ----------------------------------------
229 UndoElementWithData::UndoElementWithData(
230 const OUString & rActionString,
231 const Reference< frame::XModel > & xModel ) :
232 UndoElement( rActionString, xModel )
234 initializeData();
237 UndoElementWithData::UndoElementWithData(
238 const Reference< frame::XModel > & xModel ) :
239 UndoElement( xModel )
241 initializeData();
245 UndoElementWithData::UndoElementWithData(
246 const UndoElementWithData & rOther ) :
247 UndoElement( rOther )
249 initializeData();
252 UndoElementWithData::~UndoElementWithData()
255 void UndoElementWithData::initializeData()
259 Reference< chart2::XChartDocument > xChartDoc( m_xModel, uno::UNO_QUERY_THROW );
260 OSL_ASSERT( xChartDoc->hasInternalDataProvider());
261 if( xChartDoc->hasInternalDataProvider())
263 Reference< util::XCloneable > xCloneable( xChartDoc->getDataProvider(), uno::UNO_QUERY );
264 OSL_ENSURE( xCloneable.is(), "Cannot clone data" );
265 if( xCloneable.is())
266 m_xData.set( xCloneable->createClone(), uno::UNO_QUERY );
269 catch( uno::Exception & )
274 void UndoElementWithData::dispose()
276 UndoElement::dispose();
277 m_xData.set( 0 );
280 void UndoElementWithData::applyToModel(
281 Reference< frame::XModel > & xInOutModelToChange )
283 UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel, m_xData );
286 UndoElement * UndoElementWithData::createFromModel(
287 const Reference< frame::XModel > & xModel )
289 return new UndoElementWithData( getActionString(), xModel );
292 // ========================================
294 // ----------------------------------------
296 UndoElementWithSelection::UndoElementWithSelection(
297 const OUString & rActionString,
298 const Reference< frame::XModel > & xModel ) :
299 UndoElement( rActionString, xModel )
301 initialize( xModel );
304 UndoElementWithSelection::UndoElementWithSelection(
305 const Reference< frame::XModel > & xModel ) :
306 UndoElement( xModel )
308 initialize( xModel );
311 UndoElementWithSelection::UndoElementWithSelection(
312 const UndoElementWithSelection & rOther ) :
313 UndoElement( rOther )
315 initialize( rOther.m_xModel );
318 UndoElementWithSelection::~UndoElementWithSelection()
321 void UndoElementWithSelection::initialize( const Reference< frame::XModel > & xModel )
325 uno::Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY );
326 OSL_ASSERT( xSelSupp.is() );
328 if( xSelSupp.is() )
329 m_aSelection = xSelSupp->getSelection();
331 catch( const uno::Exception & )
336 void UndoElementWithSelection::dispose()
338 UndoElement::dispose();
339 m_aSelection.clear();
342 void UndoElementWithSelection::applyToModel(
343 Reference< frame::XModel > & xInOutModelToChange )
345 UndoElement::applyModelContentToModel( xInOutModelToChange, m_xModel );
346 Reference< view::XSelectionSupplier > xCurrentSelectionSuppl( xInOutModelToChange->getCurrentController(), uno::UNO_QUERY );
347 OSL_ASSERT( xCurrentSelectionSuppl.is() );
349 if( xCurrentSelectionSuppl.is())
350 xCurrentSelectionSuppl->select( m_aSelection );
353 UndoElement * UndoElementWithSelection::createFromModel(
354 const Reference< frame::XModel > & xModel )
356 return new UndoElementWithSelection( getActionString(), xModel );
359 // ========================================
361 UndoStack::UndoStack() :
362 m_nSizeLimit( 1000 )
366 UndoStack::~UndoStack()
368 disposeAndClear();
371 void UndoStack::pop()
373 if( ! empty())
375 top()->dispose();
376 delete top();
377 m_aStack.pop_back();
381 void UndoStack::push( UndoElement * pElement )
383 m_aStack.push_back( pElement );
384 applyLimitation();
387 UndoElement * UndoStack::top() const
389 return m_aStack.back();
392 OUString UndoStack::topUndoString() const
394 if( ! empty())
395 return top()->getActionString();
396 return OUString();
399 Sequence< OUString > UndoStack::getUndoStrings() const
401 sal_Int32 nSize( static_cast< sal_Int32 >( m_aStack.size()));
402 Sequence< OUString > aResult( nSize );
403 for( sal_Int32 i=0; i<nSize; ++i )
404 aResult[i] = m_aStack[i]->getActionString();
405 return aResult;
408 bool UndoStack::empty() const
410 return m_aStack.empty();
413 void UndoStack::disposeAndClear()
415 ::std::for_each( m_aStack.begin(), m_aStack.end(), ::boost::mem_fn( & UndoElement::dispose ));
416 ::std::for_each( m_aStack.begin(), m_aStack.end(), CommonFunctors::DeletePtr< UndoElement >() );
417 m_aStack.clear();
420 void UndoStack::limitSize( sal_Int32 nMaxSize )
422 m_nSizeLimit = nMaxSize;
423 applyLimitation();
426 void UndoStack::applyLimitation()
428 if( m_aStack.size() > static_cast< sal_uInt32 >( m_nSizeLimit ))
430 tUndoStackType::iterator aBegin( m_aStack.begin());
431 tUndoStackType::iterator aEnd( aBegin + (m_aStack.size() - m_nSizeLimit));
432 // dispose and remove all undo elements that are over the limit
433 ::std::for_each( aBegin, aEnd, ::boost::mem_fn( & UndoElement::dispose ));
434 ::std::for_each( aBegin, aEnd, CommonFunctors::DeletePtr< UndoElement >() );
435 m_aStack.erase( aBegin, aEnd );
439 // ================================================================================
441 namespace
443 static const OUString aUndoStepsPropName( RTL_CONSTASCII_USTRINGPARAM("Steps"));
444 } // anonymous namespace
446 UndoStepsConfigItem::UndoStepsConfigItem( ConfigItemListener & rListener ) :
447 ::utl::ConfigItem( OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Common/Undo"))),
448 m_rListener( rListener )
450 EnableNotification( Sequence< OUString >( & aUndoStepsPropName, 1 ));
453 UndoStepsConfigItem::~UndoStepsConfigItem()
457 void UndoStepsConfigItem::Notify( const Sequence< OUString > & aPropertyNames )
459 for( sal_Int32 nIdx=0; nIdx<aPropertyNames.getLength(); ++nIdx )
461 if( aPropertyNames[nIdx].equals( aUndoStepsPropName ))
462 m_rListener.notify( aPropertyNames[nIdx] );
466 // mtehod is not const, because GetProperties is not const
467 sal_Int32 UndoStepsConfigItem::getUndoSteps()
469 sal_Int32 nSteps = -1;
470 Sequence< uno::Any > aValues(
471 GetProperties( Sequence< OUString >( & aUndoStepsPropName, 1 )));
472 if( aValues.getLength())
473 aValues[0] >>= nSteps;
474 return nSteps;
477 } // namespace impl
478 } // namespace chart