1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_dbaccess.hxx"
26*b1cdbd2cSJim Jagielski #ifndef DBAUI_CONNECTIONLINE_HXX
27*b1cdbd2cSJim Jagielski #include "ConnectionLine.hxx"
28*b1cdbd2cSJim Jagielski #endif
29*b1cdbd2cSJim Jagielski #ifndef DBAUI_CONNECTIONLINEDATA_HXX
30*b1cdbd2cSJim Jagielski #include "ConnectionLineData.hxx"
31*b1cdbd2cSJim Jagielski #endif
32*b1cdbd2cSJim Jagielski #ifndef DBAUI_TABLEWINDOW_HXX
33*b1cdbd2cSJim Jagielski #include "TableWindow.hxx"
34*b1cdbd2cSJim Jagielski #endif
35*b1cdbd2cSJim Jagielski #ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
36*b1cdbd2cSJim Jagielski #include "TableWindowListBox.hxx"
37*b1cdbd2cSJim Jagielski #endif
38*b1cdbd2cSJim Jagielski #ifndef DBAUI_TABLECONNECTION_HXX
39*b1cdbd2cSJim Jagielski #include "TableConnection.hxx"
40*b1cdbd2cSJim Jagielski #endif
41*b1cdbd2cSJim Jagielski #ifndef _SV_SVAPP_HXX
42*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
43*b1cdbd2cSJim Jagielski #endif
44*b1cdbd2cSJim Jagielski #ifndef _INC_MATH
45*b1cdbd2cSJim Jagielski #include <math.h>
46*b1cdbd2cSJim Jagielski #endif
47*b1cdbd2cSJim Jagielski #ifndef _TOOLS_DEBUG_HXX
48*b1cdbd2cSJim Jagielski #include <tools/debug.hxx>
49*b1cdbd2cSJim Jagielski #endif
50*b1cdbd2cSJim Jagielski #include <vcl/lineinfo.hxx>
51*b1cdbd2cSJim Jagielski 
52*b1cdbd2cSJim Jagielski 
53*b1cdbd2cSJim Jagielski using namespace dbaui;
54*b1cdbd2cSJim Jagielski const long DESCRIPT_LINE_WIDTH = 15;
55*b1cdbd2cSJim Jagielski const long HIT_SENSITIVE_RADIUS = 5;
56*b1cdbd2cSJim Jagielski 
57*b1cdbd2cSJim Jagielski namespace
58*b1cdbd2cSJim Jagielski {
59*b1cdbd2cSJim Jagielski 	/** calcRect creates a new rectangle with the given points
60*b1cdbd2cSJim Jagielski 			@param	_rBase		the base point
61*b1cdbd2cSJim Jagielski 			@param	_aVector	the vector which will be added
62*b1cdbd2cSJim Jagielski 	*/
calcRect(const Point & _rBase,const Point & _aVector)63*b1cdbd2cSJim Jagielski 	inline Rectangle calcRect(const Point& _rBase,const Point& _aVector)
64*b1cdbd2cSJim Jagielski 	{
65*b1cdbd2cSJim Jagielski 		return Rectangle( _rBase - _aVector, _rBase + _aVector );
66*b1cdbd2cSJim Jagielski 	}
67*b1cdbd2cSJim Jagielski 	// -----------------------------------------------------------------------------
68*b1cdbd2cSJim Jagielski 	/** GetTextPos calculate the rectangle for the connection to be drawn
69*b1cdbd2cSJim Jagielski 			@param	_pWin			the table window where to draw it
70*b1cdbd2cSJim Jagielski 			@param	_aConnPos		the connection point
71*b1cdbd2cSJim Jagielski 			@param	_aDescrLinePos	the description line pos
72*b1cdbd2cSJim Jagielski 	*/
GetTextPos(const OTableWindow * _pWin,const Point & _aConnPos,const Point & _aDescrLinePos)73*b1cdbd2cSJim Jagielski 	Rectangle GetTextPos(const OTableWindow* _pWin, const Point& _aConnPos,const Point& _aDescrLinePos)
74*b1cdbd2cSJim Jagielski 	{
75*b1cdbd2cSJim Jagielski 		OTableWindowListBox* pListBox = _pWin ? _pWin->GetListBox() : NULL;
76*b1cdbd2cSJim Jagielski 		DBG_ASSERT(_pWin && pListBox, "OConnectionLine::GetSourceTextPos : invalid call !");
77*b1cdbd2cSJim Jagielski 
78*b1cdbd2cSJim Jagielski 		Rectangle aReturn;
79*b1cdbd2cSJim Jagielski 		if ( pListBox )
80*b1cdbd2cSJim Jagielski 		{
81*b1cdbd2cSJim Jagielski 			const long nRowHeight = pListBox->GetEntryHeight();
82*b1cdbd2cSJim Jagielski 			aReturn.Top() = _aConnPos.Y() - nRowHeight;
83*b1cdbd2cSJim Jagielski 			aReturn.Bottom() = aReturn.Top() + nRowHeight;
84*b1cdbd2cSJim Jagielski 			if (_aDescrLinePos.X() < _aConnPos.X())
85*b1cdbd2cSJim Jagielski 			{
86*b1cdbd2cSJim Jagielski 				aReturn.Left() = _aDescrLinePos.X();
87*b1cdbd2cSJim Jagielski 				aReturn.Right() = aReturn.Left() + _aConnPos.X() - _aDescrLinePos.X();
88*b1cdbd2cSJim Jagielski 			}
89*b1cdbd2cSJim Jagielski 			else
90*b1cdbd2cSJim Jagielski 			{
91*b1cdbd2cSJim Jagielski 				aReturn.Left() = _aConnPos.X();
92*b1cdbd2cSJim Jagielski 				aReturn.Right() = aReturn.Left() + _aDescrLinePos.X() - _aConnPos.X();
93*b1cdbd2cSJim Jagielski 			}
94*b1cdbd2cSJim Jagielski 		}
95*b1cdbd2cSJim Jagielski 
96*b1cdbd2cSJim Jagielski 		return aReturn;
97*b1cdbd2cSJim Jagielski 	}
98*b1cdbd2cSJim Jagielski 	// -----------------------------------------------------------------------------
99*b1cdbd2cSJim Jagielski 	/** calcPointsYValue calculate the points Y value in relation to the listbox entry
100*b1cdbd2cSJim Jagielski 			@param	_pWin			the corresponding window
101*b1cdbd2cSJim Jagielski 			@param	_pEntry			the source or dest entry
102*b1cdbd2cSJim Jagielski 			@param	_rNewConPos		(in/out) the connection pos
103*b1cdbd2cSJim Jagielski 			@param	_rNewDescrPos	(in/out) the description pos
104*b1cdbd2cSJim Jagielski 	*/
calcPointsYValue(const OTableWindow * _pWin,SvLBoxEntry * _pEntry,Point & _rNewConPos,Point & _rNewDescrPos)105*b1cdbd2cSJim Jagielski 	void calcPointsYValue(const OTableWindow* _pWin,SvLBoxEntry* _pEntry,Point& _rNewConPos,Point& _rNewDescrPos)
106*b1cdbd2cSJim Jagielski 	{
107*b1cdbd2cSJim Jagielski 		const OTableWindowListBox* pListBox = _pWin->GetListBox();
108*b1cdbd2cSJim Jagielski 		_rNewConPos.Y() = _pWin->GetPosPixel().Y();
109*b1cdbd2cSJim Jagielski         if ( _pEntry )
110*b1cdbd2cSJim Jagielski         {
111*b1cdbd2cSJim Jagielski             const long nRowHeight = pListBox->GetEntryHeight();
112*b1cdbd2cSJim Jagielski 		    _rNewConPos.Y() += pListBox->GetPosPixel().Y();
113*b1cdbd2cSJim Jagielski 		    long nEntryPos = pListBox->GetEntryPosition( _pEntry ).Y();
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski 		    if( nEntryPos >= 0 )
116*b1cdbd2cSJim Jagielski 		    {
117*b1cdbd2cSJim Jagielski 			    _rNewConPos.Y() += nEntryPos;
118*b1cdbd2cSJim Jagielski 			    _rNewConPos.Y() += (long)( 0.5 * nRowHeight );
119*b1cdbd2cSJim Jagielski 		    }
120*b1cdbd2cSJim Jagielski 		    else
121*b1cdbd2cSJim Jagielski 			    _rNewConPos.Y() -= (long)( 0.5 * nRowHeight );
122*b1cdbd2cSJim Jagielski 
123*b1cdbd2cSJim Jagielski 		    long nListBoxBottom = _pWin->GetPosPixel().Y()
124*b1cdbd2cSJim Jagielski 								    + pListBox->GetPosPixel().Y()
125*b1cdbd2cSJim Jagielski 								    + pListBox->GetSizePixel().Height();
126*b1cdbd2cSJim Jagielski 		    if( _rNewConPos.Y() > nListBoxBottom )
127*b1cdbd2cSJim Jagielski 			    _rNewConPos.Y() = nListBoxBottom + 2;
128*b1cdbd2cSJim Jagielski         }
129*b1cdbd2cSJim Jagielski         else
130*b1cdbd2cSJim Jagielski             _rNewConPos.Y() += static_cast<sal_Int32>(pListBox->GetPosPixel().Y()*0.5);
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski 		_rNewDescrPos.Y() = _rNewConPos.Y();
133*b1cdbd2cSJim Jagielski 	}
134*b1cdbd2cSJim Jagielski 	// -----------------------------------------------------------------------------
135*b1cdbd2cSJim Jagielski }
136*b1cdbd2cSJim Jagielski 
137*b1cdbd2cSJim Jagielski //========================================================================
138*b1cdbd2cSJim Jagielski // class OConnectionLine
139*b1cdbd2cSJim Jagielski //========================================================================
DBG_NAME(OConnectionLine)140*b1cdbd2cSJim Jagielski DBG_NAME(OConnectionLine)
141*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
142*b1cdbd2cSJim Jagielski OConnectionLine::OConnectionLine( OTableConnection* _pConn, OConnectionLineDataRef _pLineData )
143*b1cdbd2cSJim Jagielski 	: m_pTabConn( _pConn )
144*b1cdbd2cSJim Jagielski 	 ,m_pData( _pLineData )
145*b1cdbd2cSJim Jagielski {
146*b1cdbd2cSJim Jagielski 	DBG_CTOR(OConnectionLine,NULL);
147*b1cdbd2cSJim Jagielski }
148*b1cdbd2cSJim Jagielski 
149*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
OConnectionLine(const OConnectionLine & _rLine)150*b1cdbd2cSJim Jagielski OConnectionLine::OConnectionLine( const OConnectionLine& _rLine )
151*b1cdbd2cSJim Jagielski {
152*b1cdbd2cSJim Jagielski 	DBG_CTOR(OConnectionLine,NULL);
153*b1cdbd2cSJim Jagielski 	m_pData = new OConnectionLineData( *_rLine.GetData() );
154*b1cdbd2cSJim Jagielski 	*this = _rLine;
155*b1cdbd2cSJim Jagielski }
156*b1cdbd2cSJim Jagielski 
157*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
~OConnectionLine()158*b1cdbd2cSJim Jagielski OConnectionLine::~OConnectionLine()
159*b1cdbd2cSJim Jagielski {
160*b1cdbd2cSJim Jagielski 	DBG_DTOR(OConnectionLine,NULL);
161*b1cdbd2cSJim Jagielski }
162*b1cdbd2cSJim Jagielski 
163*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
operator =(const OConnectionLine & rLine)164*b1cdbd2cSJim Jagielski OConnectionLine& OConnectionLine::operator=( const OConnectionLine& rLine )
165*b1cdbd2cSJim Jagielski {
166*b1cdbd2cSJim Jagielski 	if( &rLine != this )
167*b1cdbd2cSJim Jagielski 	{
168*b1cdbd2cSJim Jagielski 		// da mir die Daten nicht gehoeren, loesche ich die alten nicht
169*b1cdbd2cSJim Jagielski 		m_pData->CopyFrom(*rLine.GetData());
170*b1cdbd2cSJim Jagielski 			// CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski 		m_pTabConn = rLine.m_pTabConn;
173*b1cdbd2cSJim Jagielski 		m_aSourceConnPos = rLine.m_aSourceConnPos;
174*b1cdbd2cSJim Jagielski 		m_aDestConnPos = rLine.m_aDestConnPos;
175*b1cdbd2cSJim Jagielski 		m_aSourceDescrLinePos = rLine.m_aSourceDescrLinePos;
176*b1cdbd2cSJim Jagielski 		m_aDestDescrLinePos = rLine.m_aDestDescrLinePos;
177*b1cdbd2cSJim Jagielski 	}
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski 	return *this;
180*b1cdbd2cSJim Jagielski }
181*b1cdbd2cSJim Jagielski 
182*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
GetBoundingRect()183*b1cdbd2cSJim Jagielski Rectangle OConnectionLine::GetBoundingRect()
184*b1cdbd2cSJim Jagielski {
185*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
186*b1cdbd2cSJim Jagielski 	// Umgebendes Rechteck bestimmen
187*b1cdbd2cSJim Jagielski 	Rectangle aBoundingRect( Point(0,0), Point(0,0) );
188*b1cdbd2cSJim Jagielski 	if( !IsValid() )
189*b1cdbd2cSJim Jagielski 		return aBoundingRect;
190*b1cdbd2cSJim Jagielski 
191*b1cdbd2cSJim Jagielski 	Point aTopLeft;
192*b1cdbd2cSJim Jagielski 	Point aBottomRight;
193*b1cdbd2cSJim Jagielski 
194*b1cdbd2cSJim Jagielski 	if( m_aSourceDescrLinePos.Y() <= m_aDestDescrLinePos.Y() )
195*b1cdbd2cSJim Jagielski 	{
196*b1cdbd2cSJim Jagielski 		aTopLeft.Y() = m_aSourceDescrLinePos.Y();
197*b1cdbd2cSJim Jagielski 		aBottomRight.Y() = m_aDestDescrLinePos.Y();
198*b1cdbd2cSJim Jagielski 	}
199*b1cdbd2cSJim Jagielski 	else
200*b1cdbd2cSJim Jagielski 	{
201*b1cdbd2cSJim Jagielski 		aTopLeft.Y() = m_aDestDescrLinePos.Y();
202*b1cdbd2cSJim Jagielski 		aBottomRight.Y() = m_aSourceDescrLinePos.Y();
203*b1cdbd2cSJim Jagielski 	}
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski 	if( m_aSourceDescrLinePos.X() <= m_aDestDescrLinePos.X() )
206*b1cdbd2cSJim Jagielski 	{
207*b1cdbd2cSJim Jagielski 		aTopLeft.X() = m_aSourceDescrLinePos.X();
208*b1cdbd2cSJim Jagielski 		aBottomRight.X() = m_aDestDescrLinePos.X();
209*b1cdbd2cSJim Jagielski 	}
210*b1cdbd2cSJim Jagielski 	else
211*b1cdbd2cSJim Jagielski 	{
212*b1cdbd2cSJim Jagielski 		aTopLeft.X() = m_aDestDescrLinePos.X();
213*b1cdbd2cSJim Jagielski 		aBottomRight.X() = m_aSourceDescrLinePos.X();
214*b1cdbd2cSJim Jagielski 	}
215*b1cdbd2cSJim Jagielski 
216*b1cdbd2cSJim Jagielski     const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
217*b1cdbd2cSJim Jagielski 	const OTableWindow* pDestWin = m_pTabConn->GetDestWin();
218*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
219*b1cdbd2cSJim Jagielski 	// Linie verlaeuft in z-Form
220*b1cdbd2cSJim Jagielski 	if( pSourceWin == pDestWin || Abs(m_aSourceConnPos.X() - m_aDestConnPos.X()) > Abs(m_aSourceDescrLinePos.X() - m_aDestDescrLinePos.X()) )
221*b1cdbd2cSJim Jagielski 	{
222*b1cdbd2cSJim Jagielski 		aTopLeft.X() -= DESCRIPT_LINE_WIDTH;
223*b1cdbd2cSJim Jagielski 		aBottomRight.X() += DESCRIPT_LINE_WIDTH;
224*b1cdbd2cSJim Jagielski 	}
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski 	aBoundingRect = Rectangle( aTopLeft-Point(2,17), aBottomRight+Point(2,2) );
227*b1cdbd2cSJim Jagielski 
228*b1cdbd2cSJim Jagielski 	return aBoundingRect;
229*b1cdbd2cSJim Jagielski }
230*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
calcPointX1(const OTableWindow * _pWin,Point & _rNewConPos,Point & _rNewDescrPos)231*b1cdbd2cSJim Jagielski void calcPointX1(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
232*b1cdbd2cSJim Jagielski {
233*b1cdbd2cSJim Jagielski 	_rNewConPos.X() = _pWin->GetPosPixel().X() + _pWin->GetSizePixel().Width();
234*b1cdbd2cSJim Jagielski 	_rNewDescrPos.X() = _rNewConPos.X();
235*b1cdbd2cSJim Jagielski 	_rNewConPos.X() += DESCRIPT_LINE_WIDTH;
236*b1cdbd2cSJim Jagielski }
237*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
calcPointX2(const OTableWindow * _pWin,Point & _rNewConPos,Point & _rNewDescrPos)238*b1cdbd2cSJim Jagielski void calcPointX2(const OTableWindow* _pWin,Point& _rNewConPos,Point& _rNewDescrPos)
239*b1cdbd2cSJim Jagielski {
240*b1cdbd2cSJim Jagielski 	_rNewConPos.X() = _pWin->GetPosPixel().X();
241*b1cdbd2cSJim Jagielski 	_rNewDescrPos.X() = _rNewConPos.X();
242*b1cdbd2cSJim Jagielski 	_rNewConPos.X() -= DESCRIPT_LINE_WIDTH;
243*b1cdbd2cSJim Jagielski }
244*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
RecalcLine()245*b1cdbd2cSJim Jagielski sal_Bool OConnectionLine::RecalcLine()
246*b1cdbd2cSJim Jagielski {
247*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
248*b1cdbd2cSJim Jagielski 	// Fenster und Entries muessen gesetzt sein
249*b1cdbd2cSJim Jagielski 	const OTableWindow* pSourceWin = m_pTabConn->GetSourceWin();
250*b1cdbd2cSJim Jagielski 	const OTableWindow* pDestWin = m_pTabConn->GetDestWin();
251*b1cdbd2cSJim Jagielski 
252*b1cdbd2cSJim Jagielski 	if( !pSourceWin || !pDestWin )
253*b1cdbd2cSJim Jagielski 		return sal_False;
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski 	SvLBoxEntry* pSourceEntry = pSourceWin->GetListBox()->GetEntryFromText( GetData()->GetSourceFieldName() );
256*b1cdbd2cSJim Jagielski 	SvLBoxEntry* pDestEntry = pDestWin->GetListBox()->GetEntryFromText( GetData()->GetDestFieldName() );
257*b1cdbd2cSJim Jagielski 
258*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
259*b1cdbd2cSJim Jagielski 	// X-Koordinaten bestimmen
260*b1cdbd2cSJim Jagielski 	Point aSourceCenter( 0, 0 );
261*b1cdbd2cSJim Jagielski 	Point aDestCenter( 0, 0 );
262*b1cdbd2cSJim Jagielski 
263*b1cdbd2cSJim Jagielski 	aSourceCenter.X() = pSourceWin->GetPosPixel().X() + (long)( 0.5*pSourceWin->GetSizePixel().Width() );
264*b1cdbd2cSJim Jagielski 	aDestCenter.X() = pDestWin->GetPosPixel().X() + (long)( 0.5*pDestWin->GetSizePixel().Width() );
265*b1cdbd2cSJim Jagielski 
266*b1cdbd2cSJim Jagielski 	const OTableWindow* pFirstWin	= pDestWin;
267*b1cdbd2cSJim Jagielski 	const OTableWindow* pSecondWin	= pSourceWin;
268*b1cdbd2cSJim Jagielski 	Point* pFirstConPos				= &m_aDestConnPos;
269*b1cdbd2cSJim Jagielski 	Point* pFirstDescrPos			= &m_aDestDescrLinePos;
270*b1cdbd2cSJim Jagielski 	Point* pSecondConPos			= &m_aSourceConnPos;
271*b1cdbd2cSJim Jagielski 	Point* pSecondDescrPos			= &m_aSourceDescrLinePos;
272*b1cdbd2cSJim Jagielski 	if( aDestCenter.X() > aSourceCenter.X() )
273*b1cdbd2cSJim Jagielski 	{
274*b1cdbd2cSJim Jagielski 		pFirstWin		= pSourceWin;
275*b1cdbd2cSJim Jagielski 		pSecondWin		= pDestWin;
276*b1cdbd2cSJim Jagielski 		pFirstConPos	= &m_aSourceConnPos;
277*b1cdbd2cSJim Jagielski 		pFirstDescrPos	= &m_aSourceDescrLinePos;
278*b1cdbd2cSJim Jagielski 		pSecondConPos	= &m_aDestConnPos;
279*b1cdbd2cSJim Jagielski 		pSecondDescrPos	= &m_aDestDescrLinePos;
280*b1cdbd2cSJim Jagielski 	}
281*b1cdbd2cSJim Jagielski 
282*b1cdbd2cSJim Jagielski     if ( pFirstWin == pSecondWin && pSourceEntry != pDestEntry )
283*b1cdbd2cSJim Jagielski         calcPointX2(pFirstWin,*pFirstConPos,*pFirstDescrPos);
284*b1cdbd2cSJim Jagielski     else
285*b1cdbd2cSJim Jagielski         calcPointX1(pFirstWin,*pFirstConPos,*pFirstDescrPos);
286*b1cdbd2cSJim Jagielski 	calcPointX2(pSecondWin,*pSecondConPos,*pSecondDescrPos);
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
289*b1cdbd2cSJim Jagielski 	// aSourceConnPosY bestimmen
290*b1cdbd2cSJim Jagielski     calcPointsYValue(pSourceWin,pSourceEntry,m_aSourceConnPos,m_aSourceDescrLinePos);
291*b1cdbd2cSJim Jagielski 
292*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
293*b1cdbd2cSJim Jagielski 	// aDestConnPosY bestimmen
294*b1cdbd2cSJim Jagielski     calcPointsYValue(pDestWin,pDestEntry,m_aDestConnPos,m_aDestDescrLinePos);
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski 	return sal_True;
297*b1cdbd2cSJim Jagielski }
298*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
299*b1cdbd2cSJim Jagielski 
300*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
Draw(OutputDevice * pOutDev)301*b1cdbd2cSJim Jagielski void OConnectionLine::Draw( OutputDevice* pOutDev )
302*b1cdbd2cSJim Jagielski {
303*b1cdbd2cSJim Jagielski 	const sal_uInt16 nRectSize = 3;
304*b1cdbd2cSJim Jagielski 
305*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
306*b1cdbd2cSJim Jagielski 	// Neue Dimensionen berechnen
307*b1cdbd2cSJim Jagielski 	if( !RecalcLine() )
308*b1cdbd2cSJim Jagielski 		return;
309*b1cdbd2cSJim Jagielski 
310*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
311*b1cdbd2cSJim Jagielski 	// Zeichnen der Linien
312*b1cdbd2cSJim Jagielski 	if (m_pTabConn->IsSelected())
313*b1cdbd2cSJim Jagielski 		pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetHighlightColor());
314*b1cdbd2cSJim Jagielski 	else
315*b1cdbd2cSJim Jagielski 		pOutDev->SetLineColor(Application::GetSettings().GetStyleSettings().GetWindowTextColor());
316*b1cdbd2cSJim Jagielski 
317*b1cdbd2cSJim Jagielski     LineInfo aLineInfo;
318*b1cdbd2cSJim Jagielski     if ( m_pTabConn->IsSelected() )
319*b1cdbd2cSJim Jagielski         aLineInfo.SetWidth(3);
320*b1cdbd2cSJim Jagielski     Polygon aPoly;
321*b1cdbd2cSJim Jagielski     aPoly.Insert(0,m_aSourceDescrLinePos);
322*b1cdbd2cSJim Jagielski     aPoly.Insert(1,m_aSourceConnPos);
323*b1cdbd2cSJim Jagielski     aPoly.Insert(2,m_aDestConnPos);
324*b1cdbd2cSJim Jagielski     aPoly.Insert(3,m_aDestDescrLinePos);
325*b1cdbd2cSJim Jagielski     pOutDev->DrawPolyLine(aPoly,aLineInfo);
326*b1cdbd2cSJim Jagielski 
327*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
328*b1cdbd2cSJim Jagielski 	// draw the connection rectangles
329*b1cdbd2cSJim Jagielski 	pOutDev->SetFillColor(Application::GetSettings().GetStyleSettings().GetWindowColor());
330*b1cdbd2cSJim Jagielski 
331*b1cdbd2cSJim Jagielski 	Point aVector(nRectSize,nRectSize);
332*b1cdbd2cSJim Jagielski 	pOutDev->DrawRect( calcRect(m_aSourceDescrLinePos,aVector) );
333*b1cdbd2cSJim Jagielski 	pOutDev->DrawRect( calcRect( m_aDestDescrLinePos,aVector) );
334*b1cdbd2cSJim Jagielski }
335*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
IsValid() const336*b1cdbd2cSJim Jagielski sal_Bool OConnectionLine::IsValid() const
337*b1cdbd2cSJim Jagielski {
338*b1cdbd2cSJim Jagielski 	return m_pData.isValid();
339*b1cdbd2cSJim Jagielski }
340*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
dist_Euklid(const Point & p1,const Point & p2,const Point & pM,Point & q)341*b1cdbd2cSJim Jagielski double dist_Euklid(const Point &p1, const Point& p2,const Point& pM, Point& q)
342*b1cdbd2cSJim Jagielski {
343*b1cdbd2cSJim Jagielski 	Point v(p2 - p1);
344*b1cdbd2cSJim Jagielski 	Point w(pM - p1);
345*b1cdbd2cSJim Jagielski 	double a = sqrt((double)(v.X()*v.X() + v.Y()*v.Y()));
346*b1cdbd2cSJim Jagielski 	double l = (v.X() * w.Y() - v.Y() * w.X()) / a;
347*b1cdbd2cSJim Jagielski 	double a2 = w.X()*v.X()+w.Y()*v.Y();
348*b1cdbd2cSJim Jagielski 	a = a2 / (a * a);
349*b1cdbd2cSJim Jagielski 	q.X() = long(p1.X() + a * v.X());
350*b1cdbd2cSJim Jagielski 	q.Y() = long(p1.Y() + a * v.Y());
351*b1cdbd2cSJim Jagielski 	return l;
352*b1cdbd2cSJim Jagielski }
353*b1cdbd2cSJim Jagielski //------------------------------------------------------------------------
CheckHit(const Point & rMousePos) const354*b1cdbd2cSJim Jagielski bool OConnectionLine::CheckHit( const Point& rMousePos ) const
355*b1cdbd2cSJim Jagielski {
356*b1cdbd2cSJim Jagielski 	//////////////////////////////////////////////////////////////////////
357*b1cdbd2cSJim Jagielski 	/*
358*b1cdbd2cSJim Jagielski 		Vorgehensweise beim HitTest:
359*b1cdbd2cSJim Jagielski 		Es wird der Abstand nach Euklid berechnet.
360*b1cdbd2cSJim Jagielski 	*/
361*b1cdbd2cSJim Jagielski 	Point q;
362*b1cdbd2cSJim Jagielski 	double l = fabs(dist_Euklid(m_aSourceConnPos,m_aDestConnPos,rMousePos,q));
363*b1cdbd2cSJim Jagielski 	if( l < HIT_SENSITIVE_RADIUS)
364*b1cdbd2cSJim Jagielski 	{
365*b1cdbd2cSJim Jagielski 		if(::std::min(m_aSourceConnPos.X(),m_aDestConnPos.X()) <= q.X() && ::std::min(m_aSourceConnPos.Y(),m_aDestConnPos.Y()) <= q.Y()
366*b1cdbd2cSJim Jagielski 			&& q.X() <= ::std::max(m_aDestConnPos.X(),m_aSourceConnPos.X())   && q.Y() <= ::std::max(m_aDestConnPos.Y(),m_aSourceConnPos.Y()))
367*b1cdbd2cSJim Jagielski 			return true;
368*b1cdbd2cSJim Jagielski 	}
369*b1cdbd2cSJim Jagielski 
370*b1cdbd2cSJim Jagielski 	return false;
371*b1cdbd2cSJim Jagielski }
372*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
GetSourceTextPos() const373*b1cdbd2cSJim Jagielski Rectangle OConnectionLine::GetSourceTextPos() const
374*b1cdbd2cSJim Jagielski {
375*b1cdbd2cSJim Jagielski 	return GetTextPos(m_pTabConn->GetSourceWin(),m_aSourceConnPos,m_aSourceDescrLinePos);
376*b1cdbd2cSJim Jagielski }
377*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
GetDestTextPos() const378*b1cdbd2cSJim Jagielski Rectangle OConnectionLine::GetDestTextPos() const
379*b1cdbd2cSJim Jagielski {
380*b1cdbd2cSJim Jagielski 	return GetTextPos(m_pTabConn->GetDestWin(),m_aDestConnPos,m_aDestDescrLinePos);
381*b1cdbd2cSJim Jagielski }
382*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
getMidPoint() const383*b1cdbd2cSJim Jagielski Point OConnectionLine::getMidPoint() const
384*b1cdbd2cSJim Jagielski {
385*b1cdbd2cSJim Jagielski 	Point aDest = m_aDestConnPos - m_aSourceConnPos;
386*b1cdbd2cSJim Jagielski 	aDest.X() /= 2;
387*b1cdbd2cSJim Jagielski 	aDest.Y() /= 2;
388*b1cdbd2cSJim Jagielski 
389*b1cdbd2cSJim Jagielski 	return m_aSourceConnPos + aDest;
390*b1cdbd2cSJim Jagielski }
391*b1cdbd2cSJim Jagielski // -----------------------------------------------------------------------------
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski 
394