merge the formfield patch from ooo-build
[ooovba.git] / dbaccess / source / ui / querydesign / JoinTableView.cxx
blob948a3d0d4087b6fd14d05f80c5f33ec652e312d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: JoinTableView.cxx,v $
10 * $Revision: 1.61 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
33 #ifndef DBAUI_QUERYTABLEVIEW_HXX
34 #include "JoinTableView.hxx"
35 #endif
36 #ifndef _TOOLS_DEBUG_HXX
37 #include <tools/debug.hxx>
38 #endif
39 #ifndef DBAUI_QUERYCONTROLLER_HXX
40 #include "querycontroller.hxx"
41 #endif
42 #ifndef DBAUI_JOINDESIGNVIEW_HXX
43 #include "JoinDesignView.hxx"
44 #endif
45 #ifndef _DBU_QRY_HRC_
46 #include "dbu_qry.hrc"
47 #endif
48 #ifndef DBAUI_TABLEWINDOW_HXX
49 #include "TableWindow.hxx"
50 #endif
51 //#ifndef DBAUI_QUERY_TABLEWINDOWDATA_HXX
52 //#include "QTableWindowData.hxx"
53 //#endif
54 #ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
55 #include "TableWindowListBox.hxx"
56 #endif
57 #ifndef DBAUI_TABLECONNECTION_HXX
58 #include "TableConnection.hxx"
59 #endif
60 #ifndef DBAUI_TABLECONNECTIONDATA_HXX
61 #include "TableConnectionData.hxx"
62 #endif
63 #ifndef DBAUI_CONNECTIONLINE_HXX
64 #include "ConnectionLine.hxx"
65 #endif
66 #ifndef DBAUI_CONNECTIONLINEDATA_HXX
67 #include "ConnectionLineData.hxx"
68 #endif
69 #ifndef DBACCESS_UI_BROWSER_ID_HXX
70 #include "browserids.hxx"
71 #endif
72 #ifndef _URLBMK_HXX
73 #include <svtools/urlbmk.hxx>
74 #endif
75 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
76 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
77 #endif
78 #ifndef DBAUI_OQUERYMOVETABWINUNDOACT_HXX
79 #include "QueryMoveTabWinUndoAct.hxx"
80 #endif
81 #ifndef DBAUI_QUERYSIZETABWINUNDOACT_HXX
82 #include "QuerySizeTabWinUndoAct.hxx"
83 #endif
84 #ifndef _SV_SVAPP_HXX
85 #include <vcl/svapp.hxx>
86 #endif
87 #ifndef DBAUI_TABLEWINDOWDATA_HXX
88 #include "TableWindowData.hxx"
89 #endif
90 #ifndef DBACCESS_JACCESS_HXX
91 #include "JAccess.hxx"
92 #endif
93 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
94 #include <com/sun/star/accessibility/XAccessible.hpp>
95 #endif
96 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HPP_
97 #include <com/sun/star/accessibility/AccessibleRole.hpp>
98 #endif
99 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
100 #ifndef DBAUI_TOOLS_HXX
101 #include "UITools.hxx"
102 #endif
103 #include <cppuhelper/exc_hlp.hxx>
104 #include <tools/diagnose_ex.h>
105 #include <boost/bind.hpp>
106 #include <algorithm>
107 #include <functional>
109 using namespace dbaui;
110 using namespace ::com::sun::star::uno;
111 using namespace ::com::sun::star::sdbc;
112 using namespace ::com::sun::star::accessibility;
113 using namespace ::com::sun::star::container;
114 using namespace ::com::sun::star::lang;
116 #define LINE_SIZE 50
117 ////////////////////////////////////////////////////////////////
118 // Konstanten fuer das Fensterlayout
119 #define TABWIN_SPACING_X 17
120 #define TABWIN_SPACING_Y 17
122 #define TABWIN_WIDTH_STD 120
123 #define TABWIN_HEIGHT_STD 120
125 DBG_NAME(OScrollWindowHelper)
126 OScrollWindowHelper::OScrollWindowHelper( Window* pParent) : Window( pParent)
127 ,m_aHScrollBar( this, WB_HSCROLL|WB_REPEAT|WB_DRAG )
128 ,m_aVScrollBar( this, WB_VSCROLL|WB_REPEAT|WB_DRAG )
129 ,m_pCornerWindow(new ScrollBarBox(this, WB_3DLOOK))
130 ,m_pTableView(NULL)
132 DBG_CTOR(OScrollWindowHelper,NULL);
134 //////////////////////////////////////////////////////////////////////
135 // ScrollBars
137 GetHScrollBar()->SetRange( Range(0, 1000) );
138 GetVScrollBar()->SetRange( Range(0, 1000) );
140 GetHScrollBar()->SetLineSize( LINE_SIZE );
141 GetVScrollBar()->SetLineSize( LINE_SIZE );
143 GetHScrollBar()->Show();
144 GetVScrollBar()->Show();
145 m_pCornerWindow->Show();
147 // normally we should be SCROLL_PANE
148 SetAccessibleRole(AccessibleRole::SCROLL_PANE);
151 // -----------------------------------------------------------------------------
152 OScrollWindowHelper::~OScrollWindowHelper()
154 DBG_DTOR(OScrollWindowHelper,NULL);
155 ::std::auto_ptr<Window> aTemp(m_pCornerWindow);
156 m_pCornerWindow = NULL;
157 m_pTableView = NULL;
160 // -----------------------------------------------------------------------------
161 void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
163 m_pTableView = _pTableView;
164 //////////////////////////////////////////////////////////////////////
165 // ScrollBars
166 GetHScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
167 GetVScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
169 // -----------------------------------------------------------------------------
170 void OScrollWindowHelper::resetRange(const Point& _aSize)
172 Point aPos = PixelToLogic(_aSize);
173 GetHScrollBar()->SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
174 GetVScrollBar()->SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
176 //------------------------------------------------------------------------------
177 void OScrollWindowHelper::Resize()
179 Window::Resize();
181 Size aTotalOutputSize = GetOutputSizePixel();
182 long nHScrollHeight = GetHScrollBar()->GetSizePixel().Height();
183 long nVScrollWidth = GetVScrollBar()->GetSizePixel().Width();
185 GetHScrollBar()->SetPosSizePixel(
186 Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
187 Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
190 GetVScrollBar()->SetPosSizePixel(
191 Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
192 Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
195 m_pCornerWindow->SetPosSizePixel(
196 Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
197 Size( nVScrollWidth, nHScrollHeight )
200 GetHScrollBar()->SetPageSize( aTotalOutputSize.Width() );
201 GetHScrollBar()->SetVisibleSize( aTotalOutputSize.Width() );
203 GetVScrollBar()->SetPageSize( aTotalOutputSize.Height() );
204 GetVScrollBar()->SetVisibleSize( aTotalOutputSize.Height() );
206 // adjust the ranges of the scrollbars if neccessary
207 long lRange = GetHScrollBar()->GetRange().Max() - GetHScrollBar()->GetRange().Min();
208 if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
209 GetHScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar()->GetRange().Min());
211 lRange = GetVScrollBar()->GetRange().Max() - GetVScrollBar()->GetRange().Min();
212 if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
213 GetVScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar()->GetRange().Min());
215 m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
217 // -----------------------------------------------------------------------------
218 // -----------------------------------------------------------------------------
219 //==================================================================
220 // class OJoinTableView
221 //==================================================================
223 //const long WINDOW_WIDTH = 1000;
224 //const long WINDOW_HEIGHT = 1000;
225 DBG_NAME(OJoinTableView);
226 //------------------------------------------------------------------------------
227 OJoinTableView::OJoinTableView( Window* pParent, OJoinDesignView* pView )
228 :Window( pParent,WB_BORDER )
229 ,DropTargetHelper(this)
230 ,m_aDragOffset( Point(0,0) )
231 ,m_aScrollOffset( Point(0,0) )
232 ,m_pDragWin( NULL )
233 ,m_pSizingWin( NULL )
234 ,m_pSelectedConn( NULL )
235 ,m_bTrackingInitiallyMoved(FALSE)
236 ,m_pLastFocusTabWin(NULL)
237 ,m_pView( pView )
238 ,m_pAccessible(NULL)
240 DBG_CTOR(OJoinTableView,NULL);
241 SetSizePixel( Size(1000, 1000) );
243 InitColors();
245 m_aDragScrollTimer.SetTimeoutHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
248 //------------------------------------------------------------------------------
249 OJoinTableView::~OJoinTableView()
251 DBG_DTOR(OJoinTableView,NULL);
252 if( m_pAccessible )
254 m_pAccessible->clearTableView();
255 m_pAccessible = NULL;
257 //////////////////////////////////////////////////////////////////////
258 // Listen loeschen
259 clearLayoutInformation();
261 //------------------------------------------------------------------------------
262 IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
264 //////////////////////////////////////////////////////////////////////
265 // Alle Fenster verschieben
266 ScrollPane( pScrollBar->GetDelta(), (pScrollBar == GetHScrollBar()), FALSE );
268 return 0;
270 //------------------------------------------------------------------------------
271 void OJoinTableView::Resize()
273 DBG_CHKTHIS(OJoinTableView,NULL);
274 Window::Resize();
275 m_aOutputSize = GetSizePixel();
277 // tab win positions may not be up-to-date
278 if (m_aTableMap.empty())
279 // no tab wins ...
280 return;
282 // we have at least one table so resize it
283 m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
284 m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
286 OTableWindow* pCheck = m_aTableMap.begin()->second;
287 Point aRealPos = pCheck->GetPosPixel();
288 Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
290 if (aRealPos == aAssumedPos)
291 // all ok
292 return;
294 OTableWindowMapIterator aIter = m_aTableMap.begin();
295 OTableWindowMapIterator aEnd = m_aTableMap.end();
296 for(;aIter != aEnd;++aIter)
298 OTableWindow* pCurrent = aIter->second;
299 Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
300 pCurrent->SetPosPixel(aPos);
303 //------------------------------------------------------------------------------
304 ULONG OJoinTableView::GetTabWinCount()
306 DBG_CHKTHIS(OJoinTableView,NULL);
307 return m_aTableMap.size();
310 //------------------------------------------------------------------------------
311 bool OJoinTableView::RemoveConnection( OTableConnection* _pConn,sal_Bool _bDelete )
313 DBG_CHKTHIS(OJoinTableView,NULL);
314 DeselectConn(_pConn);
316 // to force a redraw
317 _pConn->InvalidateConnection();
319 m_pView->getController().removeConnectionData( _pConn->GetData() );
321 m_vTableConnection.erase(
322 ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn) );
324 modified();
325 if ( m_pAccessible )
326 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
327 makeAny(_pConn->GetAccessible()),
328 Any());
329 if ( _bDelete )
331 delete _pConn;
334 return true;
337 //------------------------------------------------------------------------
338 OTableWindow* OJoinTableView::GetTabWindow( const String& rName )
340 DBG_CHKTHIS(OJoinTableView,NULL);
341 OTableWindowMapIterator aIter = m_aTableMap.find(rName);
343 return aIter == m_aTableMap.end() ? NULL : aIter->second;
345 // -----------------------------------------------------------------------------
346 TTableWindowData::value_type OJoinTableView::createTableWindowData(const ::rtl::OUString& _rComposedName
347 ,const ::rtl::OUString& _sTableName
348 ,const ::rtl::OUString& _rWinName)
350 TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
351 OJoinDesignView* pParent = getDesignView();
354 if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
356 if ( pData->isValid() )
357 onNoColumns_throw();
358 else
359 pData.reset();
362 catch ( const SQLException& )
364 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
365 pParent, pParent->getController().getORB() );
367 catch( const WrappedTargetException& e )
369 SQLException aSql;
370 if ( e.TargetException >>= aSql )
371 ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
373 catch( const Exception& )
375 DBG_UNHANDLED_EXCEPTION();
377 return pData;
379 // -----------------------------------------------------------------------------
380 OTableWindowData* OJoinTableView::CreateImpl(const ::rtl::OUString& _rComposedName
381 ,const ::rtl::OUString& _sTableName
382 ,const ::rtl::OUString& _rWinName)
384 return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
386 //------------------------------------------------------------------------------
387 void OJoinTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& rWinName, BOOL /*bNewTable*/)
389 DBG_CHKTHIS(OJoinTableView,NULL);
390 OSL_ENSURE(_rComposedName.getLength(),"There must be a table name supplied!");
392 TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
394 //////////////////////////////////////////////////////////////////
395 // Neues Fenster in Fensterliste eintragen
396 OTableWindow* pNewTabWin = createWindow( pNewTabWinData );
397 if ( pNewTabWin->Init() )
399 m_pView->getController().getTableWindowData()->push_back( pNewTabWinData);
400 // when we already have a table with this name insert the full qualified one instead
401 if(m_aTableMap.find(rWinName) != m_aTableMap.end())
402 m_aTableMap[_rComposedName] = pNewTabWin;
403 else
404 m_aTableMap[rWinName] = pNewTabWin;
406 SetDefaultTabWinPosSize( pNewTabWin );
407 pNewTabWin->Show();
409 modified();
410 if ( m_pAccessible )
411 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
412 Any(),
413 makeAny(pNewTabWin->GetAccessible()));
415 else
417 pNewTabWin->clearListBox();
418 delete pNewTabWin;
422 //------------------------------------------------------------------------------
423 void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
425 DBG_CHKTHIS(OJoinTableView,NULL);
426 //////////////////////////////////////////////////////////////////////
427 // first delete all connections of this window to others
428 bool bRemove = true;
429 TTableWindowData::value_type pData = pTabWin->GetData();
430 sal_Int32 nCount = m_vTableConnection.size();
431 ::std::vector<OTableConnection*>::reverse_iterator aIter = m_vTableConnection.rbegin();
432 while(aIter != m_vTableConnection.rend() && bRemove)
434 OTableConnection* pTabConn = (*aIter);
436 ( pData == pTabConn->GetData()->getReferencingTable()) ||
437 ( pData == pTabConn->GetData()->getReferencedTable())
440 bRemove = RemoveConnection( pTabConn ,sal_True);
441 aIter = m_vTableConnection.rbegin();
443 else
444 ++aIter;
447 //////////////////////////////////////////////////////////////////////
448 // then delete the window itself
449 if ( bRemove )
451 if ( m_pAccessible )
452 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
453 makeAny(pTabWin->GetAccessible()),Any()
456 pTabWin->Hide();
457 OJoinController& rController = m_pView->getController();
458 TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData()->begin(),rController.getTableWindowData()->end(),pData);
459 if(aFind != rController.getTableWindowData()->end())
461 rController.getTableWindowData()->erase(aFind);
462 rController.setModified(sal_True);
465 String aWinName = pTabWin->GetWinName();
466 if(m_aTableMap.find(aWinName) != m_aTableMap.end())
467 m_aTableMap.erase( aWinName );
468 else
469 m_aTableMap.erase( pTabWin->GetComposedName() );
471 if (pTabWin == m_pLastFocusTabWin)
472 m_pLastFocusTabWin = NULL;
474 pTabWin->clearListBox();
475 delete pTabWin;
478 if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
479 modified();
481 namespace
483 // -----------------------------------------------------------------------------
484 BOOL isScrollAllowed( OJoinTableView* _pView,long nDelta, BOOL bHoriz)
486 BOOL bRet = TRUE;
487 //////////////////////////////////////////////////////////////////////
488 // adjust ScrollBar-Positions
489 ScrollBar* pBar = _pView->GetVScrollBar();
490 if( bHoriz )
491 pBar = _pView->GetHScrollBar();
493 long nOldThumbPos = pBar->GetThumbPos();
494 long nNewThumbPos = nOldThumbPos + nDelta;
495 if( nNewThumbPos < 0 )
496 nNewThumbPos = 0;// bRet = FALSE;
497 else if( nNewThumbPos > pBar->GetRangeMax() )
498 nNewThumbPos = pBar->GetRangeMax();// bRet = FALSE;
500 if ( bHoriz )
502 if( nNewThumbPos == _pView->GetScrollOffset().X() )
503 return FALSE;
505 else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
506 return FALSE;
508 return bRet;
510 // -----------------------------------------------------------------------------
511 BOOL getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
513 _nScrollY = _nScrollX = 0;
514 // data about the tab win
515 Point aUpperLeft = _rPoint;
516 // normalize with respect to visibility
517 aUpperLeft -= _pView->GetScrollOffset();
518 // aUpperLeft.Y() -= _pView->GetScrollOffset().Y();
519 Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
521 // data about ourself
522 Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
524 BOOL bVisbile = TRUE;
525 BOOL bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
526 BOOL bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
527 if (!bFitsHor || !bFitsVert)
529 // #100386# OJ
530 if (!bFitsHor)
532 // ensure the visibility of the right border
533 if ( aLowerRight.X() > aSize.Width() )
534 _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
536 // ensure the visibility of the left border (higher priority)
537 // if ( (aUpperLeft.X() - _nScrollX) < 0 )
538 if ( aUpperLeft.X() < 0 )
539 _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
542 if (!bFitsVert)
544 // lower border
545 if ( aLowerRight.Y() > aSize.Height() )
546 _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
547 // upper border
548 // if ( (aUpperLeft.Y() - _nScrollY) < 0 )
549 if ( aUpperLeft.Y() < 0 )
550 _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
553 if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
554 bVisbile = isScrollAllowed(_pView,_nScrollX, TRUE);
556 if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
557 bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, FALSE);
559 if ( bVisbile )
561 sal_Int32 nHRangeMax = _pView->GetHScrollBar()->GetRangeMax();
562 sal_Int32 nVRangeMax = _pView->GetVScrollBar()->GetRangeMax();
564 if ( aSize.Width() + _pView->GetHScrollBar()->GetThumbPos() + _nScrollX > nHRangeMax )
565 bVisbile = FALSE;
566 if ( bVisbile && aSize.Height() + _pView->GetVScrollBar()->GetThumbPos() + _nScrollY > nVRangeMax )
567 bVisbile = FALSE;
572 return bVisbile;
574 } // end of ano namespace
575 // -----------------------------------------------------------------------------
576 BOOL OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
578 long nX,nY;
579 return getMovementImpl(this,_rPoint,_rSize,nX,nY);
581 //------------------------------------------------------------------------------
582 void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
584 // data about the tab win
585 TTableWindowData::value_type pData = _pWin->GetData();
586 // Point aUpperLeft = pData->GetPosition();
587 EnsureVisible( pData->GetPosition() , pData->GetSize());
588 Invalidate(INVALIDATE_NOCHILDREN);
590 //------------------------------------------------------------------------------
591 void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
593 long nScrollX,nScrollY;
595 if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
597 BOOL bVisbile = TRUE;
598 if (nScrollX)
599 bVisbile = ScrollPane(nScrollX, TRUE, TRUE);
601 if (nScrollY)
602 bVisbile = bVisbile && ScrollPane(nScrollY, FALSE, TRUE);
606 //------------------------------------------------------------------------------
607 void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
609 DBG_CHKTHIS(OJoinTableView,NULL);
610 //////////////////////////////////////////////////////////////////
611 // Position bestimmen:
612 // Das Fenster wird in Zeilen der Hoehe TABWIN_SPACING_Y+TABWIN_HEIGTH_STD aufgeteilt.
613 // Dann wird fuer jede Zeile geprueft, ob noch Platz fuer ein weiteres Fenster ist.
614 // Wenn kein Platz ist, wird die naechste Zeile ueberprueft.
615 Size aOutSize = GetSizePixel();
616 Point aNewPos( 0,0 );
617 USHORT nRow = 0;
618 BOOL bEnd = FALSE;
619 while( !bEnd )
621 //////////////////////////////////////////////////////////////////
622 // Neue Position auf Zeilenbeginn setzen
623 aNewPos.X() = TABWIN_SPACING_X;
624 aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
626 //////////////////////////////////////////////////////////////////
627 // Rectangle fuer die jeweilige Zeile bestimmen
628 Rectangle aRowRect( Point(0,0), aOutSize );
629 aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
630 aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
632 //////////////////////////////////////////////////////////////////
633 // Belegte Bereiche dieser Zeile pruefen
634 OTableWindow* pOtherTabWin;// = GetTabWinMap()->First();
635 OTableWindowMapIterator aIter = m_aTableMap.begin();
636 OTableWindowMapIterator aEnd = m_aTableMap.end();
637 for(;aIter != aEnd;++aIter)
639 pOtherTabWin = aIter->second;
640 Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
643 ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
644 ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
647 //////////////////////////////////////////////////////////////////
648 // TabWin liegt in der Zeile
649 if( aOtherTabWinRect.Right()>aNewPos.X() )
650 aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
654 //////////////////////////////////////////////////////////////////
655 // Ist in dieser Zeile noch Platz?
656 if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
658 aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
659 bEnd = TRUE;
661 else
663 if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
665 // insert it in the first row
666 sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
667 ++nCount;
668 aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
669 bEnd = TRUE;
671 else
672 nRow++;
677 //////////////////////////////////////////////////////////////////
678 // Groesse bestimmen
679 Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
681 // check if the new position in inside the scrollbars ranges
682 Point aBottom(aNewPos);
683 aBottom.X() += aNewSize.Width();
684 aBottom.Y() += aNewSize.Height();
686 if(!GetHScrollBar()->GetRange().IsInside(aBottom.X()))
687 GetHScrollBar()->SetRange( Range(0, aBottom.X()) );
688 if(!GetVScrollBar()->GetRange().IsInside(aBottom.Y()))
689 GetVScrollBar()->SetRange( Range(0, aBottom.Y()) );
691 pTabWin->SetPosSizePixel( aNewPos, aNewSize );
694 //------------------------------------------------------------------------------
695 void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
697 DBG_CHKTHIS(OJoinTableView,NULL);
698 if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
700 // nehmen wir den worst-case an : die Farben haben sich geaendert, also
701 // mich anpassen
702 InitColors();
703 Invalidate(INVALIDATE_NOCHILDREN);
704 // durch das Invalidate werden auch die Connections neu gezeichnet, so dass die auch
705 // gleich in den neuen Farben dargestellt werden
709 //------------------------------------------------------------------------------
710 void OJoinTableView::InitColors()
712 DBG_CHKTHIS(OJoinTableView,NULL);
713 // die Farben fuer die Darstellung sollten die Systemfarben sein
714 StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
715 SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
718 //------------------------------------------------------------------------------
719 void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
721 DBG_CHKTHIS(OJoinTableView,NULL);
723 if (m_pView->getController().isReadOnly())
724 return;
726 m_pDragWin = pTabWin;
727 SetPointer(Pointer(POINTER_MOVE));
728 Point aMousePos = ScreenToOutputPixel( rMousePos );
729 m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
730 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
731 m_bTrackingInitiallyMoved = FALSE;
732 StartTracking();
735 void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
737 DBG_CHKTHIS(OJoinTableView,NULL);
738 DeselectConn(GetSelectedConn());
739 BeginChildMove(pTabWin, rMousePos);
742 //------------------------------------------------------------------------------
743 void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
745 DBG_CHKTHIS(OJoinTableView,NULL);
747 if (m_pView->getController().isReadOnly())
748 return;
750 SetPointer( rPointer );
751 m_pSizingWin = pTabWin;
752 StartTracking();
755 //------------------------------------------------------------------------------
756 BOOL OJoinTableView::ScrollPane( long nDelta, BOOL bHoriz, BOOL bPaintScrollBars )
758 DBG_CHKTHIS(OJoinTableView,NULL);
759 BOOL bRet = TRUE;
761 //////////////////////////////////////////////////////////////////////
762 // ScrollBar-Positionen anpassen
763 if( bPaintScrollBars )
765 if( bHoriz )
767 long nOldThumbPos = GetHScrollBar()->GetThumbPos();
768 long nNewThumbPos = nOldThumbPos + nDelta;
769 if( nNewThumbPos < 0 )
771 nNewThumbPos = 0;
772 bRet = FALSE;
774 if( nNewThumbPos > GetHScrollBar()->GetRange().Max() )
776 nNewThumbPos = GetHScrollBar()->GetRange().Max();
777 bRet = FALSE;
779 GetHScrollBar()->SetThumbPos( nNewThumbPos );
780 nDelta = GetHScrollBar()->GetThumbPos() - nOldThumbPos;
782 else
784 long nOldThumbPos = GetVScrollBar()->GetThumbPos();
785 long nNewThumbPos = nOldThumbPos+nDelta;
786 if( nNewThumbPos < 0 )
788 nNewThumbPos = 0;
789 bRet = FALSE;
791 if( nNewThumbPos > GetVScrollBar()->GetRange().Max() )
793 nNewThumbPos = GetVScrollBar()->GetRange().Max();
794 bRet = FALSE;
796 GetVScrollBar()->SetThumbPos( nNewThumbPos );
797 nDelta = GetVScrollBar()->GetThumbPos() - nOldThumbPos;
801 //////////////////////////////////////////////////////////////////////
802 // Wenn ScrollOffset bereits an den Grenzen liegt, kein Neuzeichnen
803 if( (GetHScrollBar()->GetThumbPos()==m_aScrollOffset.X()) &&
804 (GetVScrollBar()->GetThumbPos()==m_aScrollOffset.Y()) )
805 return FALSE;
807 //////////////////////////////////////////////////////////////////////
808 // ScrollOffset neu setzen
809 if (bHoriz)
810 m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
811 else
812 m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
814 //////////////////////////////////////////////////////////////////////
815 // Alle Fenster verschieben
816 OTableWindow* pTabWin;
817 Point aPos;
819 OTableWindowMapIterator aIter = m_aTableMap.begin();
820 OTableWindowMapIterator aEnd = m_aTableMap.end();
821 for(;aIter != aEnd;++aIter)
823 pTabWin = aIter->second;
824 aPos = pTabWin->GetPosPixel();
826 if( bHoriz )
827 aPos.X() -= nDelta;
828 else aPos.Y() -= nDelta;
830 pTabWin->SetPosPixel( aPos );
833 Invalidate(); // INVALIDATE_NOCHILDREN
835 return bRet;
838 //------------------------------------------------------------------------------
839 void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
841 DBG_CHKTHIS(OJoinTableView,NULL);
842 HideTracking();
844 if (rTEvt.IsTrackingEnded())
846 if( m_pDragWin )
848 if (m_aDragScrollTimer.IsActive())
849 m_aDragScrollTimer.Stop();
851 //////////////////////////////////////////////////////////////////////
852 // Position des Childs nach Verschieben anpassen
853 //////////////////////////////////////////////////////////////////////
854 // Fenster duerfen nicht aus Anzeigebereich herausbewegt werden
855 Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
856 Size aDragWinSize = m_pDragWin->GetSizePixel();
857 if( aDragWinPos.X() < 0 )
858 aDragWinPos.X() = 0;
859 if( aDragWinPos.Y() < 0 )
860 aDragWinPos.Y() = 0;
861 if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
862 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
863 if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
864 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
865 if( aDragWinPos.X() < 0 )
866 aDragWinPos.X() = 0;
867 if( aDragWinPos.Y() < 0 )
868 aDragWinPos.Y() = 0;
869 // TODO : nicht das Fenster neu positionieren, wenn es uebersteht, sondern einfach meinen Bereich erweitern
872 //////////////////////////////////////////////////////////////////////
873 // Fenster positionieren
874 EndTracking();
875 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
876 // erst mal testen, ob ich mich ueberhaupt bewegt habe
877 // (das verhindert das Setzen des modified-Flags, wenn sich eigentlich gar nichts getan hat)
878 TTableWindowData::value_type pData = m_pDragWin->GetData();
879 if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
881 // die alten logischen Koordinaten
882 Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
883 // neu positionieren
884 m_pDragWin->SetPosPixel(aDragWinPos);
885 TabWinMoved(m_pDragWin, ptOldPos);
887 m_pDragWin->GrabFocus();
889 m_pDragWin = NULL;
890 SetPointer(Pointer(POINTER_ARROW));
892 // else we handle the resizing
893 else if( m_pSizingWin )
895 SetPointer( Pointer() );
896 EndTracking();
898 // die alten physikalischen Koordinaten
900 Size szOld = m_pSizingWin->GetSizePixel();
901 Point ptOld = m_pSizingWin->GetPosPixel();
902 Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
903 m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
904 TabWinSized(m_pSizingWin, ptOld, szOld);
906 m_pSizingWin->Invalidate( m_aSizingRect );
907 m_pSizingWin = NULL;
910 else if (rTEvt.IsTrackingCanceled())
912 if (m_aDragScrollTimer.IsActive())
913 m_aDragScrollTimer.Stop();
914 EndTracking();
916 else
918 if( m_pDragWin )
920 m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
921 // an Fenstergrenzen scrollen
922 ScrollWhileDragging();
925 if( m_pSizingWin )
927 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
928 m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
929 Update();
930 ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
935 //------------------------------------------------------------------------------
936 void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
938 DBG_CHKTHIS(OJoinTableView,NULL);
941 //------------------------------------------------------------------------------
942 void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
944 DBG_CHKTHIS(OJoinTableView,NULL);
945 GrabFocus();
946 Window::MouseButtonDown(rEvt);
949 //------------------------------------------------------------------------------
950 void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
952 DBG_CHKTHIS(OJoinTableView,NULL);
953 Window::MouseButtonUp(rEvt);
954 //////////////////////////////////////////////////////////////////////
955 // Wurde eine Connection ausgewaehlt?
956 if( !m_vTableConnection.empty() )
958 DeselectConn(GetSelectedConn());
960 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
961 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
962 for(;aIter != aEnd;++aIter)
964 if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
966 SelectConn((*aIter));
968 // Doppelclick
969 if( rEvt.GetClicks() == 2 )
970 ConnDoubleClicked( (*aIter) );
972 break;
978 //------------------------------------------------------------------------------
979 void OJoinTableView::KeyInput( const KeyEvent& rEvt )
981 DBG_CHKTHIS(OJoinTableView,NULL);
982 USHORT nCode = rEvt.GetKeyCode().GetCode();
983 BOOL bShift = rEvt.GetKeyCode().IsShift();
984 BOOL bCtrl = rEvt.GetKeyCode().IsMod1();
986 if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
988 if (GetSelectedConn())
989 RemoveConnection( GetSelectedConn() ,sal_True);
991 else
992 Window::KeyInput( rEvt );
995 //------------------------------------------------------------------------------
996 void OJoinTableView::DeselectConn(OTableConnection* pConn)
998 DBG_CHKTHIS(OJoinTableView,NULL);
999 if (!pConn || !pConn->IsSelected())
1000 return;
1002 // die zugehoerigen Eitnraege in der ListBox des Tabellenfenster deselektieren
1003 OTableWindow* pWin = pConn->GetSourceWin();
1004 if (pWin && pWin->GetListBox())
1005 pWin->GetListBox()->SelectAll(FALSE);
1007 pWin = pConn->GetDestWin();
1008 if (pWin && pWin->GetListBox())
1009 pWin->GetListBox()->SelectAll(FALSE);
1011 pConn->Deselect();
1012 m_pSelectedConn = NULL;
1015 //------------------------------------------------------------------------------
1016 void OJoinTableView::SelectConn(OTableConnection* pConn)
1018 DBG_CHKTHIS(OJoinTableView,NULL);
1019 DeselectConn(GetSelectedConn());
1021 pConn->Select();
1022 m_pSelectedConn = pConn;
1023 GrabFocus(); // has to be called here because a table window may still be focused
1025 // die betroffenene Eintraege in den Windows selektieren
1026 OTableWindow* pConnSource = pConn->GetSourceWin();
1027 OTableWindow* pConnDest = pConn->GetDestWin();
1028 if (pConnSource && pConnDest)
1030 OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
1031 OTableWindowListBox* pDestBox = pConnDest->GetListBox();
1032 if (pSourceBox && pDestBox)
1034 pSourceBox->SelectAll(FALSE);
1035 pDestBox->SelectAll(FALSE);
1037 SvLBoxEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
1038 SvLBoxEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
1040 const ::std::vector<OConnectionLine*>* pLines = pConn->GetConnLineList();
1041 ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = pLines->rbegin();
1042 for(;aIter != pLines->rend();++aIter)
1044 if ((*aIter)->IsValid())
1046 SvLBoxEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
1047 if (pSourceEntry)
1049 pSourceBox->Select(pSourceEntry, TRUE);
1050 pSourceBox->MakeVisible(pSourceEntry);
1053 SvLBoxEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
1054 if (pDestEntry)
1056 pDestBox->Select(pDestEntry, TRUE);
1057 pDestBox->MakeVisible(pDestEntry);
1063 if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
1064 || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
1065 // es wurde gescrollt -> neu zeichnen
1066 Invalidate(INVALIDATE_NOCHILDREN);
1070 //------------------------------------------------------------------------------
1071 void OJoinTableView::Paint( const Rectangle& rRect )
1073 DBG_CHKTHIS(OJoinTableView,NULL);
1074 DrawConnections( rRect );
1077 //------------------------------------------------------------------------------
1078 void OJoinTableView::InvalidateConnections()
1080 DBG_CHKTHIS(OJoinTableView,NULL);
1081 //////////////////////////////////////////////////////////////////////
1082 // Die Joins zeichnen
1083 ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
1084 ::std::mem_fun(& OTableConnection::InvalidateConnection));
1087 //------------------------------------------------------------------------------
1088 void OJoinTableView::DrawConnections( const Rectangle& rRect )
1090 DBG_CHKTHIS(OJoinTableView,NULL);
1091 //////////////////////////////////////////////////////////////////////
1092 // Die Joins zeichnen
1093 ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
1094 // zum Schluss noch mal die selektierte ueber alle anderen drueber
1095 if (GetSelectedConn())
1096 GetSelectedConn()->Draw( rRect );
1100 //------------------------------------------------------------------------------
1101 ::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
1103 return ::std::find_if( m_vTableConnection.begin(),
1104 m_vTableConnection.end(),
1105 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1107 // -----------------------------------------------------------------------------
1108 sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
1110 return ::std::count_if( m_vTableConnection.begin(),
1111 m_vTableConnection.end(),
1112 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1114 //------------------------------------------------------------------------------
1115 BOOL OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
1117 DBG_CHKTHIS(OJoinTableView,NULL);
1118 return getTableConnections(pFrom) != m_vTableConnection.end();
1120 //------------------------------------------------------------------------
1121 void OJoinTableView::ClearAll()
1123 DBG_CHKTHIS(OJoinTableView,NULL);
1124 SetUpdateMode(FALSE);
1126 HideTabWins();
1128 // und das selbe mit den Connections
1129 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1130 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1131 for(;aIter != aEnd;++aIter)
1132 RemoveConnection( *aIter ,sal_True);
1133 m_vTableConnection.clear();
1135 m_pLastFocusTabWin = NULL;
1136 m_pSelectedConn = NULL;
1138 // scroll to the upper left
1139 ScrollPane(-GetScrollOffset().X(), TRUE, TRUE);
1140 ScrollPane(-GetScrollOffset().Y(), FALSE, TRUE);
1141 Invalidate();
1144 //------------------------------------------------------------------------
1145 BOOL OJoinTableView::ScrollWhileDragging()
1147 DBG_CHKTHIS(OJoinTableView,NULL);
1148 DBG_ASSERT(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging darf nur waehrend Dragging eines Fensters aufgerufen werden !");
1150 // den Timer schon mal killen
1151 if (m_aDragScrollTimer.IsActive())
1152 m_aDragScrollTimer.Stop();
1154 Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
1155 Size aDragWinSize = m_pDragWin->GetSizePixel();
1156 Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
1158 if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1159 return TRUE;
1161 // Darstellungsfehler vermeiden (wenn bei aktivem TrackingRect gescrollt wird)
1162 HideTracking();
1164 BOOL bScrolling = FALSE;
1165 BOOL bNeedScrollTimer = FALSE;
1167 // An Fenstergrenzen scrollen
1168 // TODO : nur dann abfangen, wenn das Fenster komplett verschwinden wuerde (nicht, solange noch ein Pixel sichtbar ist)
1169 if( aDragWinPos.X() < 5 )
1171 bScrolling = ScrollPane( -LINE_SIZE, TRUE, TRUE );
1172 if( !bScrolling && (aDragWinPos.X()<0) )
1173 aDragWinPos.X() = 0;
1175 // brauche ich weiteres (timergesteuertes) Scrolling ?
1176 bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1179 if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1181 bScrolling = ScrollPane( LINE_SIZE, TRUE, TRUE ) ;
1182 if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1183 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1185 // brauche ich weiteres (timergesteuertes) Scrolling ?
1186 bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1189 if( aDragWinPos.Y() < 5 )
1191 bScrolling = ScrollPane( -LINE_SIZE, FALSE, TRUE );
1192 if( !bScrolling && (aDragWinPos.Y()<0) )
1193 aDragWinPos.Y() = 0;
1195 bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1198 if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1200 bScrolling = ScrollPane( LINE_SIZE, FALSE, TRUE );
1201 if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1202 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
1204 bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1207 // Timer neu setzen, wenn noch notwendig
1208 if (bNeedScrollTimer)
1210 m_aDragScrollTimer.SetTimeout(100);
1211 m_aDragScrollTimer.Start();
1214 // das DraggingRect neu zeichnen
1215 m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1216 Update();
1217 ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1219 return bScrolling;
1222 //------------------------------------------------------------------------
1223 IMPL_LINK(OJoinTableView, OnDragScrollTimer, void*, EMPTYARG)
1225 ScrollWhileDragging();
1226 return 0L;
1228 // -----------------------------------------------------------------------------
1229 void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1231 Invalidate(INVALIDATE_NOCHILDREN);
1232 m_pView->getController().addUndoActionAndInvalidate(_pAction);
1234 //------------------------------------------------------------------------
1235 void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1237 DBG_CHKTHIS(OJoinTableView,NULL);
1238 Point ptThumbPos(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
1239 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1241 invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1244 //------------------------------------------------------------------------
1245 void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1247 DBG_CHKTHIS(OJoinTableView,NULL);
1248 ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1249 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1251 invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1254 //------------------------------------------------------------------------------
1255 BOOL OJoinTableView::IsAddAllowed()
1257 DBG_CHKTHIS(OJoinTableView,NULL);
1259 // nicht wenn Db readonly
1260 if (m_pView->getController().isReadOnly())
1261 return FALSE;
1265 Reference< XConnection> xConnection = m_pView->getController().getConnection();
1266 if(!xConnection.is())
1267 return FALSE;
1268 // nicht wenn schon zuviele Tabellen
1269 Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1271 sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1272 if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1273 return FALSE;
1275 catch(SQLException&)
1277 return FALSE;
1280 // nicht wenn keine Joins moeglich
1281 // if (!GetDatabase()->IsCapable(SDB_CAP_JOIN) && nMax <= GetTabWinCount())
1282 // return FALSE;
1284 return TRUE;
1286 // -----------------------------------------------------------------------------
1287 void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1289 PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1290 switch (aContextMenu.Execute(this, _aPos))
1292 case SID_DELETE:
1293 RemoveConnection( _pSelConnection ,sal_True);
1294 break;
1295 case ID_QUERY_EDIT_JOINCONNECTION:
1296 ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1297 break;
1300 //------------------------------------------------------------------------------
1301 void OJoinTableView::Command(const CommandEvent& rEvt)
1303 DBG_CHKTHIS(OJoinTableView,NULL);
1305 BOOL bHandled = FALSE;
1307 switch (rEvt.GetCommand())
1309 case COMMAND_CONTEXTMENU:
1311 if( m_vTableConnection.empty() )
1312 return;
1314 OTableConnection* pSelConnection = GetSelectedConn();
1315 // when it wasn't a mouse event use the selected connection
1316 if (!rEvt.IsMouseEvent())
1318 if( pSelConnection )
1320 const ::std::vector<OConnectionLine*>* pLines = pSelConnection->GetConnLineList();
1321 ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(pLines->begin(),pLines->end(),::std::mem_fun(&OConnectionLine::IsValid));
1322 if( aIter != pLines->end() )
1323 executePopup((*aIter)->getMidPoint(),pSelConnection);
1326 else
1328 DeselectConn(pSelConnection);
1330 const Point& aMousePos = rEvt.GetMousePosPixel();
1331 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1332 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1333 for(;aIter != aEnd;++aIter)
1335 if( (*aIter)->CheckHit(aMousePos) )
1337 SelectConn(*aIter);
1338 if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1339 executePopup(rEvt.GetMousePosPixel(),*aIter);
1340 break;
1344 bHandled = TRUE;
1347 if (!bHandled)
1348 Window::Command(rEvt);
1351 //------------------------------------------------------------------------------
1352 OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1354 OTableConnection* pConn = NULL;
1355 DBG_ASSERT(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1356 // only one NULL-arg allowed
1358 if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1360 BOOL bFoundStart = _rpFirstAfter ? FALSE : TRUE;
1362 ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
1363 ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
1364 for(;aIter != aEnd;++aIter)
1366 OTableConnection* pData = *aIter;
1368 if ( ( (pData->GetSourceWin() == pLhs)
1369 && ( (pData->GetDestWin() == pRhs)
1370 || (NULL == pRhs)
1373 || ( (pData->GetSourceWin() == pRhs)
1374 && ( (pData->GetDestWin() == pLhs)
1375 || (NULL == pLhs)
1380 if ( _bSupressCrossOrNaturalJoin )
1382 if ( supressCrossNaturalJoin(pData->GetData()) )
1383 continue;
1385 if (bFoundStart)
1387 pConn = pData;
1388 break;
1391 if (!pConn)
1392 // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1393 // will be used
1394 pConn = pData;
1396 if (pData == _rpFirstAfter)
1397 bFoundStart = TRUE;
1401 return pConn;
1404 //------------------------------------------------------------------------------
1405 long OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1407 BOOL bHandled = FALSE;
1408 switch (rNEvt.GetType())
1410 case EVENT_COMMAND:
1412 const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1413 if (pCommand->GetCommand() == COMMAND_WHEEL)
1415 const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1416 if (pData->GetMode() == COMMAND_WHEEL_SCROLL)
1418 if (pData->GetDelta() > 0)
1419 ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), TRUE);
1420 else
1421 ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), TRUE);
1422 bHandled = TRUE;
1426 break;
1427 case EVENT_KEYINPUT:
1429 if (m_aTableMap.empty())
1430 // no tab wins -> no conns -> no traveling
1431 break;
1433 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1434 if (!pKeyEvent->GetKeyCode().IsMod1())
1436 switch (pKeyEvent->GetKeyCode().GetCode())
1438 case KEY_TAB:
1440 if (!HasChildPathFocus())
1441 break;
1443 BOOL bForward = !pKeyEvent->GetKeyCode().IsShift();
1444 // is there an active tab win ?
1445 OTableWindowMapIterator aIter = m_aTableMap.begin();
1446 OTableWindowMapIterator aEnd = m_aTableMap.end();
1447 for(;aIter != aEnd;++aIter)
1448 if (aIter->second && aIter->second->HasChildPathFocus())
1449 break;
1451 OTableWindow* pNextWin = NULL;
1452 OTableConnection* pNextConn = NULL;
1454 if (aIter != m_aTableMap.end())
1455 { // there is a currently active tab win
1456 // check if there is an "overflow" and we should select a conn instead of a win
1457 if (!m_vTableConnection.empty())
1459 if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1460 // the last win is active and we're travelling forward -> select the first conn
1461 pNextConn = *m_vTableConnection.begin();
1462 if ((aIter == m_aTableMap.begin()) && !bForward)
1463 // the first win is active an we're traveling backward -> select the last conn
1464 pNextConn = *m_vTableConnection.rbegin();
1467 if (!pNextConn)
1469 // no conn for any reason -> select the next or previous tab win
1470 if(bForward)
1472 if ((aIter->second == m_aTableMap.rbegin()->second))
1473 pNextWin = m_aTableMap.begin()->second;
1474 else
1476 ++aIter;
1477 pNextWin = aIter->second;
1480 else
1482 if (aIter == m_aTableMap.begin())
1483 pNextWin = m_aTableMap.rbegin()->second;
1484 else
1486 --aIter;
1487 pNextWin = aIter->second;
1492 else
1493 { // no active tab win -> travel the connections
1494 // find the currently selected conn within the conn list
1495 sal_Int32 i(0);
1496 for ( ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
1497 connectionIter != m_vTableConnection.end();
1498 ++connectionIter, ++i
1501 if ( (*connectionIter) == GetSelectedConn() )
1502 break;
1504 if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1505 // the last conn is active and we're travelling forward -> select the first win
1506 pNextWin = m_aTableMap.begin()->second;
1507 if ((i == 0) && !bForward && !m_aTableMap.empty())
1508 // the first conn is active and we're travelling backward -> select the last win
1509 pNextWin = m_aTableMap.rbegin()->second;
1511 if (pNextWin)
1512 DeselectConn(GetSelectedConn());
1513 else
1514 // no win for any reason -> select the next or previous conn
1515 if (i < (sal_Int32)m_vTableConnection.size())
1516 // there is a currently active conn
1517 pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1518 else
1519 { // no tab win selected, no conn selected
1520 if (!m_vTableConnection.empty())
1521 pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1522 else if (!m_aTableMap.empty())
1524 if(bForward)
1525 pNextWin = m_aTableMap.begin()->second;
1526 else
1527 pNextWin = m_aTableMap.rbegin()->second;
1532 // now select the object
1533 if (pNextWin)
1535 if (pNextWin->GetListBox())
1536 pNextWin->GetListBox()->GrabFocus();
1537 else
1538 pNextWin->GrabFocus();
1539 EnsureVisible(pNextWin);
1541 else if (pNextConn)
1543 GrabFocus();
1544 // neccessary : a conn may be selected even if a tab win has the focus, in this case
1545 // the next travel would select the same conn again if we would not reset te focus ...
1546 SelectConn(pNextConn);
1549 break;
1550 case KEY_RETURN:
1552 if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1553 ConnDoubleClicked(GetSelectedConn());
1554 break;
1559 break;
1560 case EVENT_GETFOCUS:
1562 if (m_aTableMap.empty())
1563 // no tab wins -> no conns -> no focus change
1564 break;
1565 Window* pSource = rNEvt.GetWindow();
1566 if (pSource)
1568 Window* pSearchFor = NULL;
1569 if (pSource->GetParent() == this)
1570 // it may be one of the tab wins
1571 pSearchFor = pSource;
1572 else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1573 // it may be one of th list boxes of one of the tab wins
1574 pSearchFor = pSource->GetParent();
1576 if (pSearchFor)
1578 OTableWindowMapIterator aIter = m_aTableMap.begin();
1579 OTableWindowMapIterator aEnd = m_aTableMap.end();
1580 for(;aIter != aEnd;++aIter)
1582 if (aIter->second == pSearchFor)
1584 m_pLastFocusTabWin = aIter->second;
1585 break;
1591 break;
1594 if (!bHandled)
1595 return Window::PreNotify(rNEvt);
1596 return 1L;
1599 //------------------------------------------------------------------------------
1600 void OJoinTableView::GrabTabWinFocus()
1602 if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1604 if (m_pLastFocusTabWin->GetListBox())
1605 m_pLastFocusTabWin->GetListBox()->GrabFocus();
1606 else
1607 m_pLastFocusTabWin->GrabFocus();
1609 else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1611 OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1612 if (pFirstWin->GetListBox())
1613 pFirstWin->GetListBox()->GrabFocus();
1614 else
1615 pFirstWin->GrabFocus();
1618 // -----------------------------------------------------------------------------
1619 void OJoinTableView::StateChanged( StateChangedType nType )
1621 Window::StateChanged( nType );
1623 if ( nType == STATE_CHANGE_ZOOM )
1625 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1627 Font aFont = rStyleSettings.GetGroupFont();
1628 if ( IsControlFont() )
1629 aFont.Merge( GetControlFont() );
1630 SetZoomedPointFont( aFont );
1632 OTableWindowMapIterator aIter = m_aTableMap.begin();
1633 OTableWindowMapIterator aEnd = m_aTableMap.end();
1634 for(;aIter != aEnd;++aIter)
1636 aIter->second->SetZoom(GetZoom());
1637 Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1638 aIter->second->SetSizePixel(aSize);
1640 Resize();
1643 //------------------------------------------------------------------------------
1644 void OJoinTableView::HideTabWins()
1646 DBG_CHKTHIS(OJoinTableView,NULL);
1647 SetUpdateMode(sal_False);
1649 OTableWindowMap* pTabWins = GetTabWinMap();
1650 if ( pTabWins )
1652 // working on a copy because the real list will be cleared in inner calls
1653 OTableWindowMap aCopy(*pTabWins);
1654 OTableWindowMap::iterator aIter = aCopy.begin();
1655 OTableWindowMap::iterator aEnd = aCopy.end();
1656 for(;aIter != aEnd;++aIter)
1657 RemoveTabWin(aIter->second);
1660 m_pView->getController().setModified(sal_True);
1662 SetUpdateMode(sal_True);
1665 // -----------------------------------------------------------------------------
1666 sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1668 return DND_ACTION_NONE;
1670 // -----------------------------------------------------------------------------
1671 sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1673 return DND_ACTION_NONE;
1675 // -----------------------------------------------------------------------------
1676 void OJoinTableView::dragFinished( )
1679 //------------------------------------------------------------------------------
1680 void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1683 // -----------------------------------------------------------------------------
1684 void OJoinTableView::clearLayoutInformation()
1686 m_pLastFocusTabWin = NULL;
1687 m_pSelectedConn = NULL;
1688 //////////////////////////////////////////////////////////////////////
1689 // Listen loeschen
1690 OTableWindowMapIterator aIter = m_aTableMap.begin();
1691 OTableWindowMapIterator aEnd = m_aTableMap.end();
1692 for(;aIter != aEnd;++aIter)
1694 if ( aIter->second )
1695 aIter->second->clearListBox();
1696 ::std::auto_ptr<Window> aTemp(aIter->second);
1697 aIter->second = NULL;
1700 m_aTableMap.clear();
1702 ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
1703 ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
1704 for(;aIter2 != aEnd2;++aIter2)
1705 delete *aIter2;
1707 m_vTableConnection.clear();
1709 // -----------------------------------------------------------------------------
1710 void OJoinTableView::lookForUiActivities()
1713 // -----------------------------------------------------------------------------
1714 void OJoinTableView::LoseFocus()
1716 DeselectConn(GetSelectedConn());
1717 Window::LoseFocus();
1719 // -----------------------------------------------------------------------------
1720 void OJoinTableView::GetFocus()
1722 Window::GetFocus();
1723 if ( !m_aTableMap.empty() && !GetSelectedConn() )
1724 GrabTabWinFocus();
1726 // -----------------------------------------------------------------------------
1727 Reference< XAccessible > OJoinTableView::CreateAccessible()
1729 m_pAccessible = new OJoinDesignViewAccess(this);
1730 return m_pAccessible;
1732 // -----------------------------------------------------------------------------
1733 void OJoinTableView::modified()
1735 OJoinController& rController = m_pView->getController();
1736 rController.setModified( sal_True );
1737 rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1738 rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1740 // -----------------------------------------------------------------------------
1741 void OJoinTableView::addConnection(OTableConnection* _pConnection,sal_Bool _bAddData)
1743 if ( _bAddData )
1745 #if OSL_DEBUG_LEVEL > 0
1746 TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
1747 OSL_ENSURE( ::std::find(pTabConnDataList->begin(),pTabConnDataList->end(),_pConnection->GetData()) == pTabConnDataList->end(),"Data already in vector!");
1748 #endif
1749 m_pView->getController().getTableConnectionData()->push_back(_pConnection->GetData());
1751 m_vTableConnection.push_back(_pConnection);
1752 _pConnection->RecalcLines();
1753 _pConnection->InvalidateConnection();
1755 modified();
1756 if ( m_pAccessible )
1757 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
1758 Any(),
1759 makeAny(_pConnection->GetAccessible()));
1761 // -----------------------------------------------------------------------------
1762 bool OJoinTableView::allowQueries() const
1764 return true;
1766 // -----------------------------------------------------------------------------
1767 void OJoinTableView::onNoColumns_throw()
1769 OSL_ENSURE( false, "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1770 throw SQLException();
1772 //------------------------------------------------------------------------------
1773 bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1775 return false;