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

Generated by: LCOV version 1.10