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