bump product version to 4.1.6.2
[LibreOffice.git] / dbaccess / source / ui / querydesign / JoinTableView.cxx
blobebe877782c342a82196c3d64a9946a6914cb2cd3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "JoinTableView.hxx"
21 #include <osl/diagnose.h>
22 #include "querycontroller.hxx"
23 #include "JoinDesignView.hxx"
24 #include "dbu_qry.hrc"
25 #include "TableWindow.hxx"
26 #include "TableWindowListBox.hxx"
27 #include "TableConnection.hxx"
28 #include "TableConnectionData.hxx"
29 #include "ConnectionLine.hxx"
30 #include "ConnectionLineData.hxx"
31 #include "browserids.hxx"
32 #include <svl/urlbmk.hxx>
33 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
34 #include "QueryMoveTabWinUndoAct.hxx"
35 #include "QuerySizeTabWinUndoAct.hxx"
36 #include <vcl/svapp.hxx>
37 #include "TableWindowData.hxx"
38 #include "JAccess.hxx"
39 #include <com/sun/star/accessibility/XAccessible.hpp>
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 #include "UITools.hxx"
43 #include <cppuhelper/exc_hlp.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <tools/diagnose_ex.h>
46 #include <boost/bind.hpp>
47 #include <algorithm>
48 #include <functional>
50 using namespace dbaui;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::accessibility;
54 using namespace ::com::sun::star::container;
55 using namespace ::com::sun::star::lang;
57 #define LINE_SIZE 50
58 ////////////////////////////////////////////////////////////////
59 // Constants for the window layout
60 #define TABWIN_SPACING_X 17
61 #define TABWIN_SPACING_Y 17
63 #define TABWIN_WIDTH_STD 120
64 #define TABWIN_HEIGHT_STD 120
66 DBG_NAME(OScrollWindowHelper)
67 OScrollWindowHelper::OScrollWindowHelper( Window* pParent) : Window( pParent)
68 ,m_aHScrollBar( this, WB_HSCROLL|WB_REPEAT|WB_DRAG )
69 ,m_aVScrollBar( this, WB_VSCROLL|WB_REPEAT|WB_DRAG )
70 ,m_pCornerWindow(new ScrollBarBox(this, WB_3DLOOK))
71 ,m_pTableView(NULL)
73 DBG_CTOR(OScrollWindowHelper,NULL);
75 //////////////////////////////////////////////////////////////////////
76 // ScrollBars
78 GetHScrollBar()->SetRange( Range(0, 1000) );
79 GetVScrollBar()->SetRange( Range(0, 1000) );
81 GetHScrollBar()->SetLineSize( LINE_SIZE );
82 GetVScrollBar()->SetLineSize( LINE_SIZE );
84 GetHScrollBar()->Show();
85 GetVScrollBar()->Show();
86 m_pCornerWindow->Show();
88 // normally we should be SCROLL_PANE
89 SetAccessibleRole(AccessibleRole::SCROLL_PANE);
92 // -----------------------------------------------------------------------------
93 OScrollWindowHelper::~OScrollWindowHelper()
95 DBG_DTOR(OScrollWindowHelper,NULL);
96 SAL_WNODEPRECATED_DECLARATIONS_PUSH
97 ::std::auto_ptr<Window> aTemp(m_pCornerWindow);
98 SAL_WNODEPRECATED_DECLARATIONS_POP
99 m_pCornerWindow = NULL;
100 m_pTableView = NULL;
103 // -----------------------------------------------------------------------------
104 void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
106 m_pTableView = _pTableView;
107 //////////////////////////////////////////////////////////////////////
108 // ScrollBars
109 GetHScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
110 GetVScrollBar()->SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
112 // -----------------------------------------------------------------------------
113 void OScrollWindowHelper::resetRange(const Point& _aSize)
115 Point aPos = PixelToLogic(_aSize);
116 GetHScrollBar()->SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
117 GetVScrollBar()->SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
119 //------------------------------------------------------------------------------
120 void OScrollWindowHelper::Resize()
122 Window::Resize();
124 Size aTotalOutputSize = GetOutputSizePixel();
125 long nHScrollHeight = GetHScrollBar()->GetSizePixel().Height();
126 long nVScrollWidth = GetVScrollBar()->GetSizePixel().Width();
128 GetHScrollBar()->SetPosSizePixel(
129 Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
130 Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
133 GetVScrollBar()->SetPosSizePixel(
134 Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
135 Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
138 m_pCornerWindow->SetPosSizePixel(
139 Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
140 Size( nVScrollWidth, nHScrollHeight )
143 GetHScrollBar()->SetPageSize( aTotalOutputSize.Width() );
144 GetHScrollBar()->SetVisibleSize( aTotalOutputSize.Width() );
146 GetVScrollBar()->SetPageSize( aTotalOutputSize.Height() );
147 GetVScrollBar()->SetVisibleSize( aTotalOutputSize.Height() );
149 // adjust the ranges of the scrollbars if necessary
150 long lRange = GetHScrollBar()->GetRange().Max() - GetHScrollBar()->GetRange().Min();
151 if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
152 GetHScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar()->GetRange().Min());
154 lRange = GetVScrollBar()->GetRange().Max() - GetVScrollBar()->GetRange().Min();
155 if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
156 GetVScrollBar()->SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar()->GetRange().Min());
158 m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
160 // -----------------------------------------------------------------------------
161 // -----------------------------------------------------------------------------
162 //==================================================================
163 // class OJoinTableView
164 //==================================================================
166 DBG_NAME(OJoinTableView);
167 //------------------------------------------------------------------------------
168 OJoinTableView::OJoinTableView( Window* pParent, OJoinDesignView* pView )
169 :Window( pParent,WB_BORDER )
170 ,DropTargetHelper(this)
171 ,m_aDragOffset( Point(0,0) )
172 ,m_aScrollOffset( Point(0,0) )
173 ,m_pDragWin( NULL )
174 ,m_pSizingWin( NULL )
175 ,m_pSelectedConn( NULL )
176 ,m_bTrackingInitiallyMoved(sal_False)
177 ,m_pLastFocusTabWin(NULL)
178 ,m_pView( pView )
179 ,m_pAccessible(NULL)
181 DBG_CTOR(OJoinTableView,NULL);
182 SetSizePixel( Size(1000, 1000) );
184 InitColors();
186 m_aDragScrollTimer.SetTimeoutHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
189 //------------------------------------------------------------------------------
190 OJoinTableView::~OJoinTableView()
192 DBG_DTOR(OJoinTableView,NULL);
193 if( m_pAccessible )
195 m_pAccessible->clearTableView();
196 m_pAccessible = NULL;
198 //////////////////////////////////////////////////////////////////////
199 // delete lists
200 clearLayoutInformation();
202 //------------------------------------------------------------------------------
203 IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
205 //////////////////////////////////////////////////////////////////////
206 // move all windows
207 ScrollPane( pScrollBar->GetDelta(), (pScrollBar == GetHScrollBar()), sal_False );
209 return 0;
211 //------------------------------------------------------------------------------
212 void OJoinTableView::Resize()
214 DBG_CHKTHIS(OJoinTableView,NULL);
215 Window::Resize();
216 m_aOutputSize = GetSizePixel();
218 // tab win positions may not be up-to-date
219 if (m_aTableMap.empty())
220 // no tab wins ...
221 return;
223 // we have at least one table so resize it
224 m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
225 m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
227 OTableWindow* pCheck = m_aTableMap.begin()->second;
228 Point aRealPos = pCheck->GetPosPixel();
229 Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
231 if (aRealPos == aAssumedPos)
232 // all ok
233 return;
235 OTableWindowMapIterator aIter = m_aTableMap.begin();
236 OTableWindowMapIterator aEnd = m_aTableMap.end();
237 for(;aIter != aEnd;++aIter)
239 OTableWindow* pCurrent = aIter->second;
240 Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
241 pCurrent->SetPosPixel(aPos);
244 //------------------------------------------------------------------------------
245 sal_uLong OJoinTableView::GetTabWinCount()
247 DBG_CHKTHIS(OJoinTableView,NULL);
248 return m_aTableMap.size();
251 //------------------------------------------------------------------------------
252 bool OJoinTableView::RemoveConnection( OTableConnection* _pConn,sal_Bool _bDelete )
254 DBG_CHKTHIS(OJoinTableView,NULL);
255 DeselectConn(_pConn);
257 // to force a redraw
258 _pConn->InvalidateConnection();
260 m_pView->getController().removeConnectionData( _pConn->GetData() );
262 m_vTableConnection.erase(
263 ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn) );
265 modified();
266 if ( m_pAccessible )
267 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
268 makeAny(_pConn->GetAccessible()),
269 Any());
270 if ( _bDelete )
272 delete _pConn;
275 return true;
278 //------------------------------------------------------------------------
279 OTableWindow* OJoinTableView::GetTabWindow( const String& rName )
281 DBG_CHKTHIS(OJoinTableView,NULL);
282 OTableWindowMapIterator aIter = m_aTableMap.find(rName);
284 return aIter == m_aTableMap.end() ? NULL : aIter->second;
286 // -----------------------------------------------------------------------------
287 TTableWindowData::value_type OJoinTableView::createTableWindowData(const OUString& _rComposedName
288 ,const OUString& _sTableName
289 ,const OUString& _rWinName)
291 TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
292 OJoinDesignView* pParent = getDesignView();
295 if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
297 if ( pData->isValid() )
298 onNoColumns_throw();
299 else
300 pData.reset();
303 catch ( const SQLException& )
305 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
306 pParent, pParent->getController().getORB() );
308 catch( const WrappedTargetException& e )
310 SQLException aSql;
311 if ( e.TargetException >>= aSql )
312 ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
314 catch( const Exception& )
316 DBG_UNHANDLED_EXCEPTION();
318 return pData;
320 // -----------------------------------------------------------------------------
321 OTableWindowData* OJoinTableView::CreateImpl(const OUString& _rComposedName
322 ,const OUString& _sTableName
323 ,const OUString& _rWinName)
325 return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
327 //------------------------------------------------------------------------------
328 void OJoinTableView::AddTabWin(const OUString& _rComposedName, const OUString& rWinName, sal_Bool /*bNewTable*/)
330 DBG_CHKTHIS(OJoinTableView,NULL);
331 OSL_ENSURE(!_rComposedName.isEmpty(),"There must be a table name supplied!");
333 TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
335 //////////////////////////////////////////////////////////////////
336 // insert new window in window list
337 OTableWindow* pNewTabWin = createWindow( pNewTabWinData );
338 if ( pNewTabWin->Init() )
340 m_pView->getController().getTableWindowData()->push_back( pNewTabWinData);
341 // when we already have a table with this name insert the full qualified one instead
342 if(m_aTableMap.find(rWinName) != m_aTableMap.end())
343 m_aTableMap[_rComposedName] = pNewTabWin;
344 else
345 m_aTableMap[rWinName] = pNewTabWin;
347 SetDefaultTabWinPosSize( pNewTabWin );
348 pNewTabWin->Show();
350 modified();
351 if ( m_pAccessible )
352 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
353 Any(),
354 makeAny(pNewTabWin->GetAccessible()));
356 else
358 pNewTabWin->clearListBox();
359 delete pNewTabWin;
363 //------------------------------------------------------------------------------
364 void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
366 DBG_CHKTHIS(OJoinTableView,NULL);
367 //////////////////////////////////////////////////////////////////////
368 // first delete all connections of this window to others
369 bool bRemove = true;
370 TTableWindowData::value_type pData = pTabWin->GetData();
371 sal_Int32 nCount = m_vTableConnection.size();
372 ::std::vector<OTableConnection*>::reverse_iterator aIter = m_vTableConnection.rbegin();
373 while(aIter != m_vTableConnection.rend() && bRemove)
375 OTableConnection* pTabConn = (*aIter);
377 ( pData == pTabConn->GetData()->getReferencingTable()) ||
378 ( pData == pTabConn->GetData()->getReferencedTable())
381 bRemove = RemoveConnection( pTabConn ,sal_True);
382 aIter = m_vTableConnection.rbegin();
384 else
385 ++aIter;
388 //////////////////////////////////////////////////////////////////////
389 // then delete the window itself
390 if ( bRemove )
392 if ( m_pAccessible )
393 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
394 makeAny(pTabWin->GetAccessible()),Any()
397 pTabWin->Hide();
398 OJoinController& rController = m_pView->getController();
399 TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData()->begin(),rController.getTableWindowData()->end(),pData);
400 if(aFind != rController.getTableWindowData()->end())
402 rController.getTableWindowData()->erase(aFind);
403 rController.setModified(sal_True);
406 String aWinName = pTabWin->GetWinName();
407 if(m_aTableMap.find(aWinName) != m_aTableMap.end())
408 m_aTableMap.erase( aWinName );
409 else
410 m_aTableMap.erase( pTabWin->GetComposedName() );
412 if (pTabWin == m_pLastFocusTabWin)
413 m_pLastFocusTabWin = NULL;
415 pTabWin->clearListBox();
416 delete pTabWin;
419 if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
420 modified();
422 namespace
424 // -----------------------------------------------------------------------------
425 sal_Bool isScrollAllowed( OJoinTableView* _pView,long nDelta, sal_Bool bHoriz)
427 //////////////////////////////////////////////////////////////////////
428 // adjust ScrollBar-Positions
429 ScrollBar* pBar = _pView->GetVScrollBar();
430 if( bHoriz )
431 pBar = _pView->GetHScrollBar();
433 long nOldThumbPos = pBar->GetThumbPos();
434 long nNewThumbPos = nOldThumbPos + nDelta;
435 if( nNewThumbPos < 0 )
436 nNewThumbPos = 0;
437 else if( nNewThumbPos > pBar->GetRangeMax() )
438 nNewThumbPos = pBar->GetRangeMax();
440 if ( bHoriz )
442 if( nNewThumbPos == _pView->GetScrollOffset().X() )
443 return sal_False;
445 else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
446 return sal_False;
448 return sal_True;
450 // -----------------------------------------------------------------------------
451 sal_Bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
453 _nScrollY = _nScrollX = 0;
454 // data about the tab win
455 Point aUpperLeft = _rPoint;
456 // normalize with respect to visibility
457 aUpperLeft -= _pView->GetScrollOffset();
458 Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
460 // data about ourself
461 Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
463 sal_Bool bVisbile = sal_True;
464 sal_Bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
465 sal_Bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
466 if (!bFitsHor || !bFitsVert)
468 if (!bFitsHor)
470 // ensure the visibility of the right border
471 if ( aLowerRight.X() > aSize.Width() )
472 _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
474 // ensure the visibility of the left border (higher priority)
475 if ( aUpperLeft.X() < 0 )
476 _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
479 if (!bFitsVert)
481 // lower border
482 if ( aLowerRight.Y() > aSize.Height() )
483 _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
484 // upper border
485 if ( aUpperLeft.Y() < 0 )
486 _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
489 if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
490 bVisbile = isScrollAllowed(_pView,_nScrollX, sal_True);
492 if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
493 bVisbile = bVisbile && isScrollAllowed(_pView,_nScrollY, sal_False);
495 if ( bVisbile )
497 sal_Int32 nHRangeMax = _pView->GetHScrollBar()->GetRangeMax();
498 sal_Int32 nVRangeMax = _pView->GetVScrollBar()->GetRangeMax();
500 if ( aSize.Width() + _pView->GetHScrollBar()->GetThumbPos() + _nScrollX > nHRangeMax )
501 bVisbile = sal_False;
502 if ( bVisbile && aSize.Height() + _pView->GetVScrollBar()->GetThumbPos() + _nScrollY > nVRangeMax )
503 bVisbile = sal_False;
508 return bVisbile;
510 } // end of ano namespace
511 // -----------------------------------------------------------------------------
512 sal_Bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
514 long nX,nY;
515 return getMovementImpl(this,_rPoint,_rSize,nX,nY);
517 //------------------------------------------------------------------------------
518 void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
520 // data about the tab win
521 TTableWindowData::value_type pData = _pWin->GetData();
522 EnsureVisible( pData->GetPosition() , pData->GetSize());
523 Invalidate(INVALIDATE_NOCHILDREN);
525 //------------------------------------------------------------------------------
526 void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
528 long nScrollX,nScrollY;
530 if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
532 sal_Bool bVisbile = sal_True;
533 if (nScrollX)
534 bVisbile = ScrollPane(nScrollX, sal_True, sal_True);
536 if (nScrollY)
537 bVisbile = bVisbile && ScrollPane(nScrollY, sal_False, sal_True);
541 //------------------------------------------------------------------------------
542 void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
544 DBG_CHKTHIS(OJoinTableView,NULL);
545 //////////////////////////////////////////////////////////////////
546 // determine position:
547 // the window is divided into lines with height TABWIN_SPACING_Y+TABWIN_HEIGTH_STD.
548 // Then for each line is checked, if there is space for another window.
549 // If there is no space, the next line is checked.
550 Size aOutSize = GetSizePixel();
551 Point aNewPos( 0,0 );
552 sal_uInt16 nRow = 0;
553 sal_Bool bEnd = sal_False;
554 while( !bEnd )
556 //////////////////////////////////////////////////////////////////
557 // Set new position to start of line
558 aNewPos.X() = TABWIN_SPACING_X;
559 aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
561 //////////////////////////////////////////////////////////////////
562 // determine rectangle for the corresponding line
563 Rectangle aRowRect( Point(0,0), aOutSize );
564 aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
565 aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
567 //////////////////////////////////////////////////////////////////
568 // check occupied areas of this line
569 OTableWindow* pOtherTabWin;
570 OTableWindowMapIterator aIter = m_aTableMap.begin();
571 OTableWindowMapIterator aEnd = m_aTableMap.end();
572 for(;aIter != aEnd;++aIter)
574 pOtherTabWin = aIter->second;
575 Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
578 ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
579 ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
582 //////////////////////////////////////////////////////////////////
583 // TabWin is in the line
584 if( aOtherTabWinRect.Right()>aNewPos.X() )
585 aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
589 //////////////////////////////////////////////////////////////////
590 // Is there space left in this line?
591 if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
593 aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
594 bEnd = sal_True;
596 else
598 if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
600 // insert it in the first row
601 sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
602 ++nCount;
603 aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
604 bEnd = sal_True;
606 else
607 nRow++;
612 //////////////////////////////////////////////////////////////////
613 // determine size
614 Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
616 // check if the new position in inside the scrollbars ranges
617 Point aBottom(aNewPos);
618 aBottom.X() += aNewSize.Width();
619 aBottom.Y() += aNewSize.Height();
621 if(!GetHScrollBar()->GetRange().IsInside(aBottom.X()))
622 GetHScrollBar()->SetRange( Range(0, aBottom.X()) );
623 if(!GetVScrollBar()->GetRange().IsInside(aBottom.Y()))
624 GetVScrollBar()->SetRange( Range(0, aBottom.Y()) );
626 pTabWin->SetPosSizePixel( aNewPos, aNewSize );
629 //------------------------------------------------------------------------------
630 void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
632 DBG_CHKTHIS(OJoinTableView,NULL);
633 if (rDCEvt.GetType() == DATACHANGED_SETTINGS)
635 // consider the worst case: the colors changed, so adjust me
636 InitColors();
637 Invalidate(INVALIDATE_NOCHILDREN);
638 // due to the Invalidate, the connections are redrawn, so that they are also pictured in the new colors
642 //------------------------------------------------------------------------------
643 void OJoinTableView::InitColors()
645 DBG_CHKTHIS(OJoinTableView,NULL);
646 // the colors for the illustration should be the system colors
647 StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
648 SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
651 //------------------------------------------------------------------------------
652 void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
654 DBG_CHKTHIS(OJoinTableView,NULL);
656 if (m_pView->getController().isReadOnly())
657 return;
659 m_pDragWin = pTabWin;
660 SetPointer(Pointer(POINTER_MOVE));
661 Point aMousePos = ScreenToOutputPixel( rMousePos );
662 m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
663 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
664 m_bTrackingInitiallyMoved = sal_False;
665 StartTracking();
668 void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point rMousePos )
670 DBG_CHKTHIS(OJoinTableView,NULL);
671 DeselectConn(GetSelectedConn());
672 BeginChildMove(pTabWin, rMousePos);
675 //------------------------------------------------------------------------------
676 void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
678 DBG_CHKTHIS(OJoinTableView,NULL);
680 if (m_pView->getController().isReadOnly())
681 return;
683 SetPointer( rPointer );
684 m_pSizingWin = pTabWin;
685 StartTracking();
688 //------------------------------------------------------------------------------
689 sal_Bool OJoinTableView::ScrollPane( long nDelta, sal_Bool bHoriz, sal_Bool bPaintScrollBars )
691 DBG_CHKTHIS(OJoinTableView,NULL);
692 sal_Bool bRet = sal_True;
694 //////////////////////////////////////////////////////////////////////
695 // adjust ScrollBar-Positions
696 if( bPaintScrollBars )
698 if( bHoriz )
700 long nOldThumbPos = GetHScrollBar()->GetThumbPos();
701 long nNewThumbPos = nOldThumbPos + nDelta;
702 if( nNewThumbPos < 0 )
704 nNewThumbPos = 0;
705 bRet = sal_False;
707 if( nNewThumbPos > GetHScrollBar()->GetRange().Max() )
709 nNewThumbPos = GetHScrollBar()->GetRange().Max();
710 bRet = sal_False;
712 GetHScrollBar()->SetThumbPos( nNewThumbPos );
713 nDelta = GetHScrollBar()->GetThumbPos() - nOldThumbPos;
715 else
717 long nOldThumbPos = GetVScrollBar()->GetThumbPos();
718 long nNewThumbPos = nOldThumbPos+nDelta;
719 if( nNewThumbPos < 0 )
721 nNewThumbPos = 0;
722 bRet = sal_False;
724 if( nNewThumbPos > GetVScrollBar()->GetRange().Max() )
726 nNewThumbPos = GetVScrollBar()->GetRange().Max();
727 bRet = sal_False;
729 GetVScrollBar()->SetThumbPos( nNewThumbPos );
730 nDelta = GetVScrollBar()->GetThumbPos() - nOldThumbPos;
734 //////////////////////////////////////////////////////////////////////
735 // If ScrollOffset hitting borders, no redrawing.
736 if( (GetHScrollBar()->GetThumbPos()==m_aScrollOffset.X()) &&
737 (GetVScrollBar()->GetThumbPos()==m_aScrollOffset.Y()) )
738 return sal_False;
740 //////////////////////////////////////////////////////////////////////
741 // set ScrollOffset anew
742 if (bHoriz)
743 m_aScrollOffset.X() = GetHScrollBar()->GetThumbPos();
744 else
745 m_aScrollOffset.Y() = GetVScrollBar()->GetThumbPos();
747 //////////////////////////////////////////////////////////////////////
748 // move all windows
749 OTableWindow* pTabWin;
750 Point aPos;
752 OTableWindowMapIterator aIter = m_aTableMap.begin();
753 OTableWindowMapIterator aEnd = m_aTableMap.end();
754 for(;aIter != aEnd;++aIter)
756 pTabWin = aIter->second;
757 aPos = pTabWin->GetPosPixel();
759 if( bHoriz )
760 aPos.X() -= nDelta;
761 else aPos.Y() -= nDelta;
763 pTabWin->SetPosPixel( aPos );
766 Invalidate(); // INVALIDATE_NOCHILDREN
768 return bRet;
771 //------------------------------------------------------------------------------
772 void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
774 DBG_CHKTHIS(OJoinTableView,NULL);
775 HideTracking();
777 if (rTEvt.IsTrackingEnded())
779 if( m_pDragWin )
781 if (m_aDragScrollTimer.IsActive())
782 m_aDragScrollTimer.Stop();
784 //////////////////////////////////////////////////////////////////////
785 // adjust position of child after moving
786 //////////////////////////////////////////////////////////////////////
787 // windows are not allowed to leave display range
788 Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
789 Size aDragWinSize = m_pDragWin->GetSizePixel();
790 if( aDragWinPos.X() < 0 )
791 aDragWinPos.X() = 0;
792 if( aDragWinPos.Y() < 0 )
793 aDragWinPos.Y() = 0;
794 if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
795 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
796 if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
797 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
798 if( aDragWinPos.X() < 0 )
799 aDragWinPos.X() = 0;
800 if( aDragWinPos.Y() < 0 )
801 aDragWinPos.Y() = 0;
802 // TODO : don't position window anew, if it is leaving range, but just expand the range
805 //////////////////////////////////////////////////////////////////////
806 // position window
807 EndTracking();
808 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
809 // check, if I really moved
810 // (this prevents setting the modified-Flag, when there actually was no change0
811 TTableWindowData::value_type pData = m_pDragWin->GetData();
812 if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
814 // old logic coordinates
815 Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
816 // new positioning
817 m_pDragWin->SetPosPixel(aDragWinPos);
818 TabWinMoved(m_pDragWin, ptOldPos);
820 m_pDragWin->GrabFocus();
822 m_pDragWin = NULL;
823 SetPointer(Pointer(POINTER_ARROW));
825 // else we handle the resizing
826 else if( m_pSizingWin )
828 SetPointer( Pointer() );
829 EndTracking();
831 // old physical coordinates
833 Size szOld = m_pSizingWin->GetSizePixel();
834 Point ptOld = m_pSizingWin->GetPosPixel();
835 Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
836 m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
837 TabWinSized(m_pSizingWin, ptOld, szOld);
839 m_pSizingWin->Invalidate( m_aSizingRect );
840 m_pSizingWin = NULL;
843 else if (rTEvt.IsTrackingCanceled())
845 if (m_aDragScrollTimer.IsActive())
846 m_aDragScrollTimer.Stop();
847 EndTracking();
849 else
851 if( m_pDragWin )
853 m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
854 // scroll at window borders
855 ScrollWhileDragging();
858 if( m_pSizingWin )
860 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
861 m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
862 Update();
863 ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
868 //------------------------------------------------------------------------------
869 void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
871 DBG_CHKTHIS(OJoinTableView,NULL);
874 //------------------------------------------------------------------------------
875 void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
877 DBG_CHKTHIS(OJoinTableView,NULL);
878 GrabFocus();
879 Window::MouseButtonDown(rEvt);
882 //------------------------------------------------------------------------------
883 void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
885 DBG_CHKTHIS(OJoinTableView,NULL);
886 Window::MouseButtonUp(rEvt);
887 //////////////////////////////////////////////////////////////////////
888 // Has a connection been selected?
889 if( !m_vTableConnection.empty() )
891 DeselectConn(GetSelectedConn());
893 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
894 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
895 for(;aIter != aEnd;++aIter)
897 if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
899 SelectConn((*aIter));
901 // Double-click
902 if( rEvt.GetClicks() == 2 )
903 ConnDoubleClicked( (*aIter) );
905 break;
911 //------------------------------------------------------------------------------
912 void OJoinTableView::KeyInput( const KeyEvent& rEvt )
914 DBG_CHKTHIS(OJoinTableView,NULL);
915 sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
916 sal_Bool bShift = rEvt.GetKeyCode().IsShift();
917 sal_Bool bCtrl = rEvt.GetKeyCode().IsMod1();
919 if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
921 if (GetSelectedConn())
922 RemoveConnection( GetSelectedConn() ,sal_True);
924 else
925 Window::KeyInput( rEvt );
928 //------------------------------------------------------------------------------
929 void OJoinTableView::DeselectConn(OTableConnection* pConn)
931 DBG_CHKTHIS(OJoinTableView,NULL);
932 if (!pConn || !pConn->IsSelected())
933 return;
935 // deselect the corresponding entries in the ListBox of the table window
936 OTableWindow* pWin = pConn->GetSourceWin();
937 if (pWin && pWin->GetListBox())
938 pWin->GetListBox()->SelectAll(sal_False);
940 pWin = pConn->GetDestWin();
941 if (pWin && pWin->GetListBox())
942 pWin->GetListBox()->SelectAll(sal_False);
944 pConn->Deselect();
945 m_pSelectedConn = NULL;
948 //------------------------------------------------------------------------------
949 void OJoinTableView::SelectConn(OTableConnection* pConn)
951 DBG_CHKTHIS(OJoinTableView,NULL);
952 DeselectConn(GetSelectedConn());
954 pConn->Select();
955 m_pSelectedConn = pConn;
956 GrabFocus(); // has to be called here because a table window may still be focused
958 // select the concerned entries in the windows
959 OTableWindow* pConnSource = pConn->GetSourceWin();
960 OTableWindow* pConnDest = pConn->GetDestWin();
961 if (pConnSource && pConnDest)
963 OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
964 OTableWindowListBox* pDestBox = pConnDest->GetListBox();
965 if (pSourceBox && pDestBox)
967 pSourceBox->SelectAll(sal_False);
968 pDestBox->SelectAll(sal_False);
970 SvTreeListEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
971 SvTreeListEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
973 const ::std::vector<OConnectionLine*>* pLines = pConn->GetConnLineList();
974 ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = pLines->rbegin();
975 for(;aIter != pLines->rend();++aIter)
977 if ((*aIter)->IsValid())
979 SvTreeListEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
980 if (pSourceEntry)
982 pSourceBox->Select(pSourceEntry, sal_True);
983 pSourceBox->MakeVisible(pSourceEntry);
986 SvTreeListEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
987 if (pDestEntry)
989 pDestBox->Select(pDestEntry, sal_True);
990 pDestBox->MakeVisible(pDestEntry);
996 if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
997 || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
998 // scrolling was done -> redraw
999 Invalidate(INVALIDATE_NOCHILDREN);
1003 //------------------------------------------------------------------------------
1004 void OJoinTableView::Paint( const Rectangle& rRect )
1006 DBG_CHKTHIS(OJoinTableView,NULL);
1007 DrawConnections( rRect );
1010 //------------------------------------------------------------------------------
1011 void OJoinTableView::InvalidateConnections()
1013 DBG_CHKTHIS(OJoinTableView,NULL);
1014 //////////////////////////////////////////////////////////////////////
1015 // draw Joins
1016 ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),
1017 ::std::mem_fun(& OTableConnection::InvalidateConnection));
1020 //------------------------------------------------------------------------------
1021 void OJoinTableView::DrawConnections( const Rectangle& rRect )
1023 DBG_CHKTHIS(OJoinTableView,NULL);
1024 //////////////////////////////////////////////////////////////////////
1025 // draw Joins
1026 ::std::for_each(m_vTableConnection.begin(),m_vTableConnection.end(),boost::bind( &OTableConnection::Draw, _1, boost::cref( rRect )));
1027 // finally redraw the selected one above all others
1028 if (GetSelectedConn())
1029 GetSelectedConn()->Draw( rRect );
1033 //------------------------------------------------------------------------------
1034 ::std::vector<OTableConnection*>::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
1036 return ::std::find_if( m_vTableConnection.begin(),
1037 m_vTableConnection.end(),
1038 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1040 // -----------------------------------------------------------------------------
1041 sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
1043 return ::std::count_if( m_vTableConnection.begin(),
1044 m_vTableConnection.end(),
1045 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
1047 //------------------------------------------------------------------------------
1048 sal_Bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
1050 DBG_CHKTHIS(OJoinTableView,NULL);
1051 return getTableConnections(pFrom) != m_vTableConnection.end();
1053 //------------------------------------------------------------------------
1054 void OJoinTableView::ClearAll()
1056 DBG_CHKTHIS(OJoinTableView,NULL);
1057 SetUpdateMode(sal_False);
1059 HideTabWins();
1061 // and the same with the Connections
1062 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1063 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1064 for(;aIter != aEnd;++aIter)
1065 RemoveConnection( *aIter ,sal_True);
1066 m_vTableConnection.clear();
1068 m_pLastFocusTabWin = NULL;
1069 m_pSelectedConn = NULL;
1071 // scroll to the upper left
1072 ScrollPane(-GetScrollOffset().X(), sal_True, sal_True);
1073 ScrollPane(-GetScrollOffset().Y(), sal_False, sal_True);
1074 Invalidate();
1077 //------------------------------------------------------------------------
1078 sal_Bool OJoinTableView::ScrollWhileDragging()
1080 DBG_CHKTHIS(OJoinTableView,NULL);
1081 OSL_ENSURE(m_pDragWin != NULL, "OJoinTableView::ScrollWhileDragging must not be called when a window is being dragged !");
1083 // kill the timer
1084 if (m_aDragScrollTimer.IsActive())
1085 m_aDragScrollTimer.Stop();
1087 Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
1088 Size aDragWinSize = m_pDragWin->GetSizePixel();
1089 Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
1091 if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1092 return sal_True;
1094 // avoid illustration errors (when scrolling with active TrackingRect)
1095 HideTracking();
1097 sal_Bool bScrolling = sal_False;
1098 sal_Bool bNeedScrollTimer = sal_False;
1100 // scroll at window borders
1101 // TODO : only catch, if window would disappear completely (don't, if there is still a pixel visible)
1102 if( aDragWinPos.X() < 5 )
1104 bScrolling = ScrollPane( -LINE_SIZE, sal_True, sal_True );
1105 if( !bScrolling && (aDragWinPos.X()<0) )
1106 aDragWinPos.X() = 0;
1108 // do I need further (timer controlled) scrolling ?
1109 bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1112 if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1114 bScrolling = ScrollPane( LINE_SIZE, sal_True, sal_True ) ;
1115 if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1116 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1118 // do I need further (timer controlled) scrolling ?
1119 bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1122 if( aDragWinPos.Y() < 5 )
1124 bScrolling = ScrollPane( -LINE_SIZE, sal_False, sal_True );
1125 if( !bScrolling && (aDragWinPos.Y()<0) )
1126 aDragWinPos.Y() = 0;
1128 bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1131 if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1133 bScrolling = ScrollPane( LINE_SIZE, sal_False, sal_True );
1134 if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1135 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
1137 bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1140 // resetting timer, if still necessary
1141 if (bNeedScrollTimer)
1143 m_aDragScrollTimer.SetTimeout(100);
1144 m_aDragScrollTimer.Start();
1147 // redraw DraggingRect
1148 m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1149 Update();
1150 ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1152 return bScrolling;
1155 //------------------------------------------------------------------------
1156 IMPL_LINK_NOARG(OJoinTableView, OnDragScrollTimer)
1158 ScrollWhileDragging();
1159 return 0L;
1161 // -----------------------------------------------------------------------------
1162 void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1164 Invalidate(INVALIDATE_NOCHILDREN);
1165 m_pView->getController().addUndoActionAndInvalidate(_pAction);
1167 //------------------------------------------------------------------------
1168 void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1170 DBG_CHKTHIS(OJoinTableView,NULL);
1171 Point ptThumbPos(GetHScrollBar()->GetThumbPos(), GetVScrollBar()->GetThumbPos());
1172 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1174 invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1177 //------------------------------------------------------------------------
1178 void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1180 DBG_CHKTHIS(OJoinTableView,NULL);
1181 ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1182 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1184 invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1187 //------------------------------------------------------------------------------
1188 sal_Bool OJoinTableView::IsAddAllowed()
1190 DBG_CHKTHIS(OJoinTableView,NULL);
1192 // not, if Db readonly
1193 if (m_pView->getController().isReadOnly())
1194 return sal_False;
1198 Reference< XConnection> xConnection = m_pView->getController().getConnection();
1199 if(!xConnection.is())
1200 return sal_False;
1201 // not, if too many tables already
1202 Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1204 sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1205 if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1206 return sal_False;
1208 catch(SQLException&)
1210 return sal_False;
1213 return sal_True;
1215 // -----------------------------------------------------------------------------
1216 void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1218 PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1219 switch (aContextMenu.Execute(this, _aPos))
1221 case SID_DELETE:
1222 RemoveConnection( _pSelConnection ,sal_True);
1223 break;
1224 case ID_QUERY_EDIT_JOINCONNECTION:
1225 ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1226 break;
1229 //------------------------------------------------------------------------------
1230 void OJoinTableView::Command(const CommandEvent& rEvt)
1232 DBG_CHKTHIS(OJoinTableView,NULL);
1234 sal_Bool bHandled = sal_False;
1236 switch (rEvt.GetCommand())
1238 case COMMAND_CONTEXTMENU:
1240 if( m_vTableConnection.empty() )
1241 return;
1243 OTableConnection* pSelConnection = GetSelectedConn();
1244 // when it wasn't a mouse event use the selected connection
1245 if (!rEvt.IsMouseEvent())
1247 if( pSelConnection )
1249 const ::std::vector<OConnectionLine*>* pLines = pSelConnection->GetConnLineList();
1250 ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(pLines->begin(),pLines->end(),::std::mem_fun(&OConnectionLine::IsValid));
1251 if( aIter != pLines->end() )
1252 executePopup((*aIter)->getMidPoint(),pSelConnection);
1255 else
1257 DeselectConn(pSelConnection);
1259 const Point& aMousePos = rEvt.GetMousePosPixel();
1260 ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
1261 ::std::vector<OTableConnection*>::iterator aEnd = m_vTableConnection.end();
1262 for(;aIter != aEnd;++aIter)
1264 if( (*aIter)->CheckHit(aMousePos) )
1266 SelectConn(*aIter);
1267 if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1268 executePopup(rEvt.GetMousePosPixel(),*aIter);
1269 break;
1273 bHandled = sal_True;
1276 if (!bHandled)
1277 Window::Command(rEvt);
1280 //------------------------------------------------------------------------------
1281 OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1283 OTableConnection* pConn = NULL;
1284 OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1285 // only one NULL-arg allowed
1287 if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1289 sal_Bool bFoundStart = _rpFirstAfter ? sal_False : sal_True;
1291 ::std::vector<OTableConnection*>::const_iterator aIter = m_vTableConnection.begin();
1292 ::std::vector<OTableConnection*>::const_iterator aEnd = m_vTableConnection.end();
1293 for(;aIter != aEnd;++aIter)
1295 OTableConnection* pData = *aIter;
1297 if ( ( (pData->GetSourceWin() == pLhs)
1298 && ( (pData->GetDestWin() == pRhs)
1299 || (NULL == pRhs)
1302 || ( (pData->GetSourceWin() == pRhs)
1303 && ( (pData->GetDestWin() == pLhs)
1304 || (NULL == pLhs)
1309 if ( _bSupressCrossOrNaturalJoin )
1311 if ( supressCrossNaturalJoin(pData->GetData()) )
1312 continue;
1314 if (bFoundStart)
1316 pConn = pData;
1317 break;
1320 if (!pConn)
1321 // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1322 // will be used
1323 pConn = pData;
1325 if (pData == _rpFirstAfter)
1326 bFoundStart = sal_True;
1330 return pConn;
1333 //------------------------------------------------------------------------------
1334 long OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1336 sal_Bool bHandled = sal_False;
1337 switch (rNEvt.GetType())
1339 case EVENT_COMMAND:
1341 const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1342 if (pCommand->GetCommand() == COMMAND_WHEEL)
1344 const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1345 if (pData->GetMode() == COMMAND_WHEEL_SCROLL)
1347 if (pData->GetDelta() > 0)
1348 ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1349 else
1350 ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), sal_True);
1351 bHandled = sal_True;
1355 break;
1356 case EVENT_KEYINPUT:
1358 if (m_aTableMap.empty())
1359 // no tab wins -> no conns -> no traveling
1360 break;
1362 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1363 if (!pKeyEvent->GetKeyCode().IsMod1())
1365 switch (pKeyEvent->GetKeyCode().GetCode())
1367 case KEY_TAB:
1369 if (!HasChildPathFocus())
1370 break;
1372 sal_Bool bForward = !pKeyEvent->GetKeyCode().IsShift();
1373 // is there an active tab win ?
1374 OTableWindowMapIterator aIter = m_aTableMap.begin();
1375 OTableWindowMapIterator aEnd = m_aTableMap.end();
1376 for(;aIter != aEnd;++aIter)
1377 if (aIter->second && aIter->second->HasChildPathFocus())
1378 break;
1380 OTableWindow* pNextWin = NULL;
1381 OTableConnection* pNextConn = NULL;
1383 if (aIter != m_aTableMap.end())
1384 { // there is a currently active tab win
1385 // check if there is an "overflow" and we should select a conn instead of a win
1386 if (!m_vTableConnection.empty())
1388 if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1389 // the last win is active and we're travelling forward -> select the first conn
1390 pNextConn = *m_vTableConnection.begin();
1391 if ((aIter == m_aTableMap.begin()) && !bForward)
1392 // the first win is active an we're traveling backward -> select the last conn
1393 pNextConn = *m_vTableConnection.rbegin();
1396 if (!pNextConn)
1398 // no conn for any reason -> select the next or previous tab win
1399 if(bForward)
1401 if ( aIter->second == m_aTableMap.rbegin()->second )
1402 pNextWin = m_aTableMap.begin()->second;
1403 else
1405 ++aIter;
1406 pNextWin = aIter->second;
1409 else
1411 if (aIter == m_aTableMap.begin())
1412 pNextWin = m_aTableMap.rbegin()->second;
1413 else
1415 --aIter;
1416 pNextWin = aIter->second;
1421 else
1422 { // no active tab win -> travel the connections
1423 // find the currently selected conn within the conn list
1424 sal_Int32 i(0);
1425 for ( ::std::vector<OTableConnection*>::iterator connectionIter = m_vTableConnection.begin();
1426 connectionIter != m_vTableConnection.end();
1427 ++connectionIter, ++i
1430 if ( (*connectionIter) == GetSelectedConn() )
1431 break;
1433 if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1434 // the last conn is active and we're travelling forward -> select the first win
1435 pNextWin = m_aTableMap.begin()->second;
1436 if ((i == 0) && !bForward && !m_aTableMap.empty())
1437 // the first conn is active and we're travelling backward -> select the last win
1438 pNextWin = m_aTableMap.rbegin()->second;
1440 if (pNextWin)
1441 DeselectConn(GetSelectedConn());
1442 else
1443 // no win for any reason -> select the next or previous conn
1444 if (i < (sal_Int32)m_vTableConnection.size())
1445 // there is a currently active conn
1446 pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1447 else
1448 { // no tab win selected, no conn selected
1449 if (!m_vTableConnection.empty())
1450 pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1451 else if (!m_aTableMap.empty())
1453 if(bForward)
1454 pNextWin = m_aTableMap.begin()->second;
1455 else
1456 pNextWin = m_aTableMap.rbegin()->second;
1461 // now select the object
1462 if (pNextWin)
1464 if (pNextWin->GetListBox())
1465 pNextWin->GetListBox()->GrabFocus();
1466 else
1467 pNextWin->GrabFocus();
1468 EnsureVisible(pNextWin);
1470 else if (pNextConn)
1472 GrabFocus();
1473 // necessary : a conn may be selected even if a tab win has the focus, in this case
1474 // the next travel would select the same conn again if we would not reset te focus ...
1475 SelectConn(pNextConn);
1478 break;
1479 case KEY_RETURN:
1481 if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1482 ConnDoubleClicked(GetSelectedConn());
1483 break;
1488 break;
1489 case EVENT_GETFOCUS:
1491 if (m_aTableMap.empty())
1492 // no tab wins -> no conns -> no focus change
1493 break;
1494 Window* pSource = rNEvt.GetWindow();
1495 if (pSource)
1497 Window* pSearchFor = NULL;
1498 if (pSource->GetParent() == this)
1499 // it may be one of the tab wins
1500 pSearchFor = pSource;
1501 else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1502 // it may be one of th list boxes of one of the tab wins
1503 pSearchFor = pSource->GetParent();
1505 if (pSearchFor)
1507 OTableWindowMapIterator aIter = m_aTableMap.begin();
1508 OTableWindowMapIterator aEnd = m_aTableMap.end();
1509 for(;aIter != aEnd;++aIter)
1511 if (aIter->second == pSearchFor)
1513 m_pLastFocusTabWin = aIter->second;
1514 break;
1520 break;
1523 if (!bHandled)
1524 return Window::PreNotify(rNEvt);
1525 return 1L;
1528 //------------------------------------------------------------------------------
1529 void OJoinTableView::GrabTabWinFocus()
1531 if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1533 if (m_pLastFocusTabWin->GetListBox())
1534 m_pLastFocusTabWin->GetListBox()->GrabFocus();
1535 else
1536 m_pLastFocusTabWin->GrabFocus();
1538 else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1540 OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1541 if (pFirstWin->GetListBox())
1542 pFirstWin->GetListBox()->GrabFocus();
1543 else
1544 pFirstWin->GrabFocus();
1547 // -----------------------------------------------------------------------------
1548 void OJoinTableView::StateChanged( StateChangedType nType )
1550 Window::StateChanged( nType );
1552 if ( nType == STATE_CHANGE_ZOOM )
1554 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1556 Font aFont = rStyleSettings.GetGroupFont();
1557 if ( IsControlFont() )
1558 aFont.Merge( GetControlFont() );
1559 SetZoomedPointFont( aFont );
1561 OTableWindowMapIterator aIter = m_aTableMap.begin();
1562 OTableWindowMapIterator aEnd = m_aTableMap.end();
1563 for(;aIter != aEnd;++aIter)
1565 aIter->second->SetZoom(GetZoom());
1566 Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1567 aIter->second->SetSizePixel(aSize);
1569 Resize();
1572 //------------------------------------------------------------------------------
1573 void OJoinTableView::HideTabWins()
1575 DBG_CHKTHIS(OJoinTableView,NULL);
1576 SetUpdateMode(sal_False);
1578 OTableWindowMap* pTabWins = GetTabWinMap();
1579 if ( pTabWins )
1581 // working on a copy because the real list will be cleared in inner calls
1582 OTableWindowMap aCopy(*pTabWins);
1583 OTableWindowMap::iterator aIter = aCopy.begin();
1584 OTableWindowMap::iterator aEnd = aCopy.end();
1585 for(;aIter != aEnd;++aIter)
1586 RemoveTabWin(aIter->second);
1589 m_pView->getController().setModified(sal_True);
1591 SetUpdateMode(sal_True);
1594 // -----------------------------------------------------------------------------
1595 sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1597 return DND_ACTION_NONE;
1599 // -----------------------------------------------------------------------------
1600 sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1602 return DND_ACTION_NONE;
1604 // -----------------------------------------------------------------------------
1605 void OJoinTableView::dragFinished( )
1608 //------------------------------------------------------------------------------
1609 void OJoinTableView::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
1612 // -----------------------------------------------------------------------------
1613 void OJoinTableView::clearLayoutInformation()
1615 m_pLastFocusTabWin = NULL;
1616 m_pSelectedConn = NULL;
1617 //////////////////////////////////////////////////////////////////////
1618 // delete lists
1619 OTableWindowMapIterator aIter = m_aTableMap.begin();
1620 OTableWindowMapIterator aEnd = m_aTableMap.end();
1621 for(;aIter != aEnd;++aIter)
1623 if ( aIter->second )
1624 aIter->second->clearListBox();
1625 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1626 ::std::auto_ptr<Window> aTemp(aIter->second);
1627 SAL_WNODEPRECATED_DECLARATIONS_POP
1628 aIter->second = NULL;
1631 m_aTableMap.clear();
1633 ::std::vector<OTableConnection*>::const_iterator aIter2 = m_vTableConnection.begin();
1634 ::std::vector<OTableConnection*>::const_iterator aEnd2 = m_vTableConnection.end();
1635 for(;aIter2 != aEnd2;++aIter2)
1636 delete *aIter2;
1638 m_vTableConnection.clear();
1640 // -----------------------------------------------------------------------------
1641 void OJoinTableView::lookForUiActivities()
1644 // -----------------------------------------------------------------------------
1645 void OJoinTableView::LoseFocus()
1647 DeselectConn(GetSelectedConn());
1648 Window::LoseFocus();
1650 // -----------------------------------------------------------------------------
1651 void OJoinTableView::GetFocus()
1653 Window::GetFocus();
1654 if ( !m_aTableMap.empty() && !GetSelectedConn() )
1655 GrabTabWinFocus();
1657 // -----------------------------------------------------------------------------
1658 Reference< XAccessible > OJoinTableView::CreateAccessible()
1660 m_pAccessible = new OJoinDesignViewAccess(this);
1661 return m_pAccessible;
1663 // -----------------------------------------------------------------------------
1664 void OJoinTableView::modified()
1666 OJoinController& rController = m_pView->getController();
1667 rController.setModified( sal_True );
1668 rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1669 rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1671 // -----------------------------------------------------------------------------
1672 void OJoinTableView::addConnection(OTableConnection* _pConnection,sal_Bool _bAddData)
1674 if ( _bAddData )
1676 #if OSL_DEBUG_LEVEL > 0
1677 TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData();
1678 OSL_ENSURE( ::std::find(pTabConnDataList->begin(),pTabConnDataList->end(),_pConnection->GetData()) == pTabConnDataList->end(),"Data already in vector!");
1679 #endif
1680 m_pView->getController().getTableConnectionData()->push_back(_pConnection->GetData());
1682 m_vTableConnection.push_back(_pConnection);
1683 _pConnection->RecalcLines();
1684 _pConnection->InvalidateConnection();
1686 modified();
1687 if ( m_pAccessible )
1688 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
1689 Any(),
1690 makeAny(_pConnection->GetAccessible()));
1692 // -----------------------------------------------------------------------------
1693 bool OJoinTableView::allowQueries() const
1695 return true;
1697 // -----------------------------------------------------------------------------
1698 void OJoinTableView::onNoColumns_throw()
1700 OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1701 throw SQLException();
1703 //------------------------------------------------------------------------------
1704 bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1706 return false;
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */