diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-10-21 14:20:12 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-10-29 13:58:47 +0100 |
commit | 09e3d45cdc5c739e5246388a83ccfc6d76bf66e9 (patch) | |
tree | 5ae533f38a626016951b02e7d2406c368b298723 /vcl/source/treelist | |
parent | 93a641d291adf86491cc68ac64f4f614c937183a (diff) |
weld fpicker cluster
Change-Id: I6566263809ff0032388a0b56571f0cf7428058d7
Reviewed-on: https://gerrit.libreoffice.org/81334
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source/treelist')
-rw-r--r-- | vcl/source/treelist/iconview.cxx | 224 | ||||
-rw-r--r-- | vcl/source/treelist/iconviewimpl.cxx | 662 |
2 files changed, 886 insertions, 0 deletions
diff --git a/vcl/source/treelist/iconview.cxx b/vcl/source/treelist/iconview.cxx new file mode 100644 index 000000000000..5c2e5b2ffed5 --- /dev/null +++ b/vcl/source/treelist/iconview.cxx @@ -0,0 +1,224 @@ +/* -*- 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 <vcl/treelistentry.hxx> +#include <vcl/viewdataentry.hxx> +#include <iconview.hxx> +#include <iconviewimpl.hxx> + +IconView::IconView( vcl::Window* pParent, WinBits nBits ) + : SvTreeListBox( pParent, nBits ) +{ + nColumns = 1; + mbCenterAndClipText = true; + SetEntryHeight( 100 ); + SetEntryWidth( 100 ); + + pImpl.reset( new IconViewImpl( this, GetModel(), GetStyle() ) ); +} + +void IconView::Resize() +{ + Size aBoxSize = Control::GetParent()->GetOutputSizePixel(); + + if ( !aBoxSize.Width() ) + return; + + SetSizePixel( aBoxSize ); + + nColumns = aBoxSize.Width() / nEntryWidth; + + SvTreeListBox::Resize(); +} + +tools::Rectangle IconView::GetFocusRect( SvTreeListEntry*, long nEntryPos ) +{ + Size aSize; + aSize.setHeight( nEntryHeight ); + aSize.setWidth( nEntryWidth ); + + Point aPos; + aPos.setX( 0 ); + aPos.setY( 0 ); + + tools::Rectangle aRect; + + short nCols = GetColumnsCount(); + + if(nCols) + { + aPos.setY( ( nEntryPos / nCols ) * nEntryHeight ); + aPos.setX( ( nEntryPos % nCols ) * nEntryWidth ); + } + + aRect.SetPos( aPos ); + aRect.SetSize( aSize ); + + return aRect; +} + +void IconView::PaintEntry(SvTreeListEntry& rEntry, long nX, long nY, + vcl::RenderContext& rRenderContext) +{ + + tools::Rectangle aRect; // multi purpose + + PreparePaint(rRenderContext, rEntry); + + pImpl->UpdateContextBmpWidthMax(&rEntry); + + short nTempEntryHeight = GetEntryHeight(); + short nTempEntryWidth = GetEntryWidth(); + + Point aEntryPos; + + Color aBackupTextColor(rRenderContext.GetTextColor()); + vcl::Font aBackupFont(rRenderContext.GetFont()); + Color aBackupColor = rRenderContext.GetFillColor(); + + bool bCurFontIsSel = false; + const WinBits nWindowStyle = GetStyle(); + const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus(); + const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings(); + + vcl::Font aHighlightFont(rRenderContext.GetFont()); + const Color aHighlightTextColor(rSettings.GetHighlightTextColor()); + aHighlightFont.SetColor(aHighlightTextColor); + + Size aRectSize(nTempEntryWidth, nTempEntryHeight); + + SvViewDataEntry* pViewDataEntry = GetViewDataEntry( &rEntry ); + + sal_uInt16 nItemCount = rEntry.ItemCount(); + sal_uInt16 nCurItem = 0; + sal_uInt16 nIconItem = nItemCount; + + while (nCurItem < nItemCount) + { + SvLBoxItem* pItem = nCurItem < nItemCount ? &rEntry.GetItem(nCurItem) : nullptr; + SvLBoxItemType nItemType = pItem->GetType(); + + if (nItemType == SvLBoxItemType::ContextBmp) + { + nIconItem = nCurItem; + nCurItem++; + continue; + } + + auto nItemHeight = SvLBoxItem::GetHeight(pViewDataEntry, nCurItem); + + aEntryPos.setX( nX ); + aEntryPos.setY( nY ); + + // set background pattern/color + + Wallpaper aWallpaper = rRenderContext.GetBackground(); + + if (pViewDataEntry->IsHighlighted()) + { + Color aNewWallColor = rSettings.GetHighlightColor(); + // if the face color is bright then the deactivate color is also bright + // -> so you can't see any deactivate selection + if (bHideSelection && !rSettings.GetFaceColor().IsBright() + && aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright()) + { + aNewWallColor = rSettings.GetDeactiveColor(); + } + // set font color to highlight + if (!bCurFontIsSel) + { + rRenderContext.SetTextColor(aHighlightTextColor); + rRenderContext.SetFont(aHighlightFont); + bCurFontIsSel = true; + } + aWallpaper.SetColor(aNewWallColor); + } + else // no selection + { + if (bCurFontIsSel) + { + bCurFontIsSel = false; + rRenderContext.SetTextColor(aBackupTextColor); + rRenderContext.SetFont(aBackupFont); + } + else + { + aWallpaper.SetColor(rEntry.GetBackColor()); + } + } + + // draw background + if (!(nTreeFlags & SvTreeFlags::USESEL)) + { + aRect.SetPos(aEntryPos); + aRect.SetSize(aRectSize); + + Color aBackgroundColor = aWallpaper.GetColor(); + if (aBackgroundColor != COL_TRANSPARENT) + { + rRenderContext.SetFillColor(aBackgroundColor); + // this case may occur for smaller horizontal resizes + if (aRect.Left() < aRect.Right()) + rRenderContext.DrawRect(aRect); + } + } + + // center vertically + aEntryPos.AdjustY((nTempEntryHeight - nItemHeight) / 2 ); + + // draw item + pViewDataEntry->SetPaintRectangle(aRect); + + aEntryPos.AdjustY(15 ); + + pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry); + + rRenderContext.SetFillColor(aBackupColor); + + nCurItem++; + } + + // draw icon + if(nIconItem != nItemCount && nIconItem < nItemCount) + { + SvLBoxItem* pItem = &rEntry.GetItem(nIconItem); + auto nItemWidth = pItem->GetWidth(this, pViewDataEntry, nIconItem); + auto nItemHeight = SvLBoxItem::GetHeight(pViewDataEntry, nIconItem); + + aEntryPos.setX( nX ); + aEntryPos.setY( nY ); + + // center horizontally + aEntryPos.AdjustX((nTempEntryWidth - nItemWidth) / 2 ); + // center vertically + aEntryPos.AdjustY((nTempEntryHeight - nItemHeight) / 2 ); + + aEntryPos.AdjustY( -10 ); + + pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry); + } + + if (bCurFontIsSel) + { + rRenderContext.SetTextColor(aBackupTextColor); + rRenderContext.SetFont(aBackupFont); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/treelist/iconviewimpl.cxx b/vcl/source/treelist/iconviewimpl.cxx new file mode 100644 index 000000000000..9014220d4820 --- /dev/null +++ b/vcl/source/treelist/iconviewimpl.cxx @@ -0,0 +1,662 @@ +/* -*- 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 <vcl/svapp.hxx> +#include <tools/debug.hxx> +#include <iconview.hxx> +#include <iconviewimpl.hxx> + +IconViewImpl::IconViewImpl( SvTreeListBox* pTreeListBox, SvTreeList* pTreeList, WinBits nWinStyle ) +: SvImpLBox( pTreeListBox, pTreeList, nWinStyle ) +{ +} + +void IconViewImpl::CursorUp() +{ + if (!m_pStartEntry) + return; + + SvTreeListEntry* pPrevFirstToDraw = m_pStartEntry; + + for(short i = 0; i < m_pView->GetColumnsCount() && pPrevFirstToDraw; i++) + pPrevFirstToDraw = m_pView->PrevVisible(pPrevFirstToDraw); + + if( !pPrevFirstToDraw ) + return; + + m_nFlags &= ~LBoxFlags::Filling; + long nEntryHeight = m_pView->GetEntryHeight(); + ShowCursor( false ); + m_pView->Update(); + m_pStartEntry = pPrevFirstToDraw; + tools::Rectangle aArea( GetVisibleArea() ); + aArea.AdjustBottom( -nEntryHeight ); + m_pView->Scroll( 0, nEntryHeight, aArea, ScrollFlags::NoChildren ); + m_pView->Update(); + ShowCursor( true ); + m_pView->NotifyScrolled(); +} + +void IconViewImpl::CursorDown() +{ + if (!m_pStartEntry) + return; + + SvTreeListEntry* pNextFirstToDraw = m_pStartEntry; + + for(short i = 0; i < m_pView->GetColumnsCount(); i++) + pNextFirstToDraw = m_pView->NextVisible(pNextFirstToDraw); + + if( pNextFirstToDraw ) + { + m_nFlags &= ~LBoxFlags::Filling; + ShowCursor( false ); + m_pView->Update(); + m_pStartEntry = pNextFirstToDraw; + tools::Rectangle aArea( GetVisibleArea() ); + m_pView->Scroll( 0, -(m_pView->GetEntryHeight()), aArea, ScrollFlags::NoChildren ); + m_pView->Update(); + ShowCursor( true ); + m_pView->NotifyScrolled(); + } +} + +void IconViewImpl::PageDown( sal_uInt16 nDelta ) +{ + sal_uInt16 nRealDelta = nDelta * m_pView->GetColumnsCount(); + + if( !nDelta ) + return; + + if (!m_pStartEntry) + return; + + SvTreeListEntry* pNext = m_pView->NextVisible(m_pStartEntry, nRealDelta); + if( pNext == m_pStartEntry ) + return; + + ShowCursor( false ); + + m_nFlags &= ~LBoxFlags::Filling; + m_pView->Update(); + m_pStartEntry = pNext; + + if( nRealDelta >= m_nVisibleCount ) + { + m_pView->Invalidate( GetVisibleArea() ); + m_pView->Update(); + } + else + { + tools::Rectangle aArea( GetVisibleArea() ); + long nScroll = m_pView->GetEntryHeight() * static_cast<long>(nRealDelta); + nScroll = -nScroll; + m_pView->Update(); + m_pView->Scroll( 0, nScroll, aArea, ScrollFlags::NoChildren ); + m_pView->Update(); + m_pView->NotifyScrolled(); + } + + ShowCursor( true ); +} + +void IconViewImpl::PageUp( sal_uInt16 nDelta ) +{ + sal_uInt16 nRealDelta = nDelta * m_pView->GetColumnsCount(); + if( !nDelta ) + return; + + if (!m_pStartEntry) + return; + + SvTreeListEntry* pPrev = m_pView->PrevVisible(m_pStartEntry, nRealDelta); + if( pPrev == m_pStartEntry ) + return; + + m_nFlags &= ~LBoxFlags::Filling; + ShowCursor( false ); + + m_pView->Update(); + m_pStartEntry = pPrev; + if( nRealDelta >= m_nVisibleCount ) + { + m_pView->Invalidate( GetVisibleArea() ); + m_pView->Update(); + } + else + { + long nEntryHeight = m_pView->GetEntryHeight(); + tools::Rectangle aArea( GetVisibleArea() ); + m_pView->Update(); + m_pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, ScrollFlags::NoChildren ); + m_pView->Update(); + m_pView->NotifyScrolled(); + } + + ShowCursor( true ); +} + +void IconViewImpl::KeyDown( bool bPageDown ) +{ + if( !m_aVerSBar->IsVisible() ) + return; + + long nDelta; + if( bPageDown ) + nDelta = m_aVerSBar->GetPageSize(); + else + nDelta = 1; + + long nThumbPos = m_aVerSBar->GetThumbPos(); + + if( nDelta <= 0 ) + return; + + m_nFlags &= ~LBoxFlags::Filling; + BeginScroll(); + + m_aVerSBar->SetThumbPos( nThumbPos+nDelta ); + if( bPageDown ) + PageDown( static_cast<short>(nDelta) ); + else + CursorDown(); + + EndScroll(); +} + +void IconViewImpl::KeyUp( bool bPageUp ) +{ + if( !m_aVerSBar->IsVisible() ) + return; + + long nDelta; + if( bPageUp ) + nDelta = m_aVerSBar->GetPageSize(); + else + nDelta = 1; + + long nThumbPos = m_aVerSBar->GetThumbPos(); + + if( nThumbPos < nDelta ) + nDelta = nThumbPos; + + if( nDelta < 0 ) + return; + + m_nFlags &= ~LBoxFlags::Filling; + BeginScroll(); + + m_aVerSBar->SetThumbPos( nThumbPos - nDelta ); + if( bPageUp ) + PageUp( static_cast<short>(nDelta) ); + else + CursorUp(); + + EndScroll(); +} + +long IconViewImpl::GetEntryLine( SvTreeListEntry* pEntry ) const +{ + if(!m_pStartEntry ) + return -1; // invisible position + + long nFirstVisPos = m_pView->GetVisiblePos( m_pStartEntry ); + long nEntryVisPos = m_pView->GetVisiblePos( pEntry ); + nFirstVisPos = nEntryVisPos - nFirstVisPos; + + return nFirstVisPos; +} + +Point IconViewImpl::GetEntryPosition( SvTreeListEntry* pEntry ) const +{ + const int pos = m_pView->GetAbsPos( pEntry ); + + return Point( ( pos % m_pView->GetColumnsCount() ) * m_pView->GetEntryWidth(), + ( pos / m_pView->GetColumnsCount() ) * m_pView->GetEntryHeight() ); +} + +SvTreeListEntry* IconViewImpl::GetClickedEntry( const Point& rPoint ) const +{ + DBG_ASSERT( m_pView->GetModel(), "IconViewImpl::GetClickedEntry: how can this ever happen?" ); + if ( !m_pView->GetModel() ) + return nullptr; + if( m_pView->GetEntryCount() == 0 || !m_pStartEntry || !m_pView->GetEntryHeight() || !m_pView->GetEntryWidth()) + return nullptr; + + sal_uInt16 nY = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() ); + sal_uInt16 nX = static_cast<sal_uInt16>(rPoint.X() / m_pView->GetEntryWidth() ); + sal_uInt16 nTemp = nY * m_pView->GetColumnsCount() + nX; + + SvTreeListEntry* pEntry = m_pView->NextVisible(m_pStartEntry, nTemp); + + return pEntry; +} + +bool IconViewImpl::IsEntryInView( SvTreeListEntry* pEntry ) const +{ + // parent collapsed + if( !m_pView->IsEntryVisible(pEntry) ) + return false; + + long nY = GetEntryLine( pEntry ) / m_pView->GetColumnsCount() * m_pView->GetEntryHeight(); + if( nY < 0 ) + return false; + + long nMax = m_nVisibleCount / m_pView->GetColumnsCount() * m_pView->GetEntryHeight(); + if( nY >= nMax ) + return false; + + long nStart = GetEntryLine( pEntry ) - GetEntryLine( m_pStartEntry ); + return nStart >= 0; +} + +void IconViewImpl::AdjustScrollBars( Size& rSize ) +{ + long nEntryHeight = m_pView->GetEntryHeight(); + if( !nEntryHeight ) + return; + + sal_uInt16 nResult = 0; + + Size aOSize( m_pView->Control::GetOutputSizePixel() ); + + const WinBits nWindowStyle = m_pView->GetStyle(); + bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0; + + // number of entries that are not collapsed + sal_uLong nTotalCount = m_pView->GetVisibleCount(); + + // number of entries visible within the view + m_nVisibleCount = aOSize.Height() / nEntryHeight * m_pView->GetColumnsCount(); + + long nRows = ( nTotalCount / m_pView->GetColumnsCount() ) + 1; + + // do we need a vertical scrollbar? + if( bVerSBar || nTotalCount > m_nVisibleCount ) + { + nResult = 1; + } + + PositionScrollBars( aOSize, nResult ); + + // adapt Range, VisibleRange etc. + + // refresh output size, in case we have to scroll + tools::Rectangle aRect; + aRect.SetSize( aOSize ); + m_aSelEng.SetVisibleArea( aRect ); + + // vertical scrollbar + if( !m_bInVScrollHdl ) + { + m_aVerSBar->SetPageSize( nTotalCount ); + m_aVerSBar->SetVisibleSize( nTotalCount - nRows ); + } + else + { + m_nFlags |= LBoxFlags::EndScrollSetVisSize; + } + + if( nResult & 0x0001 ) + m_aVerSBar->Show(); + else + m_aVerSBar->Hide(); + + rSize = aOSize; +} + +// returns 0 if position is just past the last entry +SvTreeListEntry* IconViewImpl::GetEntry( const Point& rPoint ) const +{ + if( (m_pView->GetEntryCount() == 0) || !m_pStartEntry || + (rPoint.Y() > m_aOutputSize.Height()) + || !m_pView->GetEntryHeight() + || !m_pView->GetEntryWidth()) + return nullptr; + + sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() * m_pView->GetColumnsCount() + rPoint.X() / m_pView->GetEntryWidth() ); + sal_uInt16 nTemp = nClickedEntry; + SvTreeListEntry* pEntry = m_pView->NextVisible(m_pStartEntry, nTemp); + if( nTemp != nClickedEntry ) + pEntry = nullptr; + return pEntry; +} + +void IconViewImpl::SyncVerThumb() +{ + if( m_pStartEntry ) + { + long nEntryPos = m_pView->GetVisiblePos( m_pStartEntry ); + m_aVerSBar->SetThumbPos( nEntryPos ); + } + else + m_aVerSBar->SetThumbPos( 0 ); +} + +void IconViewImpl::UpdateAll( bool bInvalidateCompleteView ) +{ + FindMostRight( nullptr ); + m_aVerSBar->SetRange( Range( 0, m_pView->GetVisibleCount() ) ); + SyncVerThumb(); + FillView(); + ShowVerSBar(); + if( m_bSimpleTravel && m_pCursor && m_pView->HasFocus() ) + m_pView->Select( m_pCursor ); + ShowCursor( true ); + if( bInvalidateCompleteView ) + m_pView->Invalidate(); + else + m_pView->Invalidate( GetVisibleArea() ); +} + +void IconViewImpl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) +{ + if (!m_pView->GetVisibleCount()) + return; + + m_nFlags |= LBoxFlags::InPaint; + + if (m_nFlags & LBoxFlags::Filling) + { + SvTreeListEntry* pFirst = m_pView->First(); + if (pFirst != m_pStartEntry) + { + ShowCursor(false); + m_pStartEntry = m_pView->First(); + m_aVerSBar->SetThumbPos( 0 ); + StopUserEvent(); + ShowCursor(true); + m_nCurUserEvent = Application::PostUserEvent(LINK(this, SvImpLBox, MyUserEvent), + reinterpret_cast<void*>(1)); + return; + } + } + + if (!m_pStartEntry) + { + m_pStartEntry = m_pView->First(); + } + + long nRectHeight = rRect.GetHeight(); + long nRectWidth = rRect.GetWidth(); + long nEntryHeight = m_pView->GetEntryHeight(); + long nEntryWidth = m_pView->GetEntryWidth(); + + // calculate area for the entries we want to draw + sal_uInt16 nStartId = static_cast<sal_uInt16>(rRect.Top() / nEntryHeight * m_pView->GetColumnsCount() + (rRect.Left() / nEntryWidth)); + sal_uInt16 nCount = static_cast<sal_uInt16>(( nRectHeight / nEntryHeight + 1 ) * nRectWidth / nEntryWidth); + nCount += 2; // don't miss an entry + + long nY = nStartId / m_pView->GetColumnsCount() * nEntryHeight; + long nX = 0; + SvTreeListEntry* pEntry = m_pStartEntry; + while (nStartId && pEntry) + { + pEntry = m_pView->NextVisible(pEntry); + nStartId--; + } + + vcl::Region aClipRegion(GetClipRegionRect()); + + if (!m_pCursor && !mbNoAutoCurEntry) + { + // do not select if multiselection or explicit set + bool bNotSelect = (m_aSelEng.GetSelectionMode() == SelectionMode::Multiple ) || ((m_nStyle & WB_NOINITIALSELECTION) == WB_NOINITIALSELECTION); + SetCursor(m_pStartEntry, bNotSelect); + } + + for(sal_uInt16 n = 0; n< nCount && pEntry; n++) + { + static_cast<IconView*>(m_pView.get())->PaintEntry(*pEntry, nX, nY, rRenderContext); + nX += nEntryWidth; + + if(nX + m_pView->GetEntryWidth() > nEntryWidth * m_pView->GetColumnsCount()) + { + nY += nEntryHeight; + nX = 0; + } + pEntry = m_pView->NextVisible(pEntry); + } + + m_nFlags &= ~LBoxFlags::DeselectAll; + rRenderContext.SetClipRegion(); + m_nFlags &= ~LBoxFlags::InPaint; +} + +void IconViewImpl::InvalidateEntry( long nId ) const +{ + if( m_nFlags & LBoxFlags::InPaint ) + return; + + tools::Rectangle aRect( GetVisibleArea() ); + long nMaxBottom = aRect.Bottom(); + aRect.SetTop( nId / m_pView->GetColumnsCount() * m_pView->GetEntryHeight() ); + aRect.SetBottom( aRect.Top() ); aRect.AdjustBottom(m_pView->GetEntryHeight() ); + + if( aRect.Top() > nMaxBottom ) + return; + if( aRect.Bottom() > nMaxBottom ) + aRect.SetBottom( nMaxBottom ); + m_pView->Invalidate( aRect ); +} + +bool IconViewImpl::KeyInput( const KeyEvent& rKEvt ) +{ + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + + if( rKeyCode.IsMod2() ) + return false; // don't evaluate Alt key + + m_nFlags &= ~LBoxFlags::Filling; + + if( !m_pCursor ) + m_pCursor = m_pStartEntry; + if( !m_pCursor ) + return false; + + sal_uInt16 aCode = rKeyCode.GetCode(); + + bool bShift = rKeyCode.IsShift(); + bool bMod1 = rKeyCode.IsMod1(); + + SvTreeListEntry* pNewCursor; + + bool bHandled = true; + + long i; + long nColumns = m_pView->GetColumnsCount(); + + switch( aCode ) + { + case KEY_LEFT: + if( !IsEntryInView( m_pCursor ) ) + MakeVisible( m_pCursor ); + + pNewCursor = m_pCursor; + do + { + pNewCursor = m_pView->PrevVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if (!pNewCursor) + pNewCursor = m_pCursor; + + m_aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + if( !IsEntryInView( pNewCursor ) ) + KeyUp( false ); + break; + + case KEY_RIGHT: + if( !IsEntryInView( m_pCursor ) ) + MakeVisible( m_pCursor ); + + pNewCursor = m_pCursor; + do + { + pNewCursor = m_pView->NextVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && m_pCursor ) + pNewCursor = m_pCursor; + + if( pNewCursor ) + { + m_aSelEng.CursorPosChanging( bShift, bMod1 ); + if( IsEntryInView( pNewCursor ) ) + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + else + { + if( m_pCursor ) + m_pView->Select( m_pCursor, false ); + KeyDown( false ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + } + } + else + KeyDown( false ); // because scrollbar range might still + // allow scrolling + break; + + case KEY_UP: + { + if( !IsEntryInView( m_pCursor ) ) + MakeVisible( m_pCursor ); + + pNewCursor = m_pCursor; + for( i = 0; i < nColumns && pNewCursor; i++) + { + do + { + pNewCursor = m_pView->PrevVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + } + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && m_pCursor ) + pNewCursor = m_pCursor; + + if( pNewCursor ) + { + m_aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + if( !IsEntryInView( pNewCursor ) ) + KeyUp( false ); + } + break; + } + + case KEY_DOWN: + { + if( !IsEntryInView( m_pCursor ) ) + MakeVisible( m_pCursor ); + + pNewCursor = m_pCursor; + for( i = 0; i < nColumns && pNewCursor; i++) + { + do + { + pNewCursor = m_pView->NextVisible(pNewCursor); + } while( pNewCursor && !IsSelectable(pNewCursor) ); + } + + // if there is no next entry, take the current one + // this ensures that in case of _one_ entry in the list, this entry is selected when pressing + // the cursor key + if ( !pNewCursor && m_pCursor ) + pNewCursor = m_pCursor; + + if( pNewCursor ) + { + m_aSelEng.CursorPosChanging( bShift, bMod1 ); + if( IsEntryInView( pNewCursor ) ) + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + else + { + if( m_pCursor ) + m_pView->Select( m_pCursor, false ); + KeyDown( false ); + SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on + } + } + else + KeyDown( false ); // because scrollbar range might still + // allow scrolling + break; + } + + case KEY_RETURN: + { + m_pView->aDoubleClickHdl.Call( m_pView ); + bHandled = true; + + break; + } + + case KEY_END: + { + pNewCursor = m_pView->GetModel()->Last(); + + while( pNewCursor && !IsSelectable(pNewCursor) ) + { + pNewCursor = m_pView->PrevVisible(pNewCursor); + } + + m_pStartEntry = pNewCursor; + + while( m_pStartEntry && m_pView->GetAbsPos( m_pStartEntry ) % m_pView->GetColumnsCount() != 0 ) + { + m_pStartEntry = m_pView->PrevVisible(m_pStartEntry); + } + + if( pNewCursor && pNewCursor != m_pCursor) + { +// SelAllDestrAnch( false ); + m_aSelEng.CursorPosChanging( bShift, bMod1 ); + SetCursor( pNewCursor ); + SyncVerThumb(); + } + + bHandled = true; + + break; + } + + default: + { + bHandled = false; + break; + } + } + + if(!bHandled) + return SvImpLBox::KeyInput( rKEvt ); + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |