Kaydet (Commit) c0ff8a24 authored tarafından Brian Fraser's avatar Brian Fraser Kaydeden (comit) Jim Raykowski

Impress: Delete an empty paragraph's animation over a non-empty one's

- Backspacing into empty paragraph deletes empty paragraph's animation,
  not the next paragraph's animation.
- Pressing delete while in empty paragraph deletes its animation, not next
  paragraph's animation.
- Changing indent level of an animated paragraph no longer collapses any
  expanded animations in the animation list side panel.

Change-Id: I65ff5813893b1ffe91687cc106f276447de4b225
Reviewed-on: https://gerrit.libreoffice.org/70792
Tested-by: Jenkins
Reviewed-by: 's avatarJim Raykowski <raykowj@gmail.com>
üst db393365
......@@ -2176,6 +2176,39 @@ void EffectSequenceHelper::insertTextRange( const css::uno::Any& aTarget )
rebuild();
}
static bool isParagraphTargetTextEmpty( ParagraphTarget aParaTarget )
{
// get paragraph
Reference< XText > xText ( aParaTarget.Shape, UNO_QUERY );
if( xText.is() )
{
Reference< XEnumerationAccess > xEA( xText, UNO_QUERY );
if( xEA.is() )
{
Reference< XEnumeration > xEnumeration( xEA->createEnumeration(), UNO_QUERY );
if( xEnumeration.is() )
{
// advance to the Nth paragraph
sal_Int32 nPara = aParaTarget.Paragraph;
while( xEnumeration->hasMoreElements() && nPara-- )
xEnumeration->nextElement();
// get Nth paragraph's text and check if it's empty
if( xEnumeration->hasMoreElements() )
{
Reference< XTextRange > xRange( xEnumeration->nextElement(), UNO_QUERY );
if( xRange.is() )
{
OUString text = xRange->getString();
return text.isEmpty();
}
}
}
}
}
return false;
}
void EffectSequenceHelper::disposeTextRange( const css::uno::Any& aTarget )
{
ParagraphTarget aParaTarget;
......@@ -2183,49 +2216,67 @@ void EffectSequenceHelper::disposeTextRange( const css::uno::Any& aTarget )
return;
bool bChanges = false;
bool bErased = false;
EffectSequence::iterator aIter( maEffects.begin() );
while( aIter != maEffects.end() )
// building list of effects for target shape; process effects not on target shape
EffectSequence aTargetParagraphEffects;
for( const auto &pEffect : maEffects )
{
Any aIterTarget( (*aIter)->getTarget() );
Any aIterTarget( pEffect->getTarget() );
if( aIterTarget.getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
{
ParagraphTarget aIterParaTarget;
if( (aIterTarget >>= aIterParaTarget) && (aIterParaTarget.Shape == aParaTarget.Shape) )
{
if( aIterParaTarget.Paragraph == aParaTarget.Paragraph )
{
// delete this effect if it targets the disposed paragraph directly
(*aIter)->setEffectSequence( nullptr );
aIter = maEffects.erase( aIter );
bChanges = true;
bErased = true;
}
else
{
if( aIterParaTarget.Paragraph > aParaTarget.Paragraph )
{
// shift all paragraphs after disposed paragraph
aIterParaTarget.Paragraph--;
(*aIter)->setTarget( makeAny( aIterParaTarget ) );
}
}
aTargetParagraphEffects.push_back(pEffect);
}
}
else if( (*aIter)->getTargetShape() == aParaTarget.Shape )
else if( pEffect->getTargetShape() == aParaTarget.Shape )
{
bChanges |= (*aIter)->checkForText();
bChanges |= pEffect->checkForText();
}
}
if( bErased )
bErased = false;
else
++aIter;
// select effect to delete:
// if paragraph before target is blank, then delete its animation effect (if any) instead
ParagraphTarget aPreviousParagraph = aParaTarget;
--aPreviousParagraph.Paragraph;
bool bIsPreviousParagraphEmpty = isParagraphTargetTextEmpty( aPreviousParagraph );
sal_Int16 anParaNumToDelete = bIsPreviousParagraphEmpty ? aPreviousParagraph.Paragraph : aParaTarget.Paragraph;
// update effects
for( const auto &pEffect : aTargetParagraphEffects )
{
Any aIterTarget( pEffect->getTarget() );
ParagraphTarget aIterParaTarget;
aIterTarget >>= aIterParaTarget;
// delete effect for target paragraph (may have effects in more than one text group)
if( aIterParaTarget.Paragraph == anParaNumToDelete )
{
auto aItr = find( pEffect );
DBG_ASSERT( aItr != maEffects.end(), "sd::EffectSequenceHelper::disposeTextRange(), Expected effect missing.");
if( aItr != maEffects.end() )
{
(*aItr)->setEffectSequence( nullptr );
maEffects.erase(aItr);
bChanges = true;
}
}
// shift all paragraphs after disposed paragraph
if( aIterParaTarget.Paragraph > anParaNumToDelete )
{
--aIterParaTarget.Paragraph;
pEffect->setTarget( makeAny( aIterParaTarget ) );
bChanges = true;
}
}
if( bChanges )
{
rebuild();
}
}
CustomAnimationTextGroup::CustomAnimationTextGroup( const Reference< XShape >& rTarget, sal_Int32 nGroupId )
......@@ -3246,7 +3297,7 @@ void EffectSequenceHelper::onTextChanged( const Reference< XShape >& xShape )
});
if( bChanges )
EffectSequenceHelper::implRebuild();
rebuild();
}
void MainSequence::rebuild()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment