LCOV - code coverage report
Current view: top level - sd/source/ui/animations - CustomAnimationList.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 459 0.0 %
Date: 2014-04-14 Functions: 0 47 0.0 %
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 = true )
     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() == ::getCppuType((const ParagraphTarget*)0) )
     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             : 
     202             : 
     203             : class CustomAnimationListEntryItem : public SvLBoxString
     204             : {
     205             : public:
     206             :                     CustomAnimationListEntryItem( SvTreeListEntry*,sal_uInt16 nFlags, const OUString& aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent  );
     207             :     virtual         ~CustomAnimationListEntryItem();
     208             :     void            InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* ) SAL_OVERRIDE;
     209             :     SvLBoxItem*     Create() const SAL_OVERRIDE;
     210             :     void            Clone( SvLBoxItem* pSource ) SAL_OVERRIDE;
     211             : 
     212             :     virtual void Paint(
     213             :         const Point&, SvTreeListBox& rDev, const SvViewDataEntry* pView,const SvTreeListEntry* pEntry) SAL_OVERRIDE;
     214             : private:
     215             :     CustomAnimationList* mpParent;
     216             :     OUString        maDescription;
     217             :     CustomAnimationEffectPtr mpEffect;
     218             : };
     219             : 
     220             : 
     221             : 
     222           0 : CustomAnimationListEntryItem::CustomAnimationListEntryItem( SvTreeListEntry* pEntry, sal_uInt16 nFlags, const OUString& aDescription, CustomAnimationEffectPtr pEffect, CustomAnimationList* pParent  )
     223             : : SvLBoxString( pEntry, nFlags, aDescription )
     224             : , mpParent( pParent )
     225             : , maDescription( aDescription )
     226           0 : , mpEffect(pEffect)
     227             : {
     228           0 : }
     229             : 
     230             : 
     231             : 
     232           0 : CustomAnimationListEntryItem::~CustomAnimationListEntryItem()
     233             : {
     234           0 : }
     235             : 
     236             : 
     237             : 
     238           0 : void CustomAnimationListEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
     239             : {
     240           0 :     if( !pViewData )
     241           0 :         pViewData = pView->GetViewDataItem( pEntry, this );
     242             : 
     243           0 :     Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() );
     244           0 :     if( aSize.Height() < 19 )
     245           0 :         aSize.Height() = 19;
     246           0 :     pViewData->maSize = aSize;
     247           0 : }
     248             : 
     249             : 
     250             : 
     251           0 : void CustomAnimationListEntryItem::Paint(
     252             :     const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/, const SvTreeListEntry* pEntry)
     253             : {
     254             : 
     255           0 :     const SvViewDataItem* pViewData = mpParent->GetViewDataItem( pEntry, this );
     256             : 
     257           0 :     Point aPos( rPos );
     258           0 :     Size aSize( pViewData->maSize );
     259             : 
     260           0 :     sal_Int16 nNodeType = mpEffect->getNodeType();
     261           0 :     if( nNodeType == EffectNodeType::ON_CLICK )
     262             :     {
     263           0 :         rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_ON_CLICK ) );
     264             :     }
     265           0 :     else if( nNodeType == EffectNodeType::AFTER_PREVIOUS )
     266             :     {
     267           0 :         rDev.DrawImage( aPos, mpParent->getImage( IMG_CUSTOMANIMATION_AFTER_PREVIOUS ) );
     268             :     }
     269             : 
     270           0 :     aPos.X() += 19;
     271             : 
     272             :     sal_uInt16 nImage;
     273           0 :     switch( mpEffect->getPresetClass() )
     274             :     {
     275           0 :     case EffectPresetClass::ENTRANCE:   nImage = IMG_CUSTOMANIMATION_ENTRANCE_EFFECT; break;
     276           0 :     case EffectPresetClass::EXIT:       nImage =  IMG_CUSTOMANIMATION_EXIT_EFFECT; break;
     277           0 :     case EffectPresetClass::EMPHASIS:   nImage =  IMG_CUSTOMANIMATION_EMPHASIS_EFFECT; break;
     278           0 :     case EffectPresetClass::MOTIONPATH: nImage = IMG_CUSTOMANIMATION_MOTION_PATH; break;
     279           0 :     case EffectPresetClass::OLEACTION:  nImage = IMG_CUSTOMANIMATION_OLE; break;
     280             :     case EffectPresetClass::MEDIACALL:
     281           0 :         switch( mpEffect->getCommand() )
     282             :         {
     283           0 :         case EffectCommands::TOGGLEPAUSE:   nImage = IMG_CUSTOMANIMATION_MEDIA_PAUSE; break;
     284           0 :         case EffectCommands::STOP:          nImage = IMG_CUSTOMANIMATION_MEDIA_STOP; break;
     285             :         case EffectCommands::PLAY:
     286           0 :         default:                            nImage = IMG_CUSTOMANIMATION_MEDIA_PLAY; break;
     287             :         }
     288           0 :         break;
     289           0 :     default:                            nImage = 0xffff;
     290             :     }
     291             : 
     292           0 :     if( nImage != 0xffff )
     293             :     {
     294           0 :         const Image& rImage = mpParent->getImage( nImage );
     295           0 :         Point aImagePos( aPos );
     296           0 :         aImagePos.Y() += ( aSize.Height() - rImage.GetSizePixel().Height() ) >> 1;
     297           0 :         rDev.DrawImage( aImagePos, rImage );
     298             :     }
     299             : 
     300           0 :     aPos.X() += 19;
     301           0 :     aPos.Y() += ( aSize.Height() - rDev.GetTextHeight()) >> 1;
     302             : 
     303           0 :     rDev.DrawText( aPos, rDev.GetEllipsisString( maDescription, rDev.GetOutputSizePixel().Width() - aPos.X() ) );
     304           0 : }
     305             : 
     306             : 
     307             : 
     308           0 : SvLBoxItem* CustomAnimationListEntryItem::Create() const
     309             : {
     310           0 :     return NULL;
     311             : }
     312             : 
     313             : 
     314             : 
     315           0 : void CustomAnimationListEntryItem::Clone( SvLBoxItem* )
     316             : {
     317           0 : }
     318             : 
     319             : 
     320             : 
     321             : class CustomAnimationListEntry : public SvTreeListEntry
     322             : {
     323             : public:
     324             :     CustomAnimationListEntry();
     325             :     CustomAnimationListEntry( CustomAnimationEffectPtr pEffect );
     326             :     virtual ~CustomAnimationListEntry();
     327             : 
     328           0 :     CustomAnimationEffectPtr getEffect() const { return mpEffect; }
     329             : 
     330             : private:
     331             :     CustomAnimationEffectPtr mpEffect;
     332             : };
     333             : 
     334             : 
     335             : 
     336           0 : CustomAnimationListEntry::CustomAnimationListEntry()
     337             : {
     338           0 : }
     339             : 
     340             : 
     341             : 
     342           0 : CustomAnimationListEntry::CustomAnimationListEntry( CustomAnimationEffectPtr pEffect )
     343           0 : : mpEffect( pEffect )
     344             : {
     345           0 : }
     346             : 
     347             : 
     348             : 
     349           0 : CustomAnimationListEntry::~CustomAnimationListEntry()
     350             : {
     351           0 : }
     352             : 
     353             : 
     354             : 
     355             : class CustomAnimationTriggerEntryItem : public SvLBoxString
     356             : {
     357             : public:
     358             :                     CustomAnimationTriggerEntryItem( SvTreeListEntry*,sal_uInt16 nFlags, const OUString& aDescription );
     359             :     virtual         ~CustomAnimationTriggerEntryItem();
     360             :     void            InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem* ) SAL_OVERRIDE;
     361             :     SvLBoxItem*     Create() const SAL_OVERRIDE;
     362             :     void            Clone( SvLBoxItem* pSource ) SAL_OVERRIDE;
     363             :     virtual void Paint(
     364             :         const Point& rPos, SvTreeListBox& rOutDev, const SvViewDataEntry* pView, const SvTreeListEntry* pEntry) SAL_OVERRIDE;
     365             : 
     366             : private:
     367             :     OUString        maDescription;
     368             : };
     369             : 
     370             : 
     371             : 
     372           0 : CustomAnimationTriggerEntryItem::CustomAnimationTriggerEntryItem( SvTreeListEntry* pEntry, sal_uInt16 nFlags, const 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           0 : void CustomAnimationTriggerEntryItem::InitViewData( SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData )
     385             : {
     386           0 :     if( !pViewData )
     387           0 :         pViewData = pView->GetViewDataItem( pEntry, this );
     388             : 
     389           0 :     Size aSize(pView->GetTextWidth( maDescription ) + 2 * 19, pView->GetTextHeight() );
     390           0 :     if( aSize.Height() < 19 )
     391           0 :         aSize.Height() = 19;
     392           0 :     pViewData->maSize = aSize;
     393           0 : }
     394             : 
     395             : 
     396             : 
     397           0 : void CustomAnimationTriggerEntryItem::Paint(
     398             :     const Point& rPos, SvTreeListBox& rDev, const SvViewDataEntry* /*pView*/, const SvTreeListEntry* /*pEntry*/)
     399             : {
     400           0 :     Size aSize( rDev.GetOutputSizePixel().Width(), static_cast< SvTreeListBox* >(&rDev)->GetEntryHeight() );
     401             : 
     402           0 :     Point aPos( 0, rPos.Y() );
     403             : 
     404           0 :     Rectangle aOutRect( aPos, aSize );
     405             : 
     406             :     // fill the background
     407           0 :     Color aColor (rDev.GetSettings().GetStyleSettings().GetDialogColor());
     408             : 
     409           0 :     rDev.Push();
     410           0 :     rDev.SetFillColor (aColor);
     411           0 :     rDev.SetLineColor ();
     412           0 :     rDev.DrawRect(aOutRect);
     413             : 
     414             :     // Erase the four corner pixels to make the rectangle appear rounded.
     415           0 :     rDev.SetLineColor( rDev.GetSettings().GetStyleSettings().GetWindowColor());
     416           0 :     rDev.DrawPixel( aOutRect.TopLeft());
     417           0 :     rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Top()));
     418           0 :     rDev.DrawPixel( Point(aOutRect.Left(), aOutRect.Bottom()));
     419           0 :     rDev.DrawPixel( Point(aOutRect.Right(), aOutRect.Bottom()));
     420             : 
     421             :     // draw the category title
     422             : 
     423           0 :     int nVertBorder = (( aSize.Height() - rDev.GetTextHeight()) >> 1);
     424           0 :     int nHorzBorder = rDev.LogicToPixel( Size( 3, 3 ), MAP_APPFONT ).Width();
     425             : 
     426           0 :     aOutRect.Left() += nHorzBorder;
     427           0 :     aOutRect.Right() -= nHorzBorder;
     428           0 :     aOutRect.Top() += nVertBorder;
     429           0 :     aOutRect.Bottom() -= nVertBorder;
     430             : 
     431           0 :     rDev.DrawText (aOutRect, rDev.GetEllipsisString( maDescription, aOutRect.GetWidth() ) );
     432           0 :     rDev.Pop();
     433           0 : }
     434             : 
     435             : 
     436             : 
     437           0 : SvLBoxItem* CustomAnimationTriggerEntryItem::Create() const
     438             : {
     439           0 :     return NULL;
     440             : }
     441             : 
     442             : 
     443             : 
     444           0 : void CustomAnimationTriggerEntryItem::Clone( SvLBoxItem* )
     445             : {
     446           0 : }
     447             : 
     448             : 
     449             : 
     450           0 : CustomAnimationList::CustomAnimationList( ::Window* pParent )
     451             :     : SvTreeListBox( pParent, WB_TABSTOP | WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT )
     452             :     , mbIgnorePaint(false)
     453             :     , mpController(0)
     454             :     , mnLastGroupId(0)
     455           0 :     , mpLastParentEntry(0)
     456             : {
     457             : 
     458           0 :     EnableContextMenuHandling();
     459           0 :     SetSelectionMode( MULTIPLE_SELECTION );
     460           0 :     SetOptimalImageIndent();
     461           0 :     SetNodeDefaultImages();
     462           0 : }
     463             : 
     464           0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeCustomAnimationList( ::Window *pParent )
     465             : {
     466           0 :     return new CustomAnimationList( pParent );
     467             : }
     468             : 
     469             : 
     470             : 
     471           0 : const Image&  CustomAnimationList::getImage( sal_uInt16 nId )
     472             : {
     473             :     DBG_ASSERT( (nId >= IMG_CUSTOMANIMATION_ON_CLICK) && (nId <= IMG_CUSTOMANIMATION_MEDIA_STOP), "sd::CustomAnimationList::getImage(), illegal index!" );
     474             : 
     475           0 :     Image& rImage = maImages[nId - IMG_CUSTOMANIMATION_ON_CLICK];
     476             : 
     477             :     // load on demand
     478           0 :     if( rImage.GetSizePixel().Width() == 0 )
     479           0 :         rImage = Image(SdResId( nId ) );
     480             : 
     481           0 :     return rImage;
     482             : }
     483             : 
     484             : 
     485             : 
     486           0 : CustomAnimationList::~CustomAnimationList()
     487             : {
     488           0 :     if( mpMainSequence.get() )
     489           0 :         mpMainSequence->removeListener( this );
     490             : 
     491           0 :     clear();
     492           0 : }
     493             : 
     494             : 
     495             : 
     496           0 : void CustomAnimationList::KeyInput( const KeyEvent& rKEvt )
     497             : {
     498           0 :     const int nKeyCode = rKEvt.GetKeyCode().GetCode();
     499           0 :     switch( nKeyCode )
     500             :     {
     501           0 :         case KEY_DELETE:    mpController->onContextMenu( CM_REMOVE ); return;
     502           0 :         case KEY_INSERT:    mpController->onContextMenu( CM_CREATE ); return;
     503             :         case KEY_SPACE:
     504             :             {
     505           0 :                 const Point aPos;
     506           0 :                 const CommandEvent aCEvt( aPos, COMMAND_CONTEXTMENU );
     507           0 :                 Command( aCEvt );
     508           0 :                 return;
     509             :             }
     510             : 
     511             :     }
     512             : 
     513           0 :     ::SvTreeListBox::KeyInput( rKEvt );
     514             : }
     515             : 
     516             : 
     517             : 
     518             : /** selects or deselects the given effect.
     519             :     Selections of other effects are not changed */
     520           0 : void CustomAnimationList::select( CustomAnimationEffectPtr pEffect, bool bSelect /* = true */ )
     521             : {
     522           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(First());
     523           0 :     while( pEntry )
     524             :     {
     525           0 :         if( pEntry->getEffect() == pEffect )
     526             :         {
     527           0 :             Select( pEntry, bSelect );
     528           0 :             MakeVisible( pEntry );
     529           0 :             break;
     530             :         }
     531           0 :         pEntry = static_cast< CustomAnimationListEntry* >(Next( pEntry ));
     532             :     }
     533             : 
     534           0 :     if( !pEntry && bSelect )
     535             :     {
     536           0 :         append( pEffect );
     537           0 :         select( pEffect );
     538             :     }
     539           0 : }
     540             : 
     541             : 
     542             : 
     543           0 : void CustomAnimationList::clear()
     544             : {
     545           0 :     Clear();
     546             : 
     547           0 :     mpLastParentEntry = 0;
     548           0 :     mxLastTargetShape = 0;
     549           0 : }
     550             : 
     551             : 
     552             : 
     553           0 : void CustomAnimationList::update( MainSequencePtr pMainSequence )
     554             : {
     555           0 :     if( mpMainSequence.get() )
     556           0 :         mpMainSequence->removeListener( this );
     557             : 
     558           0 :     mpMainSequence = pMainSequence;
     559           0 :     update();
     560             : 
     561           0 :     if( mpMainSequence.get() )
     562           0 :         mpMainSequence->addListener( this );
     563           0 : }
     564             : 
     565             : 
     566             : 
     567             : struct stl_append_effect_func : public std::unary_function<CustomAnimationEffectPtr, void>
     568             : {
     569           0 :     stl_append_effect_func( CustomAnimationList& rList ) : mrList( rList ) {}
     570             :     void operator()(CustomAnimationEffectPtr pEffect);
     571             :     CustomAnimationList& mrList;
     572             : };
     573             : 
     574           0 : void stl_append_effect_func::operator()(CustomAnimationEffectPtr pEffect)
     575             : {
     576           0 :     mrList.append( pEffect );
     577           0 : }
     578             : 
     579             : 
     580           0 : void CustomAnimationList::update()
     581             : {
     582           0 :     mbIgnorePaint = true;
     583           0 :     SetUpdateMode( false );
     584             : 
     585           0 :     CustomAnimationListEntry* pEntry = 0;
     586             : 
     587           0 :     std::list< CustomAnimationEffectPtr > aExpanded;
     588           0 :     std::list< CustomAnimationEffectPtr > aSelected;
     589             : 
     590           0 :     CustomAnimationEffectPtr pFirstSelEffect;
     591           0 :     CustomAnimationEffectPtr pLastSelEffect;
     592           0 :     long nFirstVis = -1;
     593           0 :     long nLastVis = -1;
     594           0 :     long nFirstSelOld = -1;
     595           0 :     long nLastSelOld = -1;
     596           0 :     bool bMoved = false;
     597           0 :     bool bMovedUp = false;
     598           0 :     bool bMovedDown = false;
     599             : 
     600           0 :     if( mpMainSequence.get() )
     601             :     {
     602             :         // save scroll position
     603           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetFirstEntryInView());
     604           0 :         if( pEntry )
     605           0 :             nFirstVis = GetAbsPos( pEntry );
     606             : 
     607           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetLastEntryInView());
     608           0 :         if( pEntry )
     609           0 :             nLastVis = GetAbsPos( pEntry );
     610             : 
     611           0 :         pEntry = static_cast<CustomAnimationListEntry*>(FirstSelected());
     612           0 :         if( pEntry )
     613             :         {
     614           0 :             pFirstSelEffect = pEntry->getEffect();
     615           0 :             nFirstSelOld = GetAbsPos( pEntry );
     616             :         }
     617             : 
     618           0 :         pEntry = static_cast<CustomAnimationListEntry*>(LastSelected());
     619           0 :         if( pEntry )
     620             :         {
     621           0 :             pLastSelEffect = pEntry->getEffect();
     622           0 :             nLastSelOld = GetAbsPos( pEntry );
     623             :         }
     624             : 
     625             :         // save selection and expand states
     626           0 :         pEntry = static_cast<CustomAnimationListEntry*>(First());
     627             : 
     628           0 :         while( pEntry )
     629             :         {
     630           0 :             CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     631           0 :             if( pEffect.get() )
     632             :             {
     633           0 :                 if( IsExpanded( pEntry ) )
     634           0 :                     aExpanded.push_back( pEffect );
     635             : 
     636           0 :                 if( IsSelected( pEntry ) )
     637           0 :                     aSelected.push_back( pEffect );
     638             :             }
     639             : 
     640           0 :             pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     641           0 :         }
     642             :     }
     643             : 
     644             :     // rebuild list
     645           0 :     clear();
     646           0 :     if( mpMainSequence.get() )
     647             :     {
     648           0 :         long nFirstSelNew = -1;
     649           0 :         long nLastSelNew = -1;
     650           0 :         std::for_each( mpMainSequence->getBegin(), mpMainSequence->getEnd(), stl_append_effect_func( *this ) );
     651           0 :         mpLastParentEntry = 0;
     652             : 
     653           0 :         const InteractiveSequenceList& rISL = mpMainSequence->getInteractiveSequenceList();
     654             : 
     655           0 :         InteractiveSequenceList::const_iterator aIter( rISL.begin() );
     656           0 :         const InteractiveSequenceList::const_iterator aEnd( rISL.end() );
     657           0 :         while( aIter != aEnd )
     658             :         {
     659           0 :             InteractiveSequencePtr pIS( (*aIter++) );
     660             : 
     661           0 :             Reference< XShape > xShape( pIS->getTriggerShape() );
     662           0 :             if( xShape.is() )
     663             :             {
     664           0 :                 SvTreeListEntry* pLBoxEntry = new CustomAnimationListEntry;
     665           0 :                 pLBoxEntry->AddItem( new SvLBoxContextBmp( pLBoxEntry, 0, Image(), Image(), false));
     666           0 :                 OUString aDescription = SD_RESSTR(STR_CUSTOMANIMATION_TRIGGER);
     667           0 :                 aDescription += ": ";
     668           0 :                 aDescription += getShapeDescription( xShape, false );
     669           0 :                 pLBoxEntry->AddItem( new CustomAnimationTriggerEntryItem( pLBoxEntry, 0, aDescription ) );
     670           0 :                 Insert( pLBoxEntry );
     671           0 :                 SvViewDataEntry* pViewData = GetViewData( pLBoxEntry );
     672           0 :                 if( pViewData )
     673           0 :                     pViewData->SetSelectable(false);
     674             : 
     675           0 :                 std::for_each( pIS->getBegin(), pIS->getEnd(), stl_append_effect_func( *this ) );
     676           0 :                 mpLastParentEntry = 0;
     677             :             }
     678           0 :         }
     679             : 
     680             :         // restore selection and expand states
     681           0 :         pEntry = static_cast<CustomAnimationListEntry*>(First());
     682             : 
     683           0 :         while( pEntry )
     684             :         {
     685           0 :             CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     686           0 :             if( pEffect.get() )
     687             :             {
     688           0 :                 if( std::find( aExpanded.begin(), aExpanded.end(), pEffect ) != aExpanded.end() )
     689           0 :                     Expand( pEntry );
     690             : 
     691           0 :                 if( std::find( aSelected.begin(), aSelected.end(), pEffect ) != aSelected.end() )
     692           0 :                     Select( pEntry );
     693             : 
     694           0 :                 if( pEffect == pFirstSelEffect )
     695           0 :                     nFirstSelNew = GetAbsPos( pEntry );
     696             : 
     697           0 :                 if( pEffect == pLastSelEffect )
     698           0 :                     nLastSelNew = GetAbsPos( pEntry );
     699             :             }
     700             : 
     701           0 :             pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     702           0 :         }
     703             : 
     704             :         // Scroll to a selected entry, depending on where the selection moved.
     705           0 :         bMoved = nFirstSelNew != nFirstSelOld;
     706           0 :         bMovedUp = nFirstSelNew < nFirstSelOld;
     707           0 :         bMovedDown = nFirstSelNew > nFirstSelOld;
     708             : 
     709           0 :         if( bMoved && nLastSelOld < nFirstVis && nLastSelNew < nFirstVis )
     710             :         {
     711             :             // The selection is above the visible area.
     712             :             // Scroll up to show the last few selected entries.
     713           0 :             if( nLastSelNew - (nLastVis - nFirstVis) > nFirstSelNew)
     714             :             {
     715             :                 // The entries in the selection range can't fit in view.
     716             :                 // Scroll so the last selected entry is last in view.
     717           0 :                 ScrollToAbsPos( nLastSelNew - (nLastVis - nFirstVis) );
     718             :             }
     719             :             else
     720           0 :                 ScrollToAbsPos( nFirstSelNew );
     721             :         }
     722           0 :         else if( bMoved && nFirstSelOld > nLastVis && nFirstSelNew > nLastVis )
     723             :         {
     724             :             // The selection is below the visible area.
     725             :             // Scroll down to the first few selected entries.
     726           0 :             ScrollToAbsPos( nFirstSelNew );
     727             :         }
     728           0 :         else if( bMovedUp && nFirstSelOld <= nFirstVis )
     729             :         {
     730             :             // A visible entry has moved up out of view; scroll up one.
     731           0 :             ScrollToAbsPos( nFirstVis - 1 );
     732             :         }
     733           0 :         else if( bMovedDown && nLastSelOld >= nLastVis )
     734             :         {
     735             :             // An entry has moved down out of view; scroll down one.
     736           0 :             ScrollToAbsPos( nFirstVis + 1 );
     737             :         }
     738           0 :         else if ( nFirstVis != -1 )
     739             :         {
     740             :             // The selection is still in view, or it hasn't moved.
     741           0 :             ScrollToAbsPos( nFirstVis );
     742             :         }
     743             :     }
     744             : 
     745           0 :     mbIgnorePaint = false;
     746           0 :     SetUpdateMode( true );
     747           0 :     Invalidate();
     748           0 : }
     749             : 
     750             : 
     751             : 
     752           0 : void CustomAnimationList::append( CustomAnimationEffectPtr pEffect )
     753             : {
     754             :     // create a ui description
     755           0 :     OUString aDescription;
     756             : 
     757           0 :     Any aTarget( pEffect->getTarget() );
     758           0 :     if( aTarget.hasValue() ) try
     759             :     {
     760           0 :         aDescription = getDescription( aTarget, pEffect->getTargetSubItem() != ShapeAnimationSubType::ONLY_BACKGROUND );
     761             : 
     762           0 :         SvTreeListEntry* pParentEntry = 0;
     763             : 
     764           0 :         Reference< XShape > xTargetShape( pEffect->getTargetShape() );
     765           0 :         sal_Int32 nGroupId = pEffect->getGroupId();
     766             : 
     767             :         // if this effect has the same target and group-id as the last root effect,
     768             :         // the last root effect is also this effects parent
     769           0 :         if( mpLastParentEntry && (nGroupId != -1) && (mxLastTargetShape == xTargetShape) && (mnLastGroupId == nGroupId) )
     770           0 :             pParentEntry = mpLastParentEntry;
     771             : 
     772             :         // create an entry for the effect
     773           0 :         SvTreeListEntry* pEntry = new CustomAnimationListEntry( pEffect );
     774             : 
     775           0 :         pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), false));
     776           0 :         pEntry->AddItem( new CustomAnimationListEntryItem( pEntry, 0, aDescription, pEffect, this ) );
     777             : 
     778           0 :         if( pParentEntry )
     779             :         {
     780             :             // add a subentry
     781           0 :             Insert( pEntry, pParentEntry );
     782             :         }
     783             :         else
     784             :         {
     785             :             // add a root entry
     786           0 :             Insert( pEntry );
     787             : 
     788             :             // and the new root entry becomes the possible next group header
     789           0 :             mxLastTargetShape = xTargetShape;
     790           0 :             mnLastGroupId = nGroupId;
     791           0 :             mpLastParentEntry = pEntry;
     792           0 :         }
     793             :     }
     794           0 :     catch( Exception& )
     795             :     {
     796             :         OSL_FAIL("sd::CustomAnimationList::append(), exception caught!" );
     797           0 :     }
     798           0 : }
     799             : 
     800             : 
     801             : 
     802           0 : void selectShape( SvTreeListBox* pTreeList, Reference< XShape > xShape )
     803             : {
     804           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->First());
     805           0 :     while( pEntry )
     806             :     {
     807           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     808           0 :         if( pEffect.get() )
     809             :         {
     810           0 :             if( pEffect->getTarget() == xShape )
     811           0 :                 pTreeList->Select( pEntry );
     812             :         }
     813             : 
     814           0 :         pEntry = static_cast< CustomAnimationListEntry* >(pTreeList->Next( pEntry ));
     815           0 :     }
     816           0 : }
     817             : 
     818             : 
     819             : 
     820           0 : void CustomAnimationList::onSelectionChanged( Any aSelection )
     821             : {
     822             :     try
     823             :     {
     824           0 :         SelectAll(false);
     825             : 
     826           0 :         if( aSelection.hasValue() )
     827             :         {
     828           0 :             Reference< XIndexAccess > xShapes( aSelection, UNO_QUERY );
     829           0 :             if( xShapes.is() )
     830             :             {
     831           0 :                 sal_Int32 nCount = xShapes->getCount();
     832             :                 sal_Int32 nIndex;
     833           0 :                 for( nIndex = 0; nIndex < nCount; nIndex++ )
     834             :                 {
     835           0 :                     Reference< XShape > xShape( xShapes->getByIndex( nIndex ), UNO_QUERY );
     836           0 :                     if( xShape.is() )
     837           0 :                         selectShape( this, xShape );
     838           0 :                 }
     839             :             }
     840             :             else
     841             :             {
     842           0 :                 Reference< XShape > xShape( aSelection, UNO_QUERY );
     843           0 :                 if( xShape.is() )
     844           0 :                     selectShape( this, xShape );
     845           0 :             }
     846             :         }
     847             : 
     848           0 :         SelectHdl();
     849             :     }
     850           0 :     catch( Exception& )
     851             :     {
     852             :         OSL_FAIL( "sd::CustomAnimationList::onSelectionChanged(), Exception caught!" );
     853             :     }
     854           0 : }
     855             : 
     856             : 
     857             : 
     858           0 : void CustomAnimationList::SelectHdl()
     859             : {
     860           0 :     if( mbIgnorePaint )
     861           0 :         return;
     862           0 :     SvTreeListBox::SelectHdl();
     863           0 :     mpController->onSelect();
     864             : }
     865             : 
     866             : 
     867             : 
     868           0 : bool CustomAnimationList::isExpanded( const CustomAnimationEffectPtr& pEffect ) const
     869             : {
     870           0 :     CustomAnimationListEntry* pEntry = static_cast<CustomAnimationListEntry*>(First());
     871             : 
     872           0 :     while( pEntry )
     873             :     {
     874           0 :         if( pEntry->getEffect() == pEffect )
     875           0 :             break;
     876             : 
     877           0 :         pEntry = static_cast<CustomAnimationListEntry*>(Next( pEntry ));
     878             :     }
     879             : 
     880           0 :     if( pEntry )
     881           0 :         pEntry = static_cast<CustomAnimationListEntry*>(GetParent( pEntry ));
     882             : 
     883           0 :     return (pEntry == 0) || IsExpanded( pEntry );
     884             : }
     885             : 
     886             : 
     887           0 : EffectSequence CustomAnimationList::getSelection() const
     888             : {
     889           0 :     EffectSequence aSelection;
     890             : 
     891           0 :     CustomAnimationListEntry* pEntry = dynamic_cast< CustomAnimationListEntry* >(FirstSelected());
     892           0 :     while( pEntry )
     893             :     {
     894           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     895           0 :         if( pEffect.get() )
     896           0 :             aSelection.push_back( pEffect );
     897             : 
     898             :         // if the selected effect is not expanded and has children
     899             :         // we say that the children are automaticly selected
     900           0 :         if( !IsExpanded( pEntry ) )
     901             :         {
     902           0 :             CustomAnimationListEntry* pChild = dynamic_cast< CustomAnimationListEntry* >( FirstChild( pEntry ) );
     903           0 :             while( pChild )
     904             :             {
     905           0 :                 if( !IsSelected( pChild ) )
     906             :                 {
     907           0 :                     CustomAnimationEffectPtr pChildEffect( pChild->getEffect() );
     908           0 :                     if( pChildEffect.get() )
     909           0 :                         aSelection.push_back( pChildEffect );
     910             :                 }
     911             : 
     912           0 :                 pChild = dynamic_cast< CustomAnimationListEntry* >(  NextSibling( pChild ) );
     913             :             }
     914             :         }
     915             : 
     916           0 :         pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
     917           0 :     }
     918             : 
     919           0 :     return aSelection;
     920             : }
     921             : 
     922             : 
     923             : 
     924           0 : bool CustomAnimationList::DoubleClickHdl()
     925             : {
     926           0 :     mpController->onDoubleClick();
     927           0 :     return false;
     928             : }
     929             : 
     930             : 
     931             : 
     932           0 : PopupMenu* CustomAnimationList::CreateContextMenu()
     933             : {
     934           0 :     PopupMenu* pMenu = new PopupMenu(SdResId( RID_EFFECT_CONTEXTMENU ));
     935             : 
     936           0 :     sal_Int16 nNodeType = -1;
     937           0 :     sal_Int16 nEntries = 0;
     938             : 
     939           0 :     CustomAnimationListEntry* pEntry = static_cast< CustomAnimationListEntry* >(FirstSelected());
     940           0 :     while( pEntry )
     941             :     {
     942           0 :         nEntries++;
     943           0 :         CustomAnimationEffectPtr pEffect( pEntry->getEffect() );
     944           0 :         if( pEffect.get() )
     945             :         {
     946           0 :             if( nNodeType == -1 )
     947             :             {
     948           0 :                 nNodeType = pEffect->getNodeType();
     949             :             }
     950             :             else
     951             :             {
     952           0 :                 if( nNodeType != pEffect->getNodeType() )
     953             :                 {
     954           0 :                     nNodeType = -1;
     955           0 :                     break;
     956             :                 }
     957             :             }
     958             :         }
     959             : 
     960           0 :         pEntry = static_cast< CustomAnimationListEntry* >(NextSelected( pEntry ));
     961           0 :     }
     962             : 
     963           0 :     pMenu->CheckItem( CM_WITH_CLICK, nNodeType == EffectNodeType::ON_CLICK );
     964           0 :     pMenu->CheckItem( CM_WITH_PREVIOUS, nNodeType == EffectNodeType::WITH_PREVIOUS );
     965           0 :     pMenu->CheckItem( CM_AFTER_PREVIOUS, nNodeType == EffectNodeType::AFTER_PREVIOUS );
     966           0 :     pMenu->EnableItem( CM_OPTIONS, nEntries == 1 );
     967           0 :     pMenu->EnableItem( CM_DURATION, nEntries == 1 );
     968             : 
     969           0 :     return pMenu;
     970             : }
     971             : 
     972             : 
     973             : 
     974           0 : void CustomAnimationList::ExcecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
     975             : {
     976           0 :     mpController->onContextMenu( nSelectedPopupEntry );
     977           0 : }
     978             : 
     979             : 
     980             : 
     981           0 : void CustomAnimationList::SetTabs()
     982             : {
     983           0 :     SvTreeListBox::SetTabs();
     984           0 : }
     985             : 
     986             : 
     987             : 
     988           0 : void CustomAnimationList::notify_change()
     989             : {
     990           0 :     update();
     991           0 :     mpController->onSelect();
     992           0 : }
     993             : 
     994           0 : void CustomAnimationList::Paint( const Rectangle& rRect )
     995             : {
     996           0 :     if( mbIgnorePaint )
     997           0 :         return;
     998             : 
     999           0 :     SvTreeListBox::Paint( rRect );
    1000             : 
    1001             :     // draw help text if list box is still empty
    1002           0 :     if( First() == 0 )
    1003             :     {
    1004           0 :         Color aOldColor( GetTextColor() );
    1005           0 :         SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
    1006           0 :         ::Point aOffset( LogicToPixel( Point( 6, 6 ), MAP_APPFONT ) );
    1007             : 
    1008           0 :         Rectangle aRect( Point( 0,0 ), GetOutputSizePixel() );
    1009             : 
    1010           0 :         aRect.Left() += aOffset.X();
    1011           0 :         aRect.Top() += aOffset.Y();
    1012           0 :         aRect.Right() -= aOffset.X();
    1013           0 :         aRect.Bottom() -= aOffset.Y();
    1014             : 
    1015             :         DrawText( aRect, SD_RESSTR(STR_CUSTOMANIMATION_LIST_HELPTEXT),
    1016           0 :             TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK | TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER );
    1017             : 
    1018           0 :         SetTextColor( aOldColor );
    1019             :     }
    1020             : }
    1021             : 
    1022             : }
    1023             : 
    1024             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10