fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / dbaccess / source / ui / querydesign / JoinTableView.cxx
bloba1dbb2df6e311768e85be2a734f1dca059e0f8ad
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 <vcl/settings.hxx>
38 #include "TableWindowData.hxx"
39 #include "JAccess.hxx"
40 #include <com/sun/star/accessibility/XAccessible.hpp>
41 #include <com/sun/star/accessibility/AccessibleRole.hpp>
42 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 #include "UITools.hxx"
44 #include <cppuhelper/exc_hlp.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <tools/diagnose_ex.h>
47 #include <boost/bind.hpp>
48 #include <boost/scoped_ptr.hpp>
49 #include <algorithm>
50 #include <functional>
52 using namespace dbaui;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::sdbc;
55 using namespace ::com::sun::star::accessibility;
56 using namespace ::com::sun::star::container;
57 using namespace ::com::sun::star::lang;
59 #define LINE_SIZE 50
60 // Constants for the window layout
61 #define TABWIN_SPACING_X 17
62 #define TABWIN_SPACING_Y 17
64 #define TABWIN_WIDTH_STD 120
65 #define TABWIN_HEIGHT_STD 120
67 OScrollWindowHelper::OScrollWindowHelper( vcl::Window* pParent) : Window( pParent)
68 ,m_aHScrollBar( VclPtr<ScrollBar>::Create(this, WB_HSCROLL|WB_REPEAT|WB_DRAG) )
69 ,m_aVScrollBar( VclPtr<ScrollBar>::Create(this, WB_VSCROLL|WB_REPEAT|WB_DRAG) )
70 ,m_pCornerWindow(VclPtr<ScrollBarBox>::Create(this, WB_3DLOOK))
71 ,m_pTableView(NULL)
74 // ScrollBars
76 GetHScrollBar().SetRange( Range(0, 1000) );
77 GetVScrollBar().SetRange( Range(0, 1000) );
79 GetHScrollBar().SetLineSize( LINE_SIZE );
80 GetVScrollBar().SetLineSize( LINE_SIZE );
82 GetHScrollBar().Show();
83 GetVScrollBar().Show();
84 m_pCornerWindow->Show();
86 // normally we should be SCROLL_PANE
87 SetAccessibleRole(AccessibleRole::SCROLL_PANE);
90 OScrollWindowHelper::~OScrollWindowHelper()
92 disposeOnce();
95 void OScrollWindowHelper::dispose()
97 m_aHScrollBar.disposeAndClear();
98 m_aVScrollBar.disposeAndClear();
99 m_pCornerWindow.disposeAndClear();
100 m_pTableView.clear();
101 vcl::Window::dispose();
104 void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
106 m_pTableView = _pTableView;
107 // ScrollBars
108 GetHScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
109 GetVScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, ScrollHdl) );
112 void OScrollWindowHelper::resetRange(const Point& _aSize)
114 Point aPos = PixelToLogic(_aSize);
115 GetHScrollBar().SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
116 GetVScrollBar().SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
119 void OScrollWindowHelper::Resize()
121 Window::Resize();
123 Size aTotalOutputSize = GetOutputSizePixel();
124 long nHScrollHeight = GetHScrollBar().GetSizePixel().Height();
125 long nVScrollWidth = GetVScrollBar().GetSizePixel().Width();
127 GetHScrollBar().SetPosSizePixel(
128 Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
129 Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
132 GetVScrollBar().SetPosSizePixel(
133 Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
134 Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
137 m_pCornerWindow->SetPosSizePixel(
138 Point( aTotalOutputSize.Width() - nVScrollWidth, aTotalOutputSize.Height() - nHScrollHeight),
139 Size( nVScrollWidth, nHScrollHeight )
142 GetHScrollBar().SetPageSize( aTotalOutputSize.Width() );
143 GetHScrollBar().SetVisibleSize( aTotalOutputSize.Width() );
145 GetVScrollBar().SetPageSize( aTotalOutputSize.Height() );
146 GetVScrollBar().SetVisibleSize( aTotalOutputSize.Height() );
148 // adjust the ranges of the scrollbars if necessary
149 long lRange = GetHScrollBar().GetRange().Max() - GetHScrollBar().GetRange().Min();
150 if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
151 GetHScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar().GetRange().Min());
153 lRange = GetVScrollBar().GetRange().Max() - GetVScrollBar().GetRange().Min();
154 if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
155 GetVScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar().GetRange().Min());
157 m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
160 // class OJoinTableView
162 OJoinTableView::OJoinTableView( vcl::Window* pParent, OJoinDesignView* pView )
163 :Window( pParent,WB_BORDER )
164 ,DropTargetHelper(this)
165 ,m_aDragOffset( Point(0,0) )
166 ,m_aScrollOffset( Point(0,0) )
167 ,m_pDragWin( NULL )
168 ,m_pSizingWin( NULL )
169 ,m_pSelectedConn( NULL )
170 ,m_bTrackingInitiallyMoved(false)
171 ,m_pLastFocusTabWin(NULL)
172 ,m_pView( pView )
173 ,m_pAccessible(NULL)
175 SetSizePixel( Size(1000, 1000) );
177 InitColors();
179 m_aDragScrollIdle.SetIdleHdl(LINK(this, OJoinTableView, OnDragScrollTimer));
182 OJoinTableView::~OJoinTableView()
184 disposeOnce();
187 void OJoinTableView::dispose()
189 if( m_pAccessible )
191 m_pAccessible->clearTableView();
192 m_pAccessible = NULL;
194 // delete lists
195 clearLayoutInformation();
196 m_pDragWin.clear();
197 m_pSizingWin.clear();
198 m_pSelectedConn.clear();
199 m_pLastFocusTabWin.clear();
200 m_pView.clear();
201 vcl::Window::dispose();
204 IMPL_LINK( OJoinTableView, ScrollHdl, ScrollBar*, pScrollBar )
206 // move all windows
207 ScrollPane( pScrollBar->GetDelta(), (pScrollBar == &GetHScrollBar()), false );
209 return 0;
212 void OJoinTableView::Resize()
214 Window::Resize();
215 m_aOutputSize = GetSizePixel();
217 // tab win positions may not be up-to-date
218 if (m_aTableMap.empty())
219 // no tab wins ...
220 return;
222 // we have at least one table so resize it
223 m_aScrollOffset.X() = GetHScrollBar().GetThumbPos();
224 m_aScrollOffset.Y() = GetVScrollBar().GetThumbPos();
226 OTableWindow* pCheck = m_aTableMap.begin()->second;
227 Point aRealPos = pCheck->GetPosPixel();
228 Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
230 if (aRealPos == aAssumedPos)
231 // all ok
232 return;
234 OTableWindowMap::iterator aIter = m_aTableMap.begin();
235 OTableWindowMap::iterator aEnd = m_aTableMap.end();
236 for(;aIter != aEnd;++aIter)
238 OTableWindow* pCurrent = aIter->second;
239 Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
240 pCurrent->SetPosPixel(aPos);
244 sal_uLong OJoinTableView::GetTabWinCount()
246 return m_aTableMap.size();
249 bool OJoinTableView::RemoveConnection( OTableConnection* _pConn, bool _bDelete )
251 DeselectConn(_pConn);
253 // to force a redraw
254 _pConn->InvalidateConnection();
256 m_pView->getController().removeConnectionData( _pConn->GetData() );
258 auto it = ::std::find(m_vTableConnection.begin(),m_vTableConnection.end(),_pConn);
259 if (it != m_vTableConnection.end())
261 it->disposeAndClear();
262 m_vTableConnection.erase( it );
265 modified();
266 if ( m_pAccessible )
267 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
268 makeAny(_pConn->GetAccessible()),
269 Any());
270 if ( _bDelete )
271 _pConn->disposeOnce();
273 return true;
276 OTableWindow* OJoinTableView::GetTabWindow( const OUString& rName )
278 OTableWindowMap::iterator aIter = m_aTableMap.find(rName);
280 return aIter == m_aTableMap.end() ? nullptr : aIter->second;
283 TTableWindowData::value_type OJoinTableView::createTableWindowData(const OUString& _rComposedName
284 ,const OUString& _sTableName
285 ,const OUString& _rWinName)
287 TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
288 OJoinDesignView* pParent = getDesignView();
291 if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
293 if ( pData->isValid() )
294 onNoColumns_throw();
295 else
296 pData.reset();
299 catch ( const SQLException& )
301 ::dbaui::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
302 pParent, pParent->getController().getORB() );
304 catch( const WrappedTargetException& e )
306 SQLException aSql;
307 if ( e.TargetException >>= aSql )
308 ::dbaui::showError( ::dbtools::SQLExceptionInfo( aSql ), pParent, pParent->getController().getORB() );
310 catch( const Exception& )
312 DBG_UNHANDLED_EXCEPTION();
314 return pData;
317 OTableWindowData* OJoinTableView::CreateImpl(const OUString& _rComposedName
318 ,const OUString& _sTableName
319 ,const OUString& _rWinName)
321 return new OTableWindowData( NULL,_rComposedName,_sTableName, _rWinName );
324 void OJoinTableView::AddTabWin(const OUString& _rComposedName, const OUString& rWinName, bool /*bNewTable*/)
326 OSL_ENSURE(!_rComposedName.isEmpty(),"There must be a table name supplied!");
328 TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
330 // insert new window in window list
331 VclPtr<OTableWindow> pNewTabWin = createWindow( pNewTabWinData );
332 if ( pNewTabWin->Init() )
334 m_pView->getController().getTableWindowData().push_back( pNewTabWinData);
335 // when we already have a table with this name insert the full qualified one instead
336 if(m_aTableMap.find(rWinName) != m_aTableMap.end())
337 m_aTableMap[_rComposedName] = pNewTabWin;
338 else
339 m_aTableMap[rWinName] = pNewTabWin;
341 SetDefaultTabWinPosSize( pNewTabWin );
342 pNewTabWin->Show();
344 modified();
345 if ( m_pAccessible )
346 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
347 Any(),
348 makeAny(pNewTabWin->GetAccessible()));
350 else
352 pNewTabWin->clearListBox();
353 pNewTabWin.disposeAndClear();
357 void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
359 // first delete all connections of this window to others
360 bool bRemove = true;
361 TTableWindowData::value_type pData = pTabWin->GetData();
362 sal_Int32 nCount = m_vTableConnection.size();
363 auto aIter = m_vTableConnection.rbegin();
364 while(aIter != m_vTableConnection.rend() && bRemove)
366 OTableConnection* pTabConn = (*aIter);
368 ( pData == pTabConn->GetData()->getReferencingTable()) ||
369 ( pData == pTabConn->GetData()->getReferencedTable())
372 bRemove = RemoveConnection( pTabConn ,true);
373 aIter = m_vTableConnection.rbegin();
375 else
376 ++aIter;
379 // then delete the window itself
380 if ( bRemove )
382 if ( m_pAccessible )
383 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
384 makeAny(pTabWin->GetAccessible()),Any()
387 pTabWin->Hide();
388 OJoinController& rController = m_pView->getController();
389 TTableWindowData::iterator aFind = ::std::find(rController.getTableWindowData().begin(), rController.getTableWindowData().end(), pData);
390 if(aFind != rController.getTableWindowData().end())
392 rController.getTableWindowData().erase(aFind);
393 rController.setModified(sal_True);
396 if ( !m_aTableMap.erase( pTabWin->GetWinName() ) )
397 m_aTableMap.erase( pTabWin->GetComposedName() );
399 if (pTabWin == m_pLastFocusTabWin)
400 m_pLastFocusTabWin = NULL;
402 pTabWin->clearListBox();
403 pTabWin->disposeOnce();
406 if ( (sal_Int32)m_vTableConnection.size() < (nCount-1) ) // if some connections could be removed
407 modified();
410 namespace
412 bool isScrollAllowed( OJoinTableView* _pView,long nDelta, bool bHoriz)
414 // adjust ScrollBar-Positions
415 ScrollBar& rBar = bHoriz ? _pView->GetHScrollBar() : _pView->GetVScrollBar() ;
417 long nOldThumbPos = rBar.GetThumbPos();
418 long nNewThumbPos = nOldThumbPos + nDelta;
419 if( nNewThumbPos < 0 )
420 nNewThumbPos = 0;
421 else if( nNewThumbPos > rBar.GetRangeMax() )
422 nNewThumbPos = rBar.GetRangeMax();
424 if ( bHoriz )
426 if( nNewThumbPos == _pView->GetScrollOffset().X() )
427 return false;
429 else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
430 return false;
432 return true;
434 bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,long& _nScrollX,long& _nScrollY)
436 _nScrollY = _nScrollX = 0;
437 // data about the tab win
438 Point aUpperLeft = _rPoint;
439 // normalize with respect to visibility
440 aUpperLeft -= _pView->GetScrollOffset();
441 Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
443 // data about ourself
444 Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
446 bool bVisible = true;
447 bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
448 bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
449 if (!bFitsHor || !bFitsVert)
451 if (!bFitsHor)
453 // ensure the visibility of the right border
454 if ( aLowerRight.X() > aSize.Width() )
455 _nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
457 // ensure the visibility of the left border (higher priority)
458 if ( aUpperLeft.X() < 0 )
459 _nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
462 if (!bFitsVert)
464 // lower border
465 if ( aLowerRight.Y() > aSize.Height() )
466 _nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
467 // upper border
468 if ( aUpperLeft.Y() < 0 )
469 _nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
472 if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
473 bVisible = isScrollAllowed(_pView,_nScrollX, true);
475 if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
476 bVisible = bVisible && isScrollAllowed(_pView,_nScrollY, false);
478 if ( bVisible )
480 sal_Int32 nHRangeMax = _pView->GetHScrollBar().GetRangeMax();
481 sal_Int32 nVRangeMax = _pView->GetVScrollBar().GetRangeMax();
483 if ( aSize.Width() + _pView->GetHScrollBar().GetThumbPos() + _nScrollX > nHRangeMax )
484 bVisible = false;
485 if ( bVisible && aSize.Height() + _pView->GetVScrollBar().GetThumbPos() + _nScrollY > nVRangeMax )
486 bVisible = false;
490 return bVisible;
492 } // end of ano namespace
494 bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
496 long nX,nY;
497 return getMovementImpl(this,_rPoint,_rSize,nX,nY);
500 void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
502 // data about the tab win
503 TTableWindowData::value_type pData = _pWin->GetData();
504 EnsureVisible( pData->GetPosition() , pData->GetSize());
505 Invalidate(INVALIDATE_NOCHILDREN);
508 void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
510 long nScrollX,nScrollY;
512 if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
514 bool bVisible = true;
515 if (nScrollX)
516 bVisible = ScrollPane(nScrollX, true, true);
518 if (nScrollY && bVisible)
519 ScrollPane(nScrollY, false, true);
523 void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
525 // determine position:
526 // the window is divided into lines with height TABWIN_SPACING_Y+TABWIN_HEIGHT_STD.
527 // Then for each line is checked, if there is space for another window.
528 // If there is no space, the next line is checked.
529 Size aOutSize = GetSizePixel();
530 Point aNewPos( 0,0 );
531 sal_uInt16 nRow = 0;
532 bool bEnd = false;
533 while( !bEnd )
535 // Set new position to start of line
536 aNewPos.X() = TABWIN_SPACING_X;
537 aNewPos.Y() = (nRow+1) * TABWIN_SPACING_Y;
539 // determine rectangle for the corresponding line
540 Rectangle aRowRect( Point(0,0), aOutSize );
541 aRowRect.Top() = nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
542 aRowRect.Bottom() = (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD );
544 // check occupied areas of this line
545 OTableWindowMap::iterator aIter = m_aTableMap.begin();
546 OTableWindowMap::iterator aEnd = m_aTableMap.end();
547 for(;aIter != aEnd;++aIter)
549 OTableWindow* pOtherTabWin = aIter->second;
550 Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
553 ( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
554 ( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
557 // TabWin is in the line
558 if( aOtherTabWinRect.Right()>aNewPos.X() )
559 aNewPos.X() = aOtherTabWinRect.Right() + TABWIN_SPACING_X;
563 // Is there space left in this line?
564 if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
566 aNewPos.Y() = aRowRect.Top() + TABWIN_SPACING_Y;
567 bEnd = true;
569 else
571 if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
573 // insert it in the first row
574 sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
575 ++nCount;
576 aNewPos.Y() = nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD);
577 bEnd = true;
579 else
580 nRow++;
585 // determine size
586 Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
588 // check if the new position in inside the scrollbars ranges
589 Point aBottom(aNewPos);
590 aBottom.X() += aNewSize.Width();
591 aBottom.Y() += aNewSize.Height();
593 if(!GetHScrollBar().GetRange().IsInside(aBottom.X()))
594 GetHScrollBar().SetRange( Range(0, aBottom.X()) );
595 if(!GetVScrollBar().GetRange().IsInside(aBottom.Y()))
596 GetVScrollBar().SetRange( Range(0, aBottom.Y()) );
598 pTabWin->SetPosSizePixel( aNewPos, aNewSize );
601 void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
603 if (rDCEvt.GetType() == DataChangedEventType::SETTINGS)
605 // consider the worst case: the colors changed, so adjust me
606 InitColors();
607 Invalidate(INVALIDATE_NOCHILDREN);
608 // due to the Invalidate, the connections are redrawn, so that they are also pictured in the new colors
612 void OJoinTableView::InitColors()
614 // the colors for the illustration should be the system colors
615 StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
616 SetBackground(Wallpaper(Color(aSystemStyle.GetDialogColor())));
619 void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
622 if (m_pView->getController().isReadOnly())
623 return;
625 m_pDragWin = pTabWin;
626 SetPointer(Pointer(PointerStyle::Move));
627 Point aMousePos = ScreenToOutputPixel( rMousePos );
628 m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
629 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
630 m_bTrackingInitiallyMoved = false;
631 StartTracking();
634 void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point& rMousePos )
636 DeselectConn(GetSelectedConn());
637 BeginChildMove(pTabWin, rMousePos);
640 void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, const Pointer& rPointer )
643 if (m_pView->getController().isReadOnly())
644 return;
646 SetPointer( rPointer );
647 m_pSizingWin = pTabWin;
648 StartTracking();
651 bool OJoinTableView::ScrollPane( long nDelta, bool bHoriz, bool bPaintScrollBars )
653 bool bRet = true;
655 // adjust ScrollBar-Positions
656 if( bPaintScrollBars )
658 if( bHoriz )
660 long nOldThumbPos = GetHScrollBar().GetThumbPos();
661 long nNewThumbPos = nOldThumbPos + nDelta;
662 if( nNewThumbPos < 0 )
664 nNewThumbPos = 0;
665 bRet = false;
667 if( nNewThumbPos > GetHScrollBar().GetRange().Max() )
669 nNewThumbPos = GetHScrollBar().GetRange().Max();
670 bRet = false;
672 GetHScrollBar().SetThumbPos( nNewThumbPos );
673 nDelta = GetHScrollBar().GetThumbPos() - nOldThumbPos;
675 else
677 long nOldThumbPos = GetVScrollBar().GetThumbPos();
678 long nNewThumbPos = nOldThumbPos+nDelta;
679 if( nNewThumbPos < 0 )
681 nNewThumbPos = 0;
682 bRet = false;
684 if( nNewThumbPos > GetVScrollBar().GetRange().Max() )
686 nNewThumbPos = GetVScrollBar().GetRange().Max();
687 bRet = false;
689 GetVScrollBar().SetThumbPos( nNewThumbPos );
690 nDelta = GetVScrollBar().GetThumbPos() - nOldThumbPos;
694 // If ScrollOffset hitting borders, no redrawing.
695 if( (GetHScrollBar().GetThumbPos()==m_aScrollOffset.X()) &&
696 (GetVScrollBar().GetThumbPos()==m_aScrollOffset.Y()) )
697 return false;
699 // set ScrollOffset anew
700 if (bHoriz)
701 m_aScrollOffset.X() = GetHScrollBar().GetThumbPos();
702 else
703 m_aScrollOffset.Y() = GetVScrollBar().GetThumbPos();
705 // move all windows
706 OTableWindow* pTabWin;
707 Point aPos;
709 OTableWindowMap::iterator aIter = m_aTableMap.begin();
710 OTableWindowMap::iterator aEnd = m_aTableMap.end();
711 for(;aIter != aEnd;++aIter)
713 pTabWin = aIter->second;
714 aPos = pTabWin->GetPosPixel();
716 if( bHoriz )
717 aPos.X() -= nDelta;
718 else aPos.Y() -= nDelta;
720 pTabWin->SetPosPixel( aPos );
723 Invalidate(); // INVALIDATE_NOCHILDREN
725 return bRet;
728 void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
730 HideTracking();
732 if (rTEvt.IsTrackingEnded())
734 if( m_pDragWin )
736 if (m_aDragScrollIdle.IsActive())
737 m_aDragScrollIdle.Stop();
739 // adjust position of child after moving
740 // windows are not allowed to leave display range
741 Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
742 Size aDragWinSize = m_pDragWin->GetSizePixel();
743 if( aDragWinPos.X() < 0 )
744 aDragWinPos.X() = 0;
745 if( aDragWinPos.Y() < 0 )
746 aDragWinPos.Y() = 0;
747 if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
748 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width() - 1;
749 if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
750 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height() - 1;
751 if( aDragWinPos.X() < 0 )
752 aDragWinPos.X() = 0;
753 if( aDragWinPos.Y() < 0 )
754 aDragWinPos.Y() = 0;
755 // TODO : don't position window anew, if it is leaving range, but just expand the range
757 // position window
758 EndTracking();
759 m_pDragWin->SetZOrder(NULL, WINDOW_ZORDER_FIRST);
760 // check, if I really moved
761 // (this prevents setting the modified-Flag, when there actually was no change0
762 TTableWindowData::value_type pData = m_pDragWin->GetData();
763 if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
765 // old logic coordinates
766 Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
767 // new positioning
768 m_pDragWin->SetPosPixel(aDragWinPos);
769 TabWinMoved(m_pDragWin, ptOldPos);
771 m_pDragWin->GrabFocus();
773 m_pDragWin = NULL;
774 SetPointer(Pointer(PointerStyle::Arrow));
776 // else we handle the resizing
777 else if( m_pSizingWin )
779 SetPointer( Pointer() );
780 EndTracking();
782 // old physical coordinates
784 Size szOld = m_pSizingWin->GetSizePixel();
785 Point ptOld = m_pSizingWin->GetPosPixel();
786 Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
787 m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
788 TabWinSized(m_pSizingWin, ptOld, szOld);
790 m_pSizingWin->Invalidate( m_aSizingRect );
791 m_pSizingWin = NULL;
794 else if (rTEvt.IsTrackingCanceled())
796 if (m_aDragScrollIdle.IsActive())
797 m_aDragScrollIdle.Stop();
798 EndTracking();
800 else
802 if( m_pDragWin )
804 m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
805 // scroll at window borders
806 ScrollWhileDragging();
809 if( m_pSizingWin )
811 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
812 m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
813 Update();
814 ShowTracking( m_aSizingRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
819 void OJoinTableView::ConnDoubleClicked( OTableConnection* /*pConnection*/ )
823 void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
825 GrabFocus();
826 Window::MouseButtonDown(rEvt);
829 void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
831 Window::MouseButtonUp(rEvt);
832 // Has a connection been selected?
833 if( !m_vTableConnection.empty() )
835 DeselectConn(GetSelectedConn());
837 auto aIter = m_vTableConnection.begin();
838 auto aEnd = m_vTableConnection.end();
839 for(;aIter != aEnd;++aIter)
841 if( (*aIter)->CheckHit(rEvt.GetPosPixel()) )
843 SelectConn((*aIter));
845 // Double-click
846 if( rEvt.GetClicks() == 2 )
847 ConnDoubleClicked( (*aIter) );
849 break;
855 void OJoinTableView::KeyInput( const KeyEvent& rEvt )
857 sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
858 bool bShift = rEvt.GetKeyCode().IsShift();
859 bool bCtrl = rEvt.GetKeyCode().IsMod1();
861 if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
863 if (GetSelectedConn())
864 RemoveConnection( GetSelectedConn() ,true);
866 else
867 Window::KeyInput( rEvt );
870 void OJoinTableView::DeselectConn(OTableConnection* pConn)
872 if (!pConn || !pConn->IsSelected())
873 return;
875 // deselect the corresponding entries in the ListBox of the table window
876 OTableWindow* pWin = pConn->GetSourceWin();
877 if (pWin && pWin->GetListBox())
878 pWin->GetListBox()->SelectAll(false);
880 pWin = pConn->GetDestWin();
881 if (pWin && pWin->GetListBox())
882 pWin->GetListBox()->SelectAll(false);
884 pConn->Deselect();
885 m_pSelectedConn = NULL;
888 void OJoinTableView::SelectConn(OTableConnection* pConn)
890 DeselectConn(GetSelectedConn());
892 pConn->Select();
893 m_pSelectedConn = pConn;
894 GrabFocus(); // has to be called here because a table window may still be focused
896 // select the concerned entries in the windows
897 OTableWindow* pConnSource = pConn->GetSourceWin();
898 OTableWindow* pConnDest = pConn->GetDestWin();
899 if (pConnSource && pConnDest)
901 OTableWindowListBox* pSourceBox = pConnSource->GetListBox();
902 OTableWindowListBox* pDestBox = pConnDest->GetListBox();
903 if (pSourceBox && pDestBox)
905 pSourceBox->SelectAll(false);
906 pDestBox->SelectAll(false);
908 SvTreeListEntry* pFirstSourceVisible = pSourceBox->GetFirstEntryInView();
909 SvTreeListEntry* pFirstDestVisible = pDestBox->GetFirstEntryInView();
911 const ::std::vector<OConnectionLine*>& rLines = pConn->GetConnLineList();
912 ::std::vector<OConnectionLine*>::const_reverse_iterator aIter = rLines.rbegin();
913 for(;aIter != rLines.rend();++aIter)
915 if ((*aIter)->IsValid())
917 SvTreeListEntry* pSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
918 if (pSourceEntry)
920 pSourceBox->Select(pSourceEntry, true);
921 pSourceBox->MakeVisible(pSourceEntry);
924 SvTreeListEntry* pDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
925 if (pDestEntry)
927 pDestBox->Select(pDestEntry, true);
928 pDestBox->MakeVisible(pDestEntry);
934 if ((pFirstSourceVisible != pSourceBox->GetFirstEntryInView())
935 || (pFirstDestVisible != pDestBox->GetFirstEntryInView()))
936 // scrolling was done -> redraw
937 Invalidate(INVALIDATE_NOCHILDREN);
942 void OJoinTableView::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
944 DrawConnections(rRenderContext, rRect);
947 void OJoinTableView::InvalidateConnections()
949 // draw Joins
950 for (auto & conn : m_vTableConnection)
951 conn->InvalidateConnection();
954 void OJoinTableView::DrawConnections(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
956 // draw Joins
957 for(auto connection : m_vTableConnection)
958 connection->Draw(rRenderContext, rRect);
959 // finally redraw the selected one above all others
960 if (GetSelectedConn())
961 GetSelectedConn()->Draw(rRenderContext, rRect);
964 ::std::vector<VclPtr<OTableConnection> >::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
966 return ::std::find_if( m_vTableConnection.begin(),
967 m_vTableConnection.end(),
968 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
971 sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
973 return ::std::count_if( m_vTableConnection.begin(),
974 m_vTableConnection.end(),
975 ::std::bind2nd(::std::mem_fun(&OTableConnection::isTableConnection),_pFromWin));
978 bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
980 return getTableConnections(pFrom) != m_vTableConnection.end();
983 void OJoinTableView::ClearAll()
985 SetUpdateMode(false);
987 HideTabWins();
989 // and the same with the Connections
990 while(true)
992 auto aIter = m_vTableConnection.begin();
993 if (aIter == m_vTableConnection.end())
994 break;
995 RemoveConnection(*aIter, true);
997 m_vTableConnection.clear();
999 m_pLastFocusTabWin = NULL;
1000 m_pSelectedConn = NULL;
1002 // scroll to the upper left
1003 ScrollPane(-GetScrollOffset().X(), true, true);
1004 ScrollPane(-GetScrollOffset().Y(), false, true);
1005 Invalidate();
1008 bool OJoinTableView::ScrollWhileDragging()
1010 OSL_ENSURE(m_pDragWin != nullptr, "OJoinTableView::ScrollWhileDragging must not be called when a window is being dragged !");
1012 // kill the timer
1013 if (m_aDragScrollIdle.IsActive())
1014 m_aDragScrollIdle.Stop();
1016 Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
1017 Size aDragWinSize = m_pDragWin->GetSizePixel();
1018 Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
1020 if (!m_bTrackingInitiallyMoved && (aDragWinPos == m_pDragWin->GetPosPixel()))
1021 return true;
1023 // avoid illustration errors (when scrolling with active TrackingRect)
1024 HideTracking();
1026 bool bScrolling = false;
1027 bool bNeedScrollTimer = false;
1029 // scroll at window borders
1030 // TODO : only catch, if window would disappear completely (don't, if there is still a pixel visible)
1031 if( aDragWinPos.X() < 5 )
1033 bScrolling = ScrollPane( -LINE_SIZE, true, true );
1034 if( !bScrolling && (aDragWinPos.X()<0) )
1035 aDragWinPos.X() = 0;
1037 // do I need further (timer controlled) scrolling ?
1038 bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
1041 if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
1043 bScrolling = ScrollPane( LINE_SIZE, true, true ) ;
1044 if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
1045 aDragWinPos.X() = m_aOutputSize.Width() - aDragWinSize.Width();
1047 // do I need further (timer controlled) scrolling ?
1048 bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
1051 if( aDragWinPos.Y() < 5 )
1053 bScrolling = ScrollPane( -LINE_SIZE, false, true );
1054 if( !bScrolling && (aDragWinPos.Y()<0) )
1055 aDragWinPos.Y() = 0;
1057 bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
1060 if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
1062 bScrolling = ScrollPane( LINE_SIZE, false, true );
1063 if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
1064 aDragWinPos.Y() = m_aOutputSize.Height() - aDragWinSize.Height();
1066 bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
1069 // resetting timer, if still necessary
1070 if (bNeedScrollTimer)
1072 m_aDragScrollIdle.SetPriority(SchedulerPriority::LOW);
1073 m_aDragScrollIdle.Start();
1076 // redraw DraggingRect
1077 m_aDragRect = Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
1078 Update();
1079 ShowTracking( m_aDragRect, SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
1081 return bScrolling;
1084 IMPL_LINK_NOARG_TYPED(OJoinTableView, OnDragScrollTimer, Idle *, void)
1086 ScrollWhileDragging();
1089 void OJoinTableView::invalidateAndModify(SfxUndoAction *_pAction)
1091 Invalidate(INVALIDATE_NOCHILDREN);
1092 m_pView->getController().addUndoActionAndInvalidate(_pAction);
1095 void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
1097 Point ptThumbPos(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
1098 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
1100 invalidateAndModify(new OJoinMoveTabWinUndoAct(this, ptOldPosition, ptWhich));
1103 void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
1105 ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
1106 ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
1108 invalidateAndModify(new OJoinSizeTabWinUndoAct(this, ptOldPosition, szOldSize, ptWhich));
1111 bool OJoinTableView::IsAddAllowed()
1114 // not, if Db readonly
1115 if (m_pView->getController().isReadOnly())
1116 return false;
1120 Reference< XConnection> xConnection = m_pView->getController().getConnection();
1121 if(!xConnection.is())
1122 return false;
1123 // not, if too many tables already
1124 Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
1126 sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
1127 if (nMax && nMax <= (sal_Int32)m_aTableMap.size())
1128 return false;
1130 catch(SQLException&)
1132 return false;
1135 return true;
1138 void OJoinTableView::executePopup(const Point& _aPos,OTableConnection* _pSelConnection)
1140 PopupMenu aContextMenu( ModuleRes( RID_MENU_JOINVIEW_CONNECTION ) );
1141 switch (aContextMenu.Execute(this, _aPos))
1143 case SID_DELETE:
1144 RemoveConnection( _pSelConnection ,true);
1145 break;
1146 case ID_QUERY_EDIT_JOINCONNECTION:
1147 ConnDoubleClicked( _pSelConnection ); // is the same as double clicked
1148 break;
1152 void OJoinTableView::Command(const CommandEvent& rEvt)
1155 bool bHandled = false;
1157 switch (rEvt.GetCommand())
1159 case CommandEventId::ContextMenu:
1161 if( m_vTableConnection.empty() )
1162 return;
1164 OTableConnection* pSelConnection = GetSelectedConn();
1165 // when it wasn't a mouse event use the selected connection
1166 if (!rEvt.IsMouseEvent())
1168 if( pSelConnection )
1170 const ::std::vector<OConnectionLine*>& rLines = pSelConnection->GetConnLineList();
1171 ::std::vector<OConnectionLine*>::const_iterator aIter = ::std::find_if(rLines.begin(), rLines.end(),::std::mem_fun(&OConnectionLine::IsValid));
1172 if( aIter != rLines.end() )
1173 executePopup((*aIter)->getMidPoint(),pSelConnection);
1176 else
1178 DeselectConn(pSelConnection);
1180 const Point& aMousePos = rEvt.GetMousePosPixel();
1181 auto aIter = m_vTableConnection.begin();
1182 auto aEnd = m_vTableConnection.end();
1183 for(;aIter != aEnd;++aIter)
1185 if( (*aIter)->CheckHit(aMousePos) )
1187 SelectConn(*aIter);
1188 if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
1189 executePopup(rEvt.GetMousePosPixel(),*aIter);
1190 break;
1194 bHandled = true;
1196 break;
1197 default: break;
1199 if (!bHandled)
1200 Window::Command(rEvt);
1203 OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSupressCrossOrNaturalJoin,const OTableConnection* _rpFirstAfter) const
1205 OTableConnection* pConn = NULL;
1206 OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
1207 // only one NULL-arg allowed
1209 if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
1211 bool bFoundStart = _rpFirstAfter == nullptr;
1213 auto aIter = m_vTableConnection.begin();
1214 auto aEnd = m_vTableConnection.end();
1215 for(;aIter != aEnd;++aIter)
1217 OTableConnection* pData = *aIter;
1219 if ( ( (pData->GetSourceWin() == pLhs)
1220 && ( (pData->GetDestWin() == pRhs)
1221 || (NULL == pRhs)
1224 || ( (pData->GetSourceWin() == pRhs)
1225 && ( (pData->GetDestWin() == pLhs)
1226 || (NULL == pLhs)
1231 if ( _bSupressCrossOrNaturalJoin )
1233 if ( supressCrossNaturalJoin(pData->GetData()) )
1234 continue;
1236 if (bFoundStart)
1238 pConn = pData;
1239 break;
1242 if (!pConn)
1243 // used as fallback : if there is no conn after _rpFirstAfter the first conn between the two tables
1244 // will be used
1245 pConn = pData;
1247 if (pData == _rpFirstAfter)
1248 bFoundStart = true;
1252 return pConn;
1255 bool OJoinTableView::PreNotify(NotifyEvent& rNEvt)
1257 bool bHandled = false;
1258 switch (rNEvt.GetType())
1260 case MouseNotifyEvent::COMMAND:
1262 const CommandEvent* pCommand = rNEvt.GetCommandEvent();
1263 if (pCommand->GetCommand() == CommandEventId::Wheel)
1265 const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
1266 if (pData->GetMode() == CommandWheelMode::SCROLL)
1268 if (pData->GetDelta() > 0)
1269 ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), true);
1270 else
1271 ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), true);
1272 bHandled = true;
1276 break;
1277 case MouseNotifyEvent::KEYINPUT:
1279 if (m_aTableMap.empty())
1280 // no tab wins -> no conns -> no traveling
1281 break;
1283 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1284 if (!pKeyEvent->GetKeyCode().IsMod1())
1286 switch (pKeyEvent->GetKeyCode().GetCode())
1288 case KEY_TAB:
1290 if (!HasChildPathFocus())
1291 break;
1293 bool bForward = !pKeyEvent->GetKeyCode().IsShift();
1294 // is there an active tab win ?
1295 OTableWindowMap::iterator aIter = m_aTableMap.begin();
1296 OTableWindowMap::iterator aEnd = m_aTableMap.end();
1297 for(;aIter != aEnd;++aIter)
1298 if (aIter->second && aIter->second->HasChildPathFocus())
1299 break;
1301 OTableWindow* pNextWin = NULL;
1302 OTableConnection* pNextConn = NULL;
1304 if (aIter != m_aTableMap.end())
1305 { // there is a currently active tab win
1306 // check if there is an "overflow" and we should select a conn instead of a win
1307 if (!m_vTableConnection.empty())
1309 if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
1310 // the last win is active and we're travelling forward -> select the first conn
1311 pNextConn = *m_vTableConnection.begin();
1312 if ((aIter == m_aTableMap.begin()) && !bForward)
1313 // the first win is active an we're traveling backward -> select the last conn
1314 pNextConn = *m_vTableConnection.rbegin();
1317 if (!pNextConn)
1319 // no conn for any reason -> select the next or previous tab win
1320 if(bForward)
1322 if ( aIter->second == m_aTableMap.rbegin()->second )
1323 pNextWin = m_aTableMap.begin()->second;
1324 else
1326 ++aIter;
1327 pNextWin = aIter->second;
1330 else
1332 if (aIter == m_aTableMap.begin())
1333 pNextWin = m_aTableMap.rbegin()->second;
1334 else
1336 --aIter;
1337 pNextWin = aIter->second;
1342 else
1343 { // no active tab win -> travel the connections
1344 // find the currently selected conn within the conn list
1345 sal_Int32 i(0);
1346 for ( auto connectionIter = m_vTableConnection.begin();
1347 connectionIter != m_vTableConnection.end();
1348 ++connectionIter, ++i
1351 if ( (*connectionIter).get() == GetSelectedConn() )
1352 break;
1354 if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
1355 // the last conn is active and we're travelling forward -> select the first win
1356 pNextWin = m_aTableMap.begin()->second;
1357 if ((i == 0) && !bForward && !m_aTableMap.empty())
1358 // the first conn is active and we're travelling backward -> select the last win
1359 pNextWin = m_aTableMap.rbegin()->second;
1361 if (pNextWin)
1362 DeselectConn(GetSelectedConn());
1363 else
1364 // no win for any reason -> select the next or previous conn
1365 if (i < (sal_Int32)m_vTableConnection.size())
1366 // there is a currently active conn
1367 pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()];
1368 else
1369 { // no tab win selected, no conn selected
1370 if (!m_vTableConnection.empty())
1371 pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1];
1372 else if (!m_aTableMap.empty())
1374 if(bForward)
1375 pNextWin = m_aTableMap.begin()->second;
1376 else
1377 pNextWin = m_aTableMap.rbegin()->second;
1382 // now select the object
1383 if (pNextWin)
1385 if (pNextWin->GetListBox())
1386 pNextWin->GetListBox()->GrabFocus();
1387 else
1388 pNextWin->GrabFocus();
1389 EnsureVisible(pNextWin);
1391 else if (pNextConn)
1393 GrabFocus();
1394 // necessary : a conn may be selected even if a tab win has the focus, in this case
1395 // the next travel would select the same conn again if we would not reset the focus ...
1396 SelectConn(pNextConn);
1399 break;
1400 case KEY_RETURN:
1402 if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
1403 ConnDoubleClicked(GetSelectedConn());
1404 break;
1409 break;
1410 case MouseNotifyEvent::GETFOCUS:
1412 if (m_aTableMap.empty())
1413 // no tab wins -> no conns -> no focus change
1414 break;
1415 vcl::Window* pSource = rNEvt.GetWindow();
1416 if (pSource)
1418 vcl::Window* pSearchFor = NULL;
1419 if (pSource->GetParent() == this)
1420 // it may be one of the tab wins
1421 pSearchFor = pSource;
1422 else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
1423 // it may be one of th list boxes of one of the tab wins
1424 pSearchFor = pSource->GetParent();
1426 if (pSearchFor)
1428 OTableWindowMap::iterator aIter = m_aTableMap.begin();
1429 OTableWindowMap::iterator aEnd = m_aTableMap.end();
1430 for(;aIter != aEnd;++aIter)
1432 if (aIter->second == pSearchFor)
1434 m_pLastFocusTabWin = aIter->second;
1435 break;
1441 break;
1442 default:
1443 break;
1446 if (!bHandled)
1447 return Window::PreNotify(rNEvt);
1448 return true;
1451 void OJoinTableView::GrabTabWinFocus()
1453 if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
1455 if (m_pLastFocusTabWin->GetListBox())
1456 m_pLastFocusTabWin->GetListBox()->GrabFocus();
1457 else
1458 m_pLastFocusTabWin->GrabFocus();
1460 else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
1462 OTableWindow* pFirstWin = m_aTableMap.begin()->second;
1463 if (pFirstWin->GetListBox())
1464 pFirstWin->GetListBox()->GrabFocus();
1465 else
1466 pFirstWin->GrabFocus();
1470 void OJoinTableView::StateChanged( StateChangedType nType )
1472 Window::StateChanged( nType );
1474 // FIXME RenderContext
1475 if ( nType == StateChangedType::Zoom )
1477 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1479 vcl::Font aFont = rStyleSettings.GetGroupFont();
1480 if ( IsControlFont() )
1481 aFont.Merge( GetControlFont() );
1482 SetZoomedPointFont(*this, aFont);
1484 OTableWindowMap::iterator aIter = m_aTableMap.begin();
1485 OTableWindowMap::iterator aEnd = m_aTableMap.end();
1486 for(;aIter != aEnd;++aIter)
1488 aIter->second->SetZoom(GetZoom());
1489 Size aSize(CalcZoom(aIter->second->GetSizePixel().Width()),CalcZoom(aIter->second->GetSizePixel().Height()));
1490 aIter->second->SetSizePixel(aSize);
1492 Resize();
1496 void OJoinTableView::HideTabWins()
1498 SetUpdateMode(false);
1500 OTableWindowMap& rTabWins = GetTabWinMap();
1502 // working on a copy because the real list will be cleared in inner calls
1503 OTableWindowMap aCopy(rTabWins);
1504 OTableWindowMap::iterator aIter = aCopy.begin();
1505 OTableWindowMap::iterator aEnd = aCopy.end();
1506 for(;aIter != aEnd;++aIter)
1507 RemoveTabWin(aIter->second);
1509 m_pView->getController().setModified(sal_True);
1511 SetUpdateMode(true);
1515 sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
1517 return DND_ACTION_NONE;
1520 sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
1522 return DND_ACTION_NONE;
1525 void OJoinTableView::dragFinished( )
1529 void OJoinTableView::clearLayoutInformation()
1531 m_pLastFocusTabWin = NULL;
1532 m_pSelectedConn = NULL;
1533 // delete lists
1534 OTableWindowMap::iterator aIter = m_aTableMap.begin();
1535 OTableWindowMap::iterator aEnd = m_aTableMap.end();
1536 for(;aIter != aEnd;++aIter)
1538 if ( aIter->second )
1539 aIter->second->clearListBox();
1540 aIter->second.disposeAndClear();
1543 m_aTableMap.clear();
1545 for(auto i = m_vTableConnection.begin();
1546 i != m_vTableConnection.end(); ++i)
1547 i->disposeAndClear();
1549 m_vTableConnection.clear();
1552 void OJoinTableView::lookForUiActivities()
1556 void OJoinTableView::LoseFocus()
1558 DeselectConn(GetSelectedConn());
1559 Window::LoseFocus();
1562 void OJoinTableView::GetFocus()
1564 Window::GetFocus();
1565 if ( !m_aTableMap.empty() && !GetSelectedConn() )
1566 GrabTabWinFocus();
1569 Reference< XAccessible > OJoinTableView::CreateAccessible()
1571 m_pAccessible = new OJoinDesignViewAccess(this);
1572 return m_pAccessible;
1575 void OJoinTableView::modified()
1577 OJoinController& rController = m_pView->getController();
1578 rController.setModified( sal_True );
1579 rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
1580 rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
1583 void OJoinTableView::addConnection(OTableConnection* _pConnection,bool _bAddData)
1585 if ( _bAddData )
1587 #if OSL_DEBUG_LEVEL > 0
1588 TTableConnectionData& rTabConnDataList = m_pView->getController().getTableConnectionData();
1589 OSL_ENSURE( ::std::find(rTabConnDataList.begin(), rTabConnDataList.end(),_pConnection->GetData()) == rTabConnDataList.end(),"Data already in vector!");
1590 #endif
1591 m_pView->getController().getTableConnectionData().push_back(_pConnection->GetData());
1593 m_vTableConnection.push_back(_pConnection);
1594 _pConnection->RecalcLines();
1595 _pConnection->InvalidateConnection();
1597 modified();
1598 if ( m_pAccessible )
1599 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
1600 Any(),
1601 makeAny(_pConnection->GetAccessible()));
1604 bool OJoinTableView::allowQueries() const
1606 return true;
1609 void OJoinTableView::onNoColumns_throw()
1611 OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
1612 throw SQLException();
1615 bool OJoinTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
1617 return false;
1620 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */