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