/* -*- 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 .
*/
// 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 (autoconst& elem : m_aTableMap)
{
OTableWindow* pCurrent = elem.second;
Point aPos(pCurrent->GetData()->GetPosition() - GetScrollOffset());
pCurrent->SetPosPixel(aPos);
}
}
void OJoinTableView::AddTabWin(const OUString& _rComposedName, const OUString& rWinName, bool/*bNewTable*/)
{
OSL_ENSURE(!_rComposedName.isEmpty(),"There must be a table name supplied!");
// 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.contains(rWinName))
m_aTableMap[_rComposedName] = pNewTabWin; else
m_aTableMap[rWinName] = pNewTabWin;
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()
);
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 (autoconst& 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++;
// check if the new position in inside the scrollbars ranges
Point aBottom(aNewPos);
aBottom.AdjustX(aNewSize.Width() );
aBottom.AdjustY(aNewSize.Height() );
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()));
}
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);
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->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;
// 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();
// 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 (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 (autoconst& 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(); elseif (!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);
} elseif (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; elseif (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 (autoconst& elem : m_aTableMap)
{ if (elem.second == pSearchFor)
{
m_pLastFocusTabWin = elem.second; break;
}
}
}
}
} break; default: break;
}
if (!bHandled) return Window::PreNotify(rNEvt); returntrue;
}
// working on a copy because the real list will be cleared in inner calls
OTableWindowMap aCopy(rTabWins); for (autoconst& elem : aCopy)
RemoveTabWin(elem.second);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.