1129 lines
38 KiB
C++
1129 lines
38 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <time.h>
|
|
#include <svl/eitem.hxx>
|
|
#include <svl/intitem.hxx>
|
|
#include <svx/svdograf.hxx>
|
|
#include <svx/svdogrp.hxx>
|
|
#include <svx/svdpagv.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <sfx2/progress.hxx>
|
|
#include <vcl/help.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/weld.hxx>
|
|
#include <vcl/virdev.hxx>
|
|
|
|
#include <anminfo.hxx>
|
|
#include <animobjs.hxx>
|
|
#include <app.hrc>
|
|
#include <strings.hrc>
|
|
#include <sdresid.hxx>
|
|
#include <View.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <sdpage.hxx>
|
|
|
|
#include <ViewShell.hxx>
|
|
|
|
#include <vcl/settings.hxx>
|
|
|
|
#include <EffectMigration.hxx>
|
|
|
|
#include <algorithm>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace sd {
|
|
|
|
/**
|
|
* SdDisplay - Control
|
|
*/
|
|
SdDisplay::SdDisplay()
|
|
: aScale(1, 1)
|
|
{
|
|
}
|
|
|
|
SdDisplay::~SdDisplay()
|
|
{
|
|
}
|
|
|
|
void SdDisplay::SetBitmapEx( BitmapEx const * pBmpEx )
|
|
{
|
|
if( pBmpEx )
|
|
{
|
|
aBitmapEx = *pBmpEx;
|
|
}
|
|
else
|
|
{
|
|
const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
|
|
const Color aFillColor = rStyles.GetFieldColor();
|
|
aBitmapEx.Erase(aFillColor);
|
|
}
|
|
}
|
|
|
|
void SdDisplay::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
|
|
{
|
|
rRenderContext.Push(vcl::PushFlags::MAPMODE);
|
|
|
|
rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel));
|
|
const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
|
|
rRenderContext.SetBackground( Wallpaper( rStyles.GetFieldColor() ) );
|
|
rRenderContext.Erase();
|
|
|
|
Point aPt;
|
|
Size aSize = GetOutputSizePixel();
|
|
|
|
Size aBmpSize = aBitmapEx.GetBitmap().GetSizePixel();
|
|
aBmpSize.setWidth( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Width()) * static_cast<double>(aScale) ) );
|
|
aBmpSize.setHeight( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Height()) * static_cast<double>(aScale) ) );
|
|
|
|
if( aBmpSize.Width() < aSize.Width() )
|
|
aPt.setX( ( aSize.Width() - aBmpSize.Width() ) / 2 );
|
|
if( aBmpSize.Height() < aSize.Height() )
|
|
aPt.setY( ( aSize.Height() - aBmpSize.Height() ) / 2 );
|
|
|
|
aBitmapEx.Draw(&rRenderContext, aPt, aBmpSize);
|
|
|
|
rRenderContext.Pop();
|
|
}
|
|
|
|
void SdDisplay::SetScale( const Fraction& rFrac )
|
|
{
|
|
aScale = rFrac;
|
|
}
|
|
|
|
void SdDisplay::SetDrawingArea(weld::DrawingArea* pDrawingArea)
|
|
{
|
|
CustomWidgetController::SetDrawingArea(pDrawingArea);
|
|
Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(147, 87), MapMode(MapUnit::MapAppFont)));
|
|
pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
|
|
SetOutputSizePixel(aSize);
|
|
}
|
|
|
|
/**
|
|
* AnimationWindow - FloatingWindow
|
|
*/
|
|
AnimationWindow::AnimationWindow(SfxBindings* pInBindings, SfxChildWindow *pCW, vcl::Window* pParent)
|
|
: SfxDockingWindow(pInBindings, pCW, pParent,
|
|
u"DockingAnimation"_ustr, u"modules/simpress/ui/dockinganimation.ui"_ustr)
|
|
, m_xCtlDisplay(new SdDisplay)
|
|
, m_xCtlDisplayWin(new weld::CustomWeld(*m_xBuilder, u"preview"_ustr, *m_xCtlDisplay))
|
|
, m_xBtnFirst(m_xBuilder->weld_button(u"first"_ustr))
|
|
, m_xBtnReverse(m_xBuilder->weld_button(u"prev"_ustr))
|
|
, m_xBtnStop(m_xBuilder->weld_button(u"stop"_ustr))
|
|
, m_xBtnPlay(m_xBuilder->weld_button(u"next"_ustr))
|
|
, m_xBtnLast(m_xBuilder->weld_button(u"last"_ustr))
|
|
, m_xNumFldBitmap(m_xBuilder->weld_spin_button(u"numbitmap"_ustr))
|
|
, m_xTimeField(m_xBuilder->weld_formatted_spin_button(u"duration"_ustr))
|
|
, m_xFormatter(new weld::TimeFormatter(*m_xTimeField))
|
|
, m_xLbLoopCount(m_xBuilder->weld_combo_box(u"loopcount"_ustr))
|
|
, m_xBtnGetOneObject(m_xBuilder->weld_button(u"getone"_ustr))
|
|
, m_xBtnGetAllObjects(m_xBuilder->weld_button(u"getall"_ustr))
|
|
, m_xBtnRemoveBitmap(m_xBuilder->weld_button(u"delone"_ustr))
|
|
, m_xBtnRemoveAll(m_xBuilder->weld_button(u"delall"_ustr))
|
|
, m_xFiCount(m_xBuilder->weld_label(u"count"_ustr))
|
|
, m_xRbtGroup(m_xBuilder->weld_radio_button(u"group"_ustr))
|
|
, m_xRbtBitmap(m_xBuilder->weld_radio_button(u"bitmap"_ustr))
|
|
, m_xFtAdjustment(m_xBuilder->weld_label(u"alignmentft"_ustr))
|
|
, m_xLbAdjustment(m_xBuilder->weld_combo_box(u"alignment"_ustr))
|
|
, m_xBtnCreateGroup(m_xBuilder->weld_button(u"create"_ustr))
|
|
, m_xBtnHelp(m_xBuilder->weld_button(u"help"_ustr))
|
|
, m_nCurrentFrame(EMPTY_FRAMELIST)
|
|
, bMovie(false)
|
|
, bAllObjects(false)
|
|
{
|
|
SetText(SdResId(STR_ANIMATION_DIALOG_TITLE));
|
|
|
|
m_xFormatter->SetDuration(true);
|
|
m_xFormatter->SetTimeFormat(TimeFieldFormat::F_SEC_CS);
|
|
m_xFormatter->EnableEmptyField(false);
|
|
|
|
// create new document with page
|
|
pMyDoc.reset( new SdDrawDocument(DocumentType::Impress, nullptr) );
|
|
rtl::Reference<SdPage> pPage = pMyDoc->AllocSdPage(false);
|
|
pMyDoc->InsertPage(pPage.get());
|
|
|
|
pControllerItem.reset( new AnimationControllerItem( SID_ANIMATOR_STATE, this, pInBindings ) );
|
|
|
|
m_xBtnFirst->connect_clicked( LINK( this, AnimationWindow, ClickFirstHdl ) );
|
|
m_xBtnReverse->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) );
|
|
m_xBtnStop->connect_clicked( LINK( this, AnimationWindow, ClickStopHdl ) );
|
|
m_xBtnPlay->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) );
|
|
m_xBtnLast->connect_clicked( LINK( this, AnimationWindow, ClickLastHdl ) );
|
|
|
|
m_xBtnGetOneObject->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
|
|
m_xBtnGetAllObjects->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
|
|
m_xBtnRemoveBitmap->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
|
|
m_xBtnRemoveAll->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
|
|
|
|
m_xRbtGroup->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) );
|
|
m_xRbtBitmap->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) );
|
|
m_xBtnCreateGroup->connect_clicked( LINK( this, AnimationWindow, ClickCreateGroupHdl ) );
|
|
m_xBtnHelp->connect_clicked( LINK( this, AnimationWindow, ClickHelpHdl ) );
|
|
m_xNumFldBitmap->connect_value_changed( LINK( this, AnimationWindow, ModifyBitmapHdl ) );
|
|
m_xTimeField->connect_value_changed( LINK( this, AnimationWindow, ModifyTimeHdl ) );
|
|
|
|
SetMinOutputSizePixel(GetOptimalSize());
|
|
|
|
ResetAttrs();
|
|
|
|
// the animator is empty; no animation group can be created
|
|
m_xBtnCreateGroup->set_sensitive(false);
|
|
}
|
|
|
|
AnimationWindow::~AnimationWindow()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void AnimationWindow::dispose()
|
|
{
|
|
pControllerItem.reset();
|
|
|
|
m_FrameList.clear();
|
|
m_nCurrentFrame = EMPTY_FRAMELIST;
|
|
|
|
// delete the clones
|
|
pMyDoc.reset();
|
|
|
|
m_xCtlDisplayWin.reset();
|
|
m_xCtlDisplay.reset();
|
|
m_xBtnFirst.reset();
|
|
m_xBtnReverse.reset();
|
|
m_xBtnStop.reset();
|
|
m_xBtnPlay.reset();
|
|
m_xBtnLast.reset();
|
|
m_xNumFldBitmap.reset();
|
|
m_xFormatter.reset();
|
|
m_xTimeField.reset();
|
|
m_xLbLoopCount.reset();
|
|
m_xBtnGetOneObject.reset();
|
|
m_xBtnGetAllObjects.reset();
|
|
m_xBtnRemoveBitmap.reset();
|
|
m_xBtnRemoveAll.reset();
|
|
m_xFiCount.reset();
|
|
m_xRbtGroup.reset();
|
|
m_xRbtBitmap.reset();
|
|
m_xFtAdjustment.reset();
|
|
m_xLbAdjustment.reset();
|
|
m_xBtnCreateGroup.reset();
|
|
m_xBtnHelp.reset();
|
|
SfxDockingWindow::dispose();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ClickFirstHdl, weld::Button&, void)
|
|
{
|
|
m_nCurrentFrame = (m_FrameList.empty()) ? EMPTY_FRAMELIST : 0;
|
|
UpdateControl();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ClickStopHdl, weld::Button&, void)
|
|
{
|
|
bMovie = false;
|
|
}
|
|
|
|
IMPL_LINK( AnimationWindow, ClickPlayHdl, weld::Button&, rButton, void )
|
|
{
|
|
ScopeLockGuard aGuard( maPlayLock );
|
|
|
|
bMovie = true;
|
|
bool bDisableCtrls = false;
|
|
size_t const nCount = m_FrameList.size();
|
|
bool bReverse = &rButton == m_xBtnReverse.get();
|
|
|
|
// it is difficult to find it later on
|
|
bool bRbtGroupEnabled = m_xRbtGroup->get_sensitive();
|
|
bool bBtnGetAllObjectsEnabled = m_xBtnGetAllObjects->get_sensitive();
|
|
bool bBtnGetOneObjectEnabled = m_xBtnGetOneObject->get_sensitive();
|
|
|
|
// calculate overall time
|
|
::tools::Long nFullTime;
|
|
if( m_xRbtBitmap->get_active() )
|
|
{
|
|
::tools::Time aTime(::tools::Time::EMPTY);
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
aTime += m_FrameList[i].second;
|
|
}
|
|
nFullTime = aTime.GetMSFromTime();
|
|
}
|
|
else
|
|
{
|
|
nFullTime = nCount * 100;
|
|
}
|
|
|
|
// StatusBarManager from 1 second
|
|
std::unique_ptr<SfxProgress> pProgress;
|
|
if( nFullTime >= 1000 )
|
|
{
|
|
bDisableCtrls = true;
|
|
m_xBtnStop->set_sensitive(true);
|
|
pProgress.reset(new SfxProgress( nullptr, u"Animator:"_ustr, nFullTime )); // "Animator:" here we should think about something smart
|
|
}
|
|
|
|
sal_uLong nTmpTime = 0;
|
|
size_t i = 0;
|
|
bool bCount = i < nCount;
|
|
if (bCount)
|
|
{
|
|
if( bReverse )
|
|
i = nCount - 1;
|
|
|
|
while (bMovie)
|
|
{
|
|
// make list and view consistent
|
|
assert(i < m_FrameList.size());
|
|
m_nCurrentFrame = i;
|
|
|
|
UpdateControl(bDisableCtrls);
|
|
|
|
if( m_xRbtBitmap->get_active() )
|
|
{
|
|
::tools::Time const & rTime = m_FrameList[i].second;
|
|
|
|
m_xFormatter->SetTime( rTime );
|
|
sal_uLong nTime = rTime.GetMSFromTime();
|
|
|
|
WaitInEffect( nTime, nTmpTime, pProgress.get() );
|
|
nTmpTime += nTime;
|
|
}
|
|
else
|
|
{
|
|
WaitInEffect( 100, nTmpTime, pProgress.get() );
|
|
nTmpTime += 100;
|
|
}
|
|
if( bReverse )
|
|
{
|
|
if (i == 0)
|
|
{
|
|
// Terminate loop.
|
|
bCount = false;
|
|
}
|
|
else
|
|
{
|
|
--i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
if (i >= nCount)
|
|
{
|
|
// Terminate loop.
|
|
bCount = false;
|
|
// Move i back into valid range.
|
|
i = nCount - 1;
|
|
}
|
|
}
|
|
|
|
if (!bCount)
|
|
break;
|
|
}
|
|
}
|
|
|
|
// to re-enable the controls
|
|
bMovie = false;
|
|
if (nCount > 0)
|
|
{
|
|
assert(i == m_nCurrentFrame);
|
|
UpdateControl();
|
|
}
|
|
|
|
if( pProgress )
|
|
{
|
|
pProgress.reset();
|
|
m_xBtnStop->set_sensitive(false);
|
|
}
|
|
|
|
m_xRbtGroup->set_sensitive( bRbtGroupEnabled );
|
|
m_xBtnGetAllObjects->set_sensitive( bBtnGetAllObjectsEnabled );
|
|
m_xBtnGetOneObject->set_sensitive( bBtnGetOneObjectEnabled );
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ClickLastHdl, weld::Button&, void)
|
|
{
|
|
m_nCurrentFrame =
|
|
(m_FrameList.empty()) ? EMPTY_FRAMELIST : m_FrameList.size() - 1 ;
|
|
UpdateControl();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ClickRbtHdl, weld::Toggleable&, void)
|
|
{
|
|
if (m_FrameList.empty() || m_xRbtGroup->get_active())
|
|
{
|
|
m_xTimeField->set_text( OUString() );
|
|
m_xTimeField->set_sensitive( false );
|
|
m_xLbLoopCount->set_sensitive( false );
|
|
}
|
|
else if (m_xRbtBitmap->get_active())
|
|
{
|
|
sal_uLong n = m_xNumFldBitmap->get_value();
|
|
if( n > 0 )
|
|
{
|
|
::tools::Time const & rTime = m_FrameList[n - 1].second;
|
|
m_xFormatter->SetTime( rTime );
|
|
m_xFormatter->ReFormat();
|
|
}
|
|
m_xTimeField->set_sensitive(true);
|
|
m_xLbLoopCount->set_sensitive(true);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(AnimationWindow, ClickHelpHdl, weld::Button&, rButton, void)
|
|
{
|
|
if (Help* pHelp = Application::GetHelp())
|
|
pHelp->Start(m_xContainer->get_help_id(), &rButton);
|
|
}
|
|
|
|
IMPL_LINK( AnimationWindow, ClickGetObjectHdl, weld::Button&, rBtn, void )
|
|
{
|
|
bAllObjects = &rBtn == m_xBtnGetAllObjects.get();
|
|
|
|
// Code now in AddObj()
|
|
SfxBoolItem aItem( SID_ANIMATOR_ADD, true );
|
|
|
|
GetBindings().GetDispatcher()->ExecuteList(
|
|
SID_ANIMATOR_ADD, SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
|
|
}
|
|
|
|
IMPL_LINK( AnimationWindow, ClickRemoveBitmapHdl, weld::Button&, rBtn, void )
|
|
{
|
|
SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
|
|
rtl::Reference<SdrObject> pObject;
|
|
|
|
// tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access
|
|
if (&rBtn == m_xBtnRemoveBitmap.get() && EMPTY_FRAMELIST != m_nCurrentFrame)
|
|
{
|
|
m_FrameList.erase(m_FrameList.begin() + m_nCurrentFrame);
|
|
|
|
pObject = pPage->GetObj(m_nCurrentFrame);
|
|
// Through acquisition of the AnimatedGIFs, objects does not need to
|
|
// exist.
|
|
if( pObject )
|
|
{
|
|
pObject = pPage->RemoveObject(m_nCurrentFrame);
|
|
DBG_ASSERT(pObject, "Clone not found during deletion");
|
|
pObject.clear();
|
|
pPage->RecalcObjOrdNums();
|
|
}
|
|
|
|
if (m_nCurrentFrame >= m_FrameList.size())
|
|
{
|
|
// tdf#95298 last frame was deleted, try to use the one before it or go on empty state
|
|
m_nCurrentFrame = m_FrameList.empty() ? EMPTY_FRAMELIST : m_FrameList.size() - 1;
|
|
}
|
|
}
|
|
else // delete everything
|
|
{
|
|
std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(),
|
|
VclMessageType::Warning, VclButtonsType::YesNo,
|
|
SdResId(STR_ASK_DELETE_ALL_PICTURES)));
|
|
short nReturn = xWarn->run();
|
|
|
|
if( nReturn == RET_YES )
|
|
{
|
|
// clear frame list
|
|
for (size_t i = m_FrameList.size(); i > 0; )
|
|
{
|
|
--i;
|
|
pObject = pPage->GetObj( i );
|
|
if( pObject )
|
|
{
|
|
pObject = pPage->RemoveObject( i );
|
|
DBG_ASSERT(pObject, "Clone not found during deletion");
|
|
pObject.clear();
|
|
//pPage->RecalcObjOrdNums();
|
|
}
|
|
}
|
|
m_FrameList.clear();
|
|
m_nCurrentFrame = EMPTY_FRAMELIST;
|
|
}
|
|
}
|
|
|
|
// can we create an animation group
|
|
if (m_FrameList.empty())
|
|
{
|
|
m_xBtnCreateGroup->set_sensitive(false);
|
|
// if previous disabled by acquisition of AnimatedGIFs:
|
|
//m_xRbtBitmap->set_sensitive(true);
|
|
m_xRbtGroup->set_sensitive(true);
|
|
}
|
|
|
|
// calculate and set zoom for DisplayWin
|
|
Fraction aFrac(GetScale());
|
|
m_xCtlDisplay->SetScale(aFrac);
|
|
|
|
UpdateControl();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ClickCreateGroupHdl, weld::Button&, void)
|
|
{
|
|
// Code now in CreatePresObj()
|
|
SfxBoolItem aItem( SID_ANIMATOR_CREATE, true );
|
|
|
|
GetBindings().GetDispatcher()->ExecuteList(SID_ANIMATOR_CREATE,
|
|
SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem });
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ModifyBitmapHdl, weld::SpinButton&, void)
|
|
{
|
|
sal_uLong nBmp = m_xNumFldBitmap->get_value();
|
|
|
|
if (nBmp > m_FrameList.size())
|
|
{
|
|
nBmp = m_FrameList.size();
|
|
}
|
|
|
|
m_nCurrentFrame = nBmp - 1;
|
|
|
|
UpdateControl();
|
|
}
|
|
|
|
IMPL_LINK_NOARG(AnimationWindow, ModifyTimeHdl, weld::FormattedSpinButton&, void)
|
|
{
|
|
sal_uLong nPos = m_xNumFldBitmap->get_value() - 1;
|
|
|
|
::tools::Time & rTime = m_FrameList[nPos].second;
|
|
|
|
rTime = m_xFormatter->GetTime();
|
|
}
|
|
|
|
void AnimationWindow::UpdateControl(bool const bDisableCtrls)
|
|
{
|
|
// tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access
|
|
if (!m_FrameList.empty() && EMPTY_FRAMELIST != m_nCurrentFrame)
|
|
{
|
|
BitmapEx aBmp(m_FrameList[m_nCurrentFrame].first);
|
|
|
|
SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
|
|
SdrObject *const pObject = pPage->GetObj(m_nCurrentFrame);
|
|
if( pObject )
|
|
{
|
|
ScopedVclPtrInstance< VirtualDevice > pVD;
|
|
::tools::Rectangle aObjRect( pObject->GetCurrentBoundRect() );
|
|
Size aObjSize( aObjRect.GetSize() );
|
|
Point aOrigin( -aObjRect.Left(), -aObjRect.Top() );
|
|
MapMode aMap( pVD->GetMapMode() );
|
|
aMap.SetMapUnit( MapUnit::Map100thMM );
|
|
aMap.SetOrigin( aOrigin );
|
|
pVD->SetMapMode( aMap );
|
|
pVD->SetOutputSize( aObjSize );
|
|
const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
|
|
pVD->SetBackground( Wallpaper( rStyles.GetFieldColor() ) );
|
|
pVD->SetDrawMode( rStyles.GetHighContrastMode()
|
|
? sd::OUTPUT_DRAWMODE_CONTRAST
|
|
: sd::OUTPUT_DRAWMODE_COLOR );
|
|
pVD->Erase();
|
|
pObject->SingleObjectPainter( *pVD );
|
|
aBmp = pVD->GetBitmapEx( aObjRect.TopLeft(), aObjSize );
|
|
}
|
|
|
|
m_xCtlDisplay->SetBitmapEx(&aBmp);
|
|
}
|
|
else
|
|
{
|
|
m_xCtlDisplay->SetBitmapEx(nullptr);
|
|
}
|
|
|
|
m_xCtlDisplay->Invalidate();
|
|
|
|
m_xFiCount->set_label(OUString::number(
|
|
m_FrameList.size()));
|
|
|
|
if (!m_FrameList.empty() && !bMovie)
|
|
{
|
|
assert(m_nCurrentFrame != EMPTY_FRAMELIST && "only arises when m_FrameList.empty()");
|
|
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
m_xNumFldBitmap->set_value(nIndex);
|
|
|
|
// if there is at least 1 object in the list
|
|
m_xBtnFirst->set_sensitive(true);
|
|
m_xBtnReverse->set_sensitive(true);
|
|
m_xBtnPlay->set_sensitive(true);
|
|
m_xBtnLast->set_sensitive(true);
|
|
m_xNumFldBitmap->set_sensitive(true);
|
|
m_xTimeField->set_sensitive(true);
|
|
m_xLbLoopCount->set_sensitive(true);
|
|
m_xBtnRemoveBitmap->set_sensitive(true);
|
|
m_xBtnRemoveAll->set_sensitive(true);
|
|
}
|
|
else
|
|
{
|
|
// if no object is in the list
|
|
m_xBtnFirst->set_sensitive( false );
|
|
m_xBtnReverse->set_sensitive( false );
|
|
m_xBtnPlay->set_sensitive( false );
|
|
m_xBtnLast->set_sensitive( false );
|
|
m_xNumFldBitmap->set_sensitive( false );
|
|
m_xTimeField->set_sensitive( false );
|
|
m_xLbLoopCount->set_sensitive( false );
|
|
m_xBtnRemoveBitmap->set_sensitive( false );
|
|
m_xBtnRemoveAll->set_sensitive( false );
|
|
}
|
|
|
|
if( bMovie && bDisableCtrls )
|
|
{
|
|
m_xBtnGetOneObject->set_sensitive( false );
|
|
m_xBtnGetAllObjects->set_sensitive( false );
|
|
m_xRbtGroup->set_sensitive( false );
|
|
m_xRbtBitmap->set_sensitive( false );
|
|
m_xBtnCreateGroup->set_sensitive( false );
|
|
m_xFtAdjustment->set_sensitive( false );
|
|
m_xLbAdjustment->set_sensitive( false );
|
|
}
|
|
else
|
|
{
|
|
// enable 'group object' only if it is not an Animated GIF
|
|
if (m_FrameList.empty())
|
|
{
|
|
m_xRbtGroup->set_sensitive(true);
|
|
}
|
|
|
|
m_xRbtBitmap->set_sensitive(true);
|
|
m_xBtnCreateGroup->set_sensitive(!m_FrameList.empty());
|
|
m_xFtAdjustment->set_sensitive(true);
|
|
m_xLbAdjustment->set_sensitive(true);
|
|
}
|
|
|
|
ClickRbtHdl(*m_xRbtGroup);
|
|
}
|
|
|
|
void AnimationWindow::ResetAttrs()
|
|
{
|
|
m_xRbtGroup->set_active(true);
|
|
m_xLbAdjustment->set_active( BA_CENTER );
|
|
// LoopCount
|
|
m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1);
|
|
|
|
UpdateControl();
|
|
}
|
|
|
|
void AnimationWindow::WaitInEffect( sal_uLong nMilliSeconds, sal_uLong nTime,
|
|
SfxProgress* pProgress ) const
|
|
{
|
|
sal_uInt64 aEnd = ::tools::Time::GetSystemTicks() + nMilliSeconds;
|
|
sal_uInt64 aCurrent = ::tools::Time::GetSystemTicks();
|
|
while (aCurrent < aEnd)
|
|
{
|
|
aCurrent = ::tools::Time::GetSystemTicks();
|
|
|
|
if( pProgress )
|
|
pProgress->SetState( nTime + nMilliSeconds + aCurrent - aEnd );
|
|
|
|
Application::Reschedule();
|
|
|
|
if( !bMovie )
|
|
return;
|
|
}
|
|
}
|
|
|
|
Fraction AnimationWindow::GetScale()
|
|
{
|
|
Fraction aFrac;
|
|
size_t const nCount = m_FrameList.size();
|
|
if (nCount > 0)
|
|
{
|
|
Size aBmpSize(0, 0);
|
|
for (size_t i = 0; i < nCount; i++)
|
|
{
|
|
BitmapEx const & rBitmap = m_FrameList[i].first;
|
|
Size aTempSize( rBitmap.GetBitmap().GetSizePixel() );
|
|
aBmpSize.setWidth( std::max( aBmpSize.Width(), aTempSize.Width() ) );
|
|
aBmpSize.setHeight( std::max( aBmpSize.Height(), aTempSize.Height() ) );
|
|
}
|
|
|
|
aBmpSize.AdjustWidth(10 );
|
|
aBmpSize.AdjustHeight(10 );
|
|
|
|
Size aDisplaySize(m_xCtlDisplay->GetOutputSizePixel());
|
|
|
|
aFrac = Fraction( std::min( static_cast<double>(aDisplaySize.Width()) / static_cast<double>(aBmpSize.Width()),
|
|
static_cast<double>(aDisplaySize.Height()) / static_cast<double>(aBmpSize.Height()) ) );
|
|
}
|
|
return aFrac;
|
|
}
|
|
|
|
void AnimationWindow::Resize()
|
|
{
|
|
SfxDockingWindow::Resize();
|
|
Fraction aFrac(GetScale());
|
|
m_xCtlDisplay->SetScale(aFrac);
|
|
}
|
|
|
|
bool AnimationWindow::Close()
|
|
{
|
|
if( maPlayLock.isLocked() )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
SfxBoolItem aItem( SID_ANIMATION_OBJECTS, false );
|
|
|
|
GetBindings().GetDispatcher()->ExecuteList(
|
|
SID_ANIMATION_OBJECTS, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
|
|
{ &aItem });
|
|
|
|
SfxDockingWindow::Close();
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void AnimationWindow::AddObj (::sd::View& rView )
|
|
{
|
|
// finish text entry mode to ensure that bitmap is identical with object
|
|
if( rView.IsTextEdit() )
|
|
rView.SdrEndTextEdit();
|
|
|
|
// clone object(s) and insert the clone(s) into the list
|
|
const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
|
|
const size_t nMarkCount = rMarkList.GetMarkCount();
|
|
SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
|
|
const size_t nCloneCount = pPage->GetObjCount();
|
|
|
|
if (nMarkCount <= 0)
|
|
return;
|
|
|
|
// If it is ONE animation object or one group object, which was
|
|
// 'individually taken', we insert the objects separately
|
|
bool bAnimObj = false;
|
|
if( nMarkCount == 1 )
|
|
{
|
|
SdrMark* pMark = rMarkList.GetMark(0);
|
|
SdrObject* pObject = pMark->GetMarkedSdrObj();
|
|
SdAnimationInfo* pAnimInfo = SdDrawDocument::GetAnimationInfo( pObject );
|
|
SdrInventor nInv = pObject->GetObjInventor();
|
|
SdrObjKind nId = pObject->GetObjIdentifier();
|
|
|
|
// Animated Bitmap (GIF)
|
|
if( nInv == SdrInventor::Default && nId == SdrObjKind::Graphic && static_cast<SdrGrafObj*>( pObject )->IsAnimated() )
|
|
{
|
|
const SdrGrafObj* pGrafObj = static_cast<SdrGrafObj*>(pObject);
|
|
Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
|
|
sal_uInt16 nCount = 0;
|
|
|
|
if( aGraphic.IsAnimated() )
|
|
nCount = aGraphic.GetAnimation().Count();
|
|
|
|
if( nCount > 0 )
|
|
{
|
|
const Animation aAnimation( aGraphic.GetAnimation() );
|
|
|
|
for( sal_uInt16 i = 0; i < nCount; i++ )
|
|
{
|
|
const AnimationFrame& rAnimationFrame = aAnimation.Get( i );
|
|
|
|
// LoopCount
|
|
if( i == 0 )
|
|
{
|
|
sal_uInt32 nLoopCount = aAnimation.GetLoopCount();
|
|
|
|
if( !nLoopCount ) // endless
|
|
m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1);
|
|
else
|
|
m_xLbLoopCount->set_active_text(OUString::number( nLoopCount ) );
|
|
}
|
|
|
|
::tools::Long nTime = rAnimationFrame.mnWait;
|
|
::tools::Time aTime( 0, 0, nTime / 100, nTime % 100 );
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
m_FrameList.insert(
|
|
m_FrameList.begin() + nIndex,
|
|
::std::make_pair(rAnimationFrame.maBitmapEx, aTime));
|
|
|
|
// increment => next one inserted after this one
|
|
++m_nCurrentFrame;
|
|
}
|
|
// if an animated GIF is taken, only such one can be created
|
|
m_xRbtBitmap->set_active(true);
|
|
m_xRbtGroup->set_sensitive( false );
|
|
bAnimObj = true;
|
|
}
|
|
}
|
|
else if( bAllObjects || ( pAnimInfo && pAnimInfo->mbIsMovie ) )
|
|
{
|
|
// several objects
|
|
SdrObjList* pObjList = static_cast<SdrObjGroup*>(pObject)->GetSubList();
|
|
|
|
for (const rtl::Reference<SdrObject>& pSnapShot : *pObjList)
|
|
{
|
|
BitmapEx aBitmapEx(SdrExchangeView::GetObjGraphic(*pSnapShot).GetBitmapEx());
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
m_FrameList.insert(
|
|
m_FrameList.begin() + nIndex,
|
|
::std::make_pair(aBitmapEx, m_xFormatter->GetTime()));
|
|
|
|
// increment => next one inserted after this one
|
|
++m_nCurrentFrame;
|
|
|
|
// Clone
|
|
pPage->InsertObject(
|
|
pSnapShot->CloneSdrObject(pPage->getSdrModelFromSdrPage()).get(),
|
|
m_nCurrentFrame);
|
|
}
|
|
bAnimObj = true;
|
|
}
|
|
}
|
|
// also one single animated object
|
|
if( !bAnimObj && !( bAllObjects && nMarkCount > 1 ) )
|
|
{
|
|
BitmapEx aBitmapEx(rView.GetAllMarkedGraphic().GetBitmapEx());
|
|
|
|
::tools::Time aTime( m_xFormatter->GetTime() );
|
|
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
m_FrameList.insert(
|
|
m_FrameList.begin() + nIndex,
|
|
::std::make_pair(aBitmapEx, aTime));
|
|
}
|
|
|
|
// one single object
|
|
if( nMarkCount == 1 && !bAnimObj )
|
|
{
|
|
SdrMark* pMark = rMarkList.GetMark(0);
|
|
SdrObject* pObject = pMark->GetMarkedSdrObj();
|
|
rtl::Reference<SdrObject> pClone(pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage()));
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
pPage->InsertObject(pClone.get(), nIndex);
|
|
}
|
|
// several objects: group the clones
|
|
else if (nMarkCount > 1)
|
|
{
|
|
// take objects separately
|
|
if( bAllObjects )
|
|
{
|
|
for( size_t nObject= 0; nObject < nMarkCount; ++nObject )
|
|
{
|
|
// Clone
|
|
SdrObject* pObject(rMarkList.GetMark(nObject)->GetMarkedSdrObj());
|
|
BitmapEx aBitmapEx(SdrExchangeView::GetObjGraphic(*pObject).GetBitmapEx());
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
m_FrameList.insert(
|
|
m_FrameList.begin() + nIndex,
|
|
::std::make_pair(aBitmapEx, m_xFormatter->GetTime()));
|
|
|
|
// increment => next one inserted after this one
|
|
++m_nCurrentFrame;
|
|
|
|
pPage->InsertObject(
|
|
pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage()).get(),
|
|
m_nCurrentFrame);
|
|
}
|
|
bAnimObj = true; // that we don't change again
|
|
}
|
|
else
|
|
{
|
|
rtl::Reference<SdrObjGroup> pCloneGroup = new SdrObjGroup(rView.getSdrModelFromSdrView());
|
|
SdrObjList* pObjList = pCloneGroup->GetSubList();
|
|
|
|
for (size_t nObject= 0; nObject < nMarkCount; ++nObject)
|
|
{
|
|
pObjList->InsertObject(
|
|
rMarkList.GetMark(nObject)->GetMarkedSdrObj()->CloneSdrObject(
|
|
pPage->getSdrModelFromSdrPage()).get());
|
|
}
|
|
|
|
size_t nIndex = m_nCurrentFrame + 1;
|
|
pPage->InsertObject(pCloneGroup.get(), nIndex);
|
|
}
|
|
}
|
|
|
|
if( !bAnimObj )
|
|
{
|
|
++m_nCurrentFrame;
|
|
}
|
|
|
|
// if there was nothing in the animator before but now is something
|
|
// there, we can create an animation group
|
|
if (nCloneCount == 0 && !m_FrameList.empty())
|
|
{
|
|
m_xBtnCreateGroup->set_sensitive(true);
|
|
}
|
|
|
|
// calculate and set zoom for DisplayWin
|
|
Fraction aFrac( GetScale() );
|
|
m_xCtlDisplay->SetScale(aFrac);
|
|
|
|
UpdateControl();
|
|
}
|
|
|
|
void AnimationWindow::CreateAnimObj (::sd::View& rView )
|
|
{
|
|
vcl::Window* pOutWin = rView.GetFirstOutputDevice()->GetOwnerWindow(); // GetWin( 0 );
|
|
DBG_ASSERT( pOutWin, "Window does not exist!" );
|
|
|
|
// find window center
|
|
const MapMode aMap100( MapUnit::Map100thMM );
|
|
Size aMaxSizeLog;
|
|
Size aMaxSizePix;
|
|
Size aTemp( pOutWin->GetOutputSizePixel() );
|
|
const Point aWindowCenter( pOutWin->PixelToLogic( Point( aTemp.Width() >> 1, aTemp.Height() >> 1 ) ) );
|
|
const OutputDevice* pDefDev = Application::GetDefaultDevice();
|
|
const size_t nCount = m_FrameList.size();
|
|
BitmapAdjustment eBA = static_cast<BitmapAdjustment>(m_xLbAdjustment->get_active());
|
|
|
|
// find biggest bitmap
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
const BitmapEx& rBmpEx = m_FrameList[i].first;
|
|
const Graphic aGraphic( rBmpEx );
|
|
Size aTmpSizeLog;
|
|
const Size aTmpSizePix( rBmpEx.GetSizePixel() );
|
|
|
|
if ( aGraphic.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel )
|
|
aTmpSizeLog = pDefDev->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
|
|
else
|
|
aTmpSizeLog = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );
|
|
|
|
aMaxSizeLog.setWidth( std::max( aMaxSizeLog.Width(), aTmpSizeLog.Width() ) );
|
|
aMaxSizeLog.setHeight( std::max( aMaxSizeLog.Height(), aTmpSizeLog.Height() ) );
|
|
|
|
aMaxSizePix.setWidth( std::max( aMaxSizePix.Width(), aTmpSizePix.Width() ) );
|
|
aMaxSizePix.setHeight( std::max( aMaxSizePix.Height(), aTmpSizePix.Height() ) );
|
|
}
|
|
|
|
SdrPageView* pPV = rView.GetSdrPageView();
|
|
|
|
if( m_xRbtBitmap->get_active() )
|
|
{
|
|
// create bitmap group (Animated GIF)
|
|
Animation aAnimation;
|
|
Point aPt;
|
|
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
::tools::Time const & rTime = m_FrameList[i].second;
|
|
::tools::Long nTime = rTime.GetNanoSec();
|
|
nTime += rTime.GetSec() * 100;
|
|
|
|
BitmapEx const & rBitmapEx = m_FrameList[i].first;
|
|
|
|
// calculate offset for the specified direction
|
|
const Size aBitmapSize( rBitmapEx.GetSizePixel() );
|
|
|
|
switch( eBA )
|
|
{
|
|
case BA_LEFT_UP:
|
|
break;
|
|
|
|
case BA_LEFT:
|
|
aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
|
|
break;
|
|
|
|
case BA_LEFT_DOWN:
|
|
aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
|
|
break;
|
|
|
|
case BA_UP:
|
|
aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
|
|
break;
|
|
|
|
case BA_CENTER:
|
|
aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
|
|
aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
|
|
break;
|
|
|
|
case BA_DOWN:
|
|
aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 );
|
|
aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
|
|
break;
|
|
|
|
case BA_RIGHT_UP:
|
|
aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
|
|
break;
|
|
|
|
case BA_RIGHT:
|
|
aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
|
|
aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 );
|
|
break;
|
|
|
|
case BA_RIGHT_DOWN:
|
|
aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() );
|
|
aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() );
|
|
break;
|
|
|
|
}
|
|
|
|
// find LoopCount (number of passes)
|
|
AnimationFrame aAnimationFrame;
|
|
sal_uInt32 nLoopCount = 0;
|
|
sal_Int32 nPos = m_xLbLoopCount->get_active();
|
|
|
|
if( nPos != -1 && nPos != m_xLbLoopCount->get_count() - 1 ) // endless
|
|
nLoopCount = m_xLbLoopCount->get_active_text().toUInt32();
|
|
|
|
aAnimationFrame.maBitmapEx = rBitmapEx;
|
|
aAnimationFrame.maPositionPixel = aPt;
|
|
aAnimationFrame.maSizePixel = aBitmapSize;
|
|
aAnimationFrame.mnWait = nTime;
|
|
aAnimationFrame.meDisposal = Disposal::Back;
|
|
aAnimationFrame.mbUserInput = false;
|
|
|
|
aAnimation.Insert( aAnimationFrame );
|
|
aAnimation.SetDisplaySizePixel( aMaxSizePix );
|
|
aAnimation.SetLoopCount( nLoopCount );
|
|
}
|
|
|
|
rtl::Reference<SdrGrafObj> pGrafObj = new SdrGrafObj(
|
|
rView.getSdrModelFromSdrView(),
|
|
Graphic(aAnimation));
|
|
const Point aOrg( aWindowCenter.X() - ( aMaxSizeLog.Width() >> 1 ), aWindowCenter.Y() - ( aMaxSizeLog.Height() >> 1 ) );
|
|
|
|
pGrafObj->SetLogicRect( ::tools::Rectangle( aOrg, aMaxSizeLog ) );
|
|
rView.InsertObjectAtView( pGrafObj.get(), *pPV, SdrInsertFlags::SETDEFLAYER);
|
|
}
|
|
else
|
|
{
|
|
// calculate offset for the specified direction
|
|
Size aOffset;
|
|
SdrObject * pClone = nullptr;
|
|
SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard);
|
|
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
pClone = pPage->GetObj(i);
|
|
::tools::Rectangle aRect( pClone->GetSnapRect() );
|
|
|
|
switch( eBA )
|
|
{
|
|
case BA_LEFT_UP:
|
|
break;
|
|
|
|
case BA_LEFT:
|
|
aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
|
|
break;
|
|
|
|
case BA_LEFT_DOWN:
|
|
aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
|
|
break;
|
|
|
|
case BA_UP:
|
|
aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
|
|
break;
|
|
|
|
case BA_CENTER:
|
|
aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
|
|
aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
|
|
break;
|
|
|
|
case BA_DOWN:
|
|
aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 );
|
|
aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
|
|
break;
|
|
|
|
case BA_RIGHT_UP:
|
|
aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
|
|
break;
|
|
|
|
case BA_RIGHT:
|
|
aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
|
|
aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 );
|
|
break;
|
|
|
|
case BA_RIGHT_DOWN:
|
|
aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() );
|
|
aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() );
|
|
break;
|
|
|
|
}
|
|
// Unfortunately, SetSnapRect is not implemented for ellipses !!!
|
|
Point aMovePt( aWindowCenter + Point( aOffset.Width(), aOffset.Height() ) - aRect.TopLeft() );
|
|
Size aMoveSize( aMovePt.X(), aMovePt.Y() );
|
|
pClone->NbcMove( aMoveSize );
|
|
}
|
|
|
|
// #i42894# Caution(!) variable pPage looks right, but it is a page from the local
|
|
// document the dialog is using (!), so get the target page from the target view
|
|
SdPage* pTargetSdPage = dynamic_cast< SdPage* >(rView.GetSdrPageView() ? rView.GetSdrPageView()->GetPage() : nullptr);
|
|
|
|
if(pTargetSdPage)
|
|
{
|
|
// create animation group
|
|
rtl::Reference<SdrObjGroup> pGroup = new SdrObjGroup(rView.getSdrModelFromSdrView());
|
|
SdrObjList* pObjList = pGroup->GetSubList();
|
|
|
|
for (size_t i = 0; i < nCount; ++i)
|
|
{
|
|
// the clone remains in the animation; we insert a clone of the
|
|
// clone into the group
|
|
pClone = pPage->GetObj(i);
|
|
rtl::Reference<SdrObject> pCloneOfClone(pClone->CloneSdrObject(pTargetSdPage->getSdrModelFromSdrPage()));
|
|
//SdrObject* pCloneOfClone = pPage->GetObj(i)->Clone();
|
|
pObjList->InsertObject(pCloneOfClone.get());
|
|
}
|
|
|
|
// until now the top left corner of the group is in the window center;
|
|
// correct the position by half of the size of the group
|
|
aTemp = aMaxSizeLog;
|
|
aTemp.setHeight( - aTemp.Height() / 2 );
|
|
aTemp.setWidth( - aTemp.Width() / 2 );
|
|
pGroup->NbcMove(aTemp);
|
|
|
|
// #i42894# create needed SMIL stuff and move child objects to page directly (see
|
|
// comments at EffectMigration::CreateAnimatedGroup why this has to be done).
|
|
EffectMigration::CreateAnimatedGroup(*pGroup, *pTargetSdPage);
|
|
}
|
|
}
|
|
|
|
ClickFirstHdl(*m_xBtnFirst);
|
|
}
|
|
|
|
void AnimationWindow::DataChanged( const DataChangedEvent& rDCEvt )
|
|
{
|
|
SfxDockingWindow::DataChanged( rDCEvt );
|
|
|
|
if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
|
|
{
|
|
UpdateControl();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ControllerItem for Animator
|
|
*/
|
|
AnimationControllerItem::AnimationControllerItem(
|
|
sal_uInt16 _nId,
|
|
AnimationWindow* pAnimWin,
|
|
SfxBindings* _pBindings)
|
|
: SfxControllerItem( _nId, *_pBindings ),
|
|
pAnimationWin( pAnimWin )
|
|
{
|
|
}
|
|
|
|
void AnimationControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId,
|
|
SfxItemState eState, const SfxPoolItem* pItem )
|
|
{
|
|
if( eState >= SfxItemState::DEFAULT && nSId == SID_ANIMATOR_STATE )
|
|
{
|
|
const SfxUInt16Item* pStateItem = dynamic_cast< const SfxUInt16Item*>( pItem );
|
|
assert(pStateItem); //SfxUInt16Item expected
|
|
if (pStateItem)
|
|
{
|
|
sal_uInt16 nState = pStateItem->GetValue();
|
|
pAnimationWin->m_xBtnGetOneObject->set_sensitive( nState & 1 );
|
|
pAnimationWin->m_xBtnGetAllObjects->set_sensitive( nState & 2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
} // end of namespace sd
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|