1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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>
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
;
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
)
96 UndoElement::UndoElement(
97 const Reference
< frame::XModel
> & 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
);
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
;
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" );
153 xResult
.set( xCloneable
->createClone(), uno::UNO_QUERY
);
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
);
178 xDestination
->setFirstDiagram( xSource
->getFirstDiagram());
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());
186 comphelper::copyProperties(
187 xSource
->getPageBackground(),
188 xDestination
->getPageBackground() );
190 // apply data (not applied in standard Undo)
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
)
237 UndoElementWithData::UndoElementWithData(
238 const Reference
< frame::XModel
> & xModel
) :
239 UndoElement( xModel
)
245 UndoElementWithData::UndoElementWithData(
246 const UndoElementWithData
& rOther
) :
247 UndoElement( rOther
)
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" );
266 m_xData
.set( xCloneable
->createClone(), uno::UNO_QUERY
);
269 catch( uno::Exception
& )
274 void UndoElementWithData::dispose()
276 UndoElement::dispose();
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() );
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() :
366 UndoStack::~UndoStack()
371 void UndoStack::pop()
381 void UndoStack::push( UndoElement
* pElement
)
383 m_aStack
.push_back( pElement
);
387 UndoElement
* UndoStack::top() const
389 return m_aStack
.back();
392 OUString
UndoStack::topUndoString() const
395 return top()->getActionString();
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();
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
>() );
420 void UndoStack::limitSize( sal_Int32 nMaxSize
)
422 m_nSizeLimit
= nMaxSize
;
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 // ================================================================================
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
;