Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svx/sdr/contact/viewcontact.hxx>
30 : : #include <svx/sdr/contact/viewobjectcontact.hxx>
31 : : #include <svx/sdr/contact/objectcontact.hxx>
32 : : #include <basegfx/polygon/b2dpolygon.hxx>
33 : : #include <basegfx/polygon/b2dpolygontools.hxx>
34 : : #include <basegfx/color/bcolor.hxx>
35 : : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
36 : : #include <basegfx/matrix/b2dhommatrix.hxx>
37 : : #include <svx/sdr/contact/objectcontactofpageview.hxx>
38 : : #include <tools/debug.hxx>
39 : :
40 : : //////////////////////////////////////////////////////////////////////////////
41 : :
42 : : namespace sdr
43 : : {
44 : : namespace contact
45 : : {
46 : : // Create a Object-Specific ViewObjectContact, set ViewContact and
47 : : // ObjectContact. Always needs to return something. Default is to create
48 : : // a standard ViewObjectContact containing the given ObjectContact and *this
49 : 0 : ViewObjectContact& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
50 : : {
51 [ # # ]: 0 : return *(new ViewObjectContact(rObjectContact, *this));
52 : : }
53 : :
54 : 132860 : ViewContact::ViewContact()
55 : : : maViewObjectContactVector(),
56 [ + - ]: 132860 : mxViewIndependentPrimitive2DSequence()
57 : : {
58 : 132860 : }
59 : :
60 : : // Methods to react on start getting viewed or stop getting
61 : : // viewed. This info is derived from the count of members of
62 : : // registered ViewObjectContacts. Default does nothing.
63 : 87797 : void ViewContact::StartGettingViewed()
64 : : {
65 : 87797 : }
66 : :
67 : 83660 : void ViewContact::StopGettingViewed()
68 : : {
69 : 83660 : }
70 : :
71 [ + - ]: 130990 : ViewContact::~ViewContact()
72 : : {
73 [ + - ]: 130990 : deleteAllVOCs();
74 [ - + ]: 130990 : }
75 : :
76 : 507067 : void ViewContact::deleteAllVOCs()
77 : : {
78 : : // get rid of all VOCs
79 : : // #i84257# To avoid that each 'delete pCandidate' again uses
80 : : // the local RemoveViewObjectContact with a search and removal in the
81 : : // vector, simply copy and clear local vector.
82 [ + - ]: 507067 : std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector);
83 : 507067 : maViewObjectContactVector.clear();
84 : :
85 [ + + ]: 510064 : while(!aLocalVOCList.empty())
86 : : {
87 [ + - ]: 2997 : ViewObjectContact* pCandidate = aLocalVOCList.back();
88 [ + - ]: 2997 : aLocalVOCList.pop_back();
89 : : DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList in VC (!)");
90 : :
91 : : // ViewObjectContacts only make sense with View and Object contacts.
92 : : // When the contact to the SdrObject is deleted like in this case,
93 : : // all ViewObjectContacts can be deleted, too.
94 [ + - ][ + - ]: 2997 : delete pCandidate;
95 : : }
96 : :
97 : : // assert when there were new entries added during deletion
98 : 507067 : DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)");
99 : 507067 : }
100 : :
101 : : // get a Object-specific ViewObjectContact for a specific
102 : : // ObjectContact (->View). Always needs to return something.
103 : 663473 : ViewObjectContact& ViewContact::GetViewObjectContact(ObjectContact& rObjectContact)
104 : : {
105 : 663473 : ViewObjectContact* pRetval = 0L;
106 : 663473 : const sal_uInt32 nCount(maViewObjectContactVector.size());
107 : :
108 : : // first search if there exists a VOC for the given OC
109 [ + + ][ + + ]: 1244231 : for(sal_uInt32 a(0); !pRetval && a < nCount; a++)
[ + + ]
110 : : {
111 : 580758 : ViewObjectContact* pCandidate = maViewObjectContactVector[a];
112 : : DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");
113 : :
114 [ + + ]: 580758 : if(&(pCandidate->GetObjectContact()) == &rObjectContact)
115 : : {
116 : 568429 : pRetval = pCandidate;
117 : : }
118 : : }
119 : :
120 [ + + ]: 663473 : if(!pRetval)
121 : : {
122 : : // create a new one. It's inserted to the local list from the
123 : : // VieObjectContact constructor via AddViewObjectContact()
124 : 95044 : pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact);
125 : : }
126 : :
127 : 663473 : return *pRetval;
128 : : }
129 : :
130 : : // A new ViewObjectContact was created and shall be remembered.
131 : 95044 : void ViewContact::AddViewObjectContact(ViewObjectContact& rVOContact)
132 : : {
133 [ + - ]: 95044 : maViewObjectContactVector.push_back(&rVOContact);
134 : :
135 [ + + ]: 95044 : if(1L == maViewObjectContactVector.size())
136 : : {
137 : 87797 : StartGettingViewed();
138 : : }
139 : 95044 : }
140 : :
141 : : // A ViewObjectContact was deleted and shall be forgotten.
142 : 93904 : void ViewContact::RemoveViewObjectContact(ViewObjectContact& rVOContact)
143 : : {
144 [ + - ]: 93904 : std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact);
145 : :
146 [ + - ][ + + ]: 93904 : if(aFindResult != maViewObjectContactVector.end())
147 : : {
148 [ + - ]: 90907 : maViewObjectContactVector.erase(aFindResult);
149 : :
150 [ + + ]: 90907 : if(maViewObjectContactVector.empty())
151 : : {
152 : : // This may need to get asynchron later since it eventually triggers
153 : : // deletes of OCs where the VOC is still added.
154 [ + - ]: 83660 : StopGettingViewed();
155 : : }
156 : : }
157 : 93904 : }
158 : :
159 : : // Test if this ViewContact has ViewObjectContacts at all. This can
160 : : // be used to test if this ViewContact is visualized ATM or not
161 : 12 : bool ViewContact::HasViewObjectContacts(bool bExcludePreviews) const
162 : : {
163 : 12 : const sal_uInt32 nCount(maViewObjectContactVector.size());
164 : :
165 [ + - ]: 12 : if(bExcludePreviews)
166 : : {
167 [ - + ]: 12 : for(sal_uInt32 a(0); a < nCount; a++)
168 : : {
169 [ # # ]: 0 : if(!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer())
170 : : {
171 : 0 : return true;
172 : : }
173 : : }
174 : :
175 : 12 : return false;
176 : : }
177 : : else
178 : : {
179 : 12 : return (0L != nCount);
180 : : }
181 : : }
182 : :
183 : : // Test if this ViewContact has ViewObjectContacts at all. This can
184 : : // be used to test if this ViewContact is visualized ATM or not
185 : 0 : bool ViewContact::isAnimatedInAnyViewObjectContact() const
186 : : {
187 : 0 : const sal_uInt32 nCount(maViewObjectContactVector.size());
188 : :
189 [ # # ]: 0 : for(sal_uInt32 a(0); a < nCount; a++)
190 : : {
191 [ # # ]: 0 : if(maViewObjectContactVector[a]->isAnimated())
192 : : {
193 : 0 : return true;
194 : : }
195 : : }
196 : :
197 : 0 : return false;
198 : : }
199 : :
200 : : // Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L
201 : : // and GetViewContact default pops up an assert since it's an error if
202 : : // GetObjectCount has a result != 0 and it's not overloaded.
203 : 6210 : sal_uInt32 ViewContact::GetObjectCount() const
204 : : {
205 : : // no sub-objects
206 : 6210 : return 0;
207 : : }
208 : :
209 : 0 : ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const
210 : : {
211 : : // This is the default implementation; call would be an error
212 : : OSL_FAIL("ViewContact::GetViewContact: This call needs to be overloaded when GetObjectCount() can return results != 0 (!)");
213 : 0 : return (ViewContact&)(*this);
214 : : }
215 : :
216 : 0 : ViewContact* ViewContact::GetParentContact() const
217 : : {
218 : : // default has no parent
219 : 0 : return 0;
220 : : }
221 : :
222 : 93067 : void ViewContact::ActionChildInserted(ViewContact& rChild)
223 : : {
224 : : // propagate change to all exsisting visualisations which
225 : : // will force a VOC for the new child and invalidate it's range
226 : 93067 : const sal_uInt32 nCount(maViewObjectContactVector.size());
227 : :
228 [ + + ]: 93998 : for(sal_uInt32 a(0); a < nCount; a++)
229 : : {
230 : 931 : ViewObjectContact* pCandidate = maViewObjectContactVector[a];
231 : : DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
232 : :
233 : : // take action at all VOCs. At the VOCs ObjectContact the initial
234 : : // rectangle will be invalidated at the associated OutputDevice.
235 : 931 : pCandidate->ActionChildInserted(rChild);
236 : : }
237 : 93067 : }
238 : :
239 : : // React on changes of the object of this ViewContact
240 : 1518979 : void ViewContact::ActionChanged()
241 : : {
242 : : // propagate change to all existing VOCs. This will invalidate
243 : : // all drawn visualisations in all known views
244 : 1518979 : const sal_uInt32 nCount(maViewObjectContactVector.size());
245 : :
246 [ + + ]: 1530426 : for(sal_uInt32 a(0); a < nCount; a++)
247 : : {
248 : 11447 : ViewObjectContact* pCandidate = maViewObjectContactVector[a];
249 : : DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
250 : :
251 : 11447 : pCandidate->ActionChanged();
252 : : }
253 : 1518979 : }
254 : :
255 : : // access to SdrObject and/or SdrPage. May return 0L like the default
256 : : // implementations do. Needs to be overloaded as needed.
257 : 5140 : SdrObject* ViewContact::TryToGetSdrObject() const
258 : : {
259 : 5140 : return 0L;
260 : : }
261 : :
262 : 0 : SdrPage* ViewContact::TryToGetSdrPage() const
263 : : {
264 : 0 : return 0L;
265 : : }
266 : :
267 : : //////////////////////////////////////////////////////////////////////////////
268 : : // primitive stuff
269 : :
270 : 0 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::createViewIndependentPrimitive2DSequence() const
271 : : {
272 : : // This is the default implementation and should never be called (see header). If this is called,
273 : : // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by
274 : : // providing a seqence of primitives -> which cannot be correct.
275 : : // Since we have no access to any known model data here, the default implementation creates a yellow placeholder
276 : : // hairline polygon with a default size of (1000, 1000, 5000, 3000)
277 : : OSL_FAIL("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)");
278 [ # # ][ # # ]: 0 : const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0)));
279 : 0 : const basegfx::BColor aYellow(1.0, 1.0, 0.0);
280 : : const drawinglayer::primitive2d::Primitive2DReference xReference(
281 [ # # ][ # # ]: 0 : new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow));
[ # # ]
282 : :
283 [ # # ][ # # ]: 0 : return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
284 : : }
285 : :
286 : 97058 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::getViewIndependentPrimitive2DSequence() const
287 : : {
288 : : // local up-to-date checks. Create new list and compare.
289 [ + - ]: 97058 : const drawinglayer::primitive2d::Primitive2DSequence xNew(createViewIndependentPrimitive2DSequence());
290 : :
291 [ + - ][ + + ]: 97058 : if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence, xNew))
292 : : {
293 : : // has changed, copy content
294 [ + - ]: 42983 : const_cast< ViewContact* >(this)->mxViewIndependentPrimitive2DSequence = xNew;
295 : : }
296 : :
297 : : // return current Primitive2DSequence
298 [ + - ][ + - ]: 97058 : return mxViewIndependentPrimitive2DSequence;
299 : : }
300 : :
301 : : // add Gluepoints (if available)
302 : 0 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::createGluePointPrimitive2DSequence() const
303 : : {
304 : : // default returns empty reference
305 : 0 : return drawinglayer::primitive2d::Primitive2DSequence();
306 : : }
307 : :
308 : 376077 : void ViewContact::flushViewObjectContacts(bool bWithHierarchy)
309 : : {
310 [ + - ]: 376077 : if(bWithHierarchy)
311 : : {
312 : : // flush DrawingLayer hierarchy
313 : 376077 : const sal_uInt32 nCount(GetObjectCount());
314 : :
315 [ + + ]: 658110 : for(sal_uInt32 a(0); a < nCount; a++)
316 : : {
317 : 282033 : ViewContact& rChild = GetViewContact(a);
318 : 282033 : rChild.flushViewObjectContacts(bWithHierarchy);
319 : : }
320 : : }
321 : :
322 : : // delete local VOCs
323 : 376077 : deleteAllVOCs();
324 : 376077 : }
325 : : } // end of namespace contact
326 : : } // end of namespace sdr
327 : :
328 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|