merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / tools / UndoManager.cxx
blobfe77fa2735c19138d7e6c926ed5a35230c233421
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: UndoManager.cxx,v $
10 * $Revision: 1.5 $
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 "UndoManager.hxx"
35 #include "ImplUndoManager.hxx"
36 #include "DisposeHelper.hxx"
37 #include "MutexContainer.hxx"
38 #include "macros.hxx"
39 #include "ChartViewHelper.hxx"
41 #include <com/sun/star/util/XCloneable.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
43 #include <com/sun/star/chart2/XChartDocument.hpp>
45 #include <unotools/configitem.hxx>
46 #include <cppuhelper/compbase1.hxx>
48 #include <functional>
50 using namespace ::com::sun::star;
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::uno::Sequence;
54 using ::rtl::OUString;
57 // --------------------------------------------------------------------------------
59 namespace chart
62 namespace impl
64 typedef ::cppu::WeakComponentImplHelper1<
65 util::XModifyBroadcaster >
66 ModifyBroadcaster_Base;
68 class ModifyBroadcaster :
69 public ::chart::MutexContainer,
70 public ModifyBroadcaster_Base
72 public:
73 ModifyBroadcaster();
75 void fireEvent();
77 protected:
78 // ____ XModifyBroadcaster ____
79 virtual void SAL_CALL addModifyListener( const Reference< util::XModifyListener >& xListener )
80 throw (uno::RuntimeException);
81 virtual void SAL_CALL removeModifyListener( const Reference< util::XModifyListener >& xListener )
82 throw (uno::RuntimeException);
85 ModifyBroadcaster::ModifyBroadcaster() :
86 ModifyBroadcaster_Base( m_aMutex )
89 void SAL_CALL ModifyBroadcaster::addModifyListener(
90 const Reference< util::XModifyListener >& xListener )
91 throw (uno::RuntimeException)
93 rBHelper.addListener( ::getCppuType( & xListener ), xListener);
96 void SAL_CALL ModifyBroadcaster::removeModifyListener(
97 const Reference< util::XModifyListener >& xListener )
98 throw (uno::RuntimeException)
100 rBHelper.removeListener( ::getCppuType( & xListener ), xListener );
103 void ModifyBroadcaster::fireEvent()
105 ::cppu::OInterfaceContainerHelper* pIC = rBHelper.getContainer(
106 ::getCppuType((const uno::Reference< util::XModifyListener >*)0) );
107 if( pIC )
109 lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
110 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
111 while( aIt.hasMoreElements() )
112 (static_cast< util::XModifyListener*>(aIt.next()))->modified( aEvent );
116 } // namespace impl
118 UndoManager::UndoManager() :
119 impl::UndoManager_Base( m_aMutex ),
120 m_apUndoStack( new impl::UndoStack()),
121 m_apRedoStack( new impl::UndoStack()),
122 m_pLastRemeberedUndoElement( 0 ),
123 m_nMaxNumberOfUndos( 100 ),
124 m_pModifyBroadcaster( 0 )
127 UndoManager::~UndoManager()
129 DisposeHelper::Dispose( m_xModifyBroadcaster );
130 m_apUndoStack->disposeAndClear();
131 m_apRedoStack->disposeAndClear();
133 delete m_pLastRemeberedUndoElement;
134 m_pLastRemeberedUndoElement = 0;
137 void UndoManager::impl_undoRedo(
138 Reference< frame::XModel > & xCurrentModel,
139 impl::UndoStack * pStackToRemoveFrom,
140 impl::UndoStack * pStackToAddTo )
142 if( pStackToRemoveFrom && ! pStackToRemoveFrom->empty() )
144 // get model from undo/redo
145 impl::UndoElement * pTop( pStackToRemoveFrom->top());
146 if( pTop )
148 // put a clone of current model into redo/undo stack with the same
149 // action string as the undo/redo
150 pStackToAddTo->push( pTop->createFromModel( xCurrentModel ));
151 // change current model by properties of the model from undo
152 pTop->applyToModel( xCurrentModel );
153 // remove the top undo element
154 pStackToRemoveFrom->pop(), pTop = 0;
155 ChartViewHelper::setViewToDirtyState( xCurrentModel );
156 fireModifyEvent();
159 else
161 OSL_ENSURE( false, "Can't Undo/Redo" );
165 void UndoManager::fireModifyEvent()
167 if( m_xModifyBroadcaster.is())
168 m_pModifyBroadcaster->fireEvent();
172 // ____ ConfigItemListener ____
173 void UndoManager::notify( const ::rtl::OUString & rPropertyName )
175 OSL_ENSURE( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" )),
176 "Unwanted config property change Notified" );
177 if( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Steps" )))
178 retrieveConfigUndoSteps();
181 void UndoManager::retrieveConfigUndoSteps()
183 if( ! m_apUndoStepsConfigItem.get())
184 m_apUndoStepsConfigItem.reset( new impl::UndoStepsConfigItem( *this ));
185 m_nMaxNumberOfUndos = m_apUndoStepsConfigItem->getUndoSteps();
186 m_apUndoStack->limitSize( m_nMaxNumberOfUndos );
187 m_apRedoStack->limitSize( m_nMaxNumberOfUndos );
189 // a list of available undo steps could shrink here
190 fireModifyEvent();
193 // ____ XModifyBroadcaster ____
194 void SAL_CALL UndoManager::addModifyListener( const Reference< util::XModifyListener >& aListener )
195 throw (uno::RuntimeException)
197 if( ! m_xModifyBroadcaster.is())
199 m_pModifyBroadcaster = new impl::ModifyBroadcaster();
200 m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY );
202 m_xModifyBroadcaster->addModifyListener( aListener );
205 void SAL_CALL UndoManager::removeModifyListener( const Reference< util::XModifyListener >& aListener )
206 throw (uno::RuntimeException)
208 if( ! m_xModifyBroadcaster.is())
210 m_pModifyBroadcaster = new impl::ModifyBroadcaster();
211 m_xModifyBroadcaster.set( static_cast< cppu::OWeakObject* >( m_pModifyBroadcaster ), uno::UNO_QUERY );
213 m_xModifyBroadcaster->removeModifyListener( aListener );
216 // ____ chart2::XUndoManager ____
217 void SAL_CALL UndoManager::preAction( const Reference< frame::XModel >& xModelBeforeChange )
218 throw (uno::RuntimeException)
220 OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" );
221 m_pLastRemeberedUndoElement = new impl::UndoElement( xModelBeforeChange );
224 void SAL_CALL UndoManager::preActionWithArguments(
225 const Reference< frame::XModel >& xModelBeforeChange,
226 const Sequence< beans::PropertyValue >& aArguments )
227 throw (uno::RuntimeException)
229 bool bActionHandled( false );
230 OSL_ENSURE( ! m_pLastRemeberedUndoElement, "Looks like postAction or cancelAction call was missing" );
231 if( aArguments.getLength() > 0 )
233 OSL_ENSURE( aArguments.getLength() == 1, "More than one argument is not supported yet" );
234 if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithData")))
236 m_pLastRemeberedUndoElement = new impl::UndoElementWithData( xModelBeforeChange );
237 bActionHandled = true;
239 else if( aArguments[0].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("WithSelection")))
241 m_pLastRemeberedUndoElement = new impl::UndoElementWithSelection( xModelBeforeChange );
242 bActionHandled = true;
246 if( !bActionHandled )
247 preAction( xModelBeforeChange );
250 void SAL_CALL UndoManager::postAction( const OUString& aUndoText )
251 throw (uno::RuntimeException)
253 OSL_ENSURE( m_pLastRemeberedUndoElement, "Looks like preAction call was missing" );
254 if( m_pLastRemeberedUndoElement )
256 m_pLastRemeberedUndoElement->setActionString( aUndoText );
257 m_apUndoStack->push( m_pLastRemeberedUndoElement );
258 m_pLastRemeberedUndoElement = 0;
260 // redo no longer possible
261 m_apRedoStack->disposeAndClear();
263 // it suffices to get the number of undo steps from config after the
264 // first time postAction has been called
265 if( ! m_apUndoStepsConfigItem.get())
266 retrieveConfigUndoSteps();
268 fireModifyEvent();
272 void SAL_CALL UndoManager::cancelAction()
273 throw (uno::RuntimeException)
275 delete m_pLastRemeberedUndoElement;
276 m_pLastRemeberedUndoElement = 0;
279 void SAL_CALL UndoManager::cancelActionWithUndo( Reference< frame::XModel >& xModelToRestore )
280 throw (uno::RuntimeException)
282 if( m_pLastRemeberedUndoElement )
284 m_pLastRemeberedUndoElement->applyToModel( xModelToRestore );
285 cancelAction();
289 void SAL_CALL UndoManager::undo( Reference< frame::XModel >& xCurrentModel )
290 throw (uno::RuntimeException)
292 OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get());
293 impl_undoRedo( xCurrentModel, m_apUndoStack.get(), m_apRedoStack.get());
296 void SAL_CALL UndoManager::redo( Reference< frame::XModel >& xCurrentModel )
297 throw (uno::RuntimeException)
299 OSL_ASSERT( m_apUndoStack.get() && m_apRedoStack.get());
300 impl_undoRedo( xCurrentModel, m_apRedoStack.get(), m_apUndoStack.get());
303 ::sal_Bool SAL_CALL UndoManager::undoPossible()
304 throw (uno::RuntimeException)
306 return ! m_apUndoStack->empty();
309 ::sal_Bool SAL_CALL UndoManager::redoPossible()
310 throw (uno::RuntimeException)
312 return ! m_apRedoStack->empty();
315 OUString SAL_CALL UndoManager::getCurrentUndoString()
316 throw (uno::RuntimeException)
318 return m_apUndoStack->topUndoString();
321 OUString SAL_CALL UndoManager::getCurrentRedoString()
322 throw (uno::RuntimeException)
324 return m_apRedoStack->topUndoString();
327 Sequence< OUString > SAL_CALL UndoManager::getAllUndoStrings()
328 throw (uno::RuntimeException)
330 return m_apUndoStack->getUndoStrings();
333 Sequence< OUString > SAL_CALL UndoManager::getAllRedoStrings()
334 throw (uno::RuntimeException)
336 return m_apRedoStack->getUndoStrings();
339 // ____ XUndoHelper ____
340 Reference< frame::XModel > SAL_CALL UndoManager::getModelCloneForUndo(
341 const Reference< frame::XModel >& xModelBeforeChange )
342 throw (uno::RuntimeException)
344 return impl::UndoElement::cloneModel( xModelBeforeChange );
347 void SAL_CALL UndoManager::applyModelContent(
348 Reference< frame::XModel >& xModelToChange,
349 const Reference< frame::XModel >& xModelToCopyFrom )
350 throw (uno::RuntimeException)
352 impl::UndoElement::applyModelContentToModel( xModelToChange, xModelToCopyFrom );
355 } // namespace chart