/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <JoinTableView.hxx>
#include <osl/diagnose.h>
#include <JoinController.hxx>
#include <JoinDesignView.hxx>
#include <TableWindow.hxx>
#include <TableWindowListBox.hxx>
#include <TableConnection.hxx>
#include <TableConnectionData.hxx>
#include <ConnectionLine.hxx>
#include <ConnectionLineData.hxx>
#include <browserids.hxx>
#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
#include <com/sun/star/sdbc/SQLException.hpp>
#include "QueryMoveTabWinUndoAct.hxx"
#include "QuerySizeTabWinUndoAct.hxx"
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/weldutils.hxx>
#include <TableWindowData.hxx>
#include <JAccess.hxx>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <cppuhelper/exc_hlp.hxx>
#include <connectivity/dbtools.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <algorithm>
#include <functional>
using namespace dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::accessibility;
using namespace ::com::sun::star::lang;
#define LINE_SIZE 50
// Constants for the window layout
#define TABWIN_SPACING_X 17
#define TABWIN_SPACING_Y 17
#define TABWIN_WIDTH_STD 120
#define TABWIN_HEIGHT_STD 120
OScrollWindowHelper::OScrollWindowHelper( vcl::Window* pParent) : Window( pParent)
,m_aHScrollBar( VclPtr<ScrollAdaptor>::Create(this, true) )
,m_aVScrollBar( VclPtr<ScrollAdaptor>::Create(this, false) )
,m_pTableView(nullptr)
{
StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
SetBackground(aSystemStyle.GetFaceColor());
// ScrollBars
GetHScrollBar().SetRange( Range(0, 1000) );
GetVScrollBar().SetRange( Range(0, 1000) );
GetHScrollBar().SetLineSize( LINE_SIZE );
GetVScrollBar().SetLineSize( LINE_SIZE );
GetHScrollBar().Show();
GetVScrollBar().Show();
// normally we should be SCROLL_PANE
SetAccessibleRole(AccessibleRole::SCROLL_PANE);
}
OScrollWindowHelper::~OScrollWindowHelper()
{
disposeOnce();
}
void OScrollWindowHelper::dispose()
{
m_aHScrollBar.disposeAndClear();
m_aVScrollBar.disposeAndClear();
m_pTableView.clear();
vcl::Window::dispose();
}
void OScrollWindowHelper::setTableView(OJoinTableView* _pTableView)
{
m_pTableView = _pTableView;
// ScrollBars
GetHScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, HorzScrollHdl) );
GetVScrollBar().SetScrollHdl( LINK(m_pTableView, OJoinTableView, VertScrollHdl) );
}
void OScrollWindowHelper::resetRange(const Point& _aSize)
{
Point aPos = PixelToLogic(_aSize);
GetHScrollBar().SetRange( Range(0, aPos.X() + TABWIN_SPACING_X) );
GetVScrollBar().SetRange( Range(0, aPos.Y() + TABWIN_SPACING_Y) );
}
void OScrollWindowHelper::Resize()
{
Window::Resize();
Size aTotalOutputSize = GetOutputSizePixel();
tools::Long nHScrollHeight = GetHScrollBar().GetSizePixel().Height();
tools::Long nVScrollWidth = GetVScrollBar().GetSizePixel().Width();
GetHScrollBar().SetPosSizePixel(
Point( 0, aTotalOutputSize.Height()-nHScrollHeight ),
Size( aTotalOutputSize.Width()-nVScrollWidth, nHScrollHeight )
);
GetVScrollBar().SetPosSizePixel(
Point( aTotalOutputSize.Width()-nVScrollWidth, 0 ),
Size( nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight )
);
GetHScrollBar().SetPageSize( aTotalOutputSize.Width() );
GetHScrollBar().SetVisibleSize( aTotalOutputSize.Width() );
GetVScrollBar().SetPageSize( aTotalOutputSize.Height() );
GetVScrollBar().SetVisibleSize( aTotalOutputSize.Height() );
// adjust the ranges of the scrollbars if necessary
tools::Long lRange = GetHScrollBar().GetRange().Max() - GetHScrollBar().GetRange().Min();
if (m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() > lRange)
GetHScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().X() + aTotalOutputSize.Width() + GetHScrollBar().GetRange().Min());
lRange = GetVScrollBar().GetRange().Max() - GetVScrollBar().GetRange().Min();
if (m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() > lRange)
GetVScrollBar().SetRangeMax(m_pTableView->GetScrollOffset().Y() + aTotalOutputSize.Height() + GetVScrollBar().GetRange().Min());
m_pTableView->SetPosSizePixel(Point( 0, 0 ),Size( aTotalOutputSize.Width()-nVScrollWidth, aTotalOutputSize.Height()-nHScrollHeight ));
}
OJoinTableView::OJoinTableView( vcl::Window* pParent, OJoinDesignView* pView )
:Window( pParent,WB_BORDER )
,DropTargetHelper(this)
,m_aDragScrollIdle("dbaccess OJoinTableView m_aDragScrollIdle")
,m_aDragOffset( Point(0,0) )
,m_aScrollOffset( Point(0,0) )
,m_pDragWin( nullptr )
,m_pSizingWin( nullptr )
,m_pSelectedConn( nullptr )
,m_pLastFocusTabWin(nullptr)
,m_pView( pView )
{
SetSizePixel( Size(1000, 1000) );
InitColors();
m_aDragScrollIdle.SetInvokeHandler(LINK(this, OJoinTableView, OnDragScrollTimer));
}
OJoinTableView::~OJoinTableView()
{
disposeOnce();
}
void OJoinTableView::dispose()
{
if( m_pAccessible )
{
m_pAccessible->clearTableView();
m_pAccessible = nullptr;
}
// delete lists
clearLayoutInformation();
m_pDragWin.clear();
m_pSizingWin.clear();
m_pSelectedConn.clear();
m_pLastFocusTabWin.clear();
m_pView.clear();
m_vTableConnection.clear();
vcl::Window::dispose();
}
IMPL_LINK(OJoinTableView, HorzScrollHdl, weld::Scrollbar&, rScrollbar, void)
{
// move all windows
ScrollPane(rScrollbar.adjustment_get_value() - m_aScrollOffset.X(), true, false);
}
IMPL_LINK(OJoinTableView, VertScrollHdl, weld::Scrollbar&, rScrollbar, void)
{
// move all windows
ScrollPane(rScrollbar.adjustment_get_value() - m_aScrollOffset.Y(), false, false);
}
void OJoinTableView::Resize()
{
Window::Resize();
m_aOutputSize = GetSizePixel();
// tab win positions may not be up-to-date
if (m_aTableMap.empty())
// no tab wins ...
return;
// we have at least one table so resize it
m_aScrollOffset.setX( GetHScrollBar().GetThumbPos() );
m_aScrollOffset.setY( GetVScrollBar().GetThumbPos() );
VclPtr<OTableWindow> pCheck = m_aTableMap.begin()->second;
Point aRealPos = pCheck->GetPosPixel();
Point aAssumedPos = pCheck->GetData()->GetPosition() - GetScrollOffset();
if (aRealPos == aAssumedPos)
// all ok
return;
for (auto const& elem : m_aTableMap)
{
OTableWindow* pCurrent = elem.second;
Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
pCurrent->SetPosPixel(aPos);
}
}
sal_Int64 OJoinTableView::GetTabWinCount() const
{
return m_aTableMap.size();
}
bool OJoinTableView::RemoveConnection(VclPtr<OTableConnection>& rConn, bool _bDelete)
{
VclPtr<OTableConnection> xConn(rConn);
DeselectConn(xConn);
// to force a redraw
xConn->InvalidateConnection();
m_pView->getController().removeConnectionData(xConn->GetData());
m_vTableConnection.erase(std::find(m_vTableConnection.begin(), m_vTableConnection.end(), xConn));
modified();
if ( m_pAccessible )
m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
Any(xConn->GetAccessible()),
Any());
if (_bDelete)
xConn->disposeOnce();
return true;
}
OTableWindow* OJoinTableView::GetTabWindow( const OUString& rName )
{
OTableWindowMap::const_iterator aIter = m_aTableMap.find(rName);
return aIter == m_aTableMap.end() ? nullptr : aIter->second;
}
TTableWindowData::value_type OJoinTableView::createTableWindowData(const OUString& _rComposedName
,const OUString& _sTableName
,const OUString& _rWinName)
{
TTableWindowData::value_type pData( CreateImpl(_rComposedName, _sTableName,_rWinName) );
OJoinDesignView* pParent = getDesignView();
try
{
if ( !pData->init(pParent->getController().getConnection(),allowQueries()) )
{
if ( pData->isValid() )
onNoColumns_throw();
else
pData.reset();
}
}
catch ( const SQLException& )
{
::dbtools::showError( ::dbtools::SQLExceptionInfo( ::cppu::getCaughtException() ),
VCLUnoHelper::GetInterface(pParent), pParent->getController().getORB() );
}
catch( const WrappedTargetException& e )
{
SQLException aSql;
if ( e.TargetException >>= aSql )
::dbtools::showError( ::dbtools::SQLExceptionInfo( aSql ), VCLUnoHelper::GetInterface(pParent), pParent->getController().getORB() );
}
catch( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess");
}
return pData;
}
std::shared_ptr<OTableWindowData> OJoinTableView::CreateImpl(const OUString& _rComposedName
,const OUString& _sTableName
,const OUString& _rWinName)
{
return std::make_shared<OTableWindowData>( nullptr,_rComposedName,_sTableName, _rWinName );
}
void OJoinTableView::AddTabWin(const OUString& _rComposedName, const OUString& rWinName, bool /*bNewTable*/)
{
OSL_ENSURE(!_rComposedName.isEmpty(),"There must be a table name supplied!");
TTableWindowData::value_type pNewTabWinData(createTableWindowData( _rComposedName, rWinName,rWinName ));
// insert new window in window list
VclPtr<OTableWindow> pNewTabWin = createWindow( pNewTabWinData );
if ( pNewTabWin->Init() )
{
m_pView->getController().getTableWindowData().push_back( pNewTabWinData);
// when we already have a table with this name insert the full qualified one instead
if(m_aTableMap.find(rWinName) != m_aTableMap.end())
m_aTableMap[_rComposedName] = pNewTabWin;
else
m_aTableMap[rWinName] = pNewTabWin;
SetDefaultTabWinPosSize( pNewTabWin );
pNewTabWin->Show();
modified();
if ( m_pAccessible )
m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
Any(),
Any(pNewTabWin->GetAccessible()));
}
else
{
pNewTabWin->clearListBox();
pNewTabWin.disposeAndClear();
}
}
void OJoinTableView::RemoveTabWin( OTableWindow* pTabWin )
{
// first delete all connections of this window to others
bool bRemove = true;
TTableWindowData::value_type pData = pTabWin->GetData();
sal_Int32 nCount = m_vTableConnection.size();
auto aIter = m_vTableConnection.rbegin();
while(aIter != m_vTableConnection.rend() && bRemove)
{
VclPtr<OTableConnection>& rTabConn = *aIter;
if (
(pData == rTabConn->GetData()->getReferencingTable()) ||
(pData == rTabConn->GetData()->getReferencedTable())
)
{
bRemove = RemoveConnection(rTabConn, true);
aIter = m_vTableConnection.rbegin();
}
else
++aIter;
}
// then delete the window itself
if ( bRemove )
{
if ( m_pAccessible )
m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
Any(pTabWin->GetAccessible()),Any()
);
pTabWin->Hide();
OJoinController& rController = m_pView->getController();
TTableWindowData::iterator aFind = std::find(rController.getTableWindowData().begin(), rController.getTableWindowData().end(), pData);
if(aFind != rController.getTableWindowData().end())
{
rController.getTableWindowData().erase(aFind);
rController.setModified(true);
}
if ( !m_aTableMap.erase( pTabWin->GetWinName() ) )
m_aTableMap.erase( pTabWin->GetComposedName() );
if (pTabWin == m_pLastFocusTabWin)
m_pLastFocusTabWin = nullptr;
pTabWin->clearListBox();
pTabWin->disposeOnce();
}
if ( static_cast<sal_Int32>(m_vTableConnection.size()) < (nCount-1) ) // if some connections could be removed
modified();
}
namespace
{
bool isScrollAllowed( OJoinTableView* _pView,tools::Long nDelta, bool bHoriz)
{
// adjust ScrollBar-Positions
ScrollAdaptor& rBar = bHoriz ? _pView->GetHScrollBar() : _pView->GetVScrollBar();
tools::Long nOldThumbPos = rBar.GetThumbPos();
tools::Long nNewThumbPos = nOldThumbPos + nDelta;
if( nNewThumbPos < 0 )
nNewThumbPos = 0;
else if( nNewThumbPos > rBar.GetRangeMax() )
nNewThumbPos = rBar.GetRangeMax();
if ( bHoriz )
{
if( nNewThumbPos == _pView->GetScrollOffset().X() )
return false;
}
else if ( nNewThumbPos == _pView->GetScrollOffset().Y() )
return false;
return true;
}
bool getMovementImpl(OJoinTableView* _pView,const Point& _rPoint,const Size& _rSize,tools::Long& _nScrollX,tools::Long& _nScrollY)
{
_nScrollY = _nScrollX = 0;
// data about the tab win
Point aUpperLeft = _rPoint;
// normalize with respect to visibility
aUpperLeft -= _pView->GetScrollOffset();
Point aLowerRight(aUpperLeft.X() + _rSize.Width(), aUpperLeft.Y() + _rSize.Height());
// data about ourself
Size aSize = _pView->getRealOutputSize(); //GetOutputSizePixel();
bool bVisible = true;
bool bFitsHor = (aUpperLeft.X() >= 0) && (aLowerRight.X() <= aSize.Width());
bool bFitsVert= (aUpperLeft.Y() >= 0) && (aLowerRight.Y() <= aSize.Height());
if (!bFitsHor || !bFitsVert)
{
if (!bFitsHor)
{
// ensure the visibility of the right border
if ( aLowerRight.X() > aSize.Width() )
_nScrollX = aLowerRight.X() - aSize.Width() + TABWIN_SPACING_X;
// ensure the visibility of the left border (higher priority)
if ( aUpperLeft.X() < 0 )
_nScrollX = aUpperLeft.X() - TABWIN_SPACING_X;
}
if (!bFitsVert)
{
// lower border
if ( aLowerRight.Y() > aSize.Height() )
_nScrollY = aLowerRight.Y() - aSize.Height() + TABWIN_SPACING_Y;
// upper border
if ( aUpperLeft.Y() < 0 )
_nScrollY = aUpperLeft.Y() - TABWIN_SPACING_Y;
}
if ( _nScrollX ) // aSize.Width() > _rSize.Width() &&
bVisible = isScrollAllowed(_pView,_nScrollX, true);
if ( _nScrollY ) // aSize.Height() > _rSize.Height() &&
bVisible = bVisible && isScrollAllowed(_pView,_nScrollY, false);
if ( bVisible )
{
sal_Int32 nHRangeMax = _pView->GetHScrollBar().GetRangeMax();
sal_Int32 nVRangeMax = _pView->GetVScrollBar().GetRangeMax();
if ( aSize.Width() + _pView->GetHScrollBar().GetThumbPos() + _nScrollX > nHRangeMax )
bVisible = false;
if ( bVisible && aSize.Height() + _pView->GetVScrollBar().GetThumbPos() + _nScrollY > nVRangeMax )
bVisible = false;
}
}
return bVisible;
}
} // end of ano namespace
bool OJoinTableView::isMovementAllowed(const Point& _rPoint,const Size& _rSize)
{
tools::Long nX,nY;
return getMovementImpl(this,_rPoint,_rSize,nX,nY);
}
void OJoinTableView::EnsureVisible(const OTableWindow* _pWin)
{
// data about the tab win
const TTableWindowData::value_type& pData = _pWin->GetData();
EnsureVisible( pData->GetPosition() , pData->GetSize());
Invalidate(InvalidateFlags::NoChildren);
}
void OJoinTableView::EnsureVisible(const Point& _rPoint,const Size& _rSize)
{
tools::Long nScrollX,nScrollY;
if ( getMovementImpl(this,_rPoint,_rSize,nScrollX,nScrollY) )
{
bool bVisible = true;
if (nScrollX)
bVisible = ScrollPane(nScrollX, true, true);
if (nScrollY && bVisible)
ScrollPane(nScrollY, false, true);
}
}
void OJoinTableView::SetDefaultTabWinPosSize( OTableWindow* pTabWin )
{
// determine position:
// the window is divided into lines with height TABWIN_SPACING_Y+TABWIN_HEIGHT_STD.
// Then for each line is checked, if there is space for another window.
// If there is no space, the next line is checked.
Size aOutSize = GetSizePixel();
Point aNewPos( 0,0 );
sal_uInt16 nRow = 0;
bool bEnd = false;
while( !bEnd )
{
// Set new position to start of line
aNewPos.setX( TABWIN_SPACING_X );
aNewPos.setY( (nRow+1) * TABWIN_SPACING_Y );
// determine rectangle for the corresponding line
tools::Rectangle aRowRect( Point(0,0), aOutSize );
aRowRect.SetTop( nRow * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD ) );
aRowRect.SetBottom( (nRow+1) * ( TABWIN_SPACING_Y + TABWIN_HEIGHT_STD ) );
// check occupied areas of this line
for (auto const& elem : m_aTableMap)
{
OTableWindow* pOtherTabWin = elem.second;
tools::Rectangle aOtherTabWinRect( pOtherTabWin->GetPosPixel(), pOtherTabWin->GetSizePixel() );
if(
( (aOtherTabWinRect.Top()>aRowRect.Top()) && (aOtherTabWinRect.Top()<aRowRect.Bottom()) ) ||
( (aOtherTabWinRect.Bottom()>aRowRect.Top()) && (aOtherTabWinRect.Bottom()<aRowRect.Bottom()) )
)
{
// TabWin is in the line
if( aOtherTabWinRect.Right()>aNewPos.X() )
aNewPos.setX( aOtherTabWinRect.Right() + TABWIN_SPACING_X );
}
}
// Is there space left in this line?
if( (aNewPos.X()+TABWIN_WIDTH_STD)<aRowRect.Right() )
{
aNewPos.setY( aRowRect.Top() + TABWIN_SPACING_Y );
bEnd = true;
}
else
{
if( (aRowRect.Bottom()+aRowRect.GetHeight()) > aOutSize.Height() )
{
// insert it in the first row
sal_Int32 nCount = m_aTableMap.size() % (nRow+1);
++nCount;
aNewPos.setY( nCount * TABWIN_SPACING_Y + (nCount-1)*CalcZoom(TABWIN_HEIGHT_STD) );
bEnd = true;
}
else
nRow++;
}
}
// determine size
Size aNewSize( CalcZoom(TABWIN_WIDTH_STD), CalcZoom(TABWIN_HEIGHT_STD) );
// check if the new position in inside the scrollbars ranges
Point aBottom(aNewPos);
aBottom.AdjustX(aNewSize.Width() );
aBottom.AdjustY(aNewSize.Height() );
if(!GetHScrollBar().GetRange().Contains(aBottom.X()))
GetHScrollBar().SetRange( Range(0, aBottom.X()) );
if(!GetVScrollBar().GetRange().Contains(aBottom.Y()))
GetVScrollBar().SetRange( Range(0, aBottom.Y()) );
pTabWin->SetPosSizePixel( aNewPos, aNewSize );
}
void OJoinTableView::DataChanged(const DataChangedEvent& rDCEvt)
{
if (rDCEvt.GetType() == DataChangedEventType::SETTINGS)
{
// consider the worst case: the colors changed, so adjust me
InitColors();
Invalidate(InvalidateFlags::NoChildren);
// due to the Invalidate, the connections are redrawn, so that they are also pictured in the new colors
}
}
void OJoinTableView::InitColors()
{
// the colors for the illustration should be the system colors
StyleSettings aSystemStyle = Application::GetSettings().GetStyleSettings();
SetBackground(Wallpaper(aSystemStyle.GetDialogColor()));
}
void OJoinTableView::BeginChildMove( OTableWindow* pTabWin, const Point& rMousePos )
{
if (m_pView->getController().isReadOnly())
return;
m_pDragWin = pTabWin;
SetPointer(PointerStyle::Move);
Point aMousePos = ScreenToOutputPixel( rMousePos );
m_aDragOffset = aMousePos - pTabWin->GetPosPixel();
m_pDragWin->SetZOrder(nullptr, ZOrderFlags::First);
StartTracking();
}
void OJoinTableView::NotifyTitleClicked( OTableWindow* pTabWin, const Point& rMousePos )
{
DeselectConn(GetSelectedConn());
BeginChildMove(pTabWin, rMousePos);
}
void OJoinTableView::BeginChildSizing( OTableWindow* pTabWin, PointerStyle nPointer )
{
if (m_pView->getController().isReadOnly())
return;
SetPointer( nPointer );
m_pSizingWin = pTabWin;
StartTracking();
}
bool OJoinTableView::ScrollPane( tools::Long nDelta, bool bHoriz, bool bPaintScrollBars )
{
bool bRet = true;
// adjust ScrollBar-Positions
if( bPaintScrollBars )
{
if( bHoriz )
{
tools::Long nOldThumbPos = GetHScrollBar().GetThumbPos();
tools::Long nNewThumbPos = nOldThumbPos + nDelta;
if( nNewThumbPos < 0 )
{
nNewThumbPos = 0;
bRet = false;
}
if( nNewThumbPos > GetHScrollBar().GetRange().Max() )
{
nNewThumbPos = GetHScrollBar().GetRange().Max();
bRet = false;
}
GetHScrollBar().SetThumbPos( nNewThumbPos );
nDelta = GetHScrollBar().GetThumbPos() - nOldThumbPos;
}
else
{
tools::Long nOldThumbPos = GetVScrollBar().GetThumbPos();
tools::Long nNewThumbPos = nOldThumbPos+nDelta;
if( nNewThumbPos < 0 )
{
nNewThumbPos = 0;
bRet = false;
}
if( nNewThumbPos > GetVScrollBar().GetRange().Max() )
{
nNewThumbPos = GetVScrollBar().GetRange().Max();
bRet = false;
}
GetVScrollBar().SetThumbPos( nNewThumbPos );
nDelta = GetVScrollBar().GetThumbPos() - nOldThumbPos;
}
}
// If ScrollOffset hitting borders, no redrawing.
if( (GetHScrollBar().GetThumbPos()==m_aScrollOffset.X()) &&
(GetVScrollBar().GetThumbPos()==m_aScrollOffset.Y()) )
return false;
// set ScrollOffset anew
if (bHoriz)
m_aScrollOffset.setX( GetHScrollBar().GetThumbPos() );
else
m_aScrollOffset.setY( GetVScrollBar().GetThumbPos() );
// move all windows
OTableWindow* pTabWin;
Point aPos;
for (auto const& elem : m_aTableMap)
{
pTabWin = elem.second;
aPos = pTabWin->GetPosPixel();
if( bHoriz )
aPos.AdjustX( -nDelta );
else aPos.AdjustY( -nDelta );
pTabWin->SetPosPixel( aPos );
}
Invalidate(); // InvalidateFlags::NoChildren
return bRet;
}
void OJoinTableView::Tracking( const TrackingEvent& rTEvt )
{
HideTracking();
if (rTEvt.IsTrackingEnded())
{
if( m_pDragWin )
{
if (m_aDragScrollIdle.IsActive())
m_aDragScrollIdle.Stop();
// adjust position of child after moving
// windows are not allowed to leave display range
Point aDragWinPos = rTEvt.GetMouseEvent().GetPosPixel() - m_aDragOffset;
Size aDragWinSize = m_pDragWin->GetSizePixel();
if( aDragWinPos.X() < 0 )
aDragWinPos.setX( 0 );
if( aDragWinPos.Y() < 0 )
aDragWinPos.setY( 0 );
if( (aDragWinPos.X() + aDragWinSize.Width()) > m_aOutputSize.Width() )
aDragWinPos.setX( m_aOutputSize.Width() - aDragWinSize.Width() - 1 );
if( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() )
aDragWinPos.setY( m_aOutputSize.Height() - aDragWinSize.Height() - 1 );
if( aDragWinPos.X() < 0 )
aDragWinPos.setX( 0 );
if( aDragWinPos.Y() < 0 )
aDragWinPos.setY( 0 );
// TODO : don't position window anew, if it is leaving range, but just expand the range
// position window
EndTracking();
m_pDragWin->SetZOrder(nullptr, ZOrderFlags::First);
// check, if I really moved
// (this prevents setting the modified-Flag, when there actually was no change0
TTableWindowData::value_type pData = m_pDragWin->GetData();
if ( ! (pData && pData->HasPosition() && (pData->GetPosition() == aDragWinPos)))
{
// old logic coordinates
Point ptOldPos = m_pDragWin->GetPosPixel() + Point(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
// new positioning
m_pDragWin->SetPosPixel(aDragWinPos);
TabWinMoved(m_pDragWin, ptOldPos);
m_pDragWin->GrabFocus();
}
m_pDragWin = nullptr;
SetPointer(PointerStyle::Arrow);
}
// else we handle the resizing
else if( m_pSizingWin )
{
SetPointer( PointerStyle::Arrow );
EndTracking();
// old physical coordinates
Size szOld = m_pSizingWin->GetSizePixel();
Point ptOld = m_pSizingWin->GetPosPixel();
Size aNewSize(CalcZoom(m_aSizingRect.GetSize().Width()),CalcZoom(m_aSizingRect.GetSize().Height()));
m_pSizingWin->SetPosSizePixel( m_aSizingRect.TopLeft(), aNewSize );
TabWinSized(m_pSizingWin, ptOld, szOld);
m_pSizingWin->Invalidate( m_aSizingRect );
m_pSizingWin = nullptr;
}
}
else if (rTEvt.IsTrackingCanceled())
{
if (m_aDragScrollIdle.IsActive())
m_aDragScrollIdle.Stop();
EndTracking();
}
else
{
if( m_pDragWin )
{
m_ptPrevDraggingPos = rTEvt.GetMouseEvent().GetPosPixel();
// scroll at window borders
ScrollWhileDragging();
}
if( m_pSizingWin )
{
Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
m_aSizingRect = m_pSizingWin->getSizingRect(aMousePos,m_aOutputSize);
PaintImmediately();
ShowTracking( m_aSizingRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow );
}
}
}
void OJoinTableView::ConnDoubleClicked(VclPtr<OTableConnection>& /*rConnection*/)
{
}
void OJoinTableView::MouseButtonDown( const MouseEvent& rEvt )
{
GrabFocus();
Window::MouseButtonDown(rEvt);
}
void OJoinTableView::MouseButtonUp( const MouseEvent& rEvt )
{
Window::MouseButtonUp(rEvt);
// Has a connection been selected?
if( m_vTableConnection.empty() )
return;
DeselectConn(GetSelectedConn());
for (auto & elem : m_vTableConnection)
{
if( elem->CheckHit(rEvt.GetPosPixel()) )
{
SelectConn(elem);
// Double-click
if( rEvt.GetClicks() == 2 )
ConnDoubleClicked(elem);
break;
}
}
}
void OJoinTableView::KeyInput( const KeyEvent& rEvt )
{
sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
bool bShift = rEvt.GetKeyCode().IsShift();
bool bCtrl = rEvt.GetKeyCode().IsMod1();
if( !bCtrl && !bShift && (nCode==KEY_DELETE) )
{
if (GetSelectedConn())
RemoveConnection(GetSelectedConn(), true);
}
else
Window::KeyInput( rEvt );
}
void OJoinTableView::DeselectConn(OTableConnection* pConn)
{
if (!pConn || !pConn->IsSelected())
return;
// deselect the corresponding entries in the ListBox of the table window
OTableWindow* pWin = pConn->GetSourceWin();
if (pWin && pWin->GetListBox())
pWin->GetListBox()->get_widget().unselect_all();
pWin = pConn->GetDestWin();
if (pWin && pWin->GetListBox())
pWin->GetListBox()->get_widget().unselect_all();
pConn->Deselect();
m_pSelectedConn = nullptr;
}
void OJoinTableView::SelectConn(OTableConnection* pConn)
{
DeselectConn(GetSelectedConn());
pConn->Select();
m_pSelectedConn = pConn;
GrabFocus(); // has to be called here because a table window may still be focused
// select the concerned entries in the windows
OTableWindow* pConnSource = pConn->GetSourceWin();
OTableWindow* pConnDest = pConn->GetDestWin();
if (!(pConnSource && pConnDest))
return;
OTableWindowListBox* pSourceBox = pConnSource->GetListBox().get();
OTableWindowListBox* pDestBox = pConnDest->GetListBox().get();
if (!(pSourceBox && pDestBox))
return;
pSourceBox->get_widget().unselect_all();
pDestBox->get_widget().unselect_all();
bool bScrolled = false;
const std::vector<std::unique_ptr<OConnectionLine>>& rLines = pConn->GetConnLineList();
auto aIter = rLines.rbegin();
for(;aIter != rLines.rend();++aIter)
{
if ((*aIter)->IsValid())
{
int nSourceEntry = pSourceBox->GetEntryFromText((*aIter)->GetData()->GetSourceFieldName());
if (nSourceEntry != -1)
{
pSourceBox->get_widget().select(nSourceEntry);
pSourceBox->get_widget().scroll_to_row(nSourceEntry);
bScrolled = true;
}
int nDestEntry = pDestBox->GetEntryFromText((*aIter)->GetData()->GetDestFieldName());
if (nDestEntry != -1)
{
pDestBox->get_widget().select(nDestEntry);
pDestBox->get_widget().scroll_to_row(nDestEntry);
bScrolled = true;
}
}
}
if (bScrolled)
{
// scrolling was done -> redraw
Invalidate(InvalidateFlags::NoChildren);
}
}
void OJoinTableView::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
DrawConnections(rRenderContext, rRect);
}
void OJoinTableView::InvalidateConnections()
{
// draw Joins
for (auto & conn : m_vTableConnection)
conn->InvalidateConnection();
}
void OJoinTableView::DrawConnections(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
// draw Joins
for(const auto& connection : m_vTableConnection)
connection->Draw(rRenderContext, rRect);
// finally redraw the selected one above all others
if (GetSelectedConn())
GetSelectedConn()->Draw(rRenderContext, rRect);
}
std::vector<VclPtr<OTableConnection> >::const_iterator OJoinTableView::getTableConnections(const OTableWindow* _pFromWin) const
{
return std::find_if( m_vTableConnection.begin(),
m_vTableConnection.end(),
[_pFromWin](OTableConnection * p) { return p->isTableConnection(_pFromWin); });
}
sal_Int32 OJoinTableView::getConnectionCount(const OTableWindow* _pFromWin) const
{
return std::count_if( m_vTableConnection.begin(),
m_vTableConnection.end(),
[_pFromWin](OTableConnection * p) { return p->isTableConnection(_pFromWin); });
}
bool OJoinTableView::ExistsAConn(const OTableWindow* pFrom) const
{
return getTableConnections(pFrom) != m_vTableConnection.end();
}
void OJoinTableView::ClearAll()
{
SetUpdateMode(false);
HideTabWins();
// and the same with the Connections
for (auto & elem : m_vTableConnection)
{
RemoveConnection(elem, true);
}
m_vTableConnection.clear();
m_pLastFocusTabWin = nullptr;
m_pSelectedConn = nullptr;
// scroll to the upper left
ScrollPane(-GetScrollOffset().X(), true, true);
ScrollPane(-GetScrollOffset().Y(), false, true);
Invalidate();
}
void OJoinTableView::ScrollWhileDragging()
{
OSL_ENSURE(m_pDragWin != nullptr, "OJoinTableView::ScrollWhileDragging must not be called when a window is being dragged !");
// kill the timer
if (m_aDragScrollIdle.IsActive())
m_aDragScrollIdle.Stop();
Point aDragWinPos = m_ptPrevDraggingPos - m_aDragOffset;
Size aDragWinSize = m_pDragWin->GetSizePixel();
Point aLowerRight(aDragWinPos.X() + aDragWinSize.Width(), aDragWinPos.Y() + aDragWinSize.Height());
if (aDragWinPos == m_pDragWin->GetPosPixel())
return;
// avoid illustration errors (when scrolling with active TrackingRect)
HideTracking();
bool bScrolling = false;
bool bNeedScrollTimer = false;
// scroll at window borders
// TODO : only catch, if window would disappear completely (don't, if there is still a pixel visible)
if( aDragWinPos.X() < 5 )
{
bScrolling = ScrollPane( -LINE_SIZE, true, true );
if( !bScrolling && (aDragWinPos.X()<0) )
aDragWinPos.setX( 0 );
// do I need further (timer controlled) scrolling ?
bNeedScrollTimer = bScrolling && (aDragWinPos.X() < 5);
}
if( aLowerRight.X() > m_aOutputSize.Width() - 5 )
{
bScrolling = ScrollPane( LINE_SIZE, true, true ) ;
if( !bScrolling && ( aLowerRight.X() > m_aOutputSize.Width() ) )
aDragWinPos.setX( m_aOutputSize.Width() - aDragWinSize.Width() );
// do I need further (timer controlled) scrolling ?
bNeedScrollTimer = bScrolling && (aLowerRight.X() > m_aOutputSize.Width() - 5);
}
if( aDragWinPos.Y() < 5 )
{
bScrolling = ScrollPane( -LINE_SIZE, false, true );
if( !bScrolling && (aDragWinPos.Y()<0) )
aDragWinPos.setY( 0 );
bNeedScrollTimer = bScrolling && (aDragWinPos.Y() < 5);
}
if( aLowerRight.Y() > m_aOutputSize.Height() - 5 )
{
bScrolling = ScrollPane( LINE_SIZE, false, true );
if( !bScrolling && ( (aDragWinPos.Y() + aDragWinSize.Height()) > m_aOutputSize.Height() ) )
aDragWinPos.setY( m_aOutputSize.Height() - aDragWinSize.Height() );
bNeedScrollTimer = bScrolling && (aLowerRight.Y() > m_aOutputSize.Height() - 5);
}
// resetting timer, if still necessary
if (bNeedScrollTimer)
{
m_aDragScrollIdle.SetPriority( TaskPriority::HIGH_IDLE );
m_aDragScrollIdle.Start();
}
// redraw DraggingRect
m_aDragRect = tools::Rectangle(m_ptPrevDraggingPos - m_aDragOffset, m_pDragWin->GetSizePixel());
PaintImmediately();
ShowTracking( m_aDragRect, ShowTrackFlags::Small | ShowTrackFlags::TrackWindow );
}
IMPL_LINK_NOARG(OJoinTableView, OnDragScrollTimer, Timer *, void)
{
ScrollWhileDragging();
}
void OJoinTableView::invalidateAndModify(std::unique_ptr<SfxUndoAction> _pAction)
{
Invalidate(InvalidateFlags::NoChildren);
m_pView->getController().addUndoActionAndInvalidate(std::move(_pAction));
}
void OJoinTableView::TabWinMoved(OTableWindow* ptWhich, const Point& ptOldPosition)
{
Point ptThumbPos(GetHScrollBar().GetThumbPos(), GetVScrollBar().GetThumbPos());
ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel() + ptThumbPos);
invalidateAndModify(std::make_unique<OJoinMoveTabWinUndoAct>(this, ptOldPosition, ptWhich));
}
void OJoinTableView::TabWinSized(OTableWindow* ptWhich, const Point& ptOldPosition, const Size& szOldSize)
{
ptWhich->GetData()->SetSize(ptWhich->GetSizePixel());
ptWhich->GetData()->SetPosition(ptWhich->GetPosPixel());
invalidateAndModify(std::make_unique<OJoinSizeTabWinUndoAct>(this, ptOldPosition, szOldSize, ptWhich));
}
bool OJoinTableView::IsAddAllowed()
{
// not, if Db readonly
if (m_pView->getController().isReadOnly())
return false;
try
{
Reference< XConnection> xConnection = m_pView->getController().getConnection();
if(!xConnection.is())
return false;
// not, if too many tables already
Reference < XDatabaseMetaData > xMetaData( xConnection->getMetaData() );
sal_Int32 nMax = xMetaData.is() ? xMetaData->getMaxTablesInSelect() : 0;
if (nMax && nMax <= static_cast<sal_Int32>(m_aTableMap.size()))
return false;
}
catch(SQLException&)
{
return false;
}
return true;
}
void OJoinTableView::executePopup(const Point& rPos, VclPtr<OTableConnection>& rSelConnection)
{
::tools::Rectangle aRect(rPos, Size(1, 1));
weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, u"dbaccess/ui/joinviewmenu.ui"_ustr));
std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu(u"menu"_ustr));
OUString sIdent = xContextMenu->popup_at_rect(pPopupParent, aRect);
if (sIdent == "delete")
RemoveConnection(rSelConnection, true);
else if (sIdent == "edit")
ConnDoubleClicked(rSelConnection); // is the same as double clicked
}
void OJoinTableView::Command(const CommandEvent& rEvt)
{
bool bHandled = false;
switch (rEvt.GetCommand())
{
case CommandEventId::ContextMenu:
{
if( m_vTableConnection.empty() )
return;
VclPtr<OTableConnection>& rSelConnection = GetSelectedConn();
// when it wasn't a mouse event use the selected connection
if (!rEvt.IsMouseEvent())
{
if (rSelConnection)
{
const std::vector<std::unique_ptr<OConnectionLine>>& rLines = rSelConnection->GetConnLineList();
auto aIter = std::find_if(rLines.begin(), rLines.end(),std::mem_fn(&OConnectionLine::IsValid));
if( aIter != rLines.end() )
executePopup((*aIter)->getMidPoint(), rSelConnection);
}
}
else
{
DeselectConn(rSelConnection);
const Point& aMousePos = rEvt.GetMousePosPixel();
for (auto & elem : m_vTableConnection)
{
if( elem->CheckHit(aMousePos) )
{
SelectConn(elem);
if(!getDesignView()->getController().isReadOnly() && getDesignView()->getController().isConnected())
executePopup(rEvt.GetMousePosPixel(),elem);
break;
}
}
}
bHandled = true;
}
break;
default: break;
}
if (!bHandled)
Window::Command(rEvt);
}
OTableConnection* OJoinTableView::GetTabConn(const OTableWindow* pLhs,const OTableWindow* pRhs,bool _bSuppressCrossOrNaturalJoin) const
{
OTableConnection* pConn = nullptr;
OSL_ENSURE(pRhs || pLhs, "OJoinTableView::GetTabConn : invalid args !");
// only one NULL-arg allowed
if ((!pLhs || pLhs->ExistsAConn()) && (!pRhs || pRhs->ExistsAConn()))
{
for(VclPtr<OTableConnection> const & pData : m_vTableConnection)
{
if ( ( (pData->GetSourceWin() == pLhs)
&& ( (pData->GetDestWin() == pRhs)
|| (nullptr == pRhs)
)
)
|| ( (pData->GetSourceWin() == pRhs)
&& ( (pData->GetDestWin() == pLhs)
|| (nullptr == pLhs)
)
)
)
{
if ( _bSuppressCrossOrNaturalJoin )
{
if ( suppressCrossNaturalJoin(pData->GetData()) )
continue;
}
pConn = pData;
break;
}
}
}
return pConn;
}
bool OJoinTableView::PreNotify(NotifyEvent& rNEvt)
{
bool bHandled = false;
switch (rNEvt.GetType())
{
case NotifyEventType::COMMAND:
{
const CommandEvent* pCommand = rNEvt.GetCommandEvent();
if (pCommand->GetCommand() == CommandEventId::Wheel)
{
const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
if (pData->GetMode() == CommandWheelMode::SCROLL)
{
if (pData->GetDelta() > 0)
ScrollPane(-10 * pData->GetScrollLines(), pData->IsHorz(), true);
else
ScrollPane(10 * pData->GetScrollLines(), pData->IsHorz(), true);
bHandled = true;
}
}
}
break;
case NotifyEventType::KEYINPUT:
{
if (m_aTableMap.empty())
// no tab wins -> no conns -> no traveling
break;
const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
if (!pKeyEvent->GetKeyCode().IsMod1())
{
switch (pKeyEvent->GetKeyCode().GetCode())
{
case KEY_TAB:
{
if (!HasChildPathFocus())
break;
bool bForward = !pKeyEvent->GetKeyCode().IsShift();
// is there an active tab win ?
OTableWindowMap::const_iterator aIter = std::find_if(m_aTableMap.begin(), m_aTableMap.end(),
[](const OTableWindowMap::value_type& rEntry) { return rEntry.second && rEntry.second->HasChildPathFocus(); });
OTableWindow* pNextWin = nullptr;
OTableConnection* pNextConn = nullptr;
if (aIter != m_aTableMap.end())
{ // there is a currently active tab win
// check if there is an "overflow" and we should select a conn instead of a win
if (!m_vTableConnection.empty())
{
if ((aIter->second == m_aTableMap.rbegin()->second) && bForward)
// the last win is active and we're travelling forward -> select the first conn
pNextConn = m_vTableConnection.begin()->get();
if ((aIter == m_aTableMap.begin()) && !bForward)
// the first win is active and we're traveling backward -> select the last conn
pNextConn = m_vTableConnection.rbegin()->get();
}
if (!pNextConn)
{
// no conn for any reason -> select the next or previous tab win
if(bForward)
{
if ( aIter->second == m_aTableMap.rbegin()->second )
pNextWin = m_aTableMap.begin()->second;
else
{
++aIter;
pNextWin = aIter->second;
}
}
else
{
if (aIter == m_aTableMap.begin())
pNextWin = m_aTableMap.rbegin()->second;
else
{
--aIter;
pNextWin = aIter->second;
}
}
}
}
else
{ // no active tab win -> travel the connections
// find the currently selected conn within the conn list
sal_Int32 i(0);
for (auto const& elem : m_vTableConnection)
{
if ( elem.get() == GetSelectedConn() )
break;
++i;
}
if (i == sal_Int32(m_vTableConnection.size() - 1) && bForward)
// the last conn is active and we're travelling forward -> select the first win
pNextWin = m_aTableMap.begin()->second;
if ((i == 0) && !bForward && !m_aTableMap.empty())
// the first conn is active and we're travelling backward -> select the last win
pNextWin = m_aTableMap.rbegin()->second;
if (pNextWin)
DeselectConn(GetSelectedConn());
else
// no win for any reason -> select the next or previous conn
if (i < static_cast<sal_Int32>(m_vTableConnection.size()))
// there is a currently active conn
pNextConn = m_vTableConnection[(i + (bForward ? 1 : m_vTableConnection.size() - 1)) % m_vTableConnection.size()].get();
else
{ // no tab win selected, no conn selected
if (!m_vTableConnection.empty())
pNextConn = m_vTableConnection[bForward ? 0 : m_vTableConnection.size() - 1].get();
else if (!m_aTableMap.empty())
{
if(bForward)
pNextWin = m_aTableMap.begin()->second;
else
pNextWin = m_aTableMap.rbegin()->second;
}
}
}
// now select the object
if (pNextWin)
{
if (pNextWin->GetListBox())
pNextWin->GetListBox()->GrabFocus();
else
pNextWin->GrabFocus();
EnsureVisible(pNextWin);
}
else if (pNextConn)
{
GrabFocus();
// necessary : a conn may be selected even if a tab win has the focus, in this case
// the next travel would select the same conn again if we would not reset the focus ...
SelectConn(pNextConn);
}
}
break;
case KEY_RETURN:
{
if (!pKeyEvent->GetKeyCode().IsShift() && GetSelectedConn() && HasFocus())
ConnDoubleClicked(GetSelectedConn());
break;
}
}
}
}
break;
case NotifyEventType::GETFOCUS:
{
if (m_aTableMap.empty())
// no tab wins -> no conns -> no focus change
break;
vcl::Window* pSource = rNEvt.GetWindow();
if (pSource)
{
vcl::Window* pSearchFor = nullptr;
if (pSource->GetParent() == this)
// it may be one of the tab wins
pSearchFor = pSource;
else if (pSource->GetParent() && (pSource->GetParent()->GetParent() == this))
// it may be one of th list boxes of one of the tab wins
pSearchFor = pSource->GetParent();
if (pSearchFor)
{
for (auto const& elem : m_aTableMap)
{
if (elem.second == pSearchFor)
{
m_pLastFocusTabWin = elem.second;
break;
}
}
}
}
}
break;
default:
break;
}
if (!bHandled)
return Window::PreNotify(rNEvt);
return true;
}
void OJoinTableView::GrabTabWinFocus()
{
if (m_pLastFocusTabWin && m_pLastFocusTabWin->IsVisible())
{
if (m_pLastFocusTabWin->GetListBox())
m_pLastFocusTabWin->GetListBox()->GrabFocus();
else
m_pLastFocusTabWin->GrabFocus();
}
else if (!m_aTableMap.empty() && m_aTableMap.begin()->second && m_aTableMap.begin()->second->IsVisible())
{
VclPtr<OTableWindow> pFirstWin = m_aTableMap.begin()->second;
if (pFirstWin->GetListBox())
pFirstWin->GetListBox()->GrabFocus();
else
pFirstWin->GrabFocus();
}
}
void OJoinTableView::StateChanged( StateChangedType nType )
{
Window::StateChanged( nType );
// FIXME RenderContext
if ( nType != StateChangedType::Zoom )
return;
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
vcl::Font aFont = rStyleSettings.GetGroupFont();
if ( IsControlFont() )
aFont.Merge( GetControlFont() );
SetZoomedPointFont(*GetOutDev(), aFont);
for (auto const& elem : m_aTableMap)
{
elem.second->SetZoom(GetZoom());
Size aSize(CalcZoom(elem.second->GetSizePixel().Width()),CalcZoom(elem.second->GetSizePixel().Height()));
elem.second->SetSizePixel(aSize);
}
Resize();
}
void OJoinTableView::HideTabWins()
{
SetUpdateMode(false);
OTableWindowMap& rTabWins = GetTabWinMap();
// working on a copy because the real list will be cleared in inner calls
OTableWindowMap aCopy(rTabWins);
for (auto const& elem : aCopy)
RemoveTabWin(elem.second);
m_pView->getController().setModified(true);
SetUpdateMode(true);
}
sal_Int8 OJoinTableView::AcceptDrop( const AcceptDropEvent& /*_rEvt*/ )
{
return DND_ACTION_NONE;
}
sal_Int8 OJoinTableView::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
{
return DND_ACTION_NONE;
}
void OJoinTableView::dragFinished( )
{
}
void OJoinTableView::clearLayoutInformation()
{
m_pLastFocusTabWin = nullptr;
m_pSelectedConn = nullptr;
// delete lists
for (auto & elem : m_aTableMap)
{
if ( elem.second )
elem.second->clearListBox();
elem.second.disposeAndClear();
}
m_aTableMap.clear();
for (auto & elem : m_vTableConnection)
elem.disposeAndClear();
m_vTableConnection.clear();
}
void OJoinTableView::lookForUiActivities()
{
}
void OJoinTableView::LoseFocus()
{
DeselectConn(GetSelectedConn());
Window::LoseFocus();
}
void OJoinTableView::GetFocus()
{
Window::GetFocus();
if ( !m_aTableMap.empty() && !GetSelectedConn() )
GrabTabWinFocus();
}
Reference< XAccessible > OJoinTableView::CreateAccessible()
{
m_pAccessible = new OJoinDesignViewAccess(this);
return m_pAccessible;
}
void OJoinTableView::modified()
{
OJoinController& rController = m_pView->getController();
rController.setModified( true );
rController.InvalidateFeature(ID_BROWSER_ADDTABLE);
rController.InvalidateFeature(SID_RELATION_ADD_RELATION);
}
void OJoinTableView::addConnection(OTableConnection* _pConnection,bool _bAddData)
{
if ( _bAddData )
{
#if OSL_DEBUG_LEVEL > 0
TTableConnectionData& rTabConnDataList = m_pView->getController().getTableConnectionData();
OSL_ENSURE( std::find(rTabConnDataList.begin(), rTabConnDataList.end(),_pConnection->GetData()) == rTabConnDataList.end(),"Data already in vector!");
#endif
m_pView->getController().getTableConnectionData().push_back(_pConnection->GetData());
}
m_vTableConnection.emplace_back(_pConnection);
_pConnection->RecalcLines();
_pConnection->InvalidateConnection();
modified();
if ( m_pAccessible )
m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD,
Any(),
Any(_pConnection->GetAccessible()));
}
bool OJoinTableView::allowQueries() const
{
return true;
}
void OJoinTableView::onNoColumns_throw()
{
OSL_FAIL( "OTableWindow::onNoColumns_throw: cannot really handle this!" );
throw SQLException();
}
bool OJoinTableView::suppressCrossNaturalJoin(const TTableConnectionData::value_type& ) const
{
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V1053 Calling the 'SetSizePixel' virtual function in the constructor may lead to unexpected result at runtime.