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

Generated by: LCOV version 1.10