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: viewcontact.cxx,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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/sdr/contact/viewcontact.hxx>
34 #include <svx/sdr/contact/viewobjectcontact.hxx>
35 #include <svx/sdr/contact/objectcontact.hxx>
36 #include <basegfx/polygon/b2dpolygon.hxx>
37 #include <basegfx/polygon/b2dpolygontools.hxx>
38 #include <basegfx/color/bcolor.hxx>
39 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
40 #include <basegfx/matrix/b2dhommatrix.hxx>
41 #include <svx/sdr/contact/objectcontactofpageview.hxx>
43 //////////////////////////////////////////////////////////////////////////////
49 // Create a Object-Specific ViewObjectContact, set ViewContact and
50 // ObjectContact. Always needs to return something. Default is to create
51 // a standard ViewObjectContact containing the given ObjectContact and *this
52 ViewObjectContact
& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact
& rObjectContact
)
54 return *(new ViewObjectContact(rObjectContact
, *this));
57 ViewContact::ViewContact()
58 : maViewObjectContactVector(),
59 mxViewIndependentPrimitive2DSequence()
63 // Methods to react on start getting viewed or stop getting
64 // viewed. This info is derived from the count of members of
65 // registered ViewObjectContacts. Default does nothing.
66 void ViewContact::StartGettingViewed()
70 void ViewContact::StopGettingViewed()
74 ViewContact::~ViewContact()
79 void ViewContact::deleteAllVOCs()
81 // get rid of all VOCs
82 // #i84257# To avoid that each 'delete pCandidate' again uses
83 // the local RemoveViewObjectContact with a search and removal in the
84 // vector, simply copy and clear local vector.
85 std::vector
< ViewObjectContact
* > aLocalVOCList(maViewObjectContactVector
);
86 maViewObjectContactVector
.clear();
88 while(aLocalVOCList
.size())
90 ViewObjectContact
* pCandidate
= aLocalVOCList
.back();
91 aLocalVOCList
.pop_back();
92 DBG_ASSERT(pCandidate
, "Corrupted ViewObjectContactList in VC (!)");
94 // ViewObjectContacts only make sense with View and Object contacts.
95 // When the contact to the SdrObject is deleted like in this case,
96 // all ViewObjectContacts can be deleted, too.
100 // assert when there were new entries added during deletion
101 DBG_ASSERT(maViewObjectContactVector
.empty(), "Corrupted ViewObjectContactList in VC (!)");
104 // get a Object-specific ViewObjectContact for a specific
105 // ObjectContact (->View). Always needs to return something.
106 ViewObjectContact
& ViewContact::GetViewObjectContact(ObjectContact
& rObjectContact
)
108 ViewObjectContact
* pRetval
= 0L;
109 const sal_uInt32
nCount(maViewObjectContactVector
.size());
111 // first search if there exists a VOC for the given OC
112 for(sal_uInt32
a(0); !pRetval
&& a
< nCount
; a
++)
114 ViewObjectContact
* pCandidate
= maViewObjectContactVector
[a
];
115 DBG_ASSERT(pCandidate
, "Corrupted ViewObjectContactList (!)");
117 if(&(pCandidate
->GetObjectContact()) == &rObjectContact
)
119 pRetval
= pCandidate
;
125 // create a new one. It's inserted to the local list from the
126 // VieObjectContact constructor via AddViewObjectContact()
127 pRetval
= &CreateObjectSpecificViewObjectContact(rObjectContact
);
133 // A new ViewObjectContact was created and shall be remembered.
134 void ViewContact::AddViewObjectContact(ViewObjectContact
& rVOContact
)
136 maViewObjectContactVector
.push_back(&rVOContact
);
138 if(1L == maViewObjectContactVector
.size())
140 StartGettingViewed();
144 // A ViewObjectContact was deleted and shall be forgotten.
145 void ViewContact::RemoveViewObjectContact(ViewObjectContact
& rVOContact
)
147 std::vector
< ViewObjectContact
* >::iterator aFindResult
= std::find(maViewObjectContactVector
.begin(), maViewObjectContactVector
.end(), &rVOContact
);
149 if(aFindResult
!= maViewObjectContactVector
.end())
151 maViewObjectContactVector
.erase(aFindResult
);
153 if(0 == maViewObjectContactVector
.size())
155 // This may need to get asynchron later since it eventually triggers
156 // deletes of OCs where the VOC is still added.
162 // Test if this ViewContact has ViewObjectContacts at all. This can
163 // be used to test if this ViewContact is visualized ATM or not
164 bool ViewContact::HasViewObjectContacts(bool bExcludePreviews
) const
166 const sal_uInt32
nCount(maViewObjectContactVector
.size());
170 for(sal_uInt32
a(0); a
< nCount
; a
++)
172 if(!maViewObjectContactVector
[a
]->GetObjectContact().IsPreviewRenderer())
182 return (0L != nCount
);
186 // Test if this ViewContact has ViewObjectContacts at all. This can
187 // be used to test if this ViewContact is visualized ATM or not
188 bool ViewContact::isAnimatedInAnyViewObjectContact() const
190 const sal_uInt32
nCount(maViewObjectContactVector
.size());
192 for(sal_uInt32
a(0); a
< nCount
; a
++)
194 if(maViewObjectContactVector
[a
]->isAnimated())
203 // Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L
204 // and GetViewContact default pops up an assert since it's an error if
205 // GetObjectCount has a result != 0 and it's not overloaded.
206 sal_uInt32
ViewContact::GetObjectCount() const
212 ViewContact
& ViewContact::GetViewContact(sal_uInt32
/*nIndex*/) const
214 // This is the default implementation; call would be an error
215 DBG_ERROR("ViewContact::GetViewContact: This call needs to be overloaded when GetObjectCount() can return results != 0 (!)");
216 return (ViewContact
&)(*this);
219 ViewContact
* ViewContact::GetParentContact() const
221 // default has no parent
225 void ViewContact::ActionChildInserted(ViewContact
& rChild
)
227 // propagate change to all exsisting visualisations which
228 // will force a VOC for the new child and invalidate it's range
229 const sal_uInt32
nCount(maViewObjectContactVector
.size());
231 for(sal_uInt32
a(0); a
< nCount
; a
++)
233 ViewObjectContact
* pCandidate
= maViewObjectContactVector
[a
];
234 DBG_ASSERT(pCandidate
, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
236 // take action at all VOCs. At the VOCs ObjectContact the initial
237 // rectangle will be invalidated at the associated OutputDevice.
238 pCandidate
->ActionChildInserted(rChild
);
242 // React on changes of the object of this ViewContact
243 void ViewContact::ActionChanged()
245 // propagate change to all existing VOCs. This will invalidate
246 // all drawn visualisations in all known views
247 const sal_uInt32
nCount(maViewObjectContactVector
.size());
249 for(sal_uInt32
a(0); a
< nCount
; a
++)
251 ViewObjectContact
* pCandidate
= maViewObjectContactVector
[a
];
252 DBG_ASSERT(pCandidate
, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
254 pCandidate
->ActionChanged();
258 // access to SdrObject and/or SdrPage. May return 0L like the default
259 // implementations do. Needs to be overloaded as needed.
260 SdrObject
* ViewContact::TryToGetSdrObject() const
265 SdrPage
* ViewContact::TryToGetSdrPage() const
270 //////////////////////////////////////////////////////////////////////////////
273 drawinglayer::primitive2d::Primitive2DSequence
ViewContact::createViewIndependentPrimitive2DSequence() const
275 // This is the default impelemtation and should never be called (see header). If this is called,
276 // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by
277 // providing a seqence of primitives -> which cannot be correct.
278 // Since we have no access to any known model data here, the default implementation creates a yellow placeholder
279 // hairline polygon with a default size of (1000, 1000, 5000, 3000)
280 DBG_ERROR("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)");
281 const basegfx::B2DPolygon
aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0)));
282 const basegfx::BColor
aYellow(1.0, 1.0, 0.0);
283 const drawinglayer::primitive2d::Primitive2DReference
xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline
, aYellow
));
285 return drawinglayer::primitive2d::Primitive2DSequence(&xReference
, 1);
288 drawinglayer::primitive2d::Primitive2DSequence
ViewContact::getViewIndependentPrimitive2DSequence() const
290 // local up-to-date checks. Create new list and compare.
291 const drawinglayer::primitive2d::Primitive2DSequence
xNew(createViewIndependentPrimitive2DSequence());
293 if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence
, xNew
))
295 // has changed, copy content
296 const_cast< ViewContact
* >(this)->mxViewIndependentPrimitive2DSequence
= xNew
;
299 // return current Primitive2DSequence
300 return mxViewIndependentPrimitive2DSequence
;
303 // add Gluepoints (if available)
304 drawinglayer::primitive2d::Primitive2DSequence
ViewContact::createGluePointPrimitive2DSequence() const
306 // default returns empty reference
307 return drawinglayer::primitive2d::Primitive2DSequence();
310 void ViewContact::flushViewObjectContacts(bool bWithHierarchy
)
314 // flush DrawingLayer hierarchy
315 const sal_uInt32
nCount(GetObjectCount());
317 for(sal_uInt32
a(0); a
< nCount
; a
++)
319 ViewContact
& rChild
= GetViewContact(a
);
320 rChild
.flushViewObjectContacts(bWithHierarchy
);
327 } // end of namespace contact
328 } // end of namespace sdr
330 //////////////////////////////////////////////////////////////////////////////