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

Generated by: LCOV version 1.11