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: change.hxx,v $
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 #ifndef CONFIGMGR_CHANGE_HXX
32 #define CONFIGMGR_CHANGE_HXX
33 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
34 #pragma warning(disable : 4350) // behavior change: 'member1' called instead of 'member2'
37 #include "valuenode.hxx"
38 #include "treesegment.hxx"
39 #include <sal/types.h>
40 #include <rtl/ustring.hxx>
41 #include <com/sun/star/uno/Sequence.hxx>
47 #ifndef INCLUDED_MEMORY
49 #define INCLUDED_MEMORY
55 namespace uno
= com::sun::star::uno
;
64 //==========================================================================
66 //==========================================================================
67 struct ChangeTreeAction
69 virtual void handle(ValueChange
const& aValueNode
) = 0;
70 virtual void handle(AddNode
const& aAddNode
) = 0;
71 virtual void handle(RemoveNode
const& aRemoveNode
) = 0;
72 virtual void handle(SubtreeChange
const& aSubtree
) = 0;
74 void applyToChange(Change
const& aChange
);
75 void applyToChildren(SubtreeChange
const& aSubtree
);
77 virtual ~ChangeTreeAction() {}
80 struct ChangeTreeModification
82 virtual void handle(ValueChange
& aValueNode
) = 0;
83 virtual void handle(AddNode
& aAddNode
) = 0;
84 virtual void handle(RemoveNode
& aRemoveNode
) = 0;
85 virtual void handle(SubtreeChange
& aSubtree
) = 0;
87 void applyToChange(Change
& aChange
);
88 void applyToChildren(SubtreeChange
& aSubtree
);
90 virtual ~ChangeTreeModification() {}
93 //==========================================================================
95 //==========================================================================
99 rtl::OUString m_aName
;
102 void swap(Change
& aOther
);
106 Change(rtl::OUString
const& _rName
, bool _bToDefault
)
108 , m_bIsToDefault(_bToDefault
)
113 rtl::OUString
getNodeName() const { return m_aName
; }
114 void setNodeName(const rtl::OUString
&aName
) {m_aName
= aName
;}
116 bool isToDefault() const { return m_bIsToDefault
; }
118 Change
* getSubChange(rtl::OUString
const& _rName
) { return doGetChild(_rName
); }
119 Change
const* getSubChange(rtl::OUString
const& _rName
) const { return doGetChild(_rName
); }
121 virtual void dispatch(ChangeTreeAction
& anAction
) const = 0;
122 virtual void dispatch(ChangeTreeModification
& anAction
) = 0;
124 virtual std::auto_ptr
<Change
> clone() const = 0;
127 virtual Change
* doGetChild(rtl::OUString
const& ) const { return 0; }
130 //==========================================================================
132 //==========================================================================
133 class ValueChange
: public Change
136 struct SetToDefault
{};
137 enum Mode
{ wasDefault
, changeValue
, setToDefault
, changeDefault
};
140 uno::Type m_aValueType
;
142 uno::Any m_aOldValue
;
143 node::Attributes m_aAttributes
;
147 rtl::OUString
const& _rName
,
148 const node::Attributes
& _rAttributes
,
150 uno::Any
const & aNewValue
,
151 uno::Any
const & aOldValue
= uno::Any());
153 virtual std::auto_ptr
<Change
> clone() const;
155 bool isChange() const;
157 uno::Type
getValueType() const { return m_aValueType
; }
159 uno::Any
getNewValue() const { return m_aValue
; }
160 uno::Any
getOldValue() const { return m_aOldValue
; }
162 void setNewValue(const uno::Any
& _rNewVal
);
163 void setNewValue(const uno::Any
& _rNewVal
, Mode aMode
)
164 { setNewValue(_rNewVal
); m_eMode
= aMode
;}
166 bool isReplacedValue() const {return m_aAttributes
.isReplacedForUser();}
167 bool isLocalizedValue() const {return m_aAttributes
.isLocalized();}
169 Mode
getMode() const { return m_eMode
; }
171 const node::Attributes
& getAttributes() const {return m_aAttributes
;}
173 void applyChangeNoRecover(ValueNode
& aNode
) const;
175 virtual void dispatch(ChangeTreeAction
& anAction
) const { anAction
.handle(*this); }
176 virtual void dispatch(ChangeTreeModification
& anAction
) { anAction
.handle(*this); }
178 friend class ApplyValueChange
;
181 //==========================================================================
183 //==========================================================================
184 class AddNode
: public Change
186 rtl::Reference
< data::TreeSegment
> m_aOwnNewNode
;
187 rtl::Reference
< data::TreeSegment
> m_aOwnOldNode
;
188 sharable::TreeFragment
* m_aInsertedTree
;
192 void operator=(AddNode
const&); // not implemented
194 // needed for clone()
195 AddNode(AddNode
const&);
197 AddNode(rtl::Reference
< data::TreeSegment
> const & _aAddedTree
, rtl::OUString
const& _rName
, bool _bToDefault
);
200 virtual std::auto_ptr
<Change
> clone() const;
202 /// marks this as not merely adding a node but replacing another
203 void setReplacing() { m_bReplacing
= true; }
204 /// is this not merely adding a node but replacing another ?
205 bool isReplacing() const { return m_bReplacing
; }
207 /// has this been applied and inserted
208 bool wasInserted() const { return m_aInsertedTree
!= NULL
; }
210 /** returns the node this change represents, even if this node does not own the new Node object any more.
211 This is somewhat dangerous if the node referenced by this object dies before the object itself does.<BR>
212 In this case all calls to this method will return nonsense. This case can be detected by testing
213 whether <method>getAddedNode</method> returns NULL.
215 sharable::TreeFragment
* getInsertedTree() const { return m_aInsertedTree
; }
217 /** returns the node this change represents; The Node object is owned by this change until
218 <method>releaseAddedNode</method> is called.<BR>
219 After ownership is lost this method returns NULL.
221 sharable::TreeFragment
const * getNewTreeData() const { return m_aOwnNewNode
.is() ? m_aOwnNewNode
->fragment
: 0; }
223 /** returns the node the change represents. .
225 rtl::Reference
< data::TreeSegment
> getNewTree() const { return m_aOwnNewNode
; }
227 /** returns the node the change represents, and releases ownership of it. This means that
228 afterwards <method>getAddedNode</method> will return NULL. This change object keeps a reference
229 to the node though which can be retrieved using <method>getAddedNode_unsafe</method>.
231 void clearNewTree() { m_aOwnNewNode
.clear(); }
235 void setInsertedAddress(sharable::TreeFragment
* const & _aInsertedAddress
);
238 /** returns the node this change replaces, ihe Node object is owned by this change.
239 After ownership is lost this method returns NULL.
241 sharable::TreeFragment
const * getReplacedTreeData() const { return m_aOwnOldNode
.is() ? m_aOwnOldNode
->fragment
: 0; }
243 /** returns the node the change replaces.
245 rtl::Reference
< data::TreeSegment
> getReplacedTree() const { return m_aOwnOldNode
; }
247 /** forgets about the node the change replaces
249 void clearReplacedTree() { m_aOwnOldNode
.clear(); }
251 void takeReplacedTree(rtl::Reference
< data::TreeSegment
> const& _aTree
);
253 virtual void dispatch(ChangeTreeAction
& anAction
) const { anAction
.handle(*this); }
254 virtual void dispatch(ChangeTreeModification
& anAction
) { anAction
.handle(*this); }
257 //==========================================================================
259 //==========================================================================
260 class RemoveNode
: public Change
263 rtl::Reference
< data::TreeSegment
> m_aOwnOldNode
;
267 RemoveNode
& operator=(const RemoveNode
&); // not implemented
268 // needed for clone()
269 RemoveNode(const RemoveNode
&);
272 RemoveNode(rtl::OUString
const& _rName
, bool _bToDefault
);
275 virtual std::auto_ptr
<Change
> clone() const;
277 virtual void dispatch(ChangeTreeAction
& anAction
) const { anAction
.handle(*this); }
278 virtual void dispatch(ChangeTreeModification
& anAction
) { anAction
.handle(*this); }
280 /** returns the node this change removes, ihe Node object is owned by this change.
281 After ownership is lost this method returns NULL.
283 sharable::TreeFragment
const * getRemovedTreeData() const { return m_aOwnOldNode
.is() ? m_aOwnOldNode
->fragment
: 0; }
284 /** returns the node the change removes.
286 rtl::Reference
< data::TreeSegment
> getRemovedTree() const { return m_aOwnOldNode
; }
288 /** forgets about the node the change removes, returning the previous setting with ownership
290 void clearRemovedTree() { m_aOwnOldNode
.clear(); }
292 void takeRemovedTree(rtl::Reference
< data::TreeSegment
> const & _aTree
);
295 //==========================================================================
297 //==========================================================================
298 class SubtreeChange
: public Change
301 typedef ::std::map
< ::rtl::OUString
,Change
* > Children
;
303 ::rtl::OUString m_sTemplateName
; /// path of the template for child instantiation
304 ::rtl::OUString m_sTemplateModule
; /// module of the template for child instantiation
305 node::Attributes m_aAttributes
;
307 // don't create copy ops automatically
308 SubtreeChange(const SubtreeChange
&);
309 void operator=(SubtreeChange
&);
315 ChildIterator
begin() const throw();
316 ChildIterator
end() const throw();
318 class MutatingChildIterator
;
319 MutatingChildIterator
begin_changes() throw();
320 MutatingChildIterator
end_changes() throw();
322 friend class MutatingChildIterator
;
324 SubtreeChange(const rtl::OUString
& _rName
,
325 const node::Attributes
& _rAttr
,
326 bool _bToDefault
= false)
327 : Change(_rName
,_bToDefault
)
328 , m_aAttributes(_rAttr
)
330 m_aAttributes
.markAsDefault(_bToDefault
);
333 SubtreeChange(const rtl::OUString
& _rName
,
334 const rtl::OUString
& _rTemplateName
,
335 const rtl::OUString
& _rTemplateModule
,
336 const node::Attributes
& _rAttr
,
337 bool _bToDefault
= false)
338 : Change(_rName
,_bToDefault
)
339 , m_sTemplateName(_rTemplateName
)
340 , m_sTemplateModule(_rTemplateModule
)
341 , m_aAttributes(_rAttr
)
343 m_aAttributes
.markAsDefault(_bToDefault
);
346 SubtreeChange(const ISubtree
& _rTree
, bool _bToDefault
= false)
347 : Change(_rTree
.getName(),_bToDefault
)
348 , m_sTemplateName(_rTree
.getElementTemplateName())
349 , m_sTemplateModule(_rTree
.getElementTemplateModule())
350 , m_aAttributes(_rTree
.getAttributes())
352 m_aAttributes
.markAsDefault(_bToDefault
);
355 SubtreeChange(const SubtreeChange
& _rChange
, treeop::NoChildCopy
)
357 , m_sTemplateName(_rChange
.getElementTemplateName())
358 , m_sTemplateModule(_rChange
.getElementTemplateModule())
359 , m_aAttributes(_rChange
.getAttributes())
364 SubtreeChange(const SubtreeChange
&, treeop::DeepChildCopy
);
366 virtual std::auto_ptr
<Change
> clone() const;
368 void swap(SubtreeChange
& aOther
);
370 bool isReplacedNode() const { return m_aAttributes
.isReplacedForUser(); }
371 bool isLocalizedContainer() const { return m_aAttributes
.isLocalized(); }
373 const node::Attributes
& getAttributes() const {return m_aAttributes
;}
375 bool isSetNodeChange() const { return m_sTemplateName
.getLength() != 0; }
377 rtl::OUString
getElementTemplateName() const { return m_sTemplateName
; }
378 rtl::OUString
getElementTemplateModule() const { return m_sTemplateModule
; }
380 void setElementTemplate(const rtl::OUString
& _rName
, const rtl::OUString
& _rModule
)
381 { m_sTemplateName
= _rName
; m_sTemplateModule
= _rModule
; }
383 sal_Int32
size() const { return m_aChanges
.size(); }
384 uno::Sequence
< rtl::OUString
> elementNames() const;
386 void addChange(std::auto_ptr
<Change
> aChange
);
387 ::std::auto_ptr
<Change
> removeChange(rtl::OUString
const& _rName
);
389 Change
* getChange(rtl::OUString
const& _rName
);
390 Change
const* getChange(rtl::OUString
const& _rName
) const;
392 virtual void dispatch(ChangeTreeAction
& _anAction
) const;
393 virtual void dispatch(ChangeTreeModification
& _anAction
);
395 void forEachChange(ChangeTreeAction
& _anAction
) const;
396 void forEachChange(ChangeTreeModification
& _anAction
);
399 virtual Change
* doGetChild(rtl::OUString
const& _rName
) const;
402 /** iterates through all children of a <type>SubtreeChange</type>. Every non-const action on the object
403 which is beeing iterated invalidates the iterator.
405 beware of the lifetime of the tree change object : it has to live as long as the iterator does (at least) !!
407 class SubtreeChange::ChildIterator
410 uno::Sequence
< rtl::OUString
> m_aNames
;
411 const SubtreeChange
* m_pTree
;
414 friend class SubtreeChange
;
416 ChildIterator(const SubtreeChange
* _pTree
, struct EndPos
);
418 inline sal_Bool
isValid() const { return m_nPos
>= 0 && m_nPos
< m_aNames
.getLength(); }
421 ChildIterator(const SubtreeChange
* _pTree
);
423 const Change
& operator*() const;
424 const Change
* operator->() const;
426 ChildIterator
& operator++();
427 ChildIterator
operator++(int) { ChildIterator
ret(*this); ++*this; return ret
; }
429 ChildIterator
& operator--();
430 ChildIterator
operator--(int) { ChildIterator
ret(*this); --*this; return ret
; }
432 friend bool operator==(ChildIterator
const& lhs
, ChildIterator
const& rhs
);
433 friend bool operator!=(ChildIterator
const& lhs
, ChildIterator
const& rhs
) { return !(lhs
== rhs
); }
436 /** iterates through all children of a <type>SubtreeChange</type>. Every non-const action on the object
437 which is beeing iterated invalidates the iterator.
439 beware of the lifetime of the tree change object : it has to live as long as the iterator does (at least) !!
441 class SubtreeChange::MutatingChildIterator
444 SubtreeChange::Children::iterator m_aBaseIter
;
446 friend class SubtreeChange
;
447 MutatingChildIterator(SubtreeChange::Children::iterator aBase
) : m_aBaseIter(aBase
) {};
450 Change
& current() const { return *m_aBaseIter
->second
; }
452 Change
& operator*() const { return current(); }
453 Change
* operator->() const { return ¤t(); }
455 MutatingChildIterator
& operator++() { ++m_aBaseIter
; return *this; }
456 MutatingChildIterator
operator++(int) { return MutatingChildIterator(m_aBaseIter
++); }
458 MutatingChildIterator
& operator--() { ++m_aBaseIter
; return *this; }
459 MutatingChildIterator
operator--(int) { return MutatingChildIterator(m_aBaseIter
++); }
461 friend bool operator==(MutatingChildIterator
const& lhs
, MutatingChildIterator
const& rhs
)
462 { return lhs
.m_aBaseIter
== rhs
.m_aBaseIter
; }
463 friend bool operator!=(MutatingChildIterator
const& lhs
, MutatingChildIterator
const& rhs
) { return !(lhs
== rhs
); }
465 //==========================================================================
466 //= SubtreeChangeReferrer
467 //==========================================================================
468 /** a specialized SubtreeChange, which, upon desctruction, does not delete the changes
472 This implies that when using this class, you have to beware of the lifetime of the involved objects
474 class SubtreeChangeReferrer
: public SubtreeChange
476 // no explicit construction
477 SubtreeChangeReferrer() : SubtreeChange(::rtl::OUString(), node::Attributes()) { }
480 SubtreeChangeReferrer(const SubtreeChange
& _rSource
);
481 ~SubtreeChangeReferrer();
484 ////////////////////////////////////////////////////////////////////////////////
485 //==========================================================================
486 extern bool isLocalizedValueSet(SubtreeChange
const& _aSubtree
);
487 extern bool isValueSet(SubtreeChange
const& _aSubtree
);
489 //==========================================================================
491 //==========================================================================
492 inline void ChangeTreeAction::applyToChange(Change
const& aChange
)
493 { aChange
.dispatch(*this); }
494 inline void ChangeTreeAction::applyToChildren(SubtreeChange
const& aSubtree
)
495 { aSubtree
.forEachChange(*this); }
497 inline void ChangeTreeModification::applyToChange(Change
& aChange
)
498 { aChange
.dispatch(*this); }
499 inline void ChangeTreeModification::applyToChildren(SubtreeChange
& aSubtree
)
500 { aSubtree
.forEachChange(*this); }
502 ////////////////////////////////////////////////////////////////////////////////
504 } // namespace configmgr