LCOV - code coverage report
Current view: top level - sd/source/ui/animations - CustomAnimationList.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 460 0.2 %
Date: 2014-11-03 Functions: 2 49 4.1 %
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             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/drawing/XShapes.hpp>
      21             : #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
      22             : #include <com/sun/star/presentation/EffectNodeType.hpp>
      23             : #include <com/sun/star/presentation/ParagraphTarget.hpp>
      24             : #include <com/sun/star/container/XEnumerationAccess.hpp>
      25             : #include <com/sun/star/animations/XIterateContainer.hpp>
      26             : #include <com/sun/star/presentation/EffectPresetClass.hpp>
      27             : #include <com/sun/star/presentation/EffectCommands.hpp>
      28             : #include <com/sun/star/text/XTextRange.hpp>
      29             : #include <com/sun/star/beans/XPropertySet.hpp>
      30             : #include <com/sun/star/drawing/XDrawPage.hpp>
      31             : #include <svx/ShapeTypeHandler.hxx>
      32             : #include "CustomAnimationList.hxx"
      33             : #include "CustomAnimation.hrc"
      34             : #include "CustomAnimationPreset.hxx"
      35             : #include <vcl/svapp.hxx>
      36             : #include <vcl/settings.hxx>
      37             : 
      38             : #include "sdresid.hxx"
      39             : 
      40             : #include "svtools/svlbitm.hxx"
      41             : #include "svtools/treelistentry.hxx"
      42             : #include "svtools/viewdataentry.hxx"
      43             : 
      44             : #include "res_bmp.hrc"
      45             : #include "glob.hrc"
      46             : 
      47             : #include <algorithm>
      48             : 
      49             : using namespace ::com::sun::star;
      50             : using namespace ::com::sun::star::animations;
      51             : using namespace ::com::sun::star::presentation;
      52             : 
      53             : using ::com::sun::star::uno::UNO_QUERY;
      54             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      55             : using ::com::sun::star::uno::Any;
      56             : using ::com::sun::star::uno::Sequence;
      57             : using ::com::sun::star::uno::Reference;
      58             : using ::com::sun::star::uno::Exception;
      59             : using ::com::sun::star::uno::XInterface;
      60             : using ::com::sun::star::text::XTextRange;
      61             : using ::com::sun::star::drawing::XShape;
      62             : using ::com::sun::star::drawing::XShapes;
      63             : using ::com::sun::star::drawing::XDrawPage;
      64             : using ::com::sun::star::container::XChild;
      65             : using ::com::sun::star::container::XIndexAccess;
      66             : using ::com::sun::star::container::XEnumerationAccess;
      67             : using ::com::sun::star::container::XEnumeration;
      68             : using ::com::sun::star::beans::XPropertySet;
      69             : using ::com::sun::star::beans::XPropertySetInfo;
      70             : using ::accessibility::ShapeTypeHandler;
      71             : 
      72             : namespace sd {
      73             : 
      74             : // go recursivly through all shapes in the given XShapes collection and return true as soon as the
      75             : // given shape is found. nIndex is incremented for each shape with the same shape type as the given
      76             : // shape is found until the given shape is found.
      77           0 : static bool getShapeIndex(  const Reference< XShapes >& xShapes, const Reference< XShape >& xShape, sal_Int32& nIndex )
      78             : {
      79           0 :     const sal_Int32 nCount = xShapes->getCount();
      80             :     sal_Int32 n;
      81           0 :     for( n = 0; n < nCount; n++ )
      82             :     {
      83           0 :         Reference< XShape > xChild;
      84           0 :         xShapes->getByIndex( n ) >>= xChild;
      85           0 :         if( xChild == xShape )
      86           0 :             return true;
      87             : 
      88           0 :         if( xChild->getShapeType() == xShape->getShapeType() )
      89           0 :             nIndex++;
      90             : 
      91           0 :         Reference< XShapes > xChildContainer( xChild, UNO_QUERY );
      92           0 :         if( xChildContainer.is() )
      93             :         {
      94           0 :             if( getShapeIndex( xChildContainer, xShape, nIndex ) )
      95           0 :                 return true;
      96             :         }
      97           0 :     }
      98             : 
      99           0 :     return false;
     100             : }
     101             : 
     102             : // returns the index of the shape type from the given shape
     103           0 : static sal_Int32 getShapeIndex( const Reference< XShape >& xShape )
     104             : {
     105           0 :     Reference< XChild > xChild( xShape, UNO_QUERY );
     106           0 :     Reference< XShapes > xPage;
     107             : 
     108           0 :     while( xChild.is() && !xPage.is() )
     109             :     {
     110           0 :         Reference< XInterface > x( xChild->getParent() );
     111           0 :         xChild = Reference< XChild >::query( x );
     112           0 :         Reference< XDrawPage > xTestPage( x, UNO_QUERY );
     113           0 :         if( xTestPage.is() )
     114           0 :             xPage = Reference< XShapes >::query( x );
     115           0 :     }
     116             : 
     117           0 :     sal_Int32 nIndex = 1;
     118             : 
     119           0 :     if( xPage.is() && getShapeIndex( xPage, xShape, nIndex ) )
     120           0 :         return nIndex;
     121             :     else
     122           0 :         return -1;
     123             : }
     124             : 
     125           0 : OUString getShapeDescription( const Reference< XShape >& xShape, bool bWithText )
     126             : {
     127           0 :     OUString aDescription;
     128           0 :     Reference< XPropertySet > xSet( xShape, UNO_QUERY );
     129           0 :     if( xSet.is() )
     130             :     {
     131           0 :         Reference< XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
     132           0 :         const OUString aPropName( "UINameSingular");
     133           0 :         if( xInfo->hasPropertyByName( aPropName ) )
     134           0 :             xSet->getPropertyValue( aPropName ) >>= aDescription;
     135             :     }
     136             : 
     137           0 :     aDescription += " ";
     138           0 :     aDescription += OUString::number( getShapeIndex( xShape ) );
     139             : 
     140           0 :     if( bWithText )
     141             :     {
     142           0 :         Reference< XTextRange > xText( xShape, UNO_QUERY );
     143           0 :         if( xText.is() )
     144             :         {
     145           0 :             OUString aText( xText->getString() );
     146           0 :             if( !aText.isEmpty() )
     147             :             {
     148           0 :                 aDescription += ": ";
     149             : 
     150           0 :                 aText = aText.replace( (sal_Unicode)'\n', (sal_Unicode)' ' );
     151           0 :                 aText = aText.replace( (sal_Unicode)'\r', (sal_Unicode)' ' );
     152             : 
     153           0 :                 aDescription += aText;
     154           0 :             }
     155           0 :         }
     156             :     }
     157           0 :     return aDescription;
     158             : }
     159             : 
     160           0 : static OUString getDescription( const Any& rTarget, bool bWithText = true )
     161             : {
     162           0 :     OUString aDescription;
     163             : 
     164           0 :     if( rTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
     165             :     {
     166           0 :         ParagraphTarget aParaTarget;
     167           0 :         rTarget >>= aParaTarget;
     168             : 
     169           0 :         Reference< XEnumerationAccess > xText( aParaTarget.Shape, UNO_QUERY_THROW );
     170           0 :         Reference< XEnumeration > xEnumeration( xText->createEnumeration(), UNO_QUERY_THROW );
     171           0 :         sal_Int32 nPara = aParaTarget.Paragraph;
     172             : 
     173           0 :         while( xEnumeration->hasMoreElements() && nPara )
     174             :         {
     175           0 :             xEnumeration->nextElement();
     176           0 :             nPara--;
     177             :         }
     178             : 
     179             :         DBG_ASSERT( xEnumeration->hasMoreElements(), "sd::CustomAnimationEffect::prepareText(), paragraph out of range!" );
     180             : 
     181           0 :         if( xEnumeration->hasMoreElements() )
     182             :         {
     183           0 :             Reference< XTextRange > xParagraph;
     184           0 :             xEnumeration->nextElement() >>= xParagraph;
     185             : 
     186           0 :             if( xParagraph.is() )
     187           0 :                 aDescription = xParagraph->getString();
     188           0 :         }
     189             :     }
     190             :     else
     191             :     {
     192           0 :         Reference< XShape > xShape;
     193           0 :         rTarget >>= xShape;
     194           0 :         if( xShape.is() )
     195           0 :             aDescription = getShapeDescription( xShape, bWithText );
     196             :     }
     197             : 
     198           0 :     return aDescription;
     199             : }
     200             : 
     201             : class CustomAnimationListEntryItem : public SvLBoxString
     202             : {
     203             : public:
     204             :                     CustomAnimationListEntryItem( SvTreeListEntry*,sal_uInt16 nFlags, const OUString& aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent  );
     205             :     virtual         ~CustomAnimationListEntryItem();
     206             :     void            InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* ) SAL_OVERRIDE;
     207             :     SvLBoxItem*     Create() const SAL_OVERRIDE;
     208             :     void            Clone( SvLBoxItem* pSource ) SAL_OVERRIDE;
     209             : 
     210             :     virtual void Paint(
     211             :         const Point&, SvTreeListBox& rDev, const SvViewDataEntry* pView,const SvTreeListEntry* pEntry) SAL_OVERRIDE;
     212             : private:
     213             :     CustomAnimationList* mpParent;
     214             :     OUString        maDescription;
     215             :     CustomAnimationEffectPtr mpEffect;
     216             : };
     217             : 
     218           0 : CustomAnimationListEntryItem::CustomAnimationListEntryItem( SvTreeListEntry* pEntry, sal_uInt16 nFlags, const OUString& aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent  )
     219             : : SvLBoxString( pEntry, nFlags, aDescription )
     220             : , mpParent( pParent )
     221             : , maDescription( aDescription )
     222           0 : , mpEffect(pEffect)
     223             : {
     224           0 : }
     225             : 
     226           0 : CustomAnimationListEntryItem::~CustomAnimationListEntryItem()
     227             : {
     228           0 : }
     229             : 
     230           0 : void CustomAnimationListEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
     231             : {
     232           0 :     if( !pViewData )
     233           0 :         pViewData = pView->GetViewDataItem( pEntry, this );
     234             : 
     235           0 :     Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() );
     236           0 :     if( aSize.Height() < 19 )
     237           0 :         aSize.Height() = 19;
     238           0 :     pViewData->maSize = aSize;
     239           0 : }
     240             : 
     241           0 : void CustomAnimationListEntryItem::Paint(
     242             :     const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/, const SvTreeListEntry* pEntry)
     243             : {
     244             : 
     245           0 :     const SvViewDataItem* pViewData = mpParent->GetViewDataItem( pEntry, this );
     246             : 
     247           0 :     Point aPos( rPos );
     248           0 :     Size aSize( pViewData->maSize );
     249             : 
     250           0 :     sal_Int16 nNodeType = mpEffect->getNodeType();
     251           0 :     if( nNodeType == EffectNodeType::ON_CLICK )
     252             :     {
     253           0 :         rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_ON_CLICK ) );
     254             :     }
     255           0 :     else if( nNodeType == EffectNodeType::AFTER_PREVIOUS )
     256             :     {
     257           0 :         rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_AFTER_PREVIOUS ) );
     258             :     }
     259             : 
     260           0 :     aPos.X() += 19;
     261             : 
     262             :     sal_uInt16 nImage;
     263           0 :     switch( mpEffect->getPresetClass() )
     264             :     {
     265           0 :     case EffectPresetClass::ENTRANCE:   nImage = IMG_CUSTOMANIMATION_ENTRANCE_EFFECT; break;
     266           0 :     case EffectPresetClass::EXIT:       nImage =  IMG_CUSTOMANIMATION_EXIT_EFFECT; break;
     267           0 :     case EffectPresetClass::EMPHASIS:   nImage =  IMG_CUSTOMANIMATION_EMPHASIS_EFFECT; break;
     268           0 :     case EffectPresetClass::MOTIONPATH: nImage = IMG_CUSTOMANIMATION_MOTION_PATH; break;
     269           0 :     case EffectPresetClass::OLEACTION:  nImage = IMG_CUSTOMANIMATION_OLE; break;
     270             :     case EffectPresetClass::MEDIACALL:
     271           0 :         switch( mpEffect->getCommand() )
     272             :         {
     273           0 :         case EffectCommands::TOGGLEPAUSE:   nImage = IMG_CUSTOMANIMATION_MEDIA_PAUSE; break;
     274           0 :         case EffectCommands::STOP:          nImage = IMG_CUSTOMANIMATION_MEDIA_STOP; break;
     275             :         case EffectCommands::PLAY:
     276           0 :         default:                            nImage = IMG_CUSTOMANIMATION_MEDIA_PLAY; break;
     277             :         }
     278           0 :         break;
     279           0 :     default:                            nImage = 0xffff;
     280             :     }
     281             : 
     282           0 :     if( nImage != 0xffff )
     283             :     {
     284           0 :         const Image& rImage = mpParent->getImage( nImage );
     285           0 :         Point aImagePos( aPos );
     286           0 :         aImagePos.Y() += ( aSize.Height() - rImage.GetSizePixel().Height() ) >> 1;
     287           0 :         rDev.DrawImage( aImagePos, rImage );
     288             :     }
     289             : 
     290           0 :     aPos.X() += 19;
     291           0 :     aPos.Y() += ( aSize.Height() - rDev.GetTextHeight()) >> 1;
     292             : 
     293           0 :     rDev.DrawText( aPos, rDev.GetEllipsisString( maDescription, rDev.GetOutputSizePixel().Width() - aPos.X() ) );
     294           0 : }
     295             : 
     296           0 : SvLBoxItem* CustomAnimationListEntryItem::Create() const
     297             : {
     298           0 :     return NULL;
     299             : }
     300             : 
     301           0 : void CustomAnimationListEntryItem::Clone( SvLBoxItem* )
     302             : {
     303           0 : }
     304             : 
     305             : class CustomAnimationListEntry : public SvTreeListEntry
     306             : {
     307             : public:
     308             :     CustomAnimationListEntry();
     309             :     CustomAnimationListEntry( CustomAnimationEffectPtr pEffect );
     310             :     virtual ~CustomAnimationListEntry();
     311             : 
     312           0 :     CustomAnimationEffectPtr getEffect() const { return mpEffect; }
     313             : 
     314             : private:
     315             :     CustomAnimationEffectPtr mpEffect;
     316             : };
     317             : 
     318           0 : CustomAnimationListEntry::CustomAnimationListEntry()
     319             : {
     320           0 : }
     321             : 
     322           0 : CustomAnimationListEntry::CustomAnimationListEntry( CustomAnimationEffectPtr pEffect )
     323           0 : : mpEffect( pEffect )
     324             : {
     325           0 : }
     326             : 
     327           0 : CustomAnimationListEntry::~CustomAnimationListEntry()
     328             : {
     329           0 : }
     330             : 
     331             : class CustomAnimationTriggerEntryItem : public SvLBoxString
     332             : {
     333             : public:
     334             :                     CustomAnimationTriggerEntryItem( SvTreeListEntry*,sal_uInt16 nFlags, const OUString& aDescription );
     335             :     virtual         ~CustomAnimationTriggerEntryItem();
     336             :     void            InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* ) SAL_OVERRIDE;
     337             :     SvLBoxItem*     Create() const SAL_OVERRIDE;
     338             :     void            Clone( SvLBoxItem* pSource ) SAL_OVERRIDE;
     339             :     virtual void Paint(
     340             :         const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry) SAL_OVERRIDE;
     341             : 
     342             : private:
     343             :     OUString        maDescription;
     344             : };
     345             : 
     346           0 : CustomAnimationTriggerEntryItem::CustomAnimationTriggerEntryItem( SvTreeListEntry* pEntry, sal_uInt16 nFlags, const OUString& aDescription )
     347           0 : : SvLBoxString( pEntry, nFlags, aDescription ), maDescription( aDescription )
     348             : {
     349           0 : }
     350             : 
     351           0 : CustomAnimationTriggerEntryItem::~CustomAnimationTriggerEntryItem()
     352             : {
     353           0 : }
     354             : 
     355           0 : void CustomAnimationTriggerEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
     356             : {
     357           0 :     if( !pViewData )
     358           0 :         pViewData = pView->GetViewDataItem( pEntry, this );
     359             : 
     360           0 :     Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() );
     361           0 :     if( aSize.Height() < 19 )
     362           0 :         aSize.Height() = 19;
     363           0 :     pViewData->maSize = aSize;
     364           0 : }
     365             : 
     366           0 : void CustomAnimationTriggerEntryItem::Paint(
     367             :     const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/, const SvTreeListEntry* /*pEntry*/)
     368             : {
     369           0 :     Size aSize( rDev.GetOutputSizePixel().Width(), static_cast< SvTreeListBox* >(&rDev)->GetEntryHeight() );
     370             : 
     371           0 :     Point aPos( 0, rPos.Y() );
     372             : 
     373           0 :     Rectangle aOutRect( aPos, aSize );
     374             : 
     375             :     // fill the background
     376           0 :     Color aColor (rDev.GetSettings().GetStyleSettings().GetDialogColor());
     377             : 
     378           0 :     rDev.Push();
     379           0 :     rDev.SetFillColor (aColor);
     380           0 :     rDev.SetLineColor ();
     381           0 :     rDev.DrawRect(aOutRect);
     382             : 
     383             :     // Erase the four corner pixels to make the rectangle appear rounded.
     384           0 :     rDev.SetLineColor( rDev.GetSettings().GetStyleSettings().GetWindowColor());
     385           0 :     rDev.DrawPixel( aOutRect.TopLeft());
     386           0 :     rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Top()));
     387           0 :     rDev.DrawPixel( Point(aOutRect.Left(), aOutRect.Bottom()));
     388           0 :     rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Bottom()));
     389             : 
     390             :     // draw the category title
     391             : 
     392           0 :     int nVertBorder = (( aSize.Height() - rDev.GetTextHeight()) >> 1);
     393           0 :     int nHorzBorder = rDev.LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
     394             : 
     395           0 :     aOutRect.Left() += nHorzBorder;
     396           0 :     aOutRect.Right() -= nHorzBorder;
     397           0 :     aOutRect.Top() += nVertBorder;
     398           0 :     aOutRect.Bottom() -= nVertBorder;
     399             : 
     400           0 :     rDev.DrawText (aOutRect, rDev.GetEllipsisString( maDescription, aOutRect.GetWidth() ) );
     401           0 :     rDev.Pop();
     402           0 : }
     403             : 
     404           0 : SvLBoxItem* CustomAnimationTriggerEntryItem::Create() const
     405             : {
     406           0 :     return NULL;
     407             : }
     408             : 
     409           0 : void CustomAnimationTriggerEntryItem::Clone( SvLBoxItem* )
     410             : {
     411           0 : }
     412             : 
     413           0 : CustomAnimationList::CustomAnimationList( vcl::Window* pParent )
     414             :     : SvTreeListBox( pParent, WB_TABSTOP | WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT )
     415             :     , mbIgnorePaint(false)
     416             :     , mpController(0)
     417             :     , mnLastGroupId(0)
     418           0 :     , mpLastParentEntry(0)
     419             : {
     420             : 
     421           0 :     EnableContextMenuHandling();
     422           0 :     SetSelectionMode( MULTIPLE_SELECTION );
     423           0 :     SetOptimalImageIndent();
     424           0 :     SetNodeDefaultImages();
     425           0 : }
     426             : 
     427           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeCustomAnimationList( vcl::Window *pParent )
     428             : {
     429           0 :     return new CustomAnimationList( pParent );
     430             : }
     431             : 
     432           0 : const Image&  CustomAnimationList::getImage( sal_uInt16 nId )
     433             : {
     434             :     DBG_ASSERT( (nId >= IMG_CUSTOMANIMATION_ON_CLICK) && (nId <= IMG_CUSTOMANIMATION_MEDIA_STOP), "sd::CustomAnimationList::getImage(), illegal index!" );
     435             : 
     436           0 :     Image& rImage = maImages[nId - IMG_CUSTOMANIMATION_ON_CLICK];
     437             : 
     438             :     // load on demand
     439           0 :     if( rImage.GetSizePixel().Width() == 0 )
     440           0 :         rImage = Image(SdResId( nId ) );
     441             : 
     442           0 :     return rImage;
     443             : }
     444             : 
     445           0 : CustomAnimationList::~CustomAnimationList()
     446             : {
     447           0 :     if( mpMainSequence.get() )
     448           0 :         mpMainSequence->removeListener( this );
     449             : 
     450           0 :     clear();
     451           0 : }
     452             : 
     453           0 : void CustomAnimationList::KeyInput( const KeyEvent& rKEvt )
     454             : {
     455           0 :     const int nKeyCode = rKEvt.GetKeyCode().GetCode();
     456           0 :     switch( nKeyCode )
     457             :     {
     458           0 :         case KEY_DELETE:    mpController->onContextMenu( CM_REMOVE ); return;
     459           0 :         case KEY_INSERT:    mpController->onContextMenu( CM_CREATE ); return;
     460             :         case KEY_SPACE:
     461             :             {
     462           0 :                 const Point aPos;
     463           0 :                 const CommandEvent aCEvt( aPos, COMMAND_CONTEXTMENU );
     464           0 :                 Command( aCEvt );
     465           0 :                 return;
     466             :             }
     467             : 
     468             :     }
     469             : 
     470           0 :     ::SvTreeListBox::KeyInput( rKEvt );
     471             : }
     472             : 
     473             : /** selects or deselects the given effect.
     474             :     Selections of other effects are not changed */
     475           0 : void CustomAnimationList::select( CustomAnimationEffectPtr pEffect, bool bSelect /* = true */ )
     476             : {
     477           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(First());
     478           0 :     while( pEntry )
     479             :     {
     480           0 :         if( pEntry->getEffect() == pEffect )
     481             :         {
     482           0 :             Select( pEntry, bSelect );
     483           0 :             MakeVisible( pEntry );
     484           0 :             break;
     485             :         }
     486           0 :         pEntry = static_cast< CustomAnimationListEntry* >(Next( pEntry ));
     487             :     }
     488             : 
     489           0 :     if( !pEntry && bSelect )
     490             :     {
     491           0 :         append( pEffect );
     492           0 :         select( pEffect );
     493             :     }
     494           0 : }
     495             : 
     496           0 : void CustomAnimationList::clear()
     497             : {
     498           0 :     Clear();
     499             : 
     500           0 :     mpLastParentEntry = 0;
     501           0 :     mxLastTargetShape = 0;
     502           0 : }
     503             : 
     504           0 : void CustomAnimationList::update( MainSequencePtr pMainSequence )
     505             : {
     506           0 :     if( mpMainSequence.get() )
     507           0 :         mpMainSequence->removeListener( this );
     508             : 
     509           0 :     mpMainSequence = pMainSequence;
     510           0 :     update();
     511             : 
     512           0 :     if( mpMainSequence.get() )
     513           0 :         mpMainSequence->addListener( this );
     514           0 : }
     515             : 
     516             : struct stl_append_effect_func : public std::unary_function<CustomAnimationEffectPtr, void>
     517             : {
     518           0 :     stl_append_effect_func( CustomAnimationList& rList ) : mrList( rList ) {}
     519             :     void operator()(CustomAnimationEffectPtr pEffect);
     520             :     CustomAnimationList& mrList;
     521             : };
     522             : 
     523           0 : void stl_append_effect_func::operator()(CustomAnimationEffectPtr pEffect)
     524             : {
     525           0 :     mrList.append( pEffect );
     526           0 : }
     527             : 
     528           0 : void CustomAnimationList::update()
     529             : {
     530           0 :     mbIgnorePaint = true;
     531           0 :     SetUpdateMode( false );
     532             : 
     533           0 :     CustomAnimationListEntry* pEntry = 0;
     534             : 
     535           0 :     std::list< CustomAnimationEffectPtr > aExpanded;
     536           0 :     std::list< CustomAnimationEffectPtr > aSelected;
     537             : 
     538           0 :     CustomAnimationEffectPtr pFirstSelEffect;
     539           0 :     CustomAnimationEffectPtr pLastSelEffect;
     540           0 :     long nFirstVis = -1;
     541           0 :     long nLastVis = -1;
     542           0 :     long nFirstSelOld = -1;
     543           0 :     long nLastSelOld = -1;
     544           0 :     bool bMoved = false;
     545           0 :     bool bMovedUp = false;
     546           0 :     bool bMovedDown = false;
     547             : 
     548           0 :     if( mpMainSequence.get() )
     549             :     {
     550             :         // save scroll position
     551           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetFirstEntryInView());
     552           0 :         if( pEntry )
     553           0 :             nFirstVis = GetAbsPos( pEntry );
     554             : 
     555           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetLastEntryInView());
     556           0 :         if( pEntry )
     557           0 :             nLastVis = GetAbsPos( pEntry );
     558             : 
     559           0 :         pEntry = static_cast<CustomAnimationListEntry*>(FirstSelected());
     560           0 :         if( pEntry )
     561             :         {
     562           0 :             pFirstSelEffect = pEntry->getEffect();
     563           0 :             nFirstSelOld = GetAbsPos( pEntry );
     564             :         }
     565             : 
     566           0 :         pEntry = static_cast<CustomAnimationListEntry*>(LastSelected());
     567           0 :         if( pEntry )
     568             :         {
     569           0 :             pLastSelEffect = pEntry->getEffect();
     570           0 :             nLastSelOld = GetAbsPos( pEntry );
     571             :         }
     572             : 
     573             :         // save selection and expand states
     574           0 :         pEntry = static_cast<CustomAnimationListEntry*>(First());
     575             : 
     576           0 :         while( pEntry )
     577             :         {
     578           0 :             CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     579           0 :             if( pEffect.get() )
     580             :             {
     581           0 :                 if( IsExpanded( pEntry ) )
     582           0 :                     aExpanded.push_back( pEffect );
     583             : 
     584           0 :                 if( IsSelected( pEntry ) )
     585           0 :                     aSelected.push_back( pEffect );
     586             :             }
     587             : 
     588           0 :             pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     589           0 :         }
     590             :     }
     591             : 
     592             :     // rebuild list
     593           0 :     clear();
     594           0 :     if( mpMainSequence.get() )
     595             :     {
     596           0 :         long nFirstSelNew = -1;
     597           0 :         long nLastSelNew = -1;
     598           0 :         std::for_each( mpMainSequence->getBegin(), mpMainSequence->getEnd(), stl_append_effect_func( *this ) );
     599           0 :         mpLastParentEntry = 0;
     600             : 
     601           0 :         const InteractiveSequenceList& rISL = mpMainSequence->getInteractiveSequenceList();
     602             : 
     603           0 :         InteractiveSequenceList::const_iterator aIter( rISL.begin() );
     604           0 :         const InteractiveSequenceList::const_iterator aEnd( rISL.end() );
     605           0 :         while( aIter != aEnd )
     606             :         {
     607           0 :             InteractiveSequencePtr pIS( (*aIter++) );
     608             : 
     609           0 :             Reference< XShape > xShape( pIS->getTriggerShape() );
     610           0 :             if( xShape.is() )
     611             :             {
     612           0 :                 SvTreeListEntry* pLBoxEntry = new CustomAnimationListEntry;
     613           0 :                 pLBoxEntry->AddItem( new SvLBoxContextBmp( pLBoxEntry, 0, Image(), Image(), false));
     614           0 :                 OUString aDescription = SD_RESSTR(STR_CUSTOMANIMATION_TRIGGER);
     615           0 :                 aDescription += ": ";
     616           0 :                 aDescription += getShapeDescription( xShape, false );
     617           0 :                 pLBoxEntry->AddItem( new CustomAnimationTriggerEntryItem( pLBoxEntry, 0, aDescription ) );
     618           0 :                 Insert( pLBoxEntry );
     619           0 :                 SvViewDataEntry* pViewData = GetViewData( pLBoxEntry );
     620           0 :                 if( pViewData )
     621           0 :                     pViewData->SetSelectable(false);
     622             : 
     623           0 :                 std::for_each( pIS->getBegin(), pIS->getEnd(), stl_append_effect_func( *this ) );
     624           0 :                 mpLastParentEntry = 0;
     625             :             }
     626           0 :         }
     627             : 
     628             :         // restore selection and expand states
     629           0 :         pEntry = static_cast<CustomAnimationListEntry*>(First());
     630             : 
     631           0 :         while( pEntry )
     632             :         {
     633           0 :             CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     634           0 :             if( pEffect.get() )
     635             :             {
     636           0 :                 if( std::find( aExpanded.begin(), aExpanded.end(), pEffect ) != aExpanded.end() )
     637           0 :                     Expand( pEntry );
     638             : 
     639           0 :                 if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() )
     640           0 :                     Select( pEntry );
     641             : 
     642           0 :                 if( pEffect == pFirstSelEffect )
     643           0 :                     nFirstSelNew = GetAbsPos( pEntry );
     644             : 
     645           0 :                 if( pEffect == pLastSelEffect )
     646           0 :                     nLastSelNew = GetAbsPos( pEntry );
     647             :             }
     648             : 
     649           0 :             pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     650           0 :         }
     651             : 
     652             :         // Scroll to a selected entry, depending on where the selection moved.
     653           0 :         bMoved = nFirstSelNew != nFirstSelOld;
     654           0 :         bMovedUp = nFirstSelNew < nFirstSelOld;
     655           0 :         bMovedDown = nFirstSelNew > nFirstSelOld;
     656             : 
     657           0 :         if( bMoved && nLastSelOld < nFirstVis && nLastSelNew < nFirstVis )
     658             :         {
     659             :             // The selection is above the visible area.
     660             :             // Scroll up to show the last few selected entries.
     661           0 :             if( nLastSelNew - (nLastVis - nFirstVis) > nFirstSelNew)
     662             :             {
     663             :                 // The entries in the selection range can't fit in view.
     664             :                 // Scroll so the last selected entry is last in view.
     665           0 :                 ScrollToAbsPos( nLastSelNew - (nLastVis - nFirstVis) );
     666             :             }
     667             :             else
     668           0 :                 ScrollToAbsPos( nFirstSelNew );
     669             :         }
     670           0 :         else if( bMoved && nFirstSelOld > nLastVis && nFirstSelNew > nLastVis )
     671             :         {
     672             :             // The selection is below the visible area.
     673             :             // Scroll down to the first few selected entries.
     674           0 :             ScrollToAbsPos( nFirstSelNew );
     675             :         }
     676           0 :         else if( bMovedUp && nFirstSelOld <= nFirstVis )
     677             :         {
     678             :             // A visible entry has moved up out of view; scroll up one.
     679           0 :             ScrollToAbsPos( nFirstVis - 1 );
     680             :         }
     681           0 :         else if( bMovedDown && nLastSelOld >= nLastVis )
     682             :         {
     683             :             // An entry has moved down out of view; scroll down one.
     684           0 :             ScrollToAbsPos( nFirstVis + 1 );
     685             :         }
     686           0 :         else if ( nFirstVis != -1 )
     687             :         {
     688             :             // The selection is still in view, or it hasn't moved.
     689           0 :             ScrollToAbsPos( nFirstVis );
     690             :         }
     691             :     }
     692             : 
     693           0 :     mbIgnorePaint = false;
     694           0 :     SetUpdateMode( true );
     695           0 :     Invalidate();
     696           0 : }
     697             : 
     698           0 : void CustomAnimationList::append( CustomAnimationEffectPtr pEffect )
     699             : {
     700             :     // create a ui description
     701           0 :     OUString aDescription;
     702             : 
     703           0 :     Any aTarget( pEffect->getTarget() );
     704           0 :     if( aTarget.hasValue() ) try
     705             :     {
     706           0 :         aDescription = getDescription( aTarget, pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_BACKGROUND );
     707             : 
     708           0 :         SvTreeListEntry* pParentEntry = 0;
     709             : 
     710           0 :         Reference< XShape > xTargetShape( pEffect->getTargetShape() );
     711           0 :         sal_Int32 nGroupId = pEffect->getGroupId();
     712             : 
     713             :         // if this effect has the same target and group-id as the last root effect,
     714             :         // the last root effect is also this effects parent
     715           0 :         if( mpLastParentEntry && (nGroupId != -1) && (mxLastTargetShape == xTargetShape) && (mnLastGroupId == nGroupId) )
     716           0 :             pParentEntry = mpLastParentEntry;
     717             : 
     718             :         // create an entry for the effect
     719           0 :         SvTreeListEntry* pEntry = new CustomAnimationListEntry( pEffect );
     720             : 
     721           0 :         pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), false));
     722           0 :         pEntry->AddItem( new CustomAnimationListEntryItem( pEntry, 0, aDescription, pEffect, this ) );
     723             : 
     724           0 :         if( pParentEntry )
     725             :         {
     726             :             // add a subentry
     727           0 :             Insert( pEntry, pParentEntry );
     728             :         }
     729             :         else
     730             :         {
     731             :             // add a root entry
     732           0 :             Insert( pEntry );
     733             : 
     734             :             // and the new root entry becomes the possible next group header
     735           0 :             mxLastTargetShape = xTargetShape;
     736           0 :             mnLastGroupId = nGroupId;
     737           0 :             mpLastParentEntry = pEntry;
     738           0 :         }
     739             :     }
     740           0 :     catch( Exception& )
     741             :     {
     742             :         OSL_FAIL("sd::CustomAnimationList::append(), exception caught!" );
     743           0 :     }
     744           0 : }
     745             : 
     746           0 : void selectShape( SvTreeListBox* pTreeList, Reference< XShape > xShape )
     747             : {
     748           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->First());
     749           0 :     while( pEntry )
     750             :     {
     751           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     752           0 :         if( pEffect.get() )
     753             :         {
     754           0 :             if( pEffect->getTarget() == xShape )
     755           0 :                 pTreeList->Select( pEntry );
     756             :         }
     757             : 
     758           0 :         pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->Next( pEntry ));
     759           0 :     }
     760           0 : }
     761             : 
     762           0 : void CustomAnimationList::onSelectionChanged( Any aSelection )
     763             : {
     764             :     try
     765             :     {
     766           0 :         SelectAll(false);
     767             : 
     768           0 :         if( aSelection.hasValue() )
     769             :         {
     770           0 :             Reference< XIndexAccess > xShapes( aSelection, UNO_QUERY );
     771           0 :             if( xShapes.is() )
     772             :             {
     773           0 :                 sal_Int32 nCount = xShapes->getCount();
     774             :                 sal_Int32 nIndex;
     775           0 :                 for( nIndex = 0; nIndex < nCount; nIndex++ )
     776             :                 {
     777           0 :                     Reference< XShape > xShape( xShapes->getByIndex( nIndex ), UNO_QUERY );
     778           0 :                     if( xShape.is() )
     779           0 :                         selectShape( this, xShape );
     780           0 :                 }
     781             :             }
     782             :             else
     783             :             {
     784           0 :                 Reference< XShape > xShape( aSelection, UNO_QUERY );
     785           0 :                 if( xShape.is() )
     786           0 :                     selectShape( this, xShape );
     787           0 :             }
     788             :         }
     789             : 
     790           0 :         SelectHdl();
     791             :     }
     792           0 :     catch( Exception& )
     793             :     {
     794             :         OSL_FAIL( "sd::CustomAnimationList::onSelectionChanged(), Exception caught!" );
     795             :     }
     796           0 : }
     797             : 
     798           0 : void CustomAnimationList::SelectHdl()
     799             : {
     800           0 :     if( mbIgnorePaint )
     801           0 :         return;
     802           0 :     SvTreeListBox::SelectHdl();
     803           0 :     mpController->onSelect();
     804             : }
     805             : 
     806           0 : bool CustomAnimationList::isExpanded( const CustomAnimationEffectPtr& pEffect ) const
     807             : {
     808           0 :     CustomAnimationListEntry* pEntry = static_cast<CustomAnimationListEntry*>(First());
     809             : 
     810           0 :     while( pEntry )
     811             :     {
     812           0 :         if( pEntry->getEffect() == pEffect )
     813           0 :             break;
     814             : 
     815           0 :         pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     816             :     }
     817             : 
     818           0 :     if( pEntry )
     819           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetParent( pEntry ));
     820             : 
     821           0 :     return (pEntry == 0) || IsExpanded( pEntry );
     822             : }
     823             : 
     824           0 : EffectSequence CustomAnimationList::getSelection() const
     825             : {
     826           0 :     EffectSequence aSelection;
     827             : 
     828           0 :     CustomAnimationListEntry* pEntry = dynamic_cast< CustomAnimationListEntry* >(FirstSelected());
     829           0 :     while( pEntry )
     830             :     {
     831           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     832           0 :         if( pEffect.get() )
     833           0 :             aSelection.push_back( pEffect );
     834             : 
     835             :         // if the selected effect is not expanded and has children
     836             :         // we say that the children are automatically selected
     837           0 :         if( !IsExpanded( pEntry ) )
     838             :         {
     839           0 :             CustomAnimationListEntry* pChild = dynamic_cast< CustomAnimationListEntry* >( FirstChild( pEntry ) );
     840           0 :             while( pChild )
     841             :             {
     842           0 :                 if( !IsSelected( pChild ) )
     843             :                 {
     844           0 :                     CustomAnimationEffectPtr pChildEffect( pChild->getEffect() );
     845           0 :                     if( pChildEffect.get() )
     846           0 :                         aSelection.push_back( pChildEffect );
     847             :                 }
     848             : 
     849           0 :                 pChild = dynamic_cast< CustomAnimationListEntry* >(  NextSibling( pChild ) );
     850             :             }
     851             :         }
     852             : 
     853           0 :         pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
     854           0 :     }
     855             : 
     856           0 :     return aSelection;
     857             : }
     858             : 
     859           0 : bool CustomAnimationList::DoubleClickHdl()
     860             : {
     861           0 :     mpController->onDoubleClick();
     862           0 :     return false;
     863             : }
     864             : 
     865           0 : PopupMenu* CustomAnimationList::CreateContextMenu()
     866             : {
     867           0 :     PopupMenu* pMenu = new PopupMenu(SdResId( RID_EFFECT_CONTEXTMENU ));
     868             : 
     869           0 :     sal_Int16 nNodeType = -1;
     870           0 :     sal_Int16 nEntries = 0;
     871             : 
     872           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(FirstSelected());
     873           0 :     while( pEntry )
     874             :     {
     875           0 :         nEntries++;
     876           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     877           0 :         if( pEffect.get() )
     878             :         {
     879           0 :             if( nNodeType == -1 )
     880             :             {
     881           0 :                 nNodeType = pEffect->getNodeType();
     882             :             }
     883             :             else
     884             :             {
     885           0 :                 if( nNodeType != pEffect->getNodeType() )
     886             :                 {
     887           0 :                     nNodeType = -1;
     888           0 :                     break;
     889             :                 }
     890             :             }
     891             :         }
     892             : 
     893           0 :         pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
     894           0 :     }
     895             : 
     896           0 :     pMenu->CheckItem( CM_WITH_CLICK, nNodeType == EffectNodeType::ON_CLICK );
     897           0 :     pMenu->CheckItem( CM_WITH_PREVIOUS, nNodeType == EffectNodeType::WITH_PREVIOUS );
     898           0 :     pMenu->CheckItem( CM_AFTER_PREVIOUS, nNodeType == EffectNodeType::AFTER_PREVIOUS );
     899           0 :     pMenu->EnableItem( CM_OPTIONS, nEntries == 1 );
     900           0 :     pMenu->EnableItem( CM_DURATION, nEntries == 1 );
     901             : 
     902           0 :     return pMenu;
     903             : }
     904             : 
     905           0 : void CustomAnimationList::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
     906             : {
     907           0 :     mpController->onContextMenu( nSelectedPopupEntry );
     908           0 : }
     909             : 
     910           0 : void CustomAnimationList::SetTabs()
     911             : {
     912           0 :     SvTreeListBox::SetTabs();
     913           0 : }
     914             : 
     915           0 : void CustomAnimationList::notify_change()
     916             : {
     917           0 :     update();
     918           0 :     mpController->onSelect();
     919           0 : }
     920             : 
     921           0 : void CustomAnimationList::Paint( const Rectangle& rRect )
     922             : {
     923           0 :     if( mbIgnorePaint )
     924           0 :         return;
     925             : 
     926           0 :     SvTreeListBox::Paint( rRect );
     927             : 
     928             :     // draw help text if list box is still empty
     929           0 :     if( First() == 0 )
     930             :     {
     931           0 :         Color aOldColor( GetTextColor() );
     932           0 :         SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
     933           0 :         ::Point aOffset( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) );
     934             : 
     935           0 :         Rectangle aRect( Point( 0,0 ), GetOutputSizePixel() );
     936             : 
     937           0 :         aRect.Left() += aOffset.X();
     938           0 :         aRect.Top() += aOffset.Y();
     939           0 :         aRect.Right() -= aOffset.X();
     940           0 :         aRect.Bottom() -= aOffset.Y();
     941             : 
     942             :         DrawText( aRect, SD_RESSTR(STR_CUSTOMANIMATION_LIST_HELPTEXT),
     943           0 :             TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER );
     944             : 
     945           0 :         SetTextColor( aOldColor );
     946             :     }
     947             : }
     948             : 
     949         114 : }
     950             : 
     951             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10