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