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