LCOV - code coverage report
Current view: top level - sfx2/source/control - thumbnailview.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 236 654 36.1 %
Date: 2014-11-03 Functions: 19 53 35.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  */
       9             : 
      10             : #include <sfx2/thumbnailview.hxx>
      11             : #include <sfx2/thumbnailviewitem.hxx>
      12             : 
      13             : #include <utility>
      14             : 
      15             : #include "thumbnailviewacc.hxx"
      16             : 
      17             : #include <basegfx/color/bcolortools.hxx>
      18             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      19             : #include <basegfx/range/b2drectangle.hxx>
      20             : #include <basegfx/polygon/b2dpolygon.hxx>
      21             : #include <basegfx/vector/b2dsize.hxx>
      22             : #include <basegfx/vector/b2dvector.hxx>
      23             : #include <drawinglayer/attribute/fillgraphicattribute.hxx>
      24             : #include <drawinglayer/attribute/fontattribute.hxx>
      25             : #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
      26             : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      27             : #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
      28             : #include <drawinglayer/primitive2d/textprimitive2d.hxx>
      29             : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
      30             : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
      31             : #include <rtl/ustring.hxx>
      32             : #include <vcl/decoview.hxx>
      33             : #include <vcl/svapp.hxx>
      34             : #include <vcl/scrbar.hxx>
      35             : #include <vcl/help.hxx>
      36             : #include <vcl/settings.hxx>
      37             : 
      38             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      39             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      40             : 
      41             : #include <boost/scoped_ptr.hpp>
      42             : 
      43             : using namespace basegfx;
      44             : using namespace basegfx::tools;
      45             : using namespace drawinglayer::attribute;
      46             : using namespace drawinglayer::primitive2d;
      47             : 
      48             : enum
      49             : {
      50             :     ITEM_OFFSET = 4,
      51             :     ITEM_OFFSET_DOUBLE = 6,
      52             :     NAME_LINE_OFF_X = 2,
      53             :     NAME_LINE_OFF_Y = 2,
      54             :     NAME_LINE_HEIGHT = 2,
      55             :     NAME_OFFSET = 2,
      56             :     SCROLL_OFFSET = 4
      57             : };
      58             : 
      59           4 : ThumbnailView::ThumbnailView (vcl::Window *pParent, WinBits nWinStyle, bool bDisableTransientChildren)
      60           4 :     : Control( pParent, nWinStyle )
      61             : {
      62           4 :     mpItemAttrs = NULL;
      63           4 :     ImplInit();
      64           4 :     mbIsTransientChildrenDisabled = bDisableTransientChildren;
      65           4 : }
      66             : 
      67           8 : ThumbnailView::~ThumbnailView()
      68             : {
      69             :     com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
      70             :             xComponent(GetAccessible(false),
      71           4 :                        com::sun::star::uno::UNO_QUERY);
      72             : 
      73           4 :     if (xComponent.is())
      74           0 :         xComponent->dispose ();
      75             : 
      76           4 :     delete mpScrBar;
      77           4 :     delete mpItemAttrs;
      78           4 :     delete mpProcessor;
      79             : 
      80           4 :     ImplDeleteItems();
      81           4 : }
      82             : 
      83           0 : void ThumbnailView::MouseMove(const MouseEvent& rMEvt)
      84             : {
      85           0 :     size_t nItemCount = mFilteredItemList.size();
      86           0 :     Point aPoint = rMEvt.GetPosPixel();
      87           0 :     OUString aHelp;
      88             : 
      89           0 :     for (size_t i = 0; i < nItemCount; i++)
      90             :     {
      91           0 :         ThumbnailViewItem *pItem = mFilteredItemList[i];
      92             : 
      93           0 :         if (pItem->mbVisible && !rMEvt.IsLeaveWindow() && pItem->getDrawArea().IsInside(aPoint))
      94             :         {
      95           0 :             aHelp = pItem->getHelpText();
      96             :         }
      97             : 
      98           0 :         Rectangle aToInvalidate(pItem->updateHighlight(pItem->mbVisible && !rMEvt.IsLeaveWindow(), aPoint));
      99             : 
     100           0 :         if (!aToInvalidate.IsEmpty() && IsReallyVisible() && IsUpdateMode())
     101           0 :             Invalidate(aToInvalidate);
     102             :     }
     103             : 
     104           0 :     if (mbShowTooltips)
     105           0 :         SetQuickHelpText(aHelp);
     106           0 : }
     107             : 
     108           0 : void ThumbnailView::AppendItem(ThumbnailViewItem *pItem)
     109             : {
     110           0 :     if (maFilterFunc(pItem))
     111             :     {
     112             :         // Save current start,end range, iterator might get invalidated
     113           0 :         size_t nSelStartPos = 0;
     114           0 :         ThumbnailViewItem *pSelStartItem = NULL;
     115             : 
     116           0 :         if (mpStartSelRange != mFilteredItemList.end())
     117             :         {
     118           0 :             pSelStartItem = *mpStartSelRange;
     119           0 :             nSelStartPos = mpStartSelRange - mFilteredItemList.begin();
     120             :         }
     121             : 
     122           0 :         mFilteredItemList.push_back(pItem);
     123           0 :         mpStartSelRange = pSelStartItem != NULL ? mFilteredItemList.begin() + nSelStartPos : mFilteredItemList.end();
     124             :     }
     125             : 
     126           0 :     mItemList.push_back(pItem);
     127           0 : }
     128             : 
     129           4 : void ThumbnailView::ImplInit()
     130             : {
     131           4 :     mpScrBar            = NULL;
     132           4 :     mnHeaderHeight      = 0;
     133           4 :     mnItemWidth         = 0;
     134           4 :     mnItemHeight        = 0;
     135           4 :     mnItemPadding       = 0;
     136           4 :     mnVisLines          = 0;
     137           4 :     mnLines             = 0;
     138           4 :     mnFineness          = 5;
     139           4 :     mnFirstLine         = 0;
     140           4 :     mnCols              = 0;
     141           4 :     mbScroll            = false;
     142           4 :     mbHasVisibleItems   = false;
     143           4 :     mbShowTooltips      = false;
     144           4 :     maFilterFunc = ViewFilterAll();
     145           4 :     maColor = GetSettings().GetStyleSettings().GetFieldColor();
     146           4 :     mpStartSelRange = mFilteredItemList.end();
     147             : 
     148             :     // Create the processor and process the primitives
     149           4 :     const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
     150           4 :     mpProcessor = drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(*this, aNewViewInfos );
     151             : 
     152           4 :     ImplInitSettings( true, true, true );
     153           4 : }
     154             : 
     155           8 : void ThumbnailView::ImplDeleteItems()
     156             : {
     157           8 :     const size_t n = mItemList.size();
     158             : 
     159          12 :     for ( size_t i = 0; i < n; ++i )
     160             :     {
     161           4 :         ThumbnailViewItem *const pItem = mItemList[i];
     162             : 
     163             :         // deselect all current selected items and fire events
     164           4 :         if (pItem->isSelected())
     165             :         {
     166           0 :             pItem->setSelection(false);
     167           0 :             maItemStateHdl.Call(pItem);
     168             : 
     169             :             // fire accessible event???
     170             :         }
     171             : 
     172           4 :         if ( pItem->isVisible() && ImplHasAccessibleListeners() )
     173             :         {
     174           0 :             ::com::sun::star::uno::Any aOldAny, aNewAny;
     175             : 
     176           0 :             aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
     177           0 :             ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
     178             :         }
     179             : 
     180           4 :         delete pItem;
     181             :     }
     182             : 
     183           8 :     mItemList.clear();
     184           8 :     mFilteredItemList.clear();
     185             : 
     186           8 :     mpStartSelRange = mFilteredItemList.end();
     187           8 : }
     188             : 
     189           8 : void ThumbnailView::ImplInitSettings( bool bFont, bool bForeground, bool bBackground )
     190             : {
     191           8 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     192             : 
     193           8 :     if ( bFont )
     194             :     {
     195           4 :         vcl::Font aFont;
     196           4 :         aFont = rStyleSettings.GetAppFont();
     197           4 :         if ( IsControlFont() )
     198           0 :             aFont.Merge( GetControlFont() );
     199           4 :         SetZoomedPointFont( aFont );
     200             :     }
     201             : 
     202           8 :     if ( bForeground || bFont )
     203             :     {
     204           4 :         Color aColor;
     205           4 :         if ( IsControlForeground() )
     206           0 :             aColor = GetControlForeground();
     207             :         else
     208           4 :             aColor = rStyleSettings.GetButtonTextColor();
     209           4 :         SetTextColor( aColor );
     210           4 :         SetTextFillColor();
     211             :     }
     212             : 
     213           8 :     if ( bBackground )
     214             :     {
     215           8 :         Color aColor = rStyleSettings.GetFieldColor();
     216           8 :         SetBackground( aColor );
     217             :     }
     218             : 
     219           8 :     delete mpItemAttrs;
     220           8 :     mpItemAttrs = new ThumbnailItemAttributes;
     221           8 :     mpItemAttrs->aFillColor = maColor.getBColor();
     222           8 :     mpItemAttrs->aHighlightColor = rStyleSettings.GetHighlightColor().getBColor();
     223           8 :     mpItemAttrs->aFontAttr = getFontAttributeFromVclFont(mpItemAttrs->aFontSize,GetFont(),false,true);
     224           8 :     mpItemAttrs->nMaxTextLength = 0;
     225           8 : }
     226             : 
     227          18 : void ThumbnailView::ImplInitScrollBar()
     228             : {
     229          18 :     if ( GetStyle() & WB_VSCROLL )
     230             :     {
     231          18 :         if ( !mpScrBar )
     232             :         {
     233           4 :             mpScrBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
     234           4 :             mpScrBar->SetScrollHdl( LINK( this, ThumbnailView, ImplScrollHdl ) );
     235             :         }
     236             :         else
     237             :         {
     238             :             // adapt the width because of the changed settings
     239          14 :             long nScrBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
     240          14 :             mpScrBar->setPosSizePixel( 0, 0, nScrBarWidth, 0, WINDOW_POSSIZE_WIDTH );
     241             :         }
     242             :     }
     243          18 : }
     244             : 
     245           0 : void ThumbnailView::DrawItem (ThumbnailViewItem *pItem)
     246             : {
     247           0 :     if (pItem->isVisible())
     248             :     {
     249           0 :         Rectangle aRect = pItem->getDrawArea();
     250             : 
     251           0 :         if ( (aRect.GetHeight() > 0) && (aRect.GetWidth() > 0) )
     252           0 :             pItem->Paint(mpProcessor,mpItemAttrs);
     253             :     }
     254           0 : }
     255             : 
     256           0 : void ThumbnailView::OnItemDblClicked (ThumbnailViewItem*)
     257             : {
     258           0 : }
     259             : 
     260           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ThumbnailView::CreateAccessible()
     261             : {
     262           0 :     return new ThumbnailViewAcc( this, mbIsTransientChildrenDisabled );
     263             : }
     264             : 
     265          26 : void ThumbnailView::CalculateItemPositions (bool bScrollBarUsed)
     266             : {
     267          26 :     if (!mnItemHeight || !mnItemWidth)
     268          26 :         return;
     269             : 
     270          26 :     Size        aWinSize = GetOutputSizePixel();
     271          26 :     size_t      nItemCount = mFilteredItemList.size();
     272          26 :     WinBits     nStyle = GetStyle();
     273          26 :     ScrollBar*  pDelScrBar = NULL;
     274             : 
     275             :     // consider the scrolling
     276          26 :     if ( nStyle & WB_VSCROLL )
     277          18 :         ImplInitScrollBar();
     278             :     else
     279             :     {
     280           8 :         if ( mpScrBar )
     281             :         {
     282             :             // delete ScrollBar not until later, to prevent recursive calls
     283           0 :             pDelScrBar = mpScrBar;
     284           0 :             mpScrBar = NULL;
     285             :         }
     286             :     }
     287             : 
     288             :     // calculate window scroll ratio
     289             :     float nScrollRatio;
     290          26 :     if( bScrollBarUsed && mpScrBar )
     291           0 :         nScrollRatio = static_cast<float>(mpScrBar->GetThumbPos()) /
     292           0 :                         static_cast<float>(mpScrBar->GetRangeMax()-2);
     293             :     else
     294          26 :         nScrollRatio = 0;
     295             : 
     296             :     // calculate ScrollBar width
     297          26 :     long nScrBarWidth = 0;
     298          26 :     if ( mpScrBar )
     299          18 :         nScrBarWidth = mpScrBar->GetSizePixel().Width();
     300             : 
     301             :     // calculate maximum number of visible columns
     302          26 :     mnCols = (sal_uInt16)((aWinSize.Width()-nScrBarWidth) / (mnItemWidth));
     303             : 
     304          26 :     if (!mnCols)
     305           8 :         mnCols = 1;
     306             : 
     307             :     // calculate maximum number of visible rows
     308          26 :     mnVisLines = (sal_uInt16)((aWinSize.Height()-mnHeaderHeight) / (mnItemHeight));
     309             : 
     310             :     // calculate empty space
     311          26 :     long nHSpace = aWinSize.Width()-nScrBarWidth - mnCols*mnItemWidth;
     312          26 :     long nVSpace = aWinSize.Height()-mnHeaderHeight - mnVisLines*mnItemHeight;
     313          26 :     long nHItemSpace = nHSpace / (mnCols+1);
     314          26 :     long nVItemSpace = nVSpace / (mnVisLines+1);
     315             : 
     316             :     // calculate maximum number of rows
     317             :     // Floor( (M+N-1)/N )==Ceiling( M/N )
     318          26 :     mnLines = (static_cast<long>(nItemCount)+mnCols-1) / mnCols;
     319             : 
     320          26 :     if ( !mnLines )
     321          22 :         mnLines = 1;
     322             : 
     323          26 :     if ( mnLines <= mnVisLines )
     324          18 :         mnFirstLine = 0;
     325           8 :     else if ( mnFirstLine > (sal_uInt16)(mnLines-mnVisLines) )
     326           0 :         mnFirstLine = (sal_uInt16)(mnLines-mnVisLines);
     327             : 
     328          26 :     mbHasVisibleItems = true;
     329             : 
     330          26 :     long nItemHeightOffset = mnItemHeight + nVItemSpace;
     331             :     long nHiddenLines = (static_cast<long>(
     332          26 :         ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio ) -
     333          26 :         nVItemSpace - mnHeaderHeight) /
     334          26 :         nItemHeightOffset;
     335             : 
     336             :     // calculate offsets
     337          26 :     long nStartX = nHItemSpace;
     338          26 :     long nStartY = nVItemSpace + mnHeaderHeight;
     339             : 
     340             :     // calculate and draw items
     341          26 :     long x = nStartX;
     342          52 :     long y = nStartY - ( mnLines - 1 ) * nItemHeightOffset * nScrollRatio +
     343          52 :         nHiddenLines * nItemHeightOffset;
     344             : 
     345             :     // draw items
     346             :     // Unless we are scrolling (via scrollbar) we just use the precalculated
     347             :     // mnFirstLine -- our nHiddenLines calculation takes into account only
     348             :     // what the user has done with the scrollbar but not any changes of selection
     349             :     // using the keyboard, meaning we could accidentally hide the selected item
     350             :     // if we believe the scrollbar (fdo#72287).
     351          26 :     size_t nFirstItem = (bScrollBarUsed ? nHiddenLines : mnFirstLine) * mnCols;
     352          26 :     size_t nLastItem = nFirstItem + (mnVisLines + 1) * mnCols;
     353             : 
     354             :     // If want also draw parts of items in the last line,
     355             :     // then we add one more line if parts of these line are
     356             :     // visible
     357             : 
     358          26 :     size_t nCurCount = 0;
     359          34 :     for ( size_t i = 0; i < nItemCount; i++ )
     360             :     {
     361           8 :         ThumbnailViewItem *const pItem = mFilteredItemList[i];
     362             : 
     363           8 :         if ((nCurCount >= nFirstItem) && (nCurCount < nLastItem))
     364             :         {
     365           8 :             if( !pItem->isVisible())
     366             :             {
     367           0 :                 if ( ImplHasAccessibleListeners() )
     368             :                 {
     369           0 :                     ::com::sun::star::uno::Any aOldAny, aNewAny;
     370             : 
     371           0 :                     aNewAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
     372           0 :                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
     373             :                 }
     374             : 
     375           0 :                 pItem->show(true);
     376             : 
     377           0 :                 maItemStateHdl.Call(pItem);
     378             :             }
     379             : 
     380           8 :             pItem->setDrawArea(Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) ));
     381           8 :             pItem->calculateItemsPosition(mnThumbnailHeight,mnDisplayHeight,mnItemPadding,mpItemAttrs->nMaxTextLength,mpItemAttrs);
     382             : 
     383           8 :             if ( !((nCurCount+1) % mnCols) )
     384             :             {
     385           4 :                 x = nStartX;
     386           4 :                 y += mnItemHeight+nVItemSpace;
     387             :             }
     388             :             else
     389           4 :                 x += mnItemWidth+nHItemSpace;
     390             :         }
     391             :         else
     392             :         {
     393           0 :             if( pItem->isVisible())
     394             :             {
     395           0 :                 if ( ImplHasAccessibleListeners() )
     396             :                 {
     397           0 :                     ::com::sun::star::uno::Any aOldAny, aNewAny;
     398             : 
     399           0 :                     aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
     400           0 :                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
     401             :                 }
     402             : 
     403           0 :                 pItem->show(false);
     404             : 
     405           0 :                 maItemStateHdl.Call(pItem);
     406             :             }
     407             : 
     408             :         }
     409             : 
     410           8 :         ++nCurCount;
     411             :     }
     412             : 
     413             :     // arrange ScrollBar, set values and show it
     414          26 :     if ( mpScrBar )
     415             :     {
     416          18 :         mnLines = (nCurCount+mnCols-1)/mnCols;
     417             : 
     418             :         // check if scroll is needed
     419          18 :         mbScroll = mnLines > mnVisLines;
     420             : 
     421             : 
     422          18 :         Point aPos( aWinSize.Width() - nScrBarWidth, mnHeaderHeight );
     423          18 :         Size aSize( nScrBarWidth, aWinSize.Height() - mnHeaderHeight );
     424             : 
     425          18 :         mpScrBar->SetPosSizePixel( aPos, aSize );
     426          18 :         mpScrBar->SetRangeMax( (nCurCount+mnCols-1)*mnFineness/mnCols);
     427          18 :         mpScrBar->SetVisibleSize( mnVisLines );
     428          18 :         if (!bScrollBarUsed)
     429          18 :             mpScrBar->SetThumbPos( (long)mnFirstLine*mnFineness );
     430          18 :         long nPageSize = mnVisLines;
     431          18 :         if ( nPageSize < 1 )
     432           4 :             nPageSize = 1;
     433          18 :         mpScrBar->SetPageSize( nPageSize );
     434          18 :         mpScrBar->Show( mbScroll );
     435             :     }
     436             : 
     437             :     // delete ScrollBar
     438          26 :     delete pDelScrBar;
     439             : }
     440             : 
     441           0 : size_t ThumbnailView::ImplGetItem( const Point& rPos ) const
     442             : {
     443           0 :     if ( !mbHasVisibleItems )
     444             :     {
     445           0 :         return THUMBNAILVIEW_ITEM_NOTFOUND;
     446             :     }
     447             : 
     448           0 :     for (size_t i = 0; i < mFilteredItemList.size(); ++i)
     449             :     {
     450           0 :         if (mFilteredItemList[i]->isVisible() && mFilteredItemList[i]->getDrawArea().IsInside(rPos))
     451           0 :             return i;
     452             :     }
     453             : 
     454           0 :     return THUMBNAILVIEW_ITEM_NOTFOUND;
     455             : }
     456             : 
     457           0 : ThumbnailViewItem* ThumbnailView::ImplGetItem( size_t nPos )
     458             : {
     459           0 :     return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos] : NULL;
     460             : }
     461             : 
     462           0 : sal_uInt16 ThumbnailView::ImplGetVisibleItemCount() const
     463             : {
     464           0 :     sal_uInt16 nRet = 0;
     465           0 :     const size_t nItemCount = mItemList.size();
     466             : 
     467           0 :     for ( size_t n = 0; n < nItemCount; ++n )
     468             :     {
     469           0 :         if ( mItemList[n]->isVisible() )
     470           0 :             ++nRet;
     471             :     }
     472             : 
     473           0 :     return nRet;
     474             : }
     475             : 
     476           0 : ThumbnailViewItem* ThumbnailView::ImplGetVisibleItem( sal_uInt16 nVisiblePos )
     477             : {
     478           0 :     const size_t nItemCount = mItemList.size();
     479             : 
     480           0 :     for ( size_t n = 0; n < nItemCount; ++n )
     481             :     {
     482           0 :         ThumbnailViewItem *const pItem = mItemList[n];
     483             : 
     484           0 :         if ( pItem->isVisible() && !nVisiblePos-- )
     485           0 :             return pItem;
     486             :     }
     487             : 
     488           0 :     return NULL;
     489             : }
     490             : 
     491           0 : void ThumbnailView::ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
     492             : {
     493           0 :     ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation( GetAccessible( false ) );
     494             : 
     495           0 :     if( pAcc )
     496           0 :         pAcc->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
     497           0 : }
     498             : 
     499           4 : bool ThumbnailView::ImplHasAccessibleListeners()
     500             : {
     501           4 :     ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation( GetAccessible( false ) );
     502           4 :     return( pAcc && pAcc->HasAccessibleListeners() );
     503             : }
     504             : 
     505           0 : IMPL_LINK( ThumbnailView,ImplScrollHdl, ScrollBar*, pScrollBar )
     506             : {
     507           0 :     if ( pScrollBar->GetDelta() )
     508             :     {
     509           0 :         CalculateItemPositions(true);
     510             : 
     511           0 :         if ( IsReallyVisible() && IsUpdateMode() )
     512           0 :             Invalidate();
     513             :     }
     514           0 :     return 0;
     515             : }
     516             : 
     517           0 : IMPL_LINK (ThumbnailView, OnItemSelected, ThumbnailViewItem*, pItem)
     518             : {
     519           0 :     maItemStateHdl.Call(pItem);
     520           0 :     return 0;
     521             : }
     522             : 
     523           0 : void ThumbnailView::KeyInput( const KeyEvent& rKEvt )
     524             : {
     525             :     // Get the last selected item in the list
     526           0 :     size_t nLastPos = 0;
     527           0 :     bool bFoundLast = false;
     528           0 :     for ( long i = mFilteredItemList.size() - 1; !bFoundLast && i >= 0; --i )
     529             :     {
     530           0 :         ThumbnailViewItem* pItem = mFilteredItemList[i];
     531           0 :         if ( pItem->isSelected() )
     532             :         {
     533           0 :             nLastPos = i;
     534           0 :             bFoundLast = true;
     535             :         }
     536             :     }
     537             : 
     538           0 :     bool bValidRange = false;
     539           0 :     bool bHasSelRange = mpStartSelRange != mFilteredItemList.end();
     540           0 :     size_t nNextPos = nLastPos;
     541           0 :     vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
     542           0 :     ThumbnailViewItem* pNext = NULL;
     543             : 
     544           0 :     if (aKeyCode.IsShift() && bHasSelRange)
     545             :     {
     546             :         //If the last elemented selected is the start range position
     547             :         //search for the first selected item
     548           0 :         size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
     549             : 
     550           0 :         if (nLastPos == nSelPos)
     551             :         {
     552           0 :             while (nLastPos && mFilteredItemList[nLastPos-1]->isSelected())
     553           0 :                 --nLastPos;
     554             :         }
     555             :     }
     556             : 
     557           0 :     switch ( aKeyCode.GetCode() )
     558             :     {
     559             :         case KEY_RIGHT:
     560           0 :             if (!mFilteredItemList.empty())
     561             :             {
     562           0 :                 if ( bFoundLast && nLastPos + 1 < mFilteredItemList.size() )
     563             :                 {
     564           0 :                     bValidRange = true;
     565           0 :                     nNextPos = nLastPos + 1;
     566             :                 }
     567             : 
     568           0 :                 pNext = mFilteredItemList[nNextPos];
     569             :             }
     570           0 :             break;
     571             :         case KEY_LEFT:
     572           0 :             if (!mFilteredItemList.empty())
     573             :             {
     574           0 :                 if ( nLastPos > 0 )
     575             :                 {
     576           0 :                     bValidRange = true;
     577           0 :                     nNextPos = nLastPos - 1;
     578             :                 }
     579             : 
     580           0 :                 pNext = mFilteredItemList[nNextPos];
     581             :             }
     582           0 :             break;
     583             :         case KEY_DOWN:
     584           0 :             if (!mFilteredItemList.empty())
     585             :             {
     586           0 :                 if ( bFoundLast )
     587             :                 {
     588             :                     //If we are in the second last row just go the one in
     589             :                     //the row below, if theres not row below just go to the
     590             :                     //last item but for the last row dont do anything.
     591           0 :                     if ( nLastPos + mnCols < mFilteredItemList.size( ) )
     592             :                     {
     593           0 :                         bValidRange = true;
     594           0 :                         nNextPos = nLastPos + mnCols;
     595             :                     }
     596             :                     else
     597             :                     {
     598           0 :                         int curRow = nLastPos/mnCols;
     599             : 
     600           0 :                         if (curRow < mnLines-1)
     601           0 :                             nNextPos = mFilteredItemList.size()-1;
     602             :                     }
     603             :                 }
     604             : 
     605           0 :                 pNext = mFilteredItemList[nNextPos];
     606             :             }
     607           0 :             break;
     608             :         case KEY_UP:
     609           0 :             if (!mFilteredItemList.empty())
     610             :             {
     611           0 :                 if ( nLastPos >= mnCols )
     612             :                 {
     613           0 :                     bValidRange = true;
     614           0 :                     nNextPos = nLastPos - mnCols;
     615             :                 }
     616             : 
     617           0 :                 pNext = mFilteredItemList[nNextPos];
     618             :             }
     619           0 :             break;
     620             :         case KEY_RETURN:
     621             :             {
     622           0 :                 if ( bFoundLast )
     623           0 :                     OnItemDblClicked( mFilteredItemList[nLastPos] );
     624             :             }
     625             :             //fall-through
     626             :         default:
     627           0 :             Control::KeyInput( rKEvt );
     628             :     }
     629             : 
     630           0 :     if ( pNext )
     631             :     {
     632           0 :         if (aKeyCode.IsShift() && bValidRange)
     633             :         {
     634           0 :             std::pair<size_t,size_t> aRange;
     635           0 :             size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
     636             : 
     637           0 :             if (nLastPos < nSelPos)
     638             :             {
     639           0 :                 if (nNextPos > nLastPos)
     640             :                 {
     641           0 :                     if ( nNextPos > nSelPos)
     642           0 :                         aRange = std::make_pair(nLastPos,nNextPos);
     643             :                     else
     644           0 :                         aRange = std::make_pair(nLastPos,nNextPos-1);
     645             :                 }
     646             :                 else
     647           0 :                     aRange = std::make_pair(nNextPos,nLastPos-1);
     648             :             }
     649           0 :             else if (nLastPos == nSelPos)
     650             :             {
     651           0 :                 if (nNextPos > nLastPos)
     652           0 :                     aRange = std::make_pair(nLastPos+1,nNextPos);
     653             :                 else
     654           0 :                     aRange = std::make_pair(nNextPos,nLastPos-1);
     655             :             }
     656             :             else
     657             :             {
     658           0 :                 if (nNextPos > nLastPos)
     659           0 :                     aRange = std::make_pair(nLastPos+1,nNextPos);
     660             :                 else
     661             :                 {
     662           0 :                     if ( nNextPos < nSelPos)
     663           0 :                         aRange = std::make_pair(nNextPos,nLastPos);
     664             :                     else
     665           0 :                         aRange = std::make_pair(nNextPos+1,nLastPos);
     666             :                 }
     667             :             }
     668             : 
     669           0 :             for (size_t i = aRange.first; i <= aRange.second; ++i)
     670             :             {
     671           0 :                 if (i != nSelPos)
     672             :                 {
     673           0 :                     ThumbnailViewItem *pCurItem = mFilteredItemList[i];
     674             : 
     675           0 :                     pCurItem->setSelection(!pCurItem->isSelected());
     676             : 
     677           0 :                     if (pCurItem->isVisible())
     678           0 :                         DrawItem(pCurItem);
     679             : 
     680           0 :                     maItemStateHdl.Call(pCurItem);
     681             :                 }
     682             :             }
     683             :         }
     684           0 :         else if (!aKeyCode.IsShift())
     685             :         {
     686           0 :             deselectItems();
     687           0 :             SelectItem(pNext->mnId);
     688             : 
     689             :             //Mark it as the selection range start position
     690           0 :             mpStartSelRange = mFilteredItemList.begin() + nNextPos;
     691             :         }
     692             : 
     693           0 :         MakeItemVisible(pNext->mnId);
     694             :     }
     695           0 : }
     696             : 
     697           0 : void ThumbnailView::MakeItemVisible( sal_uInt16 nItemId )
     698             : {
     699             :     // Get the item row
     700           0 :     size_t nPos = 0;
     701           0 :     bool bFound = false;
     702           0 :     for ( size_t i = 0; !bFound && i < mFilteredItemList.size(); ++i )
     703             :     {
     704           0 :         ThumbnailViewItem* pItem = mFilteredItemList[i];
     705           0 :         if ( pItem->mnId == nItemId )
     706             :         {
     707           0 :             nPos = i;
     708           0 :             bFound = true;
     709             :         }
     710             :     }
     711           0 :     sal_uInt16 nRow = mnCols ? nPos / mnCols : 0;
     712             : 
     713             :     // Move the visible rows as little as possible to include that one
     714           0 :     if ( nRow < mnFirstLine )
     715           0 :         mnFirstLine = nRow;
     716           0 :     else if ( nRow > mnFirstLine + mnVisLines )
     717           0 :         mnFirstLine = nRow - mnVisLines;
     718             : 
     719           0 :     CalculateItemPositions();
     720           0 :     Invalidate();
     721           0 : }
     722             : 
     723           0 : void ThumbnailView::MouseButtonDown( const MouseEvent& rMEvt )
     724             : {
     725           0 :     if ( !rMEvt.IsLeft() )
     726             :     {
     727           0 :         Control::MouseButtonDown( rMEvt );
     728           0 :         return;
     729             :     }
     730             : 
     731           0 :     size_t nPos = ImplGetItem(rMEvt.GetPosPixel());
     732           0 :     ThumbnailViewItem* pItem = ImplGetItem(nPos);
     733             : 
     734           0 :     if ( !pItem )
     735             :     {
     736           0 :         deselectItems();
     737           0 :         Control::MouseButtonDown( rMEvt );
     738           0 :         return;
     739             :     }
     740             : 
     741           0 :     if ( rMEvt.GetClicks() == 2 )
     742             :     {
     743           0 :         OnItemDblClicked(pItem);
     744           0 :         return;
     745             :     }
     746             : 
     747           0 :     if ( rMEvt.GetClicks() == 1 )
     748             :     {
     749           0 :         if (rMEvt.IsMod1())
     750             :         {
     751             :             //Keep selected item group state and just invert current desired one state
     752           0 :             pItem->setSelection(!pItem->isSelected());
     753             : 
     754             :             //This one becomes the selection range start position if it changes its state to selected otherwise resets it
     755           0 :             mpStartSelRange = pItem->isSelected() ? mFilteredItemList.begin() + nPos : mFilteredItemList.end();
     756             :         }
     757           0 :         else if (rMEvt.IsShift() && mpStartSelRange != mFilteredItemList.end())
     758             :         {
     759           0 :             std::pair<size_t,size_t> aNewRange;
     760           0 :             aNewRange.first = mpStartSelRange - mFilteredItemList.begin();
     761           0 :             aNewRange.second = nPos;
     762             : 
     763           0 :             if (aNewRange.first > aNewRange.second)
     764           0 :                 std::swap(aNewRange.first,aNewRange.second);
     765             : 
     766             :             //Deselect the ones outside of it
     767           0 :             for (size_t i = 0, n = mFilteredItemList.size(); i < n; ++i)
     768             :             {
     769           0 :                 ThumbnailViewItem *pCurItem  = mFilteredItemList[i];
     770             : 
     771           0 :                 if (pCurItem->isSelected() && (i < aNewRange.first || i > aNewRange.second))
     772             :                 {
     773           0 :                     pCurItem->setSelection(false);
     774             : 
     775           0 :                     if (pCurItem->isVisible())
     776           0 :                         DrawItem(pCurItem);
     777             : 
     778           0 :                     maItemStateHdl.Call(pCurItem);
     779             :                 }
     780             :             }
     781             : 
     782           0 :             size_t nSelPos = mpStartSelRange - mFilteredItemList.begin();
     783             : 
     784             :             //Select the items between start range and the selected item
     785           0 :             if (nSelPos != nPos)
     786             :             {
     787           0 :                 int dir = nSelPos < nPos ? 1 : -1;
     788           0 :                 size_t nCurPos = nSelPos + dir;
     789             : 
     790           0 :                 while (nCurPos != nPos)
     791             :                 {
     792           0 :                     ThumbnailViewItem *pCurItem  = mFilteredItemList[nCurPos];
     793             : 
     794           0 :                     if (!pCurItem->isSelected())
     795             :                     {
     796           0 :                         pCurItem->setSelection(true);
     797             : 
     798           0 :                         if (pCurItem->isVisible())
     799           0 :                             DrawItem(pCurItem);
     800             : 
     801           0 :                         maItemStateHdl.Call(pCurItem);
     802             :                     }
     803             : 
     804           0 :                     nCurPos += dir;
     805             :                 }
     806             :             }
     807             : 
     808           0 :             pItem->setSelection(true);
     809             :         }
     810             :         else
     811             :         {
     812             :             //If we got a group of selected items deselect the rest and only keep the desired one
     813             :             //mark items as not selected to not fire unnecessary change state events.
     814           0 :             pItem->setSelection(false);
     815           0 :             deselectItems();
     816           0 :             pItem->setSelection(true);
     817             : 
     818             :             //Mark as initial selection range position and reset end one
     819           0 :             mpStartSelRange = mFilteredItemList.begin() + nPos;
     820             :         }
     821             : 
     822           0 :         if (pItem->isSelected())
     823             :         {
     824           0 :             bool bClickOnTitle = pItem->getTextArea().IsInside(rMEvt.GetPosPixel());
     825           0 :             pItem->setEditTitle(bClickOnTitle);
     826             :         }
     827             : 
     828           0 :         if (!pItem->isHighlighted())
     829           0 :             DrawItem(pItem);
     830             : 
     831           0 :         maItemStateHdl.Call(pItem);
     832             : 
     833             :         //fire accessible event??
     834             :     }
     835             : }
     836             : 
     837           0 : void ThumbnailView::MouseButtonUp( const MouseEvent& rMEvt )
     838             : {
     839           0 :     Control::MouseButtonUp( rMEvt );
     840           0 : }
     841             : 
     842           0 : void ThumbnailView::Command( const CommandEvent& rCEvt )
     843             : {
     844           0 :     if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
     845           0 :          (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
     846           0 :          (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
     847             :     {
     848           0 :         if ( HandleScrollCommand( rCEvt, NULL, mpScrBar ) )
     849           0 :             return;
     850             :     }
     851             : 
     852           0 :     Control::Command( rCEvt );
     853             : }
     854             : 
     855           0 : void ThumbnailView::Paint(const Rectangle &aRect)
     856             : {
     857           0 :     size_t nItemCount = mItemList.size();
     858             : 
     859             :     // Draw background
     860           0 :     drawinglayer::primitive2d::Primitive2DSequence aSeq(1);
     861           0 :     aSeq[0] = drawinglayer::primitive2d::Primitive2DReference(new PolyPolygonColorPrimitive2D(
     862             :                 B2DPolyPolygon(Polygon(aRect, 5, 5).getB2DPolygon()),
     863           0 :                 maColor.getBColor()));
     864             : 
     865           0 :     mpProcessor->process(aSeq);
     866             : 
     867             :     // draw items
     868           0 :     for (size_t i = 0; i < nItemCount; i++)
     869             :     {
     870           0 :         ThumbnailViewItem *const pItem = mItemList[i];
     871             : 
     872           0 :         if (pItem->isVisible())
     873           0 :             DrawItem(pItem);
     874             :     }
     875             : 
     876           0 :     if (mpScrBar && mpScrBar->IsVisible())
     877           0 :         mpScrBar->Paint(aRect);
     878           0 : }
     879             : 
     880           0 : void ThumbnailView::GetFocus()
     881             : {
     882             :     // Select the first item if nothing selected
     883           0 :     int nSelected = -1;
     884           0 :     for (size_t i = 0, n = mItemList.size(); i < n && nSelected == -1; ++i)
     885             :     {
     886           0 :         if (mItemList[i]->isSelected())
     887           0 :             nSelected = i;
     888             :     }
     889             : 
     890           0 :     if (nSelected == -1 && mItemList.size() > 0)
     891             :     {
     892           0 :         SelectItem(1);
     893             :     }
     894             : 
     895             :     // Tell the accessible object that we got the focus.
     896           0 :     ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation( GetAccessible( false ) );
     897           0 :     if( pAcc )
     898           0 :         pAcc->GetFocus();
     899             : 
     900           0 :     Control::GetFocus();
     901           0 : }
     902             : 
     903           0 : void ThumbnailView::LoseFocus()
     904             : {
     905           0 :     Control::LoseFocus();
     906             : 
     907             :     // Tell the accessible object that we lost the focus.
     908           0 :     ThumbnailViewAcc* pAcc = ThumbnailViewAcc::getImplementation( GetAccessible( false ) );
     909           0 :     if( pAcc )
     910           0 :         pAcc->LoseFocus();
     911           0 : }
     912             : 
     913          18 : void ThumbnailView::Resize()
     914             : {
     915          18 :     Control::Resize();
     916          18 :     CalculateItemPositions();
     917             : 
     918          18 :     if ( IsReallyVisible() && IsUpdateMode() )
     919          10 :         Invalidate();
     920          18 : }
     921             : 
     922          14 : void ThumbnailView::StateChanged( StateChangedType nType )
     923             : {
     924          14 :     Control::StateChanged( nType );
     925             : 
     926          14 :     if ( nType == StateChangedType::INITSHOW )
     927             :     {
     928           4 :         if ( IsReallyVisible() && IsUpdateMode() )
     929           0 :             Invalidate();
     930             :     }
     931          10 :     else if ( nType == StateChangedType::UPDATEMODE )
     932             :     {
     933           0 :         if ( IsReallyVisible() && IsUpdateMode() )
     934           0 :             Invalidate();
     935             :     }
     936          10 :     else if ( nType == StateChangedType::TEXT )
     937             :     {
     938             :     }
     939          10 :     else if ( (nType == StateChangedType::ZOOM) ||
     940             :               (nType == StateChangedType::CONTROLFONT) )
     941             :     {
     942           0 :         ImplInitSettings( true, false, false );
     943           0 :         Invalidate();
     944             :     }
     945          10 :     else if ( nType == StateChangedType::CONTROLFOREGROUND )
     946             :     {
     947           0 :         ImplInitSettings( false, true, false );
     948           0 :         Invalidate();
     949             :     }
     950          10 :     else if ( nType == StateChangedType::CONTROLBACKGROUND )
     951             :     {
     952           0 :         ImplInitSettings( false, false, true );
     953           0 :         Invalidate();
     954             :     }
     955          10 :     else if ( (nType == StateChangedType::STYLE) || (nType == StateChangedType::ENABLE) )
     956             :     {
     957           4 :         ImplInitSettings( false, false, true );
     958           4 :         Invalidate();
     959             :     }
     960          14 : }
     961             : 
     962           0 : void ThumbnailView::DataChanged( const DataChangedEvent& rDCEvt )
     963             : {
     964           0 :     Control::DataChanged( rDCEvt );
     965             : 
     966           0 :     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
     967           0 :          (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
     968           0 :          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
     969           0 :          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
     970           0 :           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
     971             :     {
     972           0 :         ImplInitSettings( true, true, true );
     973           0 :         Invalidate();
     974             :     }
     975           0 : }
     976             : 
     977           0 : void ThumbnailView::RemoveItem( sal_uInt16 nItemId )
     978             : {
     979           0 :     size_t nPos = GetItemPos( nItemId );
     980             : 
     981           0 :     if ( nPos == THUMBNAILVIEW_ITEM_NOTFOUND )
     982           0 :         return;
     983             : 
     984           0 :     if ( nPos < mFilteredItemList.size() ) {
     985             : 
     986             :         // delete item from the thumbnail list
     987           0 :         for (size_t i = 0, n = mItemList.size(); i < n; ++i)
     988             :         {
     989           0 :             if (mItemList[i]->mnId == nItemId)
     990             :             {
     991           0 :                 mItemList.erase(mItemList.begin()+i);
     992           0 :                 break;
     993             :             }
     994             :         }
     995             : 
     996             :         // delete item from the filter item list
     997           0 :         ThumbnailValueItemList::iterator it = mFilteredItemList.begin();
     998           0 :         ::std::advance( it, nPos );
     999             : 
    1000           0 :         if ((*it)->isSelected())
    1001             :         {
    1002           0 :             (*it)->setSelection(false);
    1003           0 :             maItemStateHdl.Call(*it);
    1004             :         }
    1005             : 
    1006           0 :         delete *it;
    1007           0 :         mFilteredItemList.erase( it );
    1008           0 :         mpStartSelRange = mFilteredItemList.end();
    1009             :     }
    1010             : 
    1011           0 :     CalculateItemPositions();
    1012             : 
    1013           0 :     if ( IsReallyVisible() && IsUpdateMode() )
    1014           0 :         Invalidate();
    1015             : }
    1016             : 
    1017           2 : void ThumbnailView::Clear()
    1018             : {
    1019           2 :     ImplDeleteItems();
    1020             : 
    1021             :     // reset variables
    1022           2 :     mnFirstLine     = 0;
    1023             : 
    1024           2 :     CalculateItemPositions();
    1025             : 
    1026           2 :     if ( IsReallyVisible() && IsUpdateMode() )
    1027           2 :         Invalidate();
    1028           2 : }
    1029             : 
    1030           2 : void ThumbnailView::updateItems (const std::vector<ThumbnailViewItem*> &items)
    1031             : {
    1032           2 :     ImplDeleteItems();
    1033             : 
    1034             :     // reset variables
    1035           2 :     mnFirstLine     = 0;
    1036             : 
    1037           2 :     mItemList = items;
    1038             : 
    1039           2 :     filterItems(maFilterFunc);
    1040           2 : }
    1041             : 
    1042           0 : size_t ThumbnailView::GetItemPos( sal_uInt16 nItemId ) const
    1043             : {
    1044           0 :     for ( size_t i = 0, n = mFilteredItemList.size(); i < n; ++i ) {
    1045           0 :         if ( mFilteredItemList[i]->mnId == nItemId ) {
    1046           0 :             return i;
    1047             :         }
    1048             :     }
    1049           0 :     return THUMBNAILVIEW_ITEM_NOTFOUND;
    1050             : }
    1051             : 
    1052           0 : sal_uInt16 ThumbnailView::GetItemId( size_t nPos ) const
    1053             : {
    1054           0 :     return ( nPos < mFilteredItemList.size() ) ? mFilteredItemList[nPos]->mnId : 0 ;
    1055             : }
    1056             : 
    1057           0 : sal_uInt16 ThumbnailView::GetItemId( const Point& rPos ) const
    1058             : {
    1059           0 :     size_t nItemPos = ImplGetItem( rPos );
    1060           0 :     if ( nItemPos != THUMBNAILVIEW_ITEM_NOTFOUND )
    1061           0 :         return GetItemId( nItemPos );
    1062             : 
    1063           0 :     return 0;
    1064             : }
    1065             : 
    1066           0 : sal_uInt16 ThumbnailView::getNextItemId() const
    1067             : {
    1068           0 :     return mItemList.empty() ? 1 : mItemList.back()->mnId + 1;
    1069             : }
    1070             : 
    1071           2 : void ThumbnailView::setItemMaxTextLength(sal_uInt32 nLength)
    1072             : {
    1073           2 :     mpItemAttrs->nMaxTextLength = nLength;
    1074           2 : }
    1075             : 
    1076           4 : void ThumbnailView::setItemDimensions(long itemWidth, long thumbnailHeight, long displayHeight, int itemPadding)
    1077             : {
    1078           4 :     mnItemWidth = itemWidth + 2*itemPadding;
    1079           4 :     mnThumbnailHeight = thumbnailHeight;
    1080           4 :     mnDisplayHeight = displayHeight;
    1081           4 :     mnItemPadding = itemPadding;
    1082           4 :     mnItemHeight = mnDisplayHeight + mnThumbnailHeight + 2*itemPadding;
    1083           4 : }
    1084             : 
    1085           0 : void ThumbnailView::SelectItem( sal_uInt16 nItemId )
    1086             : {
    1087           0 :     size_t nItemPos = GetItemPos( nItemId );
    1088           0 :     if ( nItemPos == THUMBNAILVIEW_ITEM_NOTFOUND )
    1089           0 :         return;
    1090             : 
    1091           0 :     ThumbnailViewItem* pItem = mFilteredItemList[nItemPos];
    1092           0 :     if (!pItem->isSelected())
    1093             :     {
    1094           0 :         pItem->setSelection(true);
    1095           0 :         maItemStateHdl.Call(pItem);
    1096             : 
    1097           0 :         if (IsReallyVisible() && IsUpdateMode())
    1098           0 :             Invalidate();
    1099             : 
    1100           0 :         bool bNewOut = IsReallyVisible() && IsUpdateMode();
    1101             : 
    1102             :         // if necessary scroll to the visible area
    1103           0 :         if ( mbScroll && nItemId )
    1104             :         {
    1105           0 :             sal_uInt16 nNewLine = (sal_uInt16)(nItemPos / mnCols);
    1106           0 :             if ( nNewLine < mnFirstLine )
    1107             :             {
    1108           0 :                 mnFirstLine = nNewLine;
    1109             :             }
    1110           0 :             else if ( nNewLine > (sal_uInt16)(mnFirstLine+mnVisLines-1) )
    1111             :             {
    1112           0 :                 mnFirstLine = (sal_uInt16)(nNewLine-mnVisLines+1);
    1113             :             }
    1114             :         }
    1115             : 
    1116           0 :         if ( bNewOut )
    1117             :         {
    1118           0 :             if ( IsReallyVisible() && IsUpdateMode() )
    1119           0 :                 Invalidate();
    1120             :         }
    1121             : 
    1122           0 :         if( ImplHasAccessibleListeners() )
    1123             :         {
    1124             :             // focus event (select)
    1125           0 :             ThumbnailViewItemAcc* pItemAcc = ThumbnailViewItemAcc::getImplementation( pItem->GetAccessible( mbIsTransientChildrenDisabled ) );
    1126             : 
    1127           0 :             if( pItemAcc )
    1128             :             {
    1129           0 :                 ::com::sun::star::uno::Any aOldAny, aNewAny;
    1130           0 :                 if( !mbIsTransientChildrenDisabled )
    1131             :                 {
    1132           0 :                     aNewAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
    1133           0 :                         static_cast< ::cppu::OWeakObject* >( pItemAcc ));
    1134           0 :                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
    1135             :                 }
    1136             :                 else
    1137             :                 {
    1138           0 :                     aNewAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
    1139           0 :                     pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
    1140           0 :                 }
    1141             :             }
    1142             : 
    1143             :             // selection event
    1144           0 :             ::com::sun::star::uno::Any aOldAny, aNewAny;
    1145           0 :             ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
    1146             :         }
    1147             :     }
    1148             : }
    1149             : 
    1150           0 : bool ThumbnailView::IsItemSelected( sal_uInt16 nItemId ) const
    1151             : {
    1152           0 :     size_t nItemPos = GetItemPos( nItemId );
    1153           0 :     if ( nItemPos == THUMBNAILVIEW_ITEM_NOTFOUND )
    1154           0 :         return false;
    1155             : 
    1156           0 :     ThumbnailViewItem* pItem = mFilteredItemList[nItemPos];
    1157           0 :     return pItem->isSelected();
    1158             : }
    1159             : 
    1160           0 : void ThumbnailView::deselectItems()
    1161             : {
    1162           0 :     for (size_t i = 0, n = mItemList.size(); i < n; ++i)
    1163             :     {
    1164           0 :         if (mItemList[i]->isSelected())
    1165             :         {
    1166           0 :             mItemList[i]->setEditTitle(false);
    1167           0 :             mItemList[i]->setSelection(false);
    1168             : 
    1169           0 :             maItemStateHdl.Call(mItemList[i]);
    1170             :         }
    1171             :     }
    1172             : 
    1173           0 :     if (IsReallyVisible() && IsUpdateMode())
    1174           0 :         Invalidate();
    1175           0 : }
    1176             : 
    1177           2 : void ThumbnailView::ShowTooltips( bool bShowTooltips )
    1178             : {
    1179           2 :     mbShowTooltips = bShowTooltips;
    1180           2 : }
    1181             : 
    1182           4 : void ThumbnailView::filterItems (const boost::function<bool (const ThumbnailViewItem*) > &func)
    1183             : {
    1184           4 :     mnFirstLine = 0;        // start at the top of the list instead of the current position
    1185           4 :     maFilterFunc = func;
    1186             : 
    1187           4 :     size_t nSelPos = 0;
    1188           4 :     bool bHasSelRange = false;
    1189           4 :     ThumbnailViewItem *curSel = mpStartSelRange != mFilteredItemList.end() ? *mpStartSelRange : NULL;
    1190             : 
    1191           4 :     mFilteredItemList.clear();
    1192             : 
    1193          12 :     for (size_t i = 0, n = mItemList.size(); i < n; ++i)
    1194             :     {
    1195           8 :         ThumbnailViewItem *const pItem = mItemList[i];
    1196             : 
    1197           8 :         if (maFilterFunc(pItem))
    1198             :         {
    1199           8 :             if (curSel == pItem)
    1200             :             {
    1201           0 :                 nSelPos = i;
    1202           0 :                 bHasSelRange = true;
    1203             :             }
    1204             : 
    1205           8 :             mFilteredItemList.push_back(pItem);
    1206             :         }
    1207             :         else
    1208             :         {
    1209           0 :             if( pItem->isVisible())
    1210             :             {
    1211           0 :                 if ( ImplHasAccessibleListeners() )
    1212             :                 {
    1213           0 :                     ::com::sun::star::uno::Any aOldAny, aNewAny;
    1214             : 
    1215           0 :                     aOldAny <<= pItem->GetAccessible( mbIsTransientChildrenDisabled );
    1216           0 :                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
    1217             :                 }
    1218             : 
    1219           0 :                 pItem->show(false);
    1220           0 :                 pItem->setSelection(false);
    1221             : 
    1222           0 :                 maItemStateHdl.Call(pItem);
    1223             :             }
    1224             :         }
    1225             :     }
    1226             : 
    1227           4 :     mpStartSelRange = bHasSelRange ? mFilteredItemList.begin()  + nSelPos : mFilteredItemList.end();
    1228           4 :     CalculateItemPositions();
    1229             : 
    1230           4 :     Invalidate();
    1231           4 : }
    1232             : 
    1233           0 : void ThumbnailView::sortItems (const boost::function<bool (const ThumbnailViewItem*, const ThumbnailViewItem*) > &func)
    1234             : {
    1235           0 :     std::sort(mItemList.begin(),mItemList.end(),func);
    1236             : 
    1237           0 :     CalculateItemPositions();
    1238             : 
    1239           0 :     Invalidate();
    1240           0 : }
    1241             : 
    1242           0 : bool ThumbnailView::renameItem(ThumbnailViewItem*, const OUString&)
    1243             : {
    1244             :     // Do nothing by default
    1245           0 :     return false;
    1246             : }
    1247             : 
    1248          20 : BitmapEx ThumbnailView::readThumbnail(const OUString &msURL)
    1249             : {
    1250             :     using namespace ::com::sun::star;
    1251             :     using namespace ::com::sun::star::uno;
    1252             : 
    1253             :     // Load the thumbnail from a template document.
    1254          20 :     uno::Reference<io::XInputStream> xIStream;
    1255             : 
    1256          40 :     uno::Reference< uno::XComponentContext > xContext(::comphelper::getProcessComponentContext());
    1257             :     try
    1258             :     {
    1259          20 :         uno::Reference<lang::XSingleServiceFactory> xStorageFactory = embed::StorageFactory::create(xContext);
    1260             : 
    1261          40 :         uno::Sequence<uno::Any> aArgs (2);
    1262          20 :         aArgs[0] <<= msURL;
    1263          20 :         aArgs[1] <<= embed::ElementModes::READ;
    1264             :         uno::Reference<embed::XStorage> xDocStorage (
    1265          20 :             xStorageFactory->createInstanceWithArguments(aArgs),
    1266          40 :             uno::UNO_QUERY);
    1267             : 
    1268             :         try
    1269             :         {
    1270          20 :             if (xDocStorage.is())
    1271             :             {
    1272             :                 uno::Reference<embed::XStorage> xStorage (
    1273          20 :                     xDocStorage->openStorageElement(
    1274             :                         "Thumbnails",
    1275          20 :                         embed::ElementModes::READ));
    1276          20 :                 if (xStorage.is())
    1277             :                 {
    1278             :                     uno::Reference<io::XStream> xThumbnailCopy (
    1279          20 :                         xStorage->cloneStreamElement("thumbnail.png"));
    1280          20 :                     if (xThumbnailCopy.is())
    1281          20 :                         xIStream = xThumbnailCopy->getInputStream();
    1282          20 :                 }
    1283             :             }
    1284             :         }
    1285           0 :         catch (const uno::Exception& rException)
    1286             :         {
    1287             :             OSL_TRACE (
    1288             :                 "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s",
    1289             :                 OUStringToOString(msURL,
    1290             :                     RTL_TEXTENCODING_UTF8).getStr(),
    1291             :                 OUStringToOString(rException.Message,
    1292             :                     RTL_TEXTENCODING_UTF8).getStr());
    1293             :         }
    1294             : 
    1295             :         try
    1296             :         {
    1297             :             // An (older) implementation had a bug - The storage
    1298             :             // name was "Thumbnail" instead of "Thumbnails".  The
    1299             :             // old name is still used as fallback but this code can
    1300             :             // be removed soon.
    1301          20 :             if ( ! xIStream.is())
    1302             :             {
    1303             :                 uno::Reference<embed::XStorage> xStorage (
    1304           0 :                     xDocStorage->openStorageElement( "Thumbnail",
    1305           0 :                         embed::ElementModes::READ));
    1306           0 :                 if (xStorage.is())
    1307             :                 {
    1308             :                     uno::Reference<io::XStream> xThumbnailCopy (
    1309           0 :                         xStorage->cloneStreamElement("thumbnail.png"));
    1310           0 :                     if (xThumbnailCopy.is())
    1311           0 :                         xIStream = xThumbnailCopy->getInputStream();
    1312           0 :                 }
    1313             :             }
    1314             :         }
    1315           0 :         catch (const uno::Exception& rException)
    1316             :         {
    1317             :             OSL_TRACE (
    1318             :                 "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s",
    1319             :                 OUStringToOString(msURL,
    1320             :                     RTL_TEXTENCODING_UTF8).getStr(),
    1321             :                 OUStringToOString(rException.Message,
    1322             :                     RTL_TEXTENCODING_UTF8).getStr());
    1323          20 :         }
    1324             :     }
    1325           0 :     catch (const uno::Exception& rException)
    1326             :     {
    1327             :         OSL_TRACE (
    1328             :             "caught exception while trying to access tuhmbnail of %s: %s",
    1329             :             OUStringToOString(msURL,
    1330             :                 RTL_TEXTENCODING_UTF8).getStr(),
    1331             :             OUStringToOString(rException.Message,
    1332             :                 RTL_TEXTENCODING_UTF8).getStr());
    1333             :     }
    1334             : 
    1335             :     // Extract the image from the stream.
    1336          20 :     BitmapEx aThumbnail;
    1337          20 :     if (xIStream.is())
    1338             :     {
    1339             :         boost::scoped_ptr<SvStream> pStream (
    1340          20 :             ::utl::UcbStreamHelper::CreateStream (xIStream));
    1341          40 :         ::vcl::PNGReader aReader (*pStream);
    1342          40 :         aThumbnail = aReader.Read ();
    1343             :     }
    1344             : 
    1345             :     // Note that the preview is returned without scaling it to the desired
    1346             :     // width.  This gives the caller the chance to take advantage of a
    1347             :     // possibly larger resolution then was asked for.
    1348          40 :     return aThumbnail;
    1349         951 : }
    1350             : 
    1351             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
    1352             : 
    1353             : 

Generated by: LCOV version 1.10