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