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

Generated by: LCOV version 1.11