xref: /trunk/main/dbaccess/source/ui/querydesign/JoinTableView.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_QUERYTABLEVIEW_HXX
31 #include "JoinTableView.hxx"
32 #endif
33 #ifndef _TOOLS_DEBUG_HXX
34 #include <tools/debug.hxx>
35 #endif
36 #ifndef DBAUI_QUERYCONTROLLER_HXX
37 #include "querycontroller.hxx"
38 #endif
39 #ifndef DBAUI_JOINDESIGNVIEW_HXX
40 #include "JoinDesignView.hxx"
41 #endif
42 #ifndef _DBU_QRY_HRC_
43 #include "dbu_qry.hrc"
44 #endif
45 #ifndef DBAUI_TABLEWINDOW_HXX
46 #include "TableWindow.hxx"
47 #endif
48 //#ifndef DBAUI_QUERY_TABLEWINDOWDATA_HXX
49 //#include "QTableWindowData.hxx"
50 //#endif
51 #ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
52 #include "TableWindowListBox.hxx"
53 #endif
54 #ifndef DBAUI_TABLECONNECTION_HXX
55 #include "TableConnection.hxx"
56 #endif
57 #ifndef DBAUI_TABLECONNECTIONDATA_HXX
58 #include "TableConnectionData.hxx"
59 #endif
60 #ifndef DBAUI_CONNECTIONLINE_HXX
61 #include "ConnectionLine.hxx"
62 #endif
63 #ifndef DBAUI_CONNECTIONLINEDATA_HXX
64 #include "ConnectionLineData.hxx"
65 #endif
66 #ifndef DBACCESS_UI_BROWSER_ID_HXX
67 #include "browserids.hxx"
68 #endif
69 #ifndef _URLBMK_HXX
70 #include <svl/urlbmk.hxx>
71 #endif
72 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
73 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
74 #endif
75 #ifndef DBAUI_OQUERYMOVETABWINUNDOACT_HXX
76 #include "QueryMoveTabWinUndoAct.hxx"
77 #endif
78 #ifndef DBAUI_QUERYSIZETABWINUNDOACT_HXX
79 #include "QuerySizeTabWinUndoAct.hxx"
80 #endif
81 #ifndef _SV_SVAPP_HXX
82 #include <vcl/svapp.hxx>
83 #endif
84 #ifndef DBAUI_TABLEWINDOWDATA_HXX
85 #include "TableWindowData.hxx"
86 #endif
87 #ifndef DBACCESS_JACCESS_HXX
88 #include "JAccess.hxx"
89 #endif
90 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
91 #include <com/sun/star/accessibility/XAccessible.hpp>
92 #endif
93 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
94 #include <com/sun/star/accessibility/AccessibleRole.hpp>
95 #endif
96 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
97 #ifndef DBAUI_TOOLS_HXX
98 #include "UITools.hxx"
99 #endif
100 #include <cppuhelper/exc_hlp.hxx>
101 #include <tools/diagnose_ex.h>
102 #include <boost/bind.hpp>
103 #include <algorithm>
104 #include <functional>
105 
106 using namespace dbaui;
107 using namespace ::com::sun::star::uno;
108 using namespace ::com::sun::star::sdbc;
109 using namespace ::com::sun::star::accessibility;
110 using namespace ::com::sun::star::container;
111 using namespace ::com::sun::star::lang;
112 
113 #define LINE_SIZE           50
114 ////////////////////////////////////////////////////////////////
115 // Konstanten fuer das Fensterlayout
116 #define TABWIN_SPACING_X    17
117 #define TABWIN_SPACING_Y    17
118 
119 #define TABWIN_WIDTH_STD    120
120 #define TABWIN_HEIGHT_STD   120
121 
122 DBG_NAME(OScrollWindowHelper)
123 OScrollWindowHelper::OScrollWindowHelper( Window* pParent) : Window( pParent)
124     ,m_aHScrollBar( this, WB_HSCROLL|WB_REPEAT|WB_DRAG )
125     ,m_aVScrollBar( this, WB_VSCROLL|WB_REPEAT|WB_DRAG )
126     ,m_pCornerWindow(new ScrollBarBox(this, WB_3DLOOK))
127     ,m_pTableView(NULL)
128 {
129     DBG_CTOR(OScrollWindowHelper,NULL);
130 
131     //////////////////////////////////////////////////////////////////////
132     // ScrollBars
133 
134     GetHScrollBar()->SetRange( Range(0, 1000) );
135     GetVScrollBar()->SetRange( Range(0, 1000) );
136 
137     GetHScrollBar()->SetLineSize( LINE_SIZE );
138     GetVScrollBar()->SetLineSize( LINE_SIZE );
139 
140     GetHScrollBar()->Show();
141     GetVScrollBar()->Show();
142     m_pCornerWindow->Show();
143 
144     // normally we should be SCROLL_PANE
145     SetAccessibleRole(AccessibleRole::SCROLL_PANE);
146 }
147 
148 // -----------------------------------------------------------------------------
149 OScrollWindowHelper::~OScrollWindowHelper()
150 {
151     DBG_DTOR(OScrollWindowHelper,NULL);
152     ::std::auto_ptr<Window> aTemp(m_pCornerWindow);
153     m_pCornerWindow = NULL;
154     m_pTableView = NULL;
155 }
156 
157 // -----------------------------------------------------------------------------
158 void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
159 {
160     m_pTableView = _pTableView;
161     //////////////////////////////////////////////////////////////////////
162     // ScrollBars
163     GetHScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
164     GetVScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
165 }
166 // -----------------------------------------------------------------------------
167 void OScrollWindowHelper::resetRange(const Point& _aSize)
168 {
169     Point aPos = PixelToLogic(_aSize);
170     GetHScrollBar()->SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
171     GetVScrollBar()->SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
172 }
173 //------------------------------------------------------------------------------
174 void OScrollWindowHelper::Resize()
175 {
176     Window::Resize();
177 
178     Size aTotalOutputSize = GetOutputSizePixel();
179     long nHScrollHeight = GetHScrollBar()->GetSizePixel().Height();
180     long nVScrollWidth = GetVScrollBar()->GetSizePixel().Width();
181 
182     GetHScrollBar()->SetPosSizePixel(
183         Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
184         Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
185         );
186 
187     GetVScrollBar()->SetPosSizePixel(
188         Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
189         Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
190         );
191 
192     m_pCornerWindow->SetPosSizePixel(
193         Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
194         Size( nVScrollWidth, nHScrollHeight )
195         );
196 
197     GetHScrollBar()->SetPageSize( aTotalOutputSize.Width() );
198     GetHScrollBar()->SetVisibleSize( aTotalOutputSize.Width() );
199 
200     GetVScrollBar()->SetPageSize( aTotalOutputSize.Height() );
201     GetVScrollBar()->SetVisibleSize( aTotalOutputSize.Height() );
202 
203     // adjust the ranges of the scrollbars if neccessary
204     long lRange = GetHScrollBar()->GetRange().Max() - GetHScrollBar()->GetRange().Min();
205     if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
206         GetHScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar()->GetRange().Min());
207 
208     lRange = GetVScrollBar()->GetRange().Max() - GetVScrollBar()->GetRange().Min();
209     if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
210         GetVScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar()->GetRange().Min());
211 
212     m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
213 }
214 // -----------------------------------------------------------------------------
215 // -----------------------------------------------------------------------------
216 //==================================================================
217 // class OJoinTableView
218 //==================================================================
219 
220 //const long WINDOW_WIDTH = 1000;
221 //const long WINDOW_HEIGHT = 1000;
222 DBG_NAME(OJoinTableView);
223 //------------------------------------------------------------------------------
224 OJoinTableView::OJoinTableView( Window* pParent, OJoinDesignView* pView )
225     :Window( pParent,WB_BORDER )
226     ,DropTargetHelper(this)
227     ,m_aDragOffset( Point(0,0) )
228     ,m_aScrollOffset( Point(0,0) )
229     ,m_pDragWin( NULL )
230     ,m_pSizingWin( NULL )
231     ,m_pSelectedConn( NULL )
232     ,m_bTrackingInitiallyMoved(sal_False)
233     ,m_pLastFocusTabWin(NULL)
234     ,m_pView( pView )
235     ,m_pAccessible(NULL)
236 {
237     DBG_CTOR(OJoinTableView,NULL);
238     SetSizePixel( Size(1000, 1000) );
239 
240     InitColors();
241 
242     m_aDragScrollTimer.SetTimeoutHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
243 }
244 
245 //------------------------------------------------------------------------------
246 OJoinTableView::~OJoinTableView()
247 {
248     DBG_DTOR(OJoinTableView,NULL);
249     if( m_pAccessible )
250     {
251         m_pAccessible->clearTableView();
252         m_pAccessible = NULL;
253     }
254     //////////////////////////////////////////////////////////////////////
255     // Listen loeschen
256     clearLayoutInformation();
257 }
258 //------------------------------------------------------------------------------
259 IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
260 {
261     //////////////////////////////////////////////////////////////////////
262     // Alle Fenster verschieben
263     ScrollPane( pScrollBar->GetDelta(), (pScrollBar == GetHScrollBar()), sal_False );
264 
265     return 0;
266 }
267 //------------------------------------------------------------------------------
268 void OJoinTableView::Resize()
269 {
270     DBG_CHKTHIS(OJoinTableView,NULL);
271     Window::Resize();
272     m_aOutputSize = GetSizePixel();
273 
274     // tab win positions may not be up-to-date
275     if (m_aTableMap.empty())
276         // no tab wins ...
277         return;
278 
279     // we have at least one table so resize it
280     m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
281     m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
282 
283     OTableWindow* pCheck = m_aTableMap.begin()->second;
284     Point aRealPos = pCheck->GetPosPixel();
285     Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
286 
287     if (aRealPos == aAssumedPos)
288         // all ok
289         return;
290 
291     OTableWindowMapIterator aIter = m_aTableMap.begin();
292     OTableWindowMapIterator aEnd = m_aTableMap.end();
293     for(;aIter != aEnd;++aIter)
294     {
295         OTableWindow* pCurrent = aIter->second;
296         Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
297         pCurrent->SetPosPixel(aPos);
298     }
299 }
300 //------------------------------------------------------------------------------
301 sal_uLong OJoinTableView::GetTabWinCount()
302 {
303     DBG_CHKTHIS(OJoinTableView,NULL);
304     return m_aTableMap.size();
305 }
306 
307 //------------------------------------------------------------------------------
308 bool OJoinTableView::RemoveConnection( OTableConnection* _pConn,sal_Bool _bDelete )
309 {
310     DBG_CHKTHIS(OJoinTableView,NULL);
311     DeselectConn(_pConn);
312 
313     // to force a redraw
314     _pConn->InvalidateConnection();
315 
316     m_pView->getController().removeConnectionData( _pConn->GetData() );
317 
318     m_vTableConnection.erase(
319                         ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn) );
320 
321     modified();
322     if ( m_pAccessible )
323         m_pAccessible->notifyAccessibleEvent(   AccessibleEventId::CHILD,
324                                                 makeAny(_pConn->GetAccessible()),
325                                                 Any());
326     if ( _bDelete )
327     {
328         delete _pConn;
329     }
330 
331     return true;
332 }
333 
334 //------------------------------------------------------------------------
335 OTableWindow* OJoinTableView::GetTabWindow( const String& rName )
336 {
337     DBG_CHKTHIS(OJoinTableView,NULL);
338     OTableWindowMapIterator aIter = m_aTableMap.find(rName);
339 
340     return aIter == m_aTableMap.end() ? NULL : aIter->second;
341 }
342 // -----------------------------------------------------------------------------
343 TTableWindowData::value_type OJoinTableView::createTableWindowData(const ::rtl::OUString& _rComposedName
344                                                                   ,const ::rtl::OUString& _sTableName
345                                                                   ,const ::rtl::OUString& _rWinName)
346 {
347     TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
348     OJoinDesignView* pParent = getDesignView();
349     try
350     {
351         if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
352         {
353             if ( pData->isValid() )
354                 onNoColumns_throw();
355             else
356                 pData.reset();
357         }
358     }
359     catch ( const SQLException& )
360     {
361         ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
362             pParent, pParent->getController().getORB() );
363     }
364     catch( const WrappedTargetException& e )
365     {
366         SQLException aSql;
367         if ( e.TargetException >>= aSql )
368             ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
369     }
370     catch( const Exception& )
371     {
372         DBG_UNHANDLED_EXCEPTION();
373     }
374     return pData;
375 }
376 // -----------------------------------------------------------------------------
377 OTableWindowData* OJoinTableView::CreateImpl(const ::rtl::OUString& _rComposedName
378                                              ,const ::rtl::OUString& _sTableName
379                                              ,const ::rtl::OUString& _rWinName)
380 {
381     return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
382 }
383 //------------------------------------------------------------------------------
384 void OJoinTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, sal_Bool /*bNewTable*/)
385 {
386     DBG_CHKTHIS(OJoinTableView,NULL);
387     OSL_ENSURE(_rComposedName.getLength(),"There must be a table name supplied!");
388 
389     TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
390 
391     //////////////////////////////////////////////////////////////////
392     // Neues Fenster in Fensterliste eintragen
393     OTableWindow* pNewTabWin = createWindow( pNewTabWinData );
394     if ( pNewTabWin->Init() )
395     {
396         m_pView->getController().getTableWindowData()->push_back( pNewTabWinData);
397         // when we already have a table with this name insert the full qualified one instead
398         if(m_aTableMap.find(rWinName) != m_aTableMap.end())
399             m_aTableMap[_rComposedName] = pNewTabWin;
400         else
401             m_aTableMap[rWinName] = pNewTabWin;
402 
403         SetDefaultTabWinPosSize( pNewTabWin );
404         pNewTabWin->Show();
405 
406         modified();
407         if ( m_pAccessible )
408             m_pAccessible->notifyAccessibleEvent(   AccessibleEventId::CHILD,
409                                                     Any(),
410                                                     makeAny(pNewTabWin->GetAccessible()));
411     }
412     else
413     {
414         pNewTabWin->clearListBox();
415         delete pNewTabWin;
416     }
417 }
418 
419 //------------------------------------------------------------------------------
420 void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
421 {
422     DBG_CHKTHIS(OJoinTableView,NULL);
423     //////////////////////////////////////////////////////////////////////
424     // first delete all connections of this window to others
425     bool bRemove = true;
426     TTableWindowData::value_type pData = pTabWin->GetData();
427     sal_Int32 nCount = m_vTableConnection.size();
428     ::std::vector<OTableConnection*>::reverse_iterator aIter = m_vTableConnection.rbegin();
429     while(aIter != m_vTableConnection.rend() && bRemove)
430     {
431         OTableConnection* pTabConn = (*aIter);
432         if(
433             ( pData == pTabConn->GetData()->getReferencingTable())      ||
434             ( pData == pTabConn->GetData()->getReferencedTable())
435         )
436         {
437           bRemove = RemoveConnection( pTabConn ,sal_True);
438           aIter = m_vTableConnection.rbegin();
439         }
440         else
441             ++aIter;
442     }
443 
444     //////////////////////////////////////////////////////////////////////
445     // then delete the window itself
446     if ( bRemove )
447     {
448         if ( m_pAccessible )
449             m_pAccessible->notifyAccessibleEvent(   AccessibleEventId::CHILD,
450                                                     makeAny(pTabWin->GetAccessible()),Any()
451                                                     );
452 
453         pTabWin->Hide();
454         OJoinController& rController = m_pView->getController();
455         TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData()->begin(),rController.getTableWindowData()->end(),pData);
456         if(aFind != rController.getTableWindowData()->end())
457         {
458             rController.getTableWindowData()->erase(aFind);
459             rController.setModified(sal_True);
460         }
461 
462         String aWinName = pTabWin->GetWinName();
463         if(m_aTableMap.find(aWinName) != m_aTableMap.end())
464             m_aTableMap.erase( aWinName );
465         else
466             m_aTableMap.erase( pTabWin->GetComposedName() );
467 
468         if (pTabWin == m_pLastFocusTabWin)
469             m_pLastFocusTabWin = NULL;
470 
471         pTabWin->clearListBox();
472         delete pTabWin;
473 
474     }
475     if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
476         modified();
477 }
478 namespace
479 {
480     // -----------------------------------------------------------------------------
481     sal_Bool isScrollAllowed( OJoinTableView* _pView,long nDelta, sal_Bool bHoriz)
482     {
483         sal_Bool bRet = sal_True;
484         //////////////////////////////////////////////////////////////////////
485         // adjust ScrollBar-Positions
486         ScrollBar* pBar = _pView->GetVScrollBar();
487         if( bHoriz )
488             pBar = _pView->GetHScrollBar();
489 
490         long nOldThumbPos = pBar->GetThumbPos();
491         long nNewThumbPos = nOldThumbPos + nDelta;
492         if( nNewThumbPos < 0 )
493             nNewThumbPos = 0;// bRet = sal_False;
494         else if( nNewThumbPos > pBar->GetRangeMax() )
495             nNewThumbPos = pBar->GetRangeMax();// bRet = sal_False;
496 
497         if ( bHoriz )
498         {
499             if( nNewThumbPos == _pView->GetScrollOffset().X() )
500                 return sal_False;
501         }
502         else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
503             return sal_False;
504 
505         return bRet;
506     }
507     // -----------------------------------------------------------------------------
508     sal_Bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
509     {
510         _nScrollY = _nScrollX = 0;
511         // data about the tab win
512         Point aUpperLeft = _rPoint;
513         // normalize with respect to visibility
514         aUpperLeft -= _pView->GetScrollOffset();
515         //  aUpperLeft.Y() -= _pView->GetScrollOffset().Y();
516         Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
517 
518         // data about ourself
519         Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
520 
521         sal_Bool bVisbile = sal_True;
522         sal_Bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
523         sal_Bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
524         if (!bFitsHor || !bFitsVert)
525         {
526             // #100386# OJ
527             if (!bFitsHor)
528             {
529                 // ensure the visibility of the right border
530                 if ( aLowerRight.X() > aSize.Width() )
531                     _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
532 
533                 // ensure the visibility of the left border (higher priority)
534                 //  if ( (aUpperLeft.X() - _nScrollX) < 0 )
535                 if ( aUpperLeft.X() < 0 )
536                     _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
537             }
538 
539             if (!bFitsVert)
540             {
541                 // lower border
542                 if ( aLowerRight.Y() > aSize.Height() )
543                     _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
544                 // upper border
545                 //  if ( (aUpperLeft.Y() - _nScrollY) < 0 )
546                 if ( aUpperLeft.Y() < 0 )
547                     _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
548             }
549 
550             if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
551                 bVisbile = isScrollAllowed(_pView,_nScrollX, sal_True);
552 
553             if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
554                 bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, sal_False);
555 
556             if ( bVisbile )
557             {
558                 sal_Int32 nHRangeMax = _pView->GetHScrollBar()->GetRangeMax();
559                 sal_Int32 nVRangeMax = _pView->GetVScrollBar()->GetRangeMax();
560 
561                 if ( aSize.Width() + _pView->GetHScrollBar()->GetThumbPos() + _nScrollX > nHRangeMax )
562                     bVisbile = sal_False;
563                 if ( bVisbile && aSize.Height() + _pView->GetVScrollBar()->GetThumbPos() + _nScrollY > nVRangeMax )
564                     bVisbile = sal_False;
565             }
566         }
567 
568 
569         return bVisbile;
570     }
571 } // end of ano namespace
572 // -----------------------------------------------------------------------------
573 sal_Bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
574 {
575     long nX,nY;
576     return getMovementImpl(this,_rPoint,_rSize,nX,nY);
577 }
578 //------------------------------------------------------------------------------
579 void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
580 {
581     // data about the tab win
582     TTableWindowData::value_type pData = _pWin->GetData();
583     //  Point aUpperLeft = pData->GetPosition();
584     EnsureVisible( pData->GetPosition() , pData->GetSize());
585     Invalidate(INVALIDATE_NOCHILDREN);
586 }
587 //------------------------------------------------------------------------------
588 void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
589 {
590     long nScrollX,nScrollY;
591 
592     if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
593     {
594         sal_Bool bVisbile = sal_True;
595         if (nScrollX)
596             bVisbile = ScrollPane(nScrollX, sal_True, sal_True);
597 
598         if (nScrollY)
599             bVisbile = bVisbile && ScrollPane(nScrollY, sal_False, sal_True);
600     }
601 }
602 
603 //------------------------------------------------------------------------------
604 void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
605 {
606     DBG_CHKTHIS(OJoinTableView,NULL);
607     //////////////////////////////////////////////////////////////////
608     // Position bestimmen:
609     // Das Fenster wird in Zeilen der Hoehe TABWIN_SPACING_Y+TABWIN_HEIGTH_STD aufgeteilt.
610     // Dann wird fuer jede Zeile geprueft, ob noch Platz fuer ein weiteres Fenster ist.
611     // Wenn kein Platz ist, wird die naechste Zeile ueberprueft.
612     Size aOutSize = GetSizePixel();
613     Point aNewPos( 0,0 );
614     sal_uInt16 nRow = 0;
615     sal_Bool bEnd = sal_False;
616     while( !bEnd )
617     {
618         //////////////////////////////////////////////////////////////////
619         // Neue Position auf Zeilenbeginn setzen
620         aNewPos.X() = TABWIN_SPACING_X;
621         aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
622 
623         //////////////////////////////////////////////////////////////////
624         // Rectangle fuer die jeweilige Zeile bestimmen
625         Rectangle aRowRect( Point(0,0), aOutSize );
626         aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
627         aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
628 
629         //////////////////////////////////////////////////////////////////
630         // Belegte Bereiche dieser Zeile pruefen
631         OTableWindow* pOtherTabWin;// = GetTabWinMap()->First();
632         OTableWindowMapIterator aIter = m_aTableMap.begin();
633         OTableWindowMapIterator aEnd = m_aTableMap.end();
634         for(;aIter != aEnd;++aIter)
635         {
636             pOtherTabWin = aIter->second;
637             Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
638 
639             if(
640                 ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
641                 ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
642               )
643             {
644                 //////////////////////////////////////////////////////////////////
645                 // TabWin liegt in der Zeile
646                 if( aOtherTabWinRect.Right()>aNewPos.X() )
647                     aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
648             }
649         }
650 
651         //////////////////////////////////////////////////////////////////
652         // Ist in dieser Zeile noch Platz?
653         if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
654         {
655             aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
656             bEnd = sal_True;
657         }
658         else
659         {
660             if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
661             {
662                 // insert it in the first row
663                 sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
664                 ++nCount;
665                 aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
666                 bEnd = sal_True;
667             }
668             else
669                 nRow++;
670 
671         }
672     }
673 
674     //////////////////////////////////////////////////////////////////
675     // Groesse bestimmen
676     Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
677 
678     // check if the new position in inside the scrollbars ranges
679     Point aBottom(aNewPos);
680     aBottom.X() += aNewSize.Width();
681     aBottom.Y() += aNewSize.Height();
682 
683     if(!GetHScrollBar()->GetRange().IsInside(aBottom.X()))
684         GetHScrollBar()->SetRange( Range(0, aBottom.X()) );
685     if(!GetVScrollBar()->GetRange().IsInside(aBottom.Y()))
686         GetVScrollBar()->SetRange( Range(0, aBottom.Y()) );
687 
688     pTabWin->SetPosSizePixel( aNewPos, aNewSize );
689 }
690 
691 //------------------------------------------------------------------------------
692 void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
693 {
694     DBG_CHKTHIS(OJoinTableView,NULL);
695     if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
696     {
697         // nehmen wir den worst-case an : die Farben haben sich geaendert, also
698         // mich anpassen
699         InitColors();
700         Invalidate(INVALIDATE_NOCHILDREN);
701         // durch das Invalidate werden auch die Connections neu gezeichnet, so dass die auch
702         // gleich in den neuen Farben dargestellt werden
703     }
704 }
705 
706 //------------------------------------------------------------------------------
707 void OJoinTableView::InitColors()
708 {
709     DBG_CHKTHIS(OJoinTableView,NULL);
710     // die Farben fuer die Darstellung sollten die Systemfarben sein
711     StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
712     SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
713 }
714 
715 //------------------------------------------------------------------------------
716 void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos  )
717 {
718     DBG_CHKTHIS(OJoinTableView,NULL);
719 
720     if (m_pView->getController().isReadOnly())
721         return;
722 
723     m_pDragWin = pTabWin;
724     SetPointer(Pointer(POINTER_MOVE));
725     Point aMousePos = ScreenToOutputPixel( rMousePos );
726     m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
727     m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
728     m_bTrackingInitiallyMoved = sal_False;
729     StartTracking();
730 }
731 
732 void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
733 {
734     DBG_CHKTHIS(OJoinTableView,NULL);
735     DeselectConn(GetSelectedConn());
736     BeginChildMove(pTabWin, rMousePos);
737 }
738 
739 //------------------------------------------------------------------------------
740 void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
741 {
742     DBG_CHKTHIS(OJoinTableView,NULL);
743 
744     if (m_pView->getController().isReadOnly())
745         return;
746 
747     SetPointer( rPointer );
748     m_pSizingWin = pTabWin;
749     StartTracking();
750 }
751 
752 //------------------------------------------------------------------------------
753 sal_Bool OJoinTableView::ScrollPane( long nDelta, sal_Bool bHoriz, sal_Bool bPaintScrollBars )
754 {
755     DBG_CHKTHIS(OJoinTableView,NULL);
756     sal_Bool bRet = sal_True;
757 
758     //////////////////////////////////////////////////////////////////////
759     // ScrollBar-Positionen anpassen
760     if( bPaintScrollBars )
761     {
762         if( bHoriz )
763         {
764             long nOldThumbPos = GetHScrollBar()->GetThumbPos();
765             long nNewThumbPos = nOldThumbPos + nDelta;
766             if( nNewThumbPos < 0 )
767             {
768                 nNewThumbPos = 0;
769                 bRet = sal_False;
770             }
771             if( nNewThumbPos > GetHScrollBar()->GetRange().Max() )
772             {
773                 nNewThumbPos = GetHScrollBar()->GetRange().Max();
774                 bRet = sal_False;
775             }
776             GetHScrollBar()->SetThumbPos( nNewThumbPos );
777             nDelta = GetHScrollBar()->GetThumbPos() - nOldThumbPos;
778         }
779         else
780         {
781             long nOldThumbPos = GetVScrollBar()->GetThumbPos();
782             long nNewThumbPos = nOldThumbPos+nDelta;
783             if( nNewThumbPos < 0 )
784             {
785                 nNewThumbPos = 0;
786                 bRet = sal_False;
787             }
788             if( nNewThumbPos > GetVScrollBar()->GetRange().Max() )
789             {
790                 nNewThumbPos = GetVScrollBar()->GetRange().Max();
791                 bRet = sal_False;
792             }
793             GetVScrollBar()->SetThumbPos( nNewThumbPos );
794             nDelta = GetVScrollBar()->GetThumbPos() - nOldThumbPos;
795         }
796     }
797 
798     //////////////////////////////////////////////////////////////////////
799     // Wenn ScrollOffset bereits an den Grenzen liegt, kein Neuzeichnen
800     if( (GetHScrollBar()->GetThumbPos()==m_aScrollOffset.X()) &&
801         (GetVScrollBar()->GetThumbPos()==m_aScrollOffset.Y()) )
802         return sal_False;
803 
804     //////////////////////////////////////////////////////////////////////
805     // ScrollOffset neu setzen
806     if (bHoriz)
807         m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
808     else
809         m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
810 
811     //////////////////////////////////////////////////////////////////////
812     // Alle Fenster verschieben
813     OTableWindow* pTabWin;
814     Point aPos;
815 
816     OTableWindowMapIterator aIter = m_aTableMap.begin();
817     OTableWindowMapIterator aEnd = m_aTableMap.end();
818     for(;aIter != aEnd;++aIter)
819     {
820         pTabWin = aIter->second;
821         aPos = pTabWin->GetPosPixel();
822 
823         if( bHoriz )
824             aPos.X() -= nDelta;
825         else aPos.Y() -= nDelta;
826 
827         pTabWin->SetPosPixel( aPos );
828     }
829 
830     Invalidate(); // INVALIDATE_NOCHILDREN
831 
832     return bRet;
833 }
834 
835 //------------------------------------------------------------------------------
836 void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
837 {
838     DBG_CHKTHIS(OJoinTableView,NULL);
839     HideTracking();
840 
841     if (rTEvt.IsTrackingEnded())
842     {
843         if( m_pDragWin )
844         {
845             if (m_aDragScrollTimer.IsActive())
846                 m_aDragScrollTimer.Stop();
847 
848             //////////////////////////////////////////////////////////////////////
849             // Position des Childs nach Verschieben anpassen
850             //////////////////////////////////////////////////////////////////////
851             // Fenster duerfen nicht aus Anzeigebereich herausbewegt werden
852             Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
853             Size aDragWinSize = m_pDragWin->GetSizePixel();
854             if( aDragWinPos.X() < 0 )
855                 aDragWinPos.X() = 0;
856             if( aDragWinPos.Y() < 0 )
857                 aDragWinPos.Y() = 0;
858             if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
859                 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
860             if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
861                 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
862             if( aDragWinPos.X() < 0 )
863                 aDragWinPos.X() = 0;
864             if( aDragWinPos.Y() < 0 )
865                 aDragWinPos.Y() = 0;
866             // TODO : nicht das Fenster neu positionieren, wenn es uebersteht, sondern einfach meinen Bereich erweitern
867 
868 
869             //////////////////////////////////////////////////////////////////////
870             // Fenster positionieren
871             EndTracking();
872             m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
873             // erst mal testen, ob ich mich ueberhaupt bewegt habe
874             // (das verhindert das Setzen des modified-Flags, wenn sich eigentlich gar nichts getan hat)
875             TTableWindowData::value_type pData = m_pDragWin->GetData();
876             if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
877             {
878                 // die alten logischen Koordinaten
879                 Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
880                 // neu positionieren
881                 m_pDragWin->SetPosPixel(aDragWinPos);
882                 TabWinMoved(m_pDragWin, ptOldPos);
883 
884                 m_pDragWin->GrabFocus();
885             }
886             m_pDragWin = NULL;
887             SetPointer(Pointer(POINTER_ARROW));
888         }
889         // else we handle the resizing
890         else if( m_pSizingWin )
891         {
892             SetPointer( Pointer() );
893             EndTracking();
894 
895             // die alten physikalischen Koordinaten
896 
897             Size szOld = m_pSizingWin->GetSizePixel();
898             Point ptOld = m_pSizingWin->GetPosPixel();
899             Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
900             m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
901             TabWinSized(m_pSizingWin, ptOld, szOld);
902 
903             m_pSizingWin->Invalidate( m_aSizingRect );
904             m_pSizingWin = NULL;
905         }
906     }
907     else if (rTEvt.IsTrackingCanceled())
908     {
909         if (m_aDragScrollTimer.IsActive())
910             m_aDragScrollTimer.Stop();
911         EndTracking();
912     }
913     else
914     {
915         if( m_pDragWin )
916         {
917             m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
918             // an Fenstergrenzen scrollen
919             ScrollWhileDragging();
920         }
921 
922         if( m_pSizingWin )
923         {
924             Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
925             m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
926             Update();
927             ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
928         }
929     }
930 }
931 
932 //------------------------------------------------------------------------------
933 void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
934 {
935     DBG_CHKTHIS(OJoinTableView,NULL);
936 }
937 
938 //------------------------------------------------------------------------------
939 void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
940 {
941     DBG_CHKTHIS(OJoinTableView,NULL);
942     GrabFocus();
943     Window::MouseButtonDown(rEvt);
944 }
945 
946 //------------------------------------------------------------------------------
947 void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
948 {
949     DBG_CHKTHIS(OJoinTableView,NULL);
950     Window::MouseButtonUp(rEvt);
951     //////////////////////////////////////////////////////////////////////
952     // Wurde eine Connection ausgewaehlt?
953     if( !m_vTableConnection.empty() )
954     {
955         DeselectConn(GetSelectedConn());
956 
957         ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
958         ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
959         for(;aIter != aEnd;++aIter)
960         {
961             if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
962             {
963                 SelectConn((*aIter));
964 
965                 // Doppelclick
966                 if( rEvt.GetClicks() == 2 )
967                     ConnDoubleClicked( (*aIter) );
968 
969                 break;
970             }
971         }
972     }
973 }
974 
975 //------------------------------------------------------------------------------
976 void OJoinTableView::KeyInput( const KeyEvent& rEvt )
977 {
978     DBG_CHKTHIS(OJoinTableView,NULL);
979     sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
980     sal_Bool   bShift = rEvt.GetKeyCode().IsShift();
981     sal_Bool   bCtrl = rEvt.GetKeyCode().IsMod1();
982 
983     if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
984     {
985         if (GetSelectedConn())
986             RemoveConnection( GetSelectedConn() ,sal_True);
987     }
988     else
989         Window::KeyInput( rEvt );
990 }
991 
992 //------------------------------------------------------------------------------
993 void OJoinTableView::DeselectConn(OTableConnection* pConn)
994 {
995     DBG_CHKTHIS(OJoinTableView,NULL);
996     if (!pConn || !pConn->IsSelected())
997         return;
998 
999     // die zugehoerigen Eitnraege in der ListBox des Tabellenfenster deselektieren
1000     OTableWindow* pWin = pConn->GetSourceWin();
1001     if (pWin && pWin->GetListBox())
1002         pWin->GetListBox()->SelectAll(sal_False);
1003 
1004     pWin = pConn->GetDestWin();
1005     if (pWin && pWin->GetListBox())
1006         pWin->GetListBox()->SelectAll(sal_False);
1007 
1008     pConn->Deselect();
1009     m_pSelectedConn = NULL;
1010 }
1011 
1012 //------------------------------------------------------------------------------
1013 void OJoinTableView::SelectConn(OTableConnection* pConn)
1014 {
1015     DBG_CHKTHIS(OJoinTableView,NULL);
1016     DeselectConn(GetSelectedConn());
1017 
1018     pConn->Select();
1019     m_pSelectedConn = pConn;
1020     GrabFocus(); // has to be called here because a table window may still be focused
1021 
1022     // die betroffenene Eintraege in den Windows selektieren
1023     OTableWindow* pConnSource = pConn->GetSourceWin();
1024     OTableWindow* pConnDest = pConn->GetDestWin();
1025     if (pConnSource && pConnDest)
1026     {
1027         OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
1028         OTableWindowListBox* pDestBox = pConnDest->GetListBox();
1029         if (pSourceBox && pDestBox)
1030         {
1031             pSourceBox->SelectAll(sal_False);
1032             pDestBox->SelectAll(sal_False);
1033 
1034             SvLBoxEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
1035             SvLBoxEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
1036 
1037             const ::std::vector<OConnectionLine*>* pLines = pConn->GetConnLineList();
1038             ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = pLines->rbegin();
1039             for(;aIter != pLines->rend();++aIter)
1040             {
1041                 if ((*aIter)->IsValid())
1042                 {
1043                     SvLBoxEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
1044                     if (pSourceEntry)
1045                     {
1046                         pSourceBox->Select(pSourceEntry, sal_True);
1047                         pSourceBox->MakeVisible(pSourceEntry);
1048                     }
1049 
1050                     SvLBoxEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
1051                     if (pDestEntry)
1052                     {
1053                         pDestBox->Select(pDestEntry, sal_True);
1054                         pDestBox->MakeVisible(pDestEntry);
1055                     }
1056 
1057                 }
1058             }
1059 
1060             if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
1061                 || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
1062                 // es wurde gescrollt -> neu zeichnen
1063                 Invalidate(INVALIDATE_NOCHILDREN);
1064         }
1065     }
1066 }
1067 //------------------------------------------------------------------------------
1068 void OJoinTableView::Paint( const Rectangle& rRect )
1069 {
1070     DBG_CHKTHIS(OJoinTableView,NULL);
1071     DrawConnections( rRect );
1072 }
1073 
1074 //------------------------------------------------------------------------------
1075 void OJoinTableView::InvalidateConnections()
1076 {
1077     DBG_CHKTHIS(OJoinTableView,NULL);
1078     //////////////////////////////////////////////////////////////////////
1079     // Die Joins zeichnen
1080     ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
1081         ::std::mem_fun(& OTableConnection::InvalidateConnection));
1082 }
1083 
1084 //------------------------------------------------------------------------------
1085 void OJoinTableView::DrawConnections( const Rectangle& rRect )
1086 {
1087     DBG_CHKTHIS(OJoinTableView,NULL);
1088     //////////////////////////////////////////////////////////////////////
1089     // Die Joins zeichnen
1090     ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
1091     // zum Schluss noch mal die selektierte ueber alle anderen drueber
1092     if (GetSelectedConn())
1093         GetSelectedConn()->Draw( rRect );
1094 }
1095 
1096 
1097 //------------------------------------------------------------------------------
1098 ::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
1099 {
1100     return ::std::find_if(  m_vTableConnection.begin(),
1101                             m_vTableConnection.end(),
1102                             ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1103 }
1104 // -----------------------------------------------------------------------------
1105 sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
1106 {
1107     return ::std::count_if( m_vTableConnection.begin(),
1108                             m_vTableConnection.end(),
1109                             ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1110 }
1111 //------------------------------------------------------------------------------
1112 sal_Bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
1113 {
1114     DBG_CHKTHIS(OJoinTableView,NULL);
1115     return getTableConnections(pFrom) != m_vTableConnection.end();
1116 }
1117 //------------------------------------------------------------------------
1118 void OJoinTableView::ClearAll()
1119 {
1120     DBG_CHKTHIS(OJoinTableView,NULL);
1121     SetUpdateMode(sal_False);
1122 
1123     HideTabWins();
1124 
1125     // und das selbe mit den Connections
1126     ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1127     ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1128     for(;aIter != aEnd;++aIter)
1129         RemoveConnection( *aIter ,sal_True);
1130     m_vTableConnection.clear();
1131 
1132     m_pLastFocusTabWin  = NULL;
1133     m_pSelectedConn     = NULL;
1134 
1135     // scroll to the upper left
1136     ScrollPane(-GetScrollOffset().X(), sal_True, sal_True);
1137     ScrollPane(-GetScrollOffset().Y(), sal_False, sal_True);
1138     Invalidate();
1139 }
1140 
1141 //------------------------------------------------------------------------
1142 sal_Bool OJoinTableView::ScrollWhileDragging()
1143 {
1144     DBG_CHKTHIS(OJoinTableView,NULL);
1145     DBG_ASSERT(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging darf nur waehrend Dragging eines Fensters aufgerufen werden !");
1146 
1147     // den Timer schon mal killen
1148     if (m_aDragScrollTimer.IsActive())
1149         m_aDragScrollTimer.Stop();
1150 
1151     Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
1152     Size aDragWinSize = m_pDragWin->GetSizePixel();
1153     Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
1154 
1155     if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1156         return sal_True;
1157 
1158     // Darstellungsfehler vermeiden (wenn bei aktivem TrackingRect gescrollt wird)
1159     HideTracking();
1160 
1161     sal_Bool bScrolling = sal_False;
1162     sal_Bool bNeedScrollTimer = sal_False;
1163 
1164     // An Fenstergrenzen scrollen
1165     // TODO : nur dann abfangen, wenn das Fenster komplett verschwinden wuerde (nicht, solange noch ein Pixel sichtbar ist)
1166     if( aDragWinPos.X() < 5 )
1167     {
1168         bScrolling = ScrollPane( -LINE_SIZE, sal_True, sal_True );
1169         if( !bScrolling && (aDragWinPos.X()<0) )
1170             aDragWinPos.X() = 0;
1171 
1172         // brauche ich weiteres (timergesteuertes) Scrolling ?
1173         bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1174     }
1175 
1176     if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1177     {
1178         bScrolling = ScrollPane( LINE_SIZE, sal_True, sal_True ) ;
1179         if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1180             aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1181 
1182         // brauche ich weiteres (timergesteuertes) Scrolling ?
1183         bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1184     }
1185 
1186     if( aDragWinPos.Y() < 5 )
1187     {
1188         bScrolling = ScrollPane( -LINE_SIZE, sal_False, sal_True );
1189         if( !bScrolling && (aDragWinPos.Y()<0) )
1190             aDragWinPos.Y() = 0;
1191 
1192         bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1193     }
1194 
1195     if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1196     {
1197         bScrolling = ScrollPane( LINE_SIZE, sal_False, sal_True );
1198         if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1199             aDragWinPos.Y() =  m_aOutputSize.Height() - aDragWinSize.Height();
1200 
1201         bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1202     }
1203 
1204     // Timer neu setzen, wenn noch notwendig
1205     if (bNeedScrollTimer)
1206     {
1207         m_aDragScrollTimer.SetTimeout(100);
1208         m_aDragScrollTimer.Start();
1209     }
1210 
1211     // das DraggingRect neu zeichnen
1212     m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1213     Update();
1214     ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1215 
1216     return bScrolling;
1217 }
1218 
1219 //------------------------------------------------------------------------
1220 IMPL_LINK(OJoinTableView, OnDragScrollTimer, void*, EMPTYARG)
1221 {
1222     ScrollWhileDragging();
1223     return 0L;
1224 }
1225 // -----------------------------------------------------------------------------
1226 void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1227 {
1228     Invalidate(INVALIDATE_NOCHILDREN);
1229     m_pView->getController().addUndoActionAndInvalidate(_pAction);
1230 }
1231 //------------------------------------------------------------------------
1232 void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1233 {
1234     DBG_CHKTHIS(OJoinTableView,NULL);
1235     Point ptThumbPos(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
1236     ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1237 
1238     invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1239 }
1240 
1241 //------------------------------------------------------------------------
1242 void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1243 {
1244     DBG_CHKTHIS(OJoinTableView,NULL);
1245     ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1246     ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1247 
1248     invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1249 }
1250 
1251 //------------------------------------------------------------------------------
1252 sal_Bool OJoinTableView::IsAddAllowed()
1253 {
1254     DBG_CHKTHIS(OJoinTableView,NULL);
1255 
1256     // nicht wenn Db readonly
1257     if (m_pView->getController().isReadOnly())
1258         return sal_False;
1259 
1260     try
1261     {
1262         Reference< XConnection> xConnection = m_pView->getController().getConnection();
1263         if(!xConnection.is())
1264             return sal_False;
1265         // nicht wenn schon zuviele Tabellen
1266         Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1267 
1268         sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1269         if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1270             return sal_False;
1271     }
1272     catch(SQLException&)
1273     {
1274         return sal_False;
1275     }
1276 
1277     // nicht wenn keine Joins moeglich
1278 //  if (!GetDatabase()->IsCapable(SDB_CAP_JOIN) && nMax <= GetTabWinCount())
1279 //      return sal_False;
1280 
1281     return sal_True;
1282 }
1283 // -----------------------------------------------------------------------------
1284 void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1285 {
1286     PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1287     switch (aContextMenu.Execute(this, _aPos))
1288     {
1289         case SID_DELETE:
1290             RemoveConnection( _pSelConnection ,sal_True);
1291             break;
1292         case ID_QUERY_EDIT_JOINCONNECTION:
1293             ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1294             break;
1295     }
1296 }
1297 //------------------------------------------------------------------------------
1298 void OJoinTableView::Command(const CommandEvent& rEvt)
1299 {
1300     DBG_CHKTHIS(OJoinTableView,NULL);
1301 
1302     sal_Bool bHandled = sal_False;
1303 
1304     switch (rEvt.GetCommand())
1305     {
1306         case COMMAND_CONTEXTMENU:
1307         {
1308             if( m_vTableConnection.empty() )
1309                 return;
1310 
1311             OTableConnection* pSelConnection = GetSelectedConn();
1312             // when it wasn't a mouse event use the selected connection
1313             if (!rEvt.IsMouseEvent())
1314             {
1315                 if( pSelConnection )
1316                 {
1317                     const ::std::vector<OConnectionLine*>* pLines = pSelConnection->GetConnLineList();
1318                     ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(pLines->begin(),pLines->end(),::std::mem_fun(&OConnectionLine::IsValid));
1319                     if( aIter != pLines->end() )
1320                         executePopup((*aIter)->getMidPoint(),pSelConnection);
1321                 }
1322             }
1323             else
1324             {
1325                 DeselectConn(pSelConnection);
1326 
1327                 const Point& aMousePos = rEvt.GetMousePosPixel();
1328                 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1329                 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1330                 for(;aIter != aEnd;++aIter)
1331                 {
1332                     if( (*aIter)->CheckHit(aMousePos) )
1333                     {
1334                         SelectConn(*aIter);
1335                         if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1336                             executePopup(rEvt.GetMousePosPixel(),*aIter);
1337                         break;
1338                     }
1339                 }
1340             }
1341             bHandled = sal_True;
1342         }
1343     }
1344     if (!bHandled)
1345         Window::Command(rEvt);
1346 }
1347 
1348 //------------------------------------------------------------------------------
1349 OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1350 {
1351     OTableConnection* pConn = NULL;
1352     DBG_ASSERT(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1353         // only one NULL-arg allowed
1354 
1355     if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1356     {
1357         sal_Bool bFoundStart = _rpFirstAfter ? sal_False : sal_True;
1358 
1359         ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
1360         ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
1361         for(;aIter != aEnd;++aIter)
1362         {
1363             OTableConnection* pData = *aIter;
1364 
1365             if  (   (   (pData->GetSourceWin() == pLhs)
1366                     &&  (   (pData->GetDestWin() == pRhs)
1367                         ||  (NULL == pRhs)
1368                         )
1369                     )
1370                 ||  (   (pData->GetSourceWin() == pRhs)
1371                     &&  (   (pData->GetDestWin() == pLhs)
1372                         ||  (NULL == pLhs)
1373                         )
1374                     )
1375                 )
1376             {
1377                 if ( _bSupressCrossOrNaturalJoin )
1378                 {
1379                     if ( supressCrossNaturalJoin(pData->GetData()) )
1380                         continue;
1381                 }
1382                 if (bFoundStart)
1383                 {
1384                     pConn = pData;
1385                     break;
1386                 }
1387 
1388                 if (!pConn)
1389                     // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1390                     // will be used
1391                     pConn = pData;
1392 
1393                 if (pData == _rpFirstAfter)
1394                     bFoundStart = sal_True;
1395             }
1396         }
1397     }
1398     return pConn;
1399 }
1400 
1401 //------------------------------------------------------------------------------
1402 long OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1403 {
1404     sal_Bool bHandled = sal_False;
1405     switch (rNEvt.GetType())
1406     {
1407         case EVENT_COMMAND:
1408         {
1409             const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1410             if (pCommand->GetCommand() == COMMAND_WHEEL)
1411             {
1412                 const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1413                 if (pData->GetMode() == COMMAND_WHEEL_SCROLL)
1414                 {
1415                     if (pData->GetDelta() > 0)
1416                         ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1417                     else
1418                         ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1419                     bHandled = sal_True;
1420                 }
1421             }
1422         }
1423         break;
1424         case EVENT_KEYINPUT:
1425         {
1426             if (m_aTableMap.empty())
1427                 // no tab wins -> no conns -> no traveling
1428                 break;
1429 
1430             const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1431             if (!pKeyEvent->GetKeyCode().IsMod1())
1432             {
1433                 switch (pKeyEvent->GetKeyCode().GetCode())
1434                 {
1435                     case KEY_TAB:
1436                     {
1437                         if (!HasChildPathFocus())
1438                             break;
1439 
1440                         sal_Bool bForward = !pKeyEvent->GetKeyCode().IsShift();
1441                         // is there an active tab win ?
1442                         OTableWindowMapIterator aIter = m_aTableMap.begin();
1443                         OTableWindowMapIterator aEnd = m_aTableMap.end();
1444                         for(;aIter != aEnd;++aIter)
1445                             if (aIter->second && aIter->second->HasChildPathFocus())
1446                                 break;
1447 
1448                         OTableWindow* pNextWin = NULL;
1449                         OTableConnection* pNextConn = NULL;
1450 
1451                         if (aIter != m_aTableMap.end())
1452                         {   // there is a currently active tab win
1453                             // check if there is an "overflow" and we should select a conn instead of a win
1454                             if (!m_vTableConnection.empty())
1455                             {
1456                                 if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1457                                     // the last win is active and we're travelling forward -> select the first conn
1458                                     pNextConn = *m_vTableConnection.begin();
1459                                 if ((aIter == m_aTableMap.begin()) && !bForward)
1460                                     // the first win is active an we're traveling backward -> select the last conn
1461                                     pNextConn = *m_vTableConnection.rbegin();
1462                             }
1463 
1464                             if (!pNextConn)
1465                             {
1466                                 // no conn for any reason -> select the next or previous tab win
1467                                 if(bForward)
1468                                 {
1469                                     if ((aIter->second == m_aTableMap.rbegin()->second))
1470                                         pNextWin = m_aTableMap.begin()->second;
1471                                     else
1472                                     {
1473                                         ++aIter;
1474                                         pNextWin = aIter->second;
1475                                     }
1476                                 }
1477                                 else
1478                                 {
1479                                     if (aIter == m_aTableMap.begin())
1480                                         pNextWin = m_aTableMap.rbegin()->second;
1481                                     else
1482                                     {
1483                                         --aIter;
1484                                         pNextWin = aIter->second;
1485                                     }
1486                                 }
1487                             }
1488                         }
1489                         else
1490                         {   // no active tab win -> travel the connections
1491                             // find the currently selected conn within the conn list
1492                             sal_Int32 i(0);
1493                             for (   ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
1494                                     connectionIter != m_vTableConnection.end();
1495                                     ++connectionIter, ++i
1496                                 )
1497                             {
1498                                 if ( (*connectionIter) == GetSelectedConn() )
1499                                     break;
1500                             }
1501                             if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1502                                 // the last conn is active and we're travelling forward -> select the first win
1503                                 pNextWin = m_aTableMap.begin()->second;
1504                             if ((i == 0) && !bForward && !m_aTableMap.empty())
1505                                 // the first conn is active and we're travelling backward -> select the last win
1506                                 pNextWin = m_aTableMap.rbegin()->second;
1507 
1508                             if (pNextWin)
1509                                 DeselectConn(GetSelectedConn());
1510                             else
1511                                 // no win for any reason -> select the next or previous conn
1512                                 if (i < (sal_Int32)m_vTableConnection.size())
1513                                     // there is a currently active conn
1514                                     pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1515                                 else
1516                                 {   // no tab win selected, no conn selected
1517                                     if (!m_vTableConnection.empty())
1518                                         pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1519                                     else if (!m_aTableMap.empty())
1520                                     {
1521                                         if(bForward)
1522                                             pNextWin = m_aTableMap.begin()->second;
1523                                         else
1524                                             pNextWin = m_aTableMap.rbegin()->second;
1525                                     }
1526                                 }
1527                         }
1528 
1529                         // now select the object
1530                         if (pNextWin)
1531                         {
1532                             if (pNextWin->GetListBox())
1533                                 pNextWin->GetListBox()->GrabFocus();
1534                             else
1535                                 pNextWin->GrabFocus();
1536                             EnsureVisible(pNextWin);
1537                         }
1538                         else if (pNextConn)
1539                         {
1540                             GrabFocus();
1541                                 // neccessary : a conn may be selected even if a tab win has the focus, in this case
1542                                 // the next travel would select the same conn again if we would not reset te focus ...
1543                             SelectConn(pNextConn);
1544                         }
1545                     }
1546                     break;
1547                     case KEY_RETURN:
1548                     {
1549                         if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1550                             ConnDoubleClicked(GetSelectedConn());
1551                         break;
1552                     }
1553                 }
1554             }
1555         }
1556         break;
1557         case EVENT_GETFOCUS:
1558         {
1559             if (m_aTableMap.empty())
1560                 // no tab wins -> no conns -> no focus change
1561                 break;
1562             Window* pSource = rNEvt.GetWindow();
1563             if (pSource)
1564             {
1565                 Window* pSearchFor = NULL;
1566                 if (pSource->GetParent() == this)
1567                     // it may be one of the tab wins
1568                     pSearchFor = pSource;
1569                 else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1570                     // it may be one of th list boxes of one of the tab wins
1571                     pSearchFor = pSource->GetParent();
1572 
1573                 if (pSearchFor)
1574                 {
1575                     OTableWindowMapIterator aIter = m_aTableMap.begin();
1576                     OTableWindowMapIterator aEnd = m_aTableMap.end();
1577                     for(;aIter != aEnd;++aIter)
1578                     {
1579                         if (aIter->second == pSearchFor)
1580                         {
1581                             m_pLastFocusTabWin = aIter->second;
1582                             break;
1583                         }
1584                     }
1585                 }
1586             }
1587         }
1588         break;
1589     }
1590 
1591     if (!bHandled)
1592         return Window::PreNotify(rNEvt);
1593     return 1L;
1594 }
1595 
1596 //------------------------------------------------------------------------------
1597 void OJoinTableView::GrabTabWinFocus()
1598 {
1599     if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1600     {
1601         if (m_pLastFocusTabWin->GetListBox())
1602             m_pLastFocusTabWin->GetListBox()->GrabFocus();
1603         else
1604             m_pLastFocusTabWin->GrabFocus();
1605     }
1606     else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1607     {
1608         OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1609         if (pFirstWin->GetListBox())
1610             pFirstWin->GetListBox()->GrabFocus();
1611         else
1612             pFirstWin->GrabFocus();
1613     }
1614 }
1615 // -----------------------------------------------------------------------------
1616 void OJoinTableView::StateChanged( StateChangedType nType )
1617 {
1618     Window::StateChanged( nType );
1619 
1620     if ( nType == STATE_CHANGE_ZOOM )
1621     {
1622         const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1623 
1624         Font aFont = rStyleSettings.GetGroupFont();
1625         if ( IsControlFont() )
1626             aFont.Merge( GetControlFont() );
1627         SetZoomedPointFont( aFont );
1628 
1629         OTableWindowMapIterator aIter = m_aTableMap.begin();
1630         OTableWindowMapIterator aEnd = m_aTableMap.end();
1631         for(;aIter != aEnd;++aIter)
1632         {
1633             aIter->second->SetZoom(GetZoom());
1634             Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1635             aIter->second->SetSizePixel(aSize);
1636         }
1637         Resize();
1638     }
1639 }
1640 //------------------------------------------------------------------------------
1641 void OJoinTableView::HideTabWins()
1642 {
1643     DBG_CHKTHIS(OJoinTableView,NULL);
1644     SetUpdateMode(sal_False);
1645 
1646     OTableWindowMap* pTabWins = GetTabWinMap();
1647     if ( pTabWins )
1648     {
1649         // working on a copy because the real list will be cleared in inner calls
1650         OTableWindowMap aCopy(*pTabWins);
1651         OTableWindowMap::iterator aIter = aCopy.begin();
1652         OTableWindowMap::iterator aEnd = aCopy.end();
1653         for(;aIter != aEnd;++aIter)
1654             RemoveTabWin(aIter->second);
1655     }
1656 
1657     m_pView->getController().setModified(sal_True);
1658 
1659     SetUpdateMode(sal_True);
1660 
1661 }
1662 // -----------------------------------------------------------------------------
1663 sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1664 {
1665     return DND_ACTION_NONE;
1666 }
1667 // -----------------------------------------------------------------------------
1668 sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1669 {
1670     return DND_ACTION_NONE;
1671 }
1672 // -----------------------------------------------------------------------------
1673 void OJoinTableView::dragFinished( )
1674 {
1675 }
1676 //------------------------------------------------------------------------------
1677 void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1678 {
1679 }
1680 // -----------------------------------------------------------------------------
1681 void OJoinTableView::clearLayoutInformation()
1682 {
1683     m_pLastFocusTabWin  = NULL;
1684     m_pSelectedConn     = NULL;
1685     //////////////////////////////////////////////////////////////////////
1686     // Listen loeschen
1687     OTableWindowMapIterator aIter = m_aTableMap.begin();
1688     OTableWindowMapIterator aEnd  = m_aTableMap.end();
1689     for(;aIter != aEnd;++aIter)
1690     {
1691         if ( aIter->second )
1692             aIter->second->clearListBox();
1693         ::std::auto_ptr<Window> aTemp(aIter->second);
1694         aIter->second = NULL;
1695     }
1696 
1697     m_aTableMap.clear();
1698 
1699     ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
1700     ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
1701     for(;aIter2 != aEnd2;++aIter2)
1702         delete *aIter2;
1703 
1704     m_vTableConnection.clear();
1705 }
1706 // -----------------------------------------------------------------------------
1707 void OJoinTableView::lookForUiActivities()
1708 {
1709 }
1710 // -----------------------------------------------------------------------------
1711 void OJoinTableView::LoseFocus()
1712 {
1713     DeselectConn(GetSelectedConn());
1714     Window::LoseFocus();
1715 }
1716 // -----------------------------------------------------------------------------
1717 void OJoinTableView::GetFocus()
1718 {
1719     Window::GetFocus();
1720     if ( !m_aTableMap.empty() && !GetSelectedConn() )
1721         GrabTabWinFocus();
1722 }
1723 // -----------------------------------------------------------------------------
1724 Reference< XAccessible > OJoinTableView::CreateAccessible()
1725 {
1726     m_pAccessible = new OJoinDesignViewAccess(this);
1727     return m_pAccessible;
1728 }
1729 // -----------------------------------------------------------------------------
1730 void OJoinTableView::modified()
1731 {
1732     OJoinController& rController = m_pView->getController();
1733     rController.setModified( sal_True );
1734     rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1735     rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1736 }
1737 // -----------------------------------------------------------------------------
1738 void OJoinTableView::addConnection(OTableConnection* _pConnection,sal_Bool _bAddData)
1739 {
1740     if ( _bAddData )
1741     {
1742 #if OSL_DEBUG_LEVEL > 0
1743         TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
1744         OSL_ENSURE( ::std::find(pTabConnDataList->begin(),pTabConnDataList->end(),_pConnection->GetData()) == pTabConnDataList->end(),"Data already in vector!");
1745 #endif
1746         m_pView->getController().getTableConnectionData()->push_back(_pConnection->GetData());
1747     }
1748     m_vTableConnection.push_back(_pConnection);
1749     _pConnection->RecalcLines();
1750     _pConnection->InvalidateConnection();
1751 
1752     modified();
1753     if ( m_pAccessible )
1754         m_pAccessible->notifyAccessibleEvent(   AccessibleEventId::CHILD,
1755                                                 Any(),
1756                                                 makeAny(_pConnection->GetAccessible()));
1757 }
1758 // -----------------------------------------------------------------------------
1759 bool OJoinTableView::allowQueries() const
1760 {
1761     return true;
1762 }
1763 // -----------------------------------------------------------------------------
1764 void OJoinTableView::onNoColumns_throw()
1765 {
1766     OSL_ENSURE( false, "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1767     throw SQLException();
1768 }
1769 //------------------------------------------------------------------------------
1770 bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1771 {
1772     return false;
1773 }
1774