1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/sdr/overlay/overlayobjectlist.hxx>
31 #include <svx/sdr/overlay/overlaymanager.hxx>
32 #include <tools/debug.hxx>
33 #include <vcl/outdev.hxx>
34 #include <basegfx/matrix/b2dhommatrix.hxx>
35 
36 // for SOLARIS compiler include of algorithm part of _STL is necesary to
37 // get access to basic algos like ::std::find
38 #include <algorithm>
39 
40 #include <drawinglayer/processor2d/hittestprocessor2d.hxx>
41 
42 //////////////////////////////////////////////////////////////////////////////
43 
44 namespace sdr
45 {
46 	namespace overlay
47 	{
48 		OverlayObjectList::~OverlayObjectList()
49 		{
50 			clear();
51 		}
52 
53 		void OverlayObjectList::clear()
54 		{
55 			OverlayObjectVector::iterator aStart(maVector.begin());
56 
57 			for(; aStart != maVector.end(); aStart++)
58 			{
59 				::sdr::overlay::OverlayObject* pCandidate = *aStart;
60 
61 				if(pCandidate->getOverlayManager())
62 				{
63 					pCandidate->getOverlayManager()->remove(*pCandidate);
64 				}
65 
66 				delete pCandidate;
67 			}
68 
69 			maVector.clear();
70 		}
71 
72 		void OverlayObjectList::remove(OverlayObject& rOverlayObject)
73 		{
74 			const OverlayObjectVector::iterator aFindResult = ::std::find(maVector.begin(), maVector.end(), &rOverlayObject);
75 			const bool bFound(aFindResult != maVector.end());
76 			OSL_ENSURE(bFound, "Could not find given object in list (!)");
77 
78 			if(bFound)
79 			{
80 				maVector.erase(aFindResult);
81 			}
82 		}
83 
84 		bool OverlayObjectList::isHitLogic(const basegfx::B2DPoint& rLogicPosition, double fLogicTolerance) const
85 		{
86 			if(!maVector.empty())
87 			{
88 				OverlayObjectVector::const_iterator aStart(maVector.begin());
89 				sdr::overlay::OverlayObject* pFirst = *aStart;
90 				OSL_ENSURE(pFirst, "Corrupt OverlayObjectList (!)");
91 				OverlayManager* pManager = pFirst->getOverlayManager();
92 
93 				if(pManager)
94 				{
95 					if(0.0 == fLogicTolerance)
96 					{
97 						const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(
98 							Size(DEFAULT_VALUE_FOR_HITTEST_PIXEL, DEFAULT_VALUE_FOR_HITTEST_PIXEL)));
99 						fLogicTolerance = aSizeLogic.Width();
100 					}
101 
102 					const drawinglayer::geometry::ViewInformation2D aViewInformation2D(pManager->getCurrentViewInformation2D());
103 					drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D(
104 						aViewInformation2D,
105 						rLogicPosition,
106 						fLogicTolerance,
107                         false);
108 
109 					for(; aStart != maVector.end(); aStart++)
110 					{
111 						sdr::overlay::OverlayObject* pCandidate = *aStart;
112 						OSL_ENSURE(pCandidate, "Corrupt OverlayObjectList (!)");
113 
114 						if(pCandidate->isHittable())
115 						{
116 							const drawinglayer::primitive2d::Primitive2DSequence& rSequence = pCandidate->getOverlayObjectPrimitive2DSequence();
117 
118 							if(rSequence.hasElements())
119 							{
120 								aHitTestProcessor2D.process(rSequence);
121 
122 								if(aHitTestProcessor2D.getHit())
123 								{
124 									return true;
125 								}
126 							}
127 						}
128 					}
129 				}
130 			}
131 
132 			return false;
133 		}
134 
135 		bool OverlayObjectList::isHitPixel(const Point& rDiscretePosition, sal_uInt32 nDiscreteTolerance) const
136 		{
137 			if(!maVector.empty())
138 			{
139 				OverlayObjectVector::const_iterator aStart(maVector.begin());
140 				sdr::overlay::OverlayObject* pCandidate = *aStart;
141 				OverlayManager* pManager = pCandidate->getOverlayManager();
142 
143 				if(pManager)
144 				{
145 					const Point aPosLogic(pManager->getOutputDevice().PixelToLogic(rDiscretePosition));
146 					const basegfx::B2DPoint aPosition(aPosLogic.X(), aPosLogic.Y());
147 
148 					if(nDiscreteTolerance)
149 					{
150 						const Size aSizeLogic(pManager->getOutputDevice().PixelToLogic(Size(nDiscreteTolerance, nDiscreteTolerance)));
151 						return isHitLogic(aPosition, (double)aSizeLogic.Width());
152 					}
153 					else
154 					{
155 						return isHitLogic(aPosition);
156 					}
157 				}
158 			}
159 
160 			return false;
161 		}
162 
163 		basegfx::B2DRange OverlayObjectList::getBaseRange() const
164 		{
165 			basegfx::B2DRange aRetval;
166 
167 			if(!maVector.empty())
168 			{
169 				OverlayObjectVector::const_iterator aStart(maVector.begin());
170 
171 				for(; aStart != maVector.end(); aStart++)
172 				{
173 					::sdr::overlay::OverlayObject* pCandidate = *aStart;
174 					aRetval.expand(pCandidate->getBaseRange());
175 				}
176 			}
177 
178 			return aRetval;
179 		}
180 	} // end of namespace overlay
181 } // end of namespace sdr
182 
183 //////////////////////////////////////////////////////////////////////////////
184 // eof
185