196de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
396de5490SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
496de5490SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
596de5490SAndrew Rist  * distributed with this work for additional information
696de5490SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
796de5490SAndrew Rist  * to you under the Apache License, Version 2.0 (the
896de5490SAndrew Rist  * "License"); you may not use this file except in compliance
996de5490SAndrew Rist  * with the License.  You may obtain a copy of the License at
1096de5490SAndrew Rist  *
1196de5490SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1296de5490SAndrew Rist  *
1396de5490SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1496de5490SAndrew Rist  * software distributed under the License is distributed on an
1596de5490SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1696de5490SAndrew Rist  * KIND, either express or implied.  See the License for the
1796de5490SAndrew Rist  * specific language governing permissions and limitations
1896de5490SAndrew Rist  * under the License.
1996de5490SAndrew Rist  *
2096de5490SAndrew Rist  *************************************************************/
2196de5490SAndrew Rist 
2296de5490SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25*b63233d8Sdamjan #include "precompiled_dbui.hxx"
26cdf0e10cSrcweir #ifndef DBAUI_TABLECONNECTION_HXX
27cdf0e10cSrcweir #include "TableConnection.hxx"
28cdf0e10cSrcweir #endif
29cdf0e10cSrcweir #ifndef DBAUI_CONNECTIONLINE_HXX
30cdf0e10cSrcweir #include "ConnectionLine.hxx"
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #ifndef DBAUI_TABLECONNECTIONDATA_HXX
33cdf0e10cSrcweir #include "TableConnectionData.hxx"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #ifndef DBAUI_JOINTABLEVIEW_HXX
36cdf0e10cSrcweir #include "JoinTableView.hxx"
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #ifndef _COMPHELPER_STLTYPES_HXX_
39cdf0e10cSrcweir #include <comphelper/stl_types.hxx>
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir #ifndef DBACCESS_CONNECTIONLINEACCESS_HXX
42cdf0e10cSrcweir #include "ConnectionLineAccess.hxx"
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir #include <algorithm>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 
47cdf0e10cSrcweir using namespace dbaui;
48cdf0e10cSrcweir using namespace comphelper;
49cdf0e10cSrcweir using namespace ::com::sun::star::uno;
50cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir //========================================================================
53cdf0e10cSrcweir // class OTableConnection
54cdf0e10cSrcweir //========================================================================
55cdf0e10cSrcweir namespace dbaui
56cdf0e10cSrcweir {
DBG_NAME(OTableConnection)57cdf0e10cSrcweir 	DBG_NAME(OTableConnection)
58cdf0e10cSrcweir 	//------------------------------------------------------------------------
59cdf0e10cSrcweir     OTableConnection::OTableConnection( OJoinTableView* _pContainer,const TTableConnectionData::value_type& _pTabConnData )
60cdf0e10cSrcweir 		:Window(_pContainer)
61cdf0e10cSrcweir 		,m_pData( _pTabConnData )
62cdf0e10cSrcweir 		,m_pParent( _pContainer )
63cdf0e10cSrcweir 		,m_bSelected( sal_False )
64cdf0e10cSrcweir 	{
65cdf0e10cSrcweir 		DBG_CTOR(OTableConnection,NULL);
66cdf0e10cSrcweir 		Init();
67cdf0e10cSrcweir 		Show();
68cdf0e10cSrcweir 	}
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	//------------------------------------------------------------------------
OTableConnection(const OTableConnection & _rConn)71cdf0e10cSrcweir 	OTableConnection::OTableConnection( const OTableConnection& _rConn ) : Window(_rConn.m_pParent)
72cdf0e10cSrcweir         ,m_pData(_rConn.GetData()->NewInstance())
73cdf0e10cSrcweir 	{
74cdf0e10cSrcweir 		DBG_CTOR(OTableConnection,NULL);
75cdf0e10cSrcweir 		*this = _rConn;
76cdf0e10cSrcweir 	}
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 	//------------------------------------------------------------------------
Init()79cdf0e10cSrcweir 	void OTableConnection::Init()
80cdf0e10cSrcweir 	{
81cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
82cdf0e10cSrcweir 		// Linienliste mit Defaults initialisieren
83cdf0e10cSrcweir 		OConnectionLineDataVec* pLineData = GetData()->GetConnLineDataList();
84cdf0e10cSrcweir 		OConnectionLineDataVec::const_iterator aIter = pLineData->begin();
85cdf0e10cSrcweir         OConnectionLineDataVec::const_iterator aEnd = pLineData->end();
86cdf0e10cSrcweir 		m_vConnLine.reserve(pLineData->size());
87cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
88cdf0e10cSrcweir 			m_vConnLine.push_back( new OConnectionLine(this, *aIter) );
89cdf0e10cSrcweir 	}
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 	//------------------------------------------------------------------------
CreateConnLine(const OConnectionLine & rConnLine)92cdf0e10cSrcweir 	OConnectionLine* OTableConnection::CreateConnLine( const OConnectionLine& rConnLine )
93cdf0e10cSrcweir 	{
94cdf0e10cSrcweir 		return new OConnectionLine( rConnLine );
95cdf0e10cSrcweir 	}
96cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
clearLineData()97cdf0e10cSrcweir 	void OTableConnection::clearLineData()
98cdf0e10cSrcweir 	{
99cdf0e10cSrcweir         ::std::vector<OConnectionLine*>::iterator aLineEnd = m_vConnLine.end();
100cdf0e10cSrcweir 		for(::std::vector<OConnectionLine*>::iterator aLineIter = m_vConnLine.begin();aLineIter != aLineEnd;++aLineIter)
101cdf0e10cSrcweir 			delete *aLineIter;
102cdf0e10cSrcweir 		m_vConnLine.clear();
103cdf0e10cSrcweir 	}
104cdf0e10cSrcweir 	//------------------------------------------------------------------------
UpdateLineList()105cdf0e10cSrcweir 	void OTableConnection::UpdateLineList()
106cdf0e10cSrcweir 	{
107cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
108cdf0e10cSrcweir 		// Linienliste loeschen
109cdf0e10cSrcweir 		clearLineData();
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 		Init();
112cdf0e10cSrcweir 	}
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	//------------------------------------------------------------------------
operator =(const OTableConnection & rConn)115cdf0e10cSrcweir 	OTableConnection& OTableConnection::operator=( const OTableConnection& rConn )
116cdf0e10cSrcweir 	{
117cdf0e10cSrcweir 		if( &rConn == this )
118cdf0e10cSrcweir 			return *this;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 		// Linienliste loeschen
121cdf0e10cSrcweir 		clearLineData();
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 		// Linienliste kopieren
124cdf0e10cSrcweir 		if(! rConn.GetConnLineList()->empty() )
125cdf0e10cSrcweir 		{
126cdf0e10cSrcweir 			const ::std::vector<OConnectionLine*>* pLine = rConn.GetConnLineList();
127cdf0e10cSrcweir 			::std::vector<OConnectionLine*>::const_iterator aIter = pLine->begin();
128cdf0e10cSrcweir             ::std::vector<OConnectionLine*>::const_iterator aEnd = pLine->end();
129cdf0e10cSrcweir 			m_vConnLine.reserve(pLine->size());
130cdf0e10cSrcweir 			for(;aIter != aEnd;++aIter)
131cdf0e10cSrcweir 				m_vConnLine.push_back( CreateConnLine( **aIter ));
132cdf0e10cSrcweir 		}
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 		// da mir die Daten nicht gehoeren, loesche ich die alten nicht
135cdf0e10cSrcweir 		m_pData->CopyFrom(*rConn.GetData());
136cdf0e10cSrcweir 			// CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 		m_bSelected = rConn.m_bSelected;
139cdf0e10cSrcweir 		m_pParent = rConn.m_pParent;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 		return *this;
142cdf0e10cSrcweir 	}
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 	//------------------------------------------------------------------------
RecalcLines()146cdf0e10cSrcweir 	bool OTableConnection::RecalcLines()
147cdf0e10cSrcweir 	{
148cdf0e10cSrcweir 		// call RecalcLines on each line
149cdf0e10cSrcweir 		::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),::std::mem_fun(&OConnectionLine::RecalcLine));
150cdf0e10cSrcweir 		return true;
151cdf0e10cSrcweir 	}
152cdf0e10cSrcweir 	//------------------------------------------------------------------------
GetSourceWin() const153cdf0e10cSrcweir 	OTableWindow* OTableConnection::GetSourceWin() const
154cdf0e10cSrcweir 	{
155cdf0e10cSrcweir         TTableWindowData::value_type pRef = GetData()->getReferencingTable();
156cdf0e10cSrcweir         OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
157cdf0e10cSrcweir         if ( !pRet )
158cdf0e10cSrcweir         {
159cdf0e10cSrcweir             pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
160cdf0e10cSrcweir         }
161cdf0e10cSrcweir 		return pRet;
162cdf0e10cSrcweir 	}
163cdf0e10cSrcweir 	//------------------------------------------------------------------------
GetDestWin() const164cdf0e10cSrcweir 	OTableWindow* OTableConnection::GetDestWin() const
165cdf0e10cSrcweir 	{
166cdf0e10cSrcweir         TTableWindowData::value_type pRef = GetData()->getReferencedTable();
167cdf0e10cSrcweir         OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
168cdf0e10cSrcweir         if ( !pRet )
169cdf0e10cSrcweir         {
170cdf0e10cSrcweir             pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
171cdf0e10cSrcweir         }
172cdf0e10cSrcweir 		return pRet;
173cdf0e10cSrcweir 	}
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	//------------------------------------------------------------------------
Select()176cdf0e10cSrcweir 	void OTableConnection::Select()
177cdf0e10cSrcweir 	{
178cdf0e10cSrcweir 		m_bSelected = sal_True;
179cdf0e10cSrcweir 		m_pParent->Invalidate( GetBoundingRect(), INVALIDATE_NOCHILDREN);
180cdf0e10cSrcweir 	}
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 	//------------------------------------------------------------------------
Deselect()183cdf0e10cSrcweir 	void OTableConnection::Deselect()
184cdf0e10cSrcweir 	{
185cdf0e10cSrcweir 		m_bSelected = sal_False;
186cdf0e10cSrcweir 		InvalidateConnection();
187cdf0e10cSrcweir 	}
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 	//------------------------------------------------------------------------
CheckHit(const Point & rMousePos) const190cdf0e10cSrcweir 	sal_Bool OTableConnection::CheckHit( const Point& rMousePos ) const
191cdf0e10cSrcweir 	{
192cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
193cdf0e10cSrcweir 		// check if the point hit our line
194cdf0e10cSrcweir 		::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(m_vConnLine.begin(),
195cdf0e10cSrcweir 																		 m_vConnLine.end(),
196cdf0e10cSrcweir 																		 ::std::bind2nd(TConnectionLineCheckHitFunctor(),rMousePos));
197cdf0e10cSrcweir 		return aIter != m_vConnLine.end();
198cdf0e10cSrcweir 	}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 	//------------------------------------------------------------------------
InvalidateConnection()201cdf0e10cSrcweir 	bool OTableConnection::InvalidateConnection()
202cdf0e10cSrcweir 	{
203cdf0e10cSrcweir 		Rectangle rcBounding = GetBoundingRect();
204cdf0e10cSrcweir 		rcBounding.Bottom() += 1;
205cdf0e10cSrcweir 		rcBounding.Right() += 1;
206cdf0e10cSrcweir 			// ich glaube, dass sich Invalidate und Draw(Rectangle) nicht konsistent verhalten : jedenfalls waere dadurch zu
207cdf0e10cSrcweir 			// erklaeren, warum ohne diesen Fake hier beim Loeschen einer Connection ein Strich an ihrem unteren Ende stehen bleibt :
208cdf0e10cSrcweir 			// Invalidate erfasst dabei offensichtlich eine Pixelzeile weniger als Draw.
209cdf0e10cSrcweir 			// Oder alles haengt ganz anders zusammen ... jedenfalls klappt es so ...
210cdf0e10cSrcweir 		m_pParent->Invalidate( rcBounding, INVALIDATE_NOCHILDREN );
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 		return true;
213cdf0e10cSrcweir 	}
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	//------------------------------------------------------------------------
GetBoundingRect() const216cdf0e10cSrcweir 	Rectangle OTableConnection::GetBoundingRect() const
217cdf0e10cSrcweir 	{
218cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
219cdf0e10cSrcweir 		// Aus allen Linien das umgebende Rechteck bestimmen
220cdf0e10cSrcweir 		Rectangle aBoundingRect( Point(0,0), Point(0,0) );
221cdf0e10cSrcweir 		Rectangle aTempRect;
222cdf0e10cSrcweir         ::std::vector<OConnectionLine*>::const_iterator aEnd = m_vConnLine.end();
223cdf0e10cSrcweir 		for(::std::vector<OConnectionLine*>::const_iterator aIter = m_vConnLine.begin();aIter != aEnd;++aIter)
224cdf0e10cSrcweir 		{
225cdf0e10cSrcweir 			aTempRect = (*aIter)->GetBoundingRect();
226cdf0e10cSrcweir 
227cdf0e10cSrcweir 			//////////////////////////////////////////////////////////////////////
228cdf0e10cSrcweir 			// Ist das BoundingRect dieser Linie gueltig?
229cdf0e10cSrcweir 			if( (aTempRect.GetWidth()!=1) && (aTempRect.GetHeight()!=1) )
230cdf0e10cSrcweir 			{
231cdf0e10cSrcweir 				if( (aBoundingRect.GetWidth()==1) && (aBoundingRect.GetHeight()==1) )
232cdf0e10cSrcweir 					aBoundingRect = aTempRect;
233cdf0e10cSrcweir 				else
234cdf0e10cSrcweir 					aBoundingRect.Union( aTempRect );
235cdf0e10cSrcweir 			}
236cdf0e10cSrcweir 		}
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 		return aBoundingRect;
239cdf0e10cSrcweir 	}
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 	//------------------------------------------------------------------------
Draw(const Rectangle &)242cdf0e10cSrcweir 	void OTableConnection::Draw( const Rectangle& /*rRect*/ )
243cdf0e10cSrcweir 	{
244cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
245cdf0e10cSrcweir 		// Linien zeichnen
246cdf0e10cSrcweir 		::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),TConnectionLineDrawFunctor(m_pParent));
247cdf0e10cSrcweir 	}
248cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
249cdf0e10cSrcweir }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 
253