xref: /trunk/main/dbaccess/source/ui/querydesign/TableConnection.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_dbaccess.hxx"
30 #ifndef DBAUI_TABLECONNECTION_HXX
31 #include "TableConnection.hxx"
32 #endif
33 #ifndef DBAUI_CONNECTIONLINE_HXX
34 #include "ConnectionLine.hxx"
35 #endif
36 #ifndef DBAUI_TABLECONNECTIONDATA_HXX
37 #include "TableConnectionData.hxx"
38 #endif
39 #ifndef DBAUI_JOINTABLEVIEW_HXX
40 #include "JoinTableView.hxx"
41 #endif
42 #ifndef _COMPHELPER_STLTYPES_HXX_
43 #include <comphelper/stl_types.hxx>
44 #endif
45 #ifndef DBACCESS_CONNECTIONLINEACCESS_HXX
46 #include "ConnectionLineAccess.hxx"
47 #endif
48 #include <algorithm>
49 
50 
51 using namespace dbaui;
52 using namespace comphelper;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::accessibility;
55 
56 //========================================================================
57 // class OTableConnection
58 //========================================================================
59 namespace dbaui
60 {
61     DBG_NAME(OTableConnection)
62     //------------------------------------------------------------------------
63     OTableConnection::OTableConnection( OJoinTableView* _pContainer,const TTableConnectionData::value_type& _pTabConnData )
64         :Window(_pContainer)
65         ,m_pData( _pTabConnData )
66         ,m_pParent( _pContainer )
67         ,m_bSelected( sal_False )
68     {
69         DBG_CTOR(OTableConnection,NULL);
70         Init();
71         Show();
72     }
73 
74     //------------------------------------------------------------------------
75     OTableConnection::OTableConnection( const OTableConnection& _rConn ) : Window(_rConn.m_pParent)
76         ,m_pData(_rConn.GetData()->NewInstance())
77     {
78         DBG_CTOR(OTableConnection,NULL);
79         *this = _rConn;
80     }
81 
82     //------------------------------------------------------------------------
83     void OTableConnection::Init()
84     {
85         //////////////////////////////////////////////////////////////////////
86         // Linienliste mit Defaults initialisieren
87         OConnectionLineDataVec* pLineData = GetData()->GetConnLineDataList();
88         OConnectionLineDataVec::const_iterator aIter = pLineData->begin();
89         OConnectionLineDataVec::const_iterator aEnd = pLineData->end();
90         m_vConnLine.reserve(pLineData->size());
91         for(;aIter != aEnd;++aIter)
92             m_vConnLine.push_back( new OConnectionLine(this, *aIter) );
93     }
94 
95     //------------------------------------------------------------------------
96     OConnectionLine* OTableConnection::CreateConnLine( const OConnectionLine& rConnLine )
97     {
98         return new OConnectionLine( rConnLine );
99     }
100     // -----------------------------------------------------------------------------
101     void OTableConnection::clearLineData()
102     {
103         ::std::vector<OConnectionLine*>::iterator aLineEnd = m_vConnLine.end();
104         for(::std::vector<OConnectionLine*>::iterator aLineIter = m_vConnLine.begin();aLineIter != aLineEnd;++aLineIter)
105             delete *aLineIter;
106         m_vConnLine.clear();
107     }
108     //------------------------------------------------------------------------
109     void OTableConnection::UpdateLineList()
110     {
111         //////////////////////////////////////////////////////////////////////
112         // Linienliste loeschen
113         clearLineData();
114 
115         Init();
116     }
117 
118     //------------------------------------------------------------------------
119     OTableConnection& OTableConnection::operator=( const OTableConnection& rConn )
120     {
121         if( &rConn == this )
122             return *this;
123 
124         // Linienliste loeschen
125         clearLineData();
126 
127         // Linienliste kopieren
128         if(! rConn.GetConnLineList()->empty() )
129         {
130             const ::std::vector<OConnectionLine*>* pLine = rConn.GetConnLineList();
131             ::std::vector<OConnectionLine*>::const_iterator aIter = pLine->begin();
132             ::std::vector<OConnectionLine*>::const_iterator aEnd = pLine->end();
133             m_vConnLine.reserve(pLine->size());
134             for(;aIter != aEnd;++aIter)
135                 m_vConnLine.push_back( CreateConnLine( **aIter ));
136         }
137 
138         // da mir die Daten nicht gehoeren, loesche ich die alten nicht
139         m_pData->CopyFrom(*rConn.GetData());
140             // CopyFrom ist virtuell, damit ist es kein Problem, wenn m_pData von einem von OTableConnectionData abgeleiteten Typ ist
141 
142         m_bSelected = rConn.m_bSelected;
143         m_pParent = rConn.m_pParent;
144 
145         return *this;
146     }
147 
148 
149     //------------------------------------------------------------------------
150     bool OTableConnection::RecalcLines()
151     {
152         // call RecalcLines on each line
153         ::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),::std::mem_fun(&OConnectionLine::RecalcLine));
154         return true;
155     }
156     //------------------------------------------------------------------------
157     OTableWindow* OTableConnection::GetSourceWin() const
158     {
159         TTableWindowData::value_type pRef = GetData()->getReferencingTable();
160         OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
161         if ( !pRet )
162         {
163             pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
164         }
165         return pRet;
166     }
167     //------------------------------------------------------------------------
168     OTableWindow* OTableConnection::GetDestWin() const
169     {
170         TTableWindowData::value_type pRef = GetData()->getReferencedTable();
171         OTableWindow* pRet = m_pParent->GetTabWindow( pRef->GetWinName() );
172         if ( !pRet )
173         {
174             pRet = m_pParent->GetTabWindow( pRef->GetComposedName() );
175         }
176         return pRet;
177     }
178 
179     //------------------------------------------------------------------------
180     void OTableConnection::Select()
181     {
182         m_bSelected = sal_True;
183         m_pParent->Invalidate( GetBoundingRect(), INVALIDATE_NOCHILDREN);
184     }
185 
186     //------------------------------------------------------------------------
187     void OTableConnection::Deselect()
188     {
189         m_bSelected = sal_False;
190         InvalidateConnection();
191     }
192 
193     //------------------------------------------------------------------------
194     sal_Bool OTableConnection::CheckHit( const Point& rMousePos ) const
195     {
196         //////////////////////////////////////////////////////////////////////
197         // check if the point hit our line
198         ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(m_vConnLine.begin(),
199                                                                          m_vConnLine.end(),
200                                                                          ::std::bind2nd(TConnectionLineCheckHitFunctor(),rMousePos));
201         return aIter != m_vConnLine.end();
202     }
203 
204     //------------------------------------------------------------------------
205     bool OTableConnection::InvalidateConnection()
206     {
207         Rectangle rcBounding = GetBoundingRect();
208         rcBounding.Bottom() += 1;
209         rcBounding.Right() += 1;
210             // ich glaube, dass sich Invalidate und Draw(Rectangle) nicht konsistent verhalten : jedenfalls waere dadurch zu
211             // erklaeren, warum ohne diesen Fake hier beim Loeschen einer Connection ein Strich an ihrem unteren Ende stehen bleibt :
212             // Invalidate erfasst dabei offensichtlich eine Pixelzeile weniger als Draw.
213             // Oder alles haengt ganz anders zusammen ... jedenfalls klappt es so ...
214         m_pParent->Invalidate( rcBounding, INVALIDATE_NOCHILDREN );
215 
216         return true;
217     }
218 
219     //------------------------------------------------------------------------
220     Rectangle OTableConnection::GetBoundingRect() const
221     {
222         //////////////////////////////////////////////////////////////////////
223         // Aus allen Linien das umgebende Rechteck bestimmen
224         Rectangle aBoundingRect( Point(0,0), Point(0,0) );
225         Rectangle aTempRect;
226         ::std::vector<OConnectionLine*>::const_iterator aEnd = m_vConnLine.end();
227         for(::std::vector<OConnectionLine*>::const_iterator aIter = m_vConnLine.begin();aIter != aEnd;++aIter)
228         {
229             aTempRect = (*aIter)->GetBoundingRect();
230 
231             //////////////////////////////////////////////////////////////////////
232             // Ist das BoundingRect dieser Linie gueltig?
233             if( (aTempRect.GetWidth()!=1) && (aTempRect.GetHeight()!=1) )
234             {
235                 if( (aBoundingRect.GetWidth()==1) && (aBoundingRect.GetHeight()==1) )
236                     aBoundingRect = aTempRect;
237                 else
238                     aBoundingRect.Union( aTempRect );
239             }
240         }
241 
242         return aBoundingRect;
243     }
244 
245     //------------------------------------------------------------------------
246     void OTableConnection::Draw( const Rectangle& /*rRect*/ )
247     {
248         //////////////////////////////////////////////////////////////////////
249         // Linien zeichnen
250         ::std::for_each(m_vConnLine.begin(),m_vConnLine.end(),TConnectionLineDrawFunctor(m_pParent));
251     }
252     // -----------------------------------------------------------------------------
253 }
254 
255 
256 
257