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

Generated by: LCOV version 1.10