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