1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10f6e50924SAndrew Rist  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12f6e50924SAndrew Rist  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19f6e50924SAndrew Rist  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/sdr/contact/viewcontact.hxx>
27cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontact.hxx>
28cdf0e10cSrcweir #include <svx/sdr/contact/objectcontact.hxx>
29cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
30cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
31cdf0e10cSrcweir #include <basegfx/color/bcolor.hxx>
32cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
33cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
34cdf0e10cSrcweir #include <svx/sdr/contact/objectcontactofpageview.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
37cdf0e10cSrcweir 
38cdf0e10cSrcweir namespace sdr
39cdf0e10cSrcweir {
40cdf0e10cSrcweir 	namespace contact
41cdf0e10cSrcweir 	{
42cdf0e10cSrcweir         // Create a Object-Specific ViewObjectContact, set ViewContact and
43cdf0e10cSrcweir 		// ObjectContact. Always needs to return something. Default is to create
44cdf0e10cSrcweir 		// a standard ViewObjectContact containing the given ObjectContact and *this
CreateObjectSpecificViewObjectContact(ObjectContact & rObjectContact)45cdf0e10cSrcweir 		ViewObjectContact& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
46cdf0e10cSrcweir 		{
47cdf0e10cSrcweir 			return *(new ViewObjectContact(rObjectContact, *this));
48cdf0e10cSrcweir 		}
49cdf0e10cSrcweir 
ViewContact()50cdf0e10cSrcweir 		ViewContact::ViewContact()
51cdf0e10cSrcweir         :	maViewObjectContactVector(),
52cdf0e10cSrcweir 			mxViewIndependentPrimitive2DSequence()
53cdf0e10cSrcweir 		{
54cdf0e10cSrcweir 		}
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 		// Methods to react on start getting viewed or stop getting
57cdf0e10cSrcweir 		// viewed. This info is derived from the count of members of
58cdf0e10cSrcweir 		// registered ViewObjectContacts. Default does nothing.
StartGettingViewed()59cdf0e10cSrcweir 		void ViewContact::StartGettingViewed()
60cdf0e10cSrcweir 		{
61cdf0e10cSrcweir 		}
62cdf0e10cSrcweir 
StopGettingViewed()63cdf0e10cSrcweir 		void ViewContact::StopGettingViewed()
64cdf0e10cSrcweir 		{
65cdf0e10cSrcweir 		}
66cdf0e10cSrcweir 
~ViewContact()67cdf0e10cSrcweir 		ViewContact::~ViewContact()
68cdf0e10cSrcweir 		{
69cdf0e10cSrcweir             deleteAllVOCs();
70cdf0e10cSrcweir         }
71cdf0e10cSrcweir 
deleteAllVOCs()72cdf0e10cSrcweir 		void ViewContact::deleteAllVOCs()
73cdf0e10cSrcweir 		{
74cdf0e10cSrcweir 			// get rid of all VOCs
75cdf0e10cSrcweir 			// #i84257# To avoid that each 'delete pCandidate' again uses
76cdf0e10cSrcweir 			// the local RemoveViewObjectContact with a search and removal in the
77cdf0e10cSrcweir 			// vector, simply copy and clear local vector.
78cdf0e10cSrcweir 			std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector);
79cdf0e10cSrcweir 			maViewObjectContactVector.clear();
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 			while(!aLocalVOCList.empty())
82cdf0e10cSrcweir 			{
83cdf0e10cSrcweir 				ViewObjectContact* pCandidate = aLocalVOCList.back();
84cdf0e10cSrcweir 				aLocalVOCList.pop_back();
85cdf0e10cSrcweir 				DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList in VC (!)");
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 				// ViewObjectContacts only make sense with View and Object contacts.
88cdf0e10cSrcweir 				// When the contact to the SdrObject is deleted like in this case,
89cdf0e10cSrcweir 				// all ViewObjectContacts can be deleted, too.
90cdf0e10cSrcweir 				delete pCandidate;
91cdf0e10cSrcweir 			}
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 			// assert when there were new entries added during deletion
94cdf0e10cSrcweir 			DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)");
95cdf0e10cSrcweir         }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 		// get a Object-specific ViewObjectContact for a specific
98cdf0e10cSrcweir 		// ObjectContact (->View). Always needs to return something.
GetViewObjectContact(ObjectContact & rObjectContact)99cdf0e10cSrcweir 		ViewObjectContact& ViewContact::GetViewObjectContact(ObjectContact& rObjectContact)
100cdf0e10cSrcweir 		{
101cdf0e10cSrcweir 			ViewObjectContact* pRetval = 0L;
102cdf0e10cSrcweir 			const sal_uInt32 nCount(maViewObjectContactVector.size());
103cdf0e10cSrcweir 
104cdf0e10cSrcweir 			// first search if there exists a VOC for the given OC
105cdf0e10cSrcweir 			for(sal_uInt32 a(0); !pRetval && a < nCount; a++)
106cdf0e10cSrcweir 			{
107cdf0e10cSrcweir 				ViewObjectContact* pCandidate = maViewObjectContactVector[a];
108cdf0e10cSrcweir 				DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 				if(&(pCandidate->GetObjectContact()) == &rObjectContact)
111cdf0e10cSrcweir 				{
112cdf0e10cSrcweir 					pRetval = pCandidate;
113cdf0e10cSrcweir 				}
114cdf0e10cSrcweir 			}
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 			if(!pRetval)
117cdf0e10cSrcweir 			{
118cdf0e10cSrcweir 				// create a new one. It's inserted to the local list from the
119cdf0e10cSrcweir 				// VieObjectContact constructor via AddViewObjectContact()
120cdf0e10cSrcweir 				pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact);
121cdf0e10cSrcweir 			}
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 			return *pRetval;
124cdf0e10cSrcweir 		}
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 		// A new ViewObjectContact was created and shall be remembered.
AddViewObjectContact(ViewObjectContact & rVOContact)127cdf0e10cSrcweir 		void ViewContact::AddViewObjectContact(ViewObjectContact& rVOContact)
128cdf0e10cSrcweir 		{
129cdf0e10cSrcweir 			maViewObjectContactVector.push_back(&rVOContact);
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 			if(1L == maViewObjectContactVector.size())
132cdf0e10cSrcweir 			{
133cdf0e10cSrcweir 				StartGettingViewed();
134cdf0e10cSrcweir 			}
135cdf0e10cSrcweir 		}
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 		// A ViewObjectContact was deleted and shall be forgotten.
RemoveViewObjectContact(ViewObjectContact & rVOContact)138cdf0e10cSrcweir 		void ViewContact::RemoveViewObjectContact(ViewObjectContact& rVOContact)
139cdf0e10cSrcweir 		{
140cdf0e10cSrcweir 			std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact);
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 			if(aFindResult != maViewObjectContactVector.end())
143cdf0e10cSrcweir 			{
144cdf0e10cSrcweir 				maViewObjectContactVector.erase(aFindResult);
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 				if(maViewObjectContactVector.empty())
147cdf0e10cSrcweir 				{
148cdf0e10cSrcweir                     // This may need to get asynchron later since it eventually triggers
149cdf0e10cSrcweir                     // deletes of OCs where the VOC is still added.
150cdf0e10cSrcweir 					StopGettingViewed();
151cdf0e10cSrcweir 				}
152cdf0e10cSrcweir 			}
153cdf0e10cSrcweir 		}
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 		// Test if this ViewContact has ViewObjectContacts at all. This can
156cdf0e10cSrcweir 		// be used to test if this ViewContact is visualized ATM or not
HasViewObjectContacts(bool bExcludePreviews) const157cdf0e10cSrcweir 		bool ViewContact::HasViewObjectContacts(bool bExcludePreviews) const
158cdf0e10cSrcweir 		{
159cdf0e10cSrcweir 			const sal_uInt32 nCount(maViewObjectContactVector.size());
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 			if(bExcludePreviews)
162cdf0e10cSrcweir             {
163cdf0e10cSrcweir                 for(sal_uInt32 a(0); a < nCount; a++)
164cdf0e10cSrcweir                 {
165cdf0e10cSrcweir                     if(!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer())
166cdf0e10cSrcweir                     {
167cdf0e10cSrcweir                         return true;
168cdf0e10cSrcweir                     }
169cdf0e10cSrcweir                 }
170cdf0e10cSrcweir 
171cdf0e10cSrcweir                 return false;
172cdf0e10cSrcweir             }
173cdf0e10cSrcweir             else
174cdf0e10cSrcweir             {
175cdf0e10cSrcweir     			return (0L != nCount);
176cdf0e10cSrcweir             }
177cdf0e10cSrcweir 		}
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 		// Test if this ViewContact has ViewObjectContacts at all. This can
180cdf0e10cSrcweir 		// be used to test if this ViewContact is visualized ATM or not
isAnimatedInAnyViewObjectContact() const181cdf0e10cSrcweir 		bool ViewContact::isAnimatedInAnyViewObjectContact() const
182cdf0e10cSrcweir 		{
183cdf0e10cSrcweir 			const sal_uInt32 nCount(maViewObjectContactVector.size());
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < nCount; a++)
186cdf0e10cSrcweir 			{
187cdf0e10cSrcweir 				if(maViewObjectContactVector[a]->isAnimated())
188cdf0e10cSrcweir 				{
189cdf0e10cSrcweir 					return true;
190cdf0e10cSrcweir 				}
191cdf0e10cSrcweir 			}
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 			return false;
194cdf0e10cSrcweir 		}
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 		// Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L
197cdf0e10cSrcweir 		// and GetViewContact default pops up an assert since it's an error if
198cdf0e10cSrcweir 		// GetObjectCount has a result != 0 and it's not overloaded.
GetObjectCount() const199cdf0e10cSrcweir 		sal_uInt32 ViewContact::GetObjectCount() const
200cdf0e10cSrcweir 		{
201cdf0e10cSrcweir 			// no sub-objects
202cdf0e10cSrcweir 			return 0;
203cdf0e10cSrcweir 		}
204cdf0e10cSrcweir 
GetViewContact(sal_uInt32) const205cdf0e10cSrcweir 		ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const
206cdf0e10cSrcweir 		{
207cdf0e10cSrcweir 			// This is the default implementation; call would be an error
208cdf0e10cSrcweir 			DBG_ERROR("ViewContact::GetViewContact: This call needs to be overloaded when GetObjectCount() can return results != 0 (!)");
209cdf0e10cSrcweir 			return (ViewContact&)(*this);
210cdf0e10cSrcweir 		}
211cdf0e10cSrcweir 
GetParentContact() const212cdf0e10cSrcweir 		ViewContact* ViewContact::GetParentContact() const
213cdf0e10cSrcweir 		{
214cdf0e10cSrcweir 			// default has no parent
215cdf0e10cSrcweir 			return 0;
216cdf0e10cSrcweir 		}
217cdf0e10cSrcweir 
ActionChildInserted(ViewContact & rChild)218cdf0e10cSrcweir 		void ViewContact::ActionChildInserted(ViewContact& rChild)
219cdf0e10cSrcweir 		{
220cdf0e10cSrcweir 			// propagate change to all exsisting visualisations which
221cdf0e10cSrcweir 			// will force a VOC for the new child and invalidate it's range
222cdf0e10cSrcweir 			const sal_uInt32 nCount(maViewObjectContactVector.size());
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < nCount; a++)
225cdf0e10cSrcweir 			{
226cdf0e10cSrcweir 				ViewObjectContact* pCandidate = maViewObjectContactVector[a];
227cdf0e10cSrcweir 				DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
228cdf0e10cSrcweir 
229cdf0e10cSrcweir 				// take action at all VOCs. At the VOCs ObjectContact the initial
230cdf0e10cSrcweir 				// rectangle will be invalidated at the associated OutputDevice.
231cdf0e10cSrcweir 				pCandidate->ActionChildInserted(rChild);
232cdf0e10cSrcweir 			}
233cdf0e10cSrcweir 		}
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 		// React on changes of the object of this ViewContact
ActionChanged()236cdf0e10cSrcweir 		void ViewContact::ActionChanged()
237cdf0e10cSrcweir 		{
238cdf0e10cSrcweir 			// propagate change to all existing VOCs. This will invalidate
239cdf0e10cSrcweir 			// all drawn visualisations in all known views
240cdf0e10cSrcweir 			const sal_uInt32 nCount(maViewObjectContactVector.size());
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < nCount; a++)
243cdf0e10cSrcweir 			{
244cdf0e10cSrcweir 				ViewObjectContact* pCandidate = maViewObjectContactVector[a];
245cdf0e10cSrcweir 				DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 				pCandidate->ActionChanged();
248cdf0e10cSrcweir 			}
249cdf0e10cSrcweir 		}
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 		// access to SdrObject and/or SdrPage. May return 0L like the default
252cdf0e10cSrcweir 		// implementations do. Needs to be overloaded as needed.
TryToGetSdrObject() const253cdf0e10cSrcweir 		SdrObject* ViewContact::TryToGetSdrObject() const
254cdf0e10cSrcweir 		{
255cdf0e10cSrcweir 			return 0L;
256cdf0e10cSrcweir 		}
257cdf0e10cSrcweir 
TryToGetSdrPage() const258cdf0e10cSrcweir 		SdrPage* ViewContact::TryToGetSdrPage() const
259cdf0e10cSrcweir 		{
260cdf0e10cSrcweir 			return 0L;
261cdf0e10cSrcweir 		}
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////////////
264cdf0e10cSrcweir 		// primitive stuff
265cdf0e10cSrcweir 
createViewIndependentPrimitive2DSequence() const266cdf0e10cSrcweir 		drawinglayer::primitive2d::Primitive2DSequence ViewContact::createViewIndependentPrimitive2DSequence() const
267cdf0e10cSrcweir 		{
268cdf0e10cSrcweir 			// This is the default impelemtation and should never be called (see header). If this is called,
269cdf0e10cSrcweir             // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by
270cdf0e10cSrcweir             // providing a seqence of primitives -> which cannot be correct.
271cdf0e10cSrcweir             // Since we have no access to any known model data here, the default implementation creates a yellow placeholder
272cdf0e10cSrcweir             // hairline polygon with a default size of (1000, 1000, 5000, 3000)
273cdf0e10cSrcweir             DBG_ERROR("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)");
274cdf0e10cSrcweir             const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0)));
275cdf0e10cSrcweir 			const basegfx::BColor aYellow(1.0, 1.0, 0.0);
276cdf0e10cSrcweir 			const drawinglayer::primitive2d::Primitive2DReference xReference(
277cdf0e10cSrcweir                 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow));
278cdf0e10cSrcweir 
279cdf0e10cSrcweir             return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
280cdf0e10cSrcweir 		}
281cdf0e10cSrcweir 
getViewIndependentPrimitive2DSequence() const282cdf0e10cSrcweir 		drawinglayer::primitive2d::Primitive2DSequence ViewContact::getViewIndependentPrimitive2DSequence() const
283cdf0e10cSrcweir 		{
284cdf0e10cSrcweir 			// local up-to-date checks. Create new list and compare.
285*025b0597SArmin Le Grand 			drawinglayer::primitive2d::Primitive2DSequence xNew(createViewIndependentPrimitive2DSequence());
286*025b0597SArmin Le Grand 
287*025b0597SArmin Le Grand             if(xNew.hasElements())
288*025b0597SArmin Le Grand             {
289*025b0597SArmin Le Grand                 // allow evtl. embedding in object-specific infos, e.g. Name, Title, Description
290*025b0597SArmin Le Grand                 xNew = embedToObjectSpecificInformation(xNew);
291*025b0597SArmin Le Grand             }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 			if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence, xNew))
294cdf0e10cSrcweir 			{
295cdf0e10cSrcweir 				// has changed, copy content
296cdf0e10cSrcweir 				const_cast< ViewContact* >(this)->mxViewIndependentPrimitive2DSequence = xNew;
297cdf0e10cSrcweir 			}
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 			// return current Primitive2DSequence
300cdf0e10cSrcweir 			return mxViewIndependentPrimitive2DSequence;
301cdf0e10cSrcweir 		}
302cdf0e10cSrcweir 
303cdf0e10cSrcweir 		// add Gluepoints (if available)
createGluePointPrimitive2DSequence() const304cdf0e10cSrcweir 		drawinglayer::primitive2d::Primitive2DSequence ViewContact::createGluePointPrimitive2DSequence() const
305cdf0e10cSrcweir 		{
306cdf0e10cSrcweir 			// default returns empty reference
307cdf0e10cSrcweir 			return drawinglayer::primitive2d::Primitive2DSequence();
308cdf0e10cSrcweir 		}
309cdf0e10cSrcweir 
embedToObjectSpecificInformation(const drawinglayer::primitive2d::Primitive2DSequence & rSource) const310*025b0597SArmin Le Grand         drawinglayer::primitive2d::Primitive2DSequence ViewContact::embedToObjectSpecificInformation(const drawinglayer::primitive2d::Primitive2DSequence& rSource) const
311*025b0597SArmin Le Grand         {
312*025b0597SArmin Le Grand             // nothing to do for default
313*025b0597SArmin Le Grand             return rSource;
314*025b0597SArmin Le Grand         }
315*025b0597SArmin Le Grand 
flushViewObjectContacts(bool bWithHierarchy)316cdf0e10cSrcweir         void ViewContact::flushViewObjectContacts(bool bWithHierarchy)
317cdf0e10cSrcweir         {
318cdf0e10cSrcweir             if(bWithHierarchy)
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 // flush DrawingLayer hierarchy
321cdf0e10cSrcweir 			    const sal_uInt32 nCount(GetObjectCount());
322cdf0e10cSrcweir 
323cdf0e10cSrcweir                 for(sal_uInt32 a(0); a < nCount; a++)
324cdf0e10cSrcweir                 {
325cdf0e10cSrcweir                     ViewContact& rChild = GetViewContact(a);
326cdf0e10cSrcweir                     rChild.flushViewObjectContacts(bWithHierarchy);
327cdf0e10cSrcweir                 }
328cdf0e10cSrcweir             }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir             // delete local VOCs
331cdf0e10cSrcweir             deleteAllVOCs();
332cdf0e10cSrcweir         }
333cdf0e10cSrcweir 	} // end of namespace contact
334cdf0e10cSrcweir } // end of namespace sdr
335cdf0e10cSrcweir 
336cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
337cdf0e10cSrcweir // eof
338