1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_sd.hxx" 24 #include <com/sun/star/presentation/EffectNodeType.hpp> 25 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp> 26 #include <com/sun/star/presentation/TextAnimationType.hpp> 27 #include <com/sun/star/presentation/ParagraphTarget.hpp> 28 #include <com/sun/star/animations/Event.hpp> 29 #include <com/sun/star/animations/EventTrigger.hpp> 30 #include <com/sun/star/animations/Timing.hpp> 31 #include <comphelper/processfactory.hxx> 32 #include <com/sun/star/animations/AnimationFill.hpp> 33 #include <com/sun/star/animations/XAnimate.hpp> 34 #include <com/sun/star/beans/NamedValue.hpp> 35 #include <svx/unoshape.hxx> 36 #include <svx/svdotext.hxx> 37 #include <svx/svdopath.hxx> 38 #include <svx/svdogrp.hxx> 39 #include <svx/svditer.hxx> 40 #include "drawdoc.hxx" 41 #include "sdpage.hxx" 42 #include <CustomAnimationPreset.hxx> 43 #include <TransitionPreset.hxx> 44 #include <EffectMigration.hxx> 45 #include <anminfo.hxx> 46 47 using namespace ::vos; 48 using namespace ::sd; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::animations; 51 using namespace ::com::sun::star::presentation; 52 using ::com::sun::star::drawing::XShape; 53 using ::rtl::OUString; 54 using ::com::sun::star::lang::XMultiServiceFactory; 55 using ::com::sun::star::drawing::XShape; 56 using ::com::sun::star::beans::NamedValue; 57 58 struct deprecated_FadeEffect_conversion_table_entry 59 { 60 FadeEffect meFadeEffect; 61 const sal_Char* mpPresetId; 62 } 63 64 deprecated_FadeEffect_conversion_table[] = 65 { 66 // OOo 1.x transitions 67 { FadeEffect_FADE_FROM_LEFT, "wipe-right" }, 68 { FadeEffect_FADE_FROM_TOP, "wipe-down" }, 69 { FadeEffect_FADE_FROM_RIGHT, "wipe-left" }, 70 { FadeEffect_FADE_FROM_BOTTOM, "wipe-up" }, 71 72 { FadeEffect_CLOCKWISE, "wheel-clockwise-1-spoke" }, 73 74 { FadeEffect_UNCOVER_TO_LEFT, "uncover-left" }, 75 { FadeEffect_UNCOVER_TO_UPPERLEFT, "uncover-left-up" }, 76 { FadeEffect_UNCOVER_TO_TOP, "uncover-up" }, 77 { FadeEffect_UNCOVER_TO_UPPERRIGHT, "uncover-right-up" }, 78 { FadeEffect_UNCOVER_TO_RIGHT, "uncover-right" }, 79 { FadeEffect_UNCOVER_TO_LOWERRIGHT, "uncover-right-down" }, 80 { FadeEffect_UNCOVER_TO_BOTTOM, "uncover-down" }, 81 { FadeEffect_UNCOVER_TO_LOWERLEFT, "uncover-left-down" }, 82 83 { FadeEffect_VERTICAL_LINES, "random-bars-vertical" }, 84 { FadeEffect_HORIZONTAL_LINES, "random-bars-horizontal" }, 85 86 { FadeEffect_VERTICAL_CHECKERBOARD, "checkerboard-down" }, 87 { FadeEffect_HORIZONTAL_CHECKERBOARD, "checkerboard-across" }, 88 89 { FadeEffect_FADE_TO_CENTER, "box-in" }, 90 { FadeEffect_FADE_FROM_CENTER, "box-out" }, 91 92 { FadeEffect_VERTICAL_STRIPES, "venetian-blinds-vertical" }, 93 { FadeEffect_HORIZONTAL_STRIPES, "venetian-blinds-horizontal" }, 94 95 { FadeEffect_MOVE_FROM_LEFT, "cover-right" }, 96 { FadeEffect_MOVE_FROM_TOP, "cover-down" }, 97 { FadeEffect_MOVE_FROM_RIGHT, "cover-left" }, 98 { FadeEffect_MOVE_FROM_BOTTOM, "cover-up" }, 99 { FadeEffect_MOVE_FROM_UPPERLEFT, "cover-right-down" }, 100 { FadeEffect_MOVE_FROM_UPPERRIGHT, "cover-left-down" }, 101 { FadeEffect_MOVE_FROM_LOWERRIGHT, "cover-left-up" }, 102 { FadeEffect_MOVE_FROM_LOWERLEFT, "cover-right-up" }, 103 104 { FadeEffect_DISSOLVE, "dissolve" }, 105 106 { FadeEffect_RANDOM, "random-transition" }, 107 108 { FadeEffect_ROLL_FROM_LEFT, "push-right" }, 109 { FadeEffect_ROLL_FROM_TOP, "push-down" }, 110 { FadeEffect_ROLL_FROM_RIGHT, "push-left" }, 111 { FadeEffect_ROLL_FROM_BOTTOM, "push-up" }, 112 113 { FadeEffect_CLOSE_VERTICAL, "split-horizontal-in" }, 114 { FadeEffect_CLOSE_HORIZONTAL, "split-vertical-in" }, 115 { FadeEffect_OPEN_VERTICAL, "split-horizontal-out" }, 116 { FadeEffect_OPEN_HORIZONTAL, "split-vertical-out" }, 117 118 { FadeEffect_FADE_FROM_UPPERLEFT, "diagonal-squares-right-down" }, 119 { FadeEffect_FADE_FROM_UPPERRIGHT, "diagonal-squares-left-down" }, 120 { FadeEffect_FADE_FROM_LOWERLEFT, "diagonal-squares-right-up" }, 121 { FadeEffect_FADE_FROM_LOWERRIGHT, "diagonal-squares-left-up" }, 122 123 // OOo 1.x transitions not in OOo 2.x 124 { FadeEffect_CLOCKWISE, "clock-wipe-twelve" }, 125 { FadeEffect_COUNTERCLOCKWISE, "reverse-clock-wipe-twelve" }, 126 { FadeEffect_SPIRALIN_LEFT, "spiral-wipe-top-left-clockwise" }, 127 { FadeEffect_SPIRALIN_RIGHT, "spiral-wipe-top-right-counter-clockwise" }, 128 { FadeEffect_SPIRALOUT_LEFT, "spiral-wipe-out-to-bottom-right-clockwise" }, 129 { FadeEffect_SPIRALOUT_RIGHT, "spiral-wipe-out-to-bottom-left-counter-clockwise" }, 130 { FadeEffect_WAVYLINE_FROM_LEFT, "snake-wipe-top-left-vertical" }, 131 { FadeEffect_WAVYLINE_FROM_TOP, "snake-wipe-top-left-horizontal" }, 132 { FadeEffect_WAVYLINE_FROM_RIGHT, "snake-wipe-bottom-right-vertical" }, 133 { FadeEffect_WAVYLINE_FROM_BOTTOM, "snake-wipe-bottom-right-horizontal" }, 134 { FadeEffect_STRETCH_FROM_LEFT, "wipe-right" }, // todo 135 { FadeEffect_STRETCH_FROM_TOP, "wipe-down" }, // todo 136 { FadeEffect_STRETCH_FROM_RIGHT, "wipe-left" }, // todo 137 { FadeEffect_STRETCH_FROM_BOTTOM, "wipe-up" }, // todo 138 139 // OOo 1.x not available transitions 140 141 { FadeEffect_CLOCKWISE, "wheel-clockwise-2-spokes" }, 142 { FadeEffect_CLOCKWISE, "wheel-clockwise-3-spokes" }, 143 { FadeEffect_CLOCKWISE, "wheel-clockwise-4-spokes" }, 144 { FadeEffect_CLOCKWISE, "wheel-clockwise-8-spokes" }, 145 146 { FadeEffect_FADE_FROM_CENTER, "shape-circle" }, 147 { FadeEffect_FADE_FROM_CENTER, "shape-diamond" }, 148 { FadeEffect_FADE_FROM_CENTER, "shape-plus" }, 149 150 { FadeEffect_CLOCKWISE, "wedge" }, 151 152 { FadeEffect_DISSOLVE, "fade-through-black" }, 153 154 { FadeEffect_CLOCKWISE, "zoom-rotate-in" }, 155 156 { FadeEffect_HORIZONTAL_LINES, "comb-horizontal" }, 157 { FadeEffect_VERTICAL_LINES, "comb-vertical" }, 158 159 { FadeEffect_DISSOLVE, "fade-smoothly" }, 160 161 { FadeEffect_NONE, 0 } 162 }; 163 164 /* todo 165 cut cut (same as NONE?) 166 cut-through-black cut toBlack 167 wedge wedge 168 */ 169 170 void EffectMigration::SetFadeEffect( SdPage* pPage, ::com::sun::star::presentation::FadeEffect eNewEffect) 171 { 172 deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table; 173 while( (pEntry->meFadeEffect != FadeEffect_NONE) && (pEntry->meFadeEffect != eNewEffect) ) 174 pEntry++; 175 176 if( pEntry->mpPresetId ) 177 { 178 const OUString aPresetId( OUString::createFromAscii( pEntry->mpPresetId ) ); 179 180 const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList(); 181 182 TransitionPresetList::const_iterator aIt( rPresetList.begin()); 183 const TransitionPresetList::const_iterator aEndIt( rPresetList.end()); 184 for( ; aIt != aEndIt; ++aIt ) 185 { 186 if( (*aIt)->getPresetId() == aPresetId) 187 { 188 pPage->setTransitionType( (*aIt)->getTransition() ); 189 pPage->setTransitionSubtype( (*aIt)->getSubtype() ); 190 pPage->setTransitionDirection( (*aIt)->getDirection() ); 191 pPage->setTransitionFadeColor( (*aIt)->getFadeColor() ); 192 break; 193 } 194 } 195 } 196 else 197 { 198 pPage->setTransitionType( 0 ); 199 pPage->setTransitionSubtype( 0 ); 200 pPage->setTransitionDirection( 0 ); 201 pPage->setTransitionFadeColor( 0 ); 202 } 203 } 204 205 FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage ) 206 { 207 const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList(); 208 TransitionPresetList::const_iterator aIt( rPresetList.begin()); 209 const TransitionPresetList::const_iterator aEndIt( rPresetList.end()); 210 for( ; aIt != aEndIt; ++aIt ) 211 { 212 if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) && 213 ( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) && 214 ( (*aIt)->getDirection() == pPage->getTransitionDirection() ) && 215 ( (*aIt)->getFadeColor() == pPage->getTransitionFadeColor() ) ) 216 { 217 const OUString& aPresetId = (*aIt)->getPresetId(); 218 219 deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table; 220 while( (pEntry->meFadeEffect != FadeEffect_NONE) && (!aPresetId.equalsAscii( pEntry->mpPresetId ) ) ) 221 pEntry++; 222 223 return pEntry->meFadeEffect; 224 } 225 } 226 return FadeEffect_NONE; 227 } 228 229 struct deprecated_AnimationEffect_conversion_table_entry 230 { 231 AnimationEffect meEffect; 232 const sal_Char* mpPresetId; 233 const sal_Char* mpPresetSubType; 234 } 235 deprecated_AnimationEffect_conversion_table[] = 236 { 237 // OOo 1.x entrance effects 238 { AnimationEffect_APPEAR, "ooo-entrance-appear",0 }, 239 240 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-box","in" }, 241 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-box","out" }, 242 243 { AnimationEffect_VERTICAL_CHECKERBOARD, "ooo-entrance-checkerboard","downward" }, 244 { AnimationEffect_HORIZONTAL_CHECKERBOARD, "ooo-entrance-checkerboard","across" }, 245 246 { AnimationEffect_FADE_FROM_UPPERLEFT, "ooo-entrance-diagonal-squares","right-to-bottom" }, 247 { AnimationEffect_FADE_FROM_UPPERRIGHT, "ooo-entrance-diagonal-squares","left-to-bottom" }, 248 { AnimationEffect_FADE_FROM_LOWERLEFT, "ooo-entrance-diagonal-squares","right-to-top" }, 249 { AnimationEffect_FADE_FROM_LOWERRIGHT, "ooo-entrance-diagonal-squares","left-to-top" }, 250 251 { AnimationEffect_DISSOLVE, "ooo-entrance-dissolve-in",0 }, 252 253 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in","from-left" }, 254 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in","from-top" }, 255 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in","from-right" }, 256 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" }, 257 { AnimationEffect_MOVE_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" }, 258 { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" }, 259 { AnimationEffect_MOVE_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" }, 260 { AnimationEffect_MOVE_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" }, 261 262 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in-slow", "from-bottom" }, 263 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in-slow", "from-left" }, 264 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in-slow", "from-right" }, 265 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in-slow", "from-top" }, 266 267 { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-peek-in","from-left" }, 268 { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-peek-in","from-top" }, 269 { AnimationEffect_MOVE_SHORT_FROM_RIGHT, "ooo-entrance-peek-in","from-right" }, 270 { AnimationEffect_MOVE_SHORT_FROM_BOTTOM, "ooo-entrance-peek-in","from-bottom" }, 271 272 { AnimationEffect_VERTICAL_LINES, "ooo-entrance-random-bars","horizontal" }, 273 { AnimationEffect_HORIZONTAL_LINES, "ooo-entrance-random-bars","vertical" }, 274 275 { AnimationEffect_RANDOM, "ooo-entrance-random",0 }, 276 277 { AnimationEffect_CLOSE_VERTICAL, "ooo-entrance-split","horizontal-in" }, 278 { AnimationEffect_CLOSE_HORIZONTAL, "ooo-entrance-split","vertical-in" }, 279 { AnimationEffect_OPEN_VERTICAL, "ooo-entrance-split","horizontal-out" }, 280 { AnimationEffect_OPEN_HORIZONTAL, "ooo-entrance-split","vertical-out" }, 281 282 { AnimationEffect_VERTICAL_STRIPES, "ooo-entrance-venetian-blinds","horizontal" }, 283 { AnimationEffect_HORIZONTAL_STRIPES, "ooo-entrance-venetian-blinds","vertical" }, 284 285 { AnimationEffect_FADE_FROM_LEFT, "ooo-entrance-wipe","from-left" }, 286 { AnimationEffect_FADE_FROM_TOP, "ooo-entrance-wipe","from-bottom" }, 287 { AnimationEffect_FADE_FROM_RIGHT, "ooo-entrance-wipe","from-right" }, 288 { AnimationEffect_FADE_FROM_BOTTOM, "ooo-entrance-wipe","from-top" }, 289 290 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-swivel","vertical" }, 291 { AnimationEffect_VERTICAL_ROTATE, "ooo-entrance-swivel","horizontal" }, 292 293 { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy","from-left" }, 294 { AnimationEffect_STRETCH_FROM_UPPERLEFT, "ooo-entrance-stretchy","from-top-left" }, 295 { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy","from-top" }, 296 { AnimationEffect_STRETCH_FROM_UPPERRIGHT, "ooo-entrance-stretchy","from-top-right" }, 297 { AnimationEffect_STRETCH_FROM_RIGHT, "ooo-entrance-stretchy","from-right" }, 298 { AnimationEffect_STRETCH_FROM_LOWERRIGHT, "ooo-entrance-stretchy","from-bottom-right" }, 299 { AnimationEffect_STRETCH_FROM_BOTTOM, "ooo-entrance-stretchy","from-bottom" }, 300 { AnimationEffect_STRETCH_FROM_LOWERLEFT, "ooo-entrance-stretchy","from-bottom-left" }, 301 302 { AnimationEffect_HORIZONTAL_STRETCH, "ooo-entrance-expand", 0 }, 303 304 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel","1" }, 305 { AnimationEffect_COUNTERCLOCKWISE, "ooo-entrance-clock-wipe","counter-clockwise" }, 306 307 { AnimationEffect_SPIRALIN_LEFT, "ooo-entrance-spiral-wipe", "from-top-left-clockwise" }, 308 { AnimationEffect_SPIRALIN_RIGHT, "ooo-entrance-spiral-wipe", "from-top-right-counter-clockwise" }, 309 { AnimationEffect_SPIRALOUT_LEFT, "ooo-entrance-spiral-wipe", "from-center-clockwise" }, 310 { AnimationEffect_SPIRALOUT_RIGHT, "ooo-entrance-spiral-wipe", "from-center-counter-clockwise" }, 311 312 { AnimationEffect_WAVYLINE_FROM_LEFT, "ooo-entrance-snake-wipe","from-top-left-vertical" }, 313 { AnimationEffect_WAVYLINE_FROM_TOP, "ooo-entrance-snake-wipe","from-top-left-horizontal" }, 314 { AnimationEffect_WAVYLINE_FROM_RIGHT, "ooo-entrance-snake-wipe","from-bottom-right-vertical" }, 315 { AnimationEffect_WAVYLINE_FROM_BOTTOM, "ooo-entrance-snake-wipe","from-bottom-right-horizontal" }, 316 317 // ooo 1.x exit effects 318 { AnimationEffect_HIDE, "ooo-exit-disappear",0 }, 319 { AnimationEffect_MOVE_TO_LEFT, "ooo-exit-fly-out", "from-right" }, 320 { AnimationEffect_MOVE_TO_TOP, "ooo-exit-fly-out", "from-bottom" }, 321 { AnimationEffect_MOVE_TO_RIGHT, "ooo-exit-fly-out", "from-left" }, 322 { AnimationEffect_MOVE_TO_BOTTOM, "ooo-exit-fly-out", "from-top" }, 323 { AnimationEffect_MOVE_TO_UPPERLEFT, "ooo-exit-fly-out", "from-top-right" }, 324 { AnimationEffect_MOVE_TO_UPPERRIGHT, "ooo-exit-fly-out", "from-top-left" }, 325 { AnimationEffect_MOVE_TO_LOWERRIGHT, "ooo-exit-fly-out", "from-bottom-left" }, 326 { AnimationEffect_MOVE_TO_LOWERLEFT, "ooo-exit-fly-out", "from-bottom-right" }, 327 { AnimationEffect_MOVE_SHORT_TO_LEFT, "ooo-exit-peek-out", "from-right" }, 328 { AnimationEffect_MOVE_SHORT_TO_UPPERLEFT, "ooo-exit-peek-out", "from-right" }, 329 { AnimationEffect_MOVE_SHORT_TO_TOP, "ooo-exit-peek-out", "from-bottom" }, 330 { AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT, "ooo-exit-peek-out", "from-bottom" }, 331 { AnimationEffect_MOVE_SHORT_TO_RIGHT, "ooo-exit-peek-out", "from-left" }, 332 { AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT, "ooo-exit-peek-out","from-left" }, 333 { AnimationEffect_MOVE_SHORT_TO_BOTTOM, "ooo-exit-peek-out", "from-top" }, 334 { AnimationEffect_MOVE_SHORT_TO_LOWERLEFT, "ooo-exit-peek-out", "from-top" }, 335 336 // no matching in OOo 2.x 337 { AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT, "ooo-entrance-peek-in","from-left" }, 338 { AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT, "ooo-entrance-peek-in","from-top" }, 339 { AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT, "ooo-entrance-peek-in","from-right" }, 340 { AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT, "ooo-entrance-peek-in","from-bottom" }, 341 { AnimationEffect_LASER_FROM_LEFT, "ooo-entrance-fly-in","from-left" }, 342 { AnimationEffect_LASER_FROM_TOP, "ooo-entrance-fly-in","from-top" }, 343 { AnimationEffect_LASER_FROM_RIGHT, "ooo-entrance-fly-in","from-right" }, 344 { AnimationEffect_LASER_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" }, 345 { AnimationEffect_LASER_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" }, 346 { AnimationEffect_LASER_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" }, 347 { AnimationEffect_LASER_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" }, 348 { AnimationEffect_LASER_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" }, 349 350 // no matching in OOo 1.x 351 352 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-circle", "in" }, 353 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-circle", "out" }, 354 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-diamond", "in" }, 355 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-diamond", "out" }, 356 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-plus", "in" }, 357 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-plus", "out" }, 358 { AnimationEffect_CLOCKWISE, "ooo-entrance-wedge", 0 }, 359 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "2" }, 360 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "3" }, 361 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "4" }, 362 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "8" }, 363 364 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-boomerang", 0 }, 365 { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-bounce", 0 }, 366 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-curve-up", 0 }, 367 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-float", 0 }, 368 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-glide", 0 }, 369 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-magnify", 0 }, 370 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-pinwheel", 0 }, 371 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-breaks", 0 }, 372 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-sling", 0 }, 373 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-spiral-in", 0 }, 374 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-thread", 0 }, 375 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-ascend", 0 }, 376 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-center-revolve", 0 }, 377 { AnimationEffect_APPEAR, "ooo-entrance-compress", 0 }, 378 { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-descend", 0 }, 379 { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-ease-in", 0 }, 380 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-rise-up", 0 }, 381 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-spin-in", 0 }, 382 { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy", "across" }, 383 { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy", "downward" }, 384 385 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in" }, 386 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-slightly" }, 387 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-from-screen-center" }, 388 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out" }, 389 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-slightly" }, 390 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-from-screen-center" }, 391 392 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in", 0 }, 393 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-zoom", 0 }, 394 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-swivel", 0 }, 395 396 // open 397 /* 398 { AnimationEffect_ZOOM_IN_FROM_LEFT, "ooo-entrance-zoom","in" }, 399 { AnimationEffect_ZOOM_IN_FROM_UPPERLEFT, "ooo-entrance-zoom","in" }, 400 { AnimationEffect_ZOOM_IN_FROM_TOP, "ooo-entrance-zoom","in" }, 401 { AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT, "ooo-entrance-zoom","in" }, 402 { AnimationEffect_ZOOM_IN_FROM_RIGHT, "ooo-entrance-zoom","in" }, 403 { AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT, "ooo-entrance-zoom","in" }, 404 { AnimationEffect_ZOOM_IN_FROM_BOTTOM, "ooo-entrance-zoom","in" }, 405 { AnimationEffect_ZOOM_IN_FROM_LOWERLEFT, "ooo-entrance-zoom","in" }, 406 { AnimationEffect_ZOOM_IN_FROM_CENTER, "ooo-entrance-zoom","in" }, 407 408 { AnimationEffect_ZOOM_OUT_FROM_LEFT, "ooo-entrance-appear",0 }, 409 { AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT, "ooo-entrance-appear",0 }, 410 { AnimationEffect_ZOOM_OUT_FROM_TOP, "ooo-entrance-appear",0 }, 411 { AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT, "ooo-entrance-appear",0 }, 412 { AnimationEffect_ZOOM_OUT_FROM_RIGHT, "ooo-entrance-appear",0 }, 413 { AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT, "ooo-entrance-appear",0 }, 414 { AnimationEffect_ZOOM_OUT_FROM_BOTTOM, "ooo-entrance-appear",0 }, 415 { AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT, "ooo-entrance-appear",0 }, 416 { AnimationEffect_ZOOM_OUT_FROM_CENTER, "ooo-entrance-appear",0 }, 417 { AnimationEffect_PATH, "ooo-entrance-spiral-in",0 }, 418 */ 419 { AnimationEffect_NONE, 0, 0 } 420 }; 421 422 EffectSequence::iterator ImplFindEffect( MainSequencePtr& pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem ) 423 { 424 EffectSequence::iterator aIter; 425 426 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 427 { 428 CustomAnimationEffectPtr pEffect( (*aIter) ); 429 if( (pEffect->getTargetShape() == rShape) && (pEffect->getTargetSubItem() == nSubItem) ) 430 break; 431 } 432 433 return aIter; 434 } 435 436 static bool implIsInsideGroup( SdrObject* pObj ) 437 { 438 return pObj && pObj->GetObjList() && pObj->GetObjList()->GetUpList(); 439 } 440 441 void EffectMigration::SetAnimationEffect( SvxShape* pShape, AnimationEffect eEffect ) 442 { 443 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 444 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 445 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 446 return; 447 448 SdrObject* pObj = pShape->GetSdrObject(); 449 if( implIsInsideGroup( pObj ) ) 450 return; 451 452 OUString aPresetId; 453 OUString aPresetSubType; 454 455 if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) ) 456 { 457 DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" ); 458 return; 459 } 460 461 const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets(); 462 463 CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) ); 464 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 465 466 if( pPreset.get() && pMainSequence.get() ) 467 { 468 const Reference< XShape > xShape( pShape ); 469 470 EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) ); 471 EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) ); 472 const EffectSequence::iterator aEnd( pMainSequence->getEnd() ); 473 474 bool bEffectCreated = false; 475 476 if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) ) 477 { 478 // check if there is already an text effect for this shape 479 EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) ); 480 if( aIterOnlyText != aEnd ) 481 { 482 // check if this is an animation text group 483 sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId(); 484 if( nGroupId >= 0 ) 485 { 486 CustomAnimationTextGroupPtr pGroup = pMainSequence->findGroup( nGroupId ); 487 if( pGroup.get() ) 488 { 489 // add an effect to animate the shape 490 pMainSequence->setAnimateForm( pGroup, true ); 491 492 // find this effect 493 EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) ); 494 495 if( aIter != aEnd ) 496 { 497 if( ((*aIter)->getPresetId() != aPresetId) || 498 ((*aIter)->getPresetSubType() != aPresetSubType) ) 499 { 500 (*aIter)->replaceNode( pPreset->create( aPresetSubType ) ); 501 pMainSequence->rebuild(); 502 bEffectCreated = true; 503 } 504 } 505 } 506 } 507 } 508 509 if( !bEffectCreated ) 510 { 511 // if there is not yet an effect that target this shape, we generate one 512 // we insert the shape effect before it 513 Reference< XAnimationNode > xNode( pPreset->create( aPresetSubType ) ); 514 DBG_ASSERT( xNode.is(), "EffectMigration::SetAnimationEffect(), could not create preset!" ); 515 if( xNode.is() ) 516 { 517 CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) ); 518 pEffect->setTarget( makeAny( xShape ) ); 519 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() ); 520 const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL); 521 if( !bManual ) 522 pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS ); 523 524 pMainSequence->append( pEffect ); 525 526 if( ( pObj->GetObjInventor() == SdrInventor ) && ( pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) ) 527 { 528 // special case for outline text, effects are always mapped to text group effect 529 pMainSequence-> 530 createTextGroup( pEffect, 10, bManual ? -1 : 0.0, sal_False, sal_False ); 531 } 532 } 533 } 534 } 535 else 536 { 537 // if there is already an effect targeting this shape 538 // just replace it 539 CustomAnimationEffectPtr pEffect; 540 if( aIterAsWhole != aEnd ) 541 { 542 pEffect = (*aIterAsWhole); 543 } 544 else 545 { 546 pEffect = (*aIterOnlyBackground); 547 } 548 549 if( pEffect.get() ) 550 { 551 if( (pEffect->getPresetId() != aPresetId) || 552 (pEffect->getPresetSubType() != aPresetSubType) ) 553 { 554 pMainSequence->replace( pEffect, pPreset, aPresetSubType ); 555 } 556 } 557 } 558 } 559 } 560 561 // -------------------------------------------------------------------- 562 563 AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape ) 564 { 565 OUString aPresetId; 566 OUString aPresetSubType; 567 568 SdrObject* pObj = pShape->GetSdrObject(); 569 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 570 571 if( pMainSequence.get() ) 572 { 573 const Reference< XShape > xShape( pShape ); 574 575 EffectSequence::iterator aIter; 576 577 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 578 { 579 CustomAnimationEffectPtr pEffect( (*aIter) ); 580 if( pEffect->getTargetShape() == xShape ) 581 { 582 if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) || 583 (pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE)) 584 { 585 if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import 586 { 587 aPresetId = (*aIter)->getPresetId(); 588 aPresetSubType = (*aIter)->getPresetSubType(); 589 break; 590 } 591 } 592 } 593 } 594 } 595 596 // now find old effect 597 AnimationEffect eEffect = AnimationEffect_NONE; 598 599 if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) ) 600 ConvertPreset( aPresetId, 0, eEffect ); 601 602 return eEffect; 603 } 604 605 606 // -------------------------------------------------------------------- 607 608 void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect ) 609 { 610 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 611 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 612 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 613 return; 614 615 SdrObject* pObj = pShape->GetSdrObject(); 616 if( implIsInsideGroup( pObj ) ) 617 return; 618 619 // first map the deprecated AnimationEffect to a preset and subtype 620 OUString aPresetId; 621 OUString aPresetSubType; 622 623 if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) ) 624 { 625 DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" ); 626 return; 627 } 628 629 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj ); 630 631 // ignore old text effects on shape without text 632 if( (pTextObj == 0) || (!pTextObj->HasText()) ) 633 return; 634 635 const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets(); 636 637 // create an effect from this preset 638 CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) ); 639 640 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 641 642 if( pPreset.get() && pMainSequence.get() ) 643 { 644 const Reference< XShape > xShape( pShape ); 645 646 EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) ); 647 const EffectSequence::iterator aEnd( pMainSequence->getEnd() ); 648 649 CustomAnimationTextGroupPtr pGroup; 650 651 // is there already an animation text group for this shape? 652 if( aIterOnlyText != aEnd ) 653 { 654 const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId(); 655 if( nGroupId >= 0 ) 656 pGroup = pMainSequence->findGroup( nGroupId ); 657 } 658 659 // if there is not yet a group, create it 660 if( pGroup.get() == 0 ) 661 { 662 CustomAnimationEffectPtr pShapeEffect; 663 664 EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) ); 665 if( aIterOnlyBackground != aEnd ) 666 { 667 pShapeEffect = (*aIterOnlyBackground); 668 } 669 else 670 { 671 EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) ); 672 if( aIterAsWhole != aEnd ) 673 { 674 pShapeEffect = (*aIterAsWhole); 675 } 676 else 677 { 678 OUString aEmpty; 679 CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo-entrance-appear" ) ) ) ); 680 681 Reference< XAnimationNode > xNode( pPreset->create( aEmpty ) ); 682 DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" ); 683 if( xNode.is() ) 684 { 685 pShapeEffect.reset( new CustomAnimationEffect( xNode ) ); 686 pShapeEffect->setTarget( makeAny( xShape ) ); 687 pShapeEffect->setDuration( 0.1 ); 688 pMainSequence->append( pShapeEffect ); 689 690 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() ); 691 if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL ) 692 pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS ); 693 } 694 } 695 } 696 697 if( pShapeEffect.get() ) 698 { 699 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() ); 700 const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL); 701 702 // now create effects for each paragraph 703 pGroup = 704 pMainSequence-> 705 createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, sal_True, sal_False ); 706 } 707 } 708 709 if( pGroup.get() != 0 ) 710 { 711 const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT); 712 713 // now we have a group, so check if all effects are same as we like to have them 714 const EffectSequence& rEffects = pGroup->getEffects(); 715 716 EffectSequence::const_iterator aIter; 717 for( aIter = rEffects.begin(); aIter != rEffects.end(); aIter++ ) 718 { 719 // only work on paragraph targets 720 if( (*aIter)->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) ) 721 { 722 if( ((*aIter)->getPresetId() != aPresetId) || 723 ((*aIter)->getPresetSubType() != aPresetSubType) ) 724 { 725 (*aIter)->replaceNode( pPreset->create( aPresetSubType ) ); 726 } 727 728 if( bLaserEffect ) 729 { 730 (*aIter)->setIterateType( TextAnimationType::BY_LETTER ); 731 (*aIter)->setIterateInterval( 0.5 );// TODO: 732 // Determine 733 // interval 734 // according 735 // to 736 // total 737 // effect 738 // duration 739 } 740 } 741 } 742 } 743 pMainSequence->rebuild(); 744 } 745 } 746 747 // -------------------------------------------------------------------- 748 749 AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape ) 750 { 751 OUString aPresetId; 752 OUString aPresetSubType; 753 754 SdrObject* pObj = pShape->GetSdrObject(); 755 if( pObj ) 756 { 757 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 758 759 if( pMainSequence.get() ) 760 { 761 const Reference< XShape > xShape( pShape ); 762 EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) ); 763 if( aIter != pMainSequence->getEnd() ) 764 { 765 aPresetId = (*aIter)->getPresetId(); 766 aPresetSubType = (*aIter)->getPresetSubType(); 767 } 768 } 769 } 770 771 // now find old effect 772 AnimationEffect eEffect = AnimationEffect_NONE; 773 774 if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) ) 775 ConvertPreset( aPresetId, 0, eEffect ); 776 777 return eEffect; 778 } 779 780 // -------------------------------------------------------------------- 781 782 bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect ) 783 { 784 rEffect = AnimationEffect_NONE; 785 if( rPresetId.getLength() ) 786 { 787 // first try a match for preset id and subtype 788 deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table; 789 while( p->mpPresetId ) 790 { 791 if( rPresetId.equalsAscii( p->mpPresetId ) && 792 (( p->mpPresetSubType == 0 ) || 793 ( pPresetSubType == 0) || 794 ( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) ) 795 { 796 rEffect = p->meEffect; 797 return true; 798 } 799 p++; 800 } 801 return false; 802 } 803 else 804 { 805 // empty preset id means AnimationEffect_NONE 806 return true; 807 } 808 } 809 810 // -------------------------------------------------------------------- 811 812 bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType ) 813 { 814 deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table; 815 while( p->mpPresetId ) 816 { 817 if( p->meEffect == rEffect ) 818 { 819 rPresetId = OUString::createFromAscii( p->mpPresetId ); 820 rPresetSubType = OUString::createFromAscii( p->mpPresetSubType ); 821 return true; 822 } 823 p++; 824 } 825 826 return false; 827 } 828 829 // -------------------------------------------------------------------- 830 831 double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed ) 832 { 833 double fDuration; 834 switch( eSpeed ) 835 { 836 case AnimationSpeed_SLOW: fDuration = 2.0; break; 837 case AnimationSpeed_FAST: fDuration = 0.5; break; 838 //case AnimationSpeed_MEDIUM: 839 default: 840 fDuration = 1.0; break; 841 } 842 return fDuration; 843 } 844 // -------------------------------------------------------------------- 845 846 void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed ) 847 { 848 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 849 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 850 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 851 return; 852 853 SdrObject* pObj = pShape->GetSdrObject(); 854 if( implIsInsideGroup( pObj ) ) 855 return; 856 857 double fDuration = ConvertAnimationSpeed( eSpeed ); 858 859 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 860 861 const Reference< XShape > xShape( pShape ); 862 863 EffectSequence::iterator aIter; 864 bool bNeedRebuild = false; 865 866 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 867 { 868 CustomAnimationEffectPtr pEffect( (*aIter) ); 869 if( pEffect->getTargetShape() == xShape ) 870 { 871 if( pEffect->getDuration() != 0.1 ) 872 pEffect->setDuration( fDuration ); 873 bNeedRebuild = true; 874 } 875 } 876 877 if( bNeedRebuild ) 878 pMainSequence->rebuild(); 879 } 880 881 // -------------------------------------------------------------------- 882 883 AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape ) 884 { 885 SdrObject* pObj = pShape->GetSdrObject(); 886 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 887 888 const Reference< XShape > xShape( pShape ); 889 890 EffectSequence::iterator aIter; 891 892 double fDuration = 1.0; 893 894 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 895 { 896 CustomAnimationEffectPtr pEffect( (*aIter) ); 897 if( pEffect->getTargetShape() == xShape ) 898 { 899 if( pEffect->getDuration() != 0.1 ) 900 { 901 fDuration = pEffect->getDuration(); 902 break; 903 } 904 } 905 } 906 907 return ConvertDuration( fDuration ); 908 } 909 910 // -------------------------------------------------------------------- 911 912 AnimationSpeed EffectMigration::ConvertDuration( double fDuration ) 913 { 914 AnimationSpeed eSpeed; 915 916 if( fDuration < 1.0 ) 917 eSpeed = AnimationSpeed_FAST; 918 else if( fDuration > 1.5 ) 919 eSpeed = AnimationSpeed_SLOW; 920 else 921 eSpeed = AnimationSpeed_MEDIUM; 922 923 return eSpeed; 924 } 925 926 // -------------------------------------------------------------------- 927 928 void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor ) 929 { 930 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 931 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 932 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 933 return; 934 935 SdrObject* pObj = pShape->GetSdrObject(); 936 if( implIsInsideGroup( pObj ) ) 937 return; 938 939 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 940 941 const Reference< XShape > xShape( pShape ); 942 943 EffectSequence::iterator aIter; 944 bool bNeedRebuild = false; 945 946 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 947 { 948 CustomAnimationEffectPtr pEffect( (*aIter) ); 949 if( pEffect->getTargetShape() == xShape ) 950 { 951 pEffect->setHasAfterEffect( true ); 952 pEffect->setDimColor( makeAny( nColor ) ); 953 pEffect->setAfterEffectOnNext( true ); 954 bNeedRebuild = true; 955 } 956 } 957 958 if( bNeedRebuild ) 959 pMainSequence->rebuild(); 960 } 961 962 // -------------------------------------------------------------------- 963 964 sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape ) 965 { 966 sal_Int32 nColor = 0; 967 if( pShape ) 968 { 969 SdrObject* pObj = pShape->GetSdrObject(); 970 if( pObj && pObj->GetPage() ) 971 { 972 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 973 974 const Reference< XShape > xShape( pShape ); 975 EffectSequence::iterator aIter; 976 977 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 978 { 979 CustomAnimationEffectPtr pEffect( (*aIter) ); 980 if( (pEffect->getTargetShape() == xShape) && 981 pEffect->getDimColor().hasValue() && 982 pEffect->hasAfterEffect()) 983 { 984 pEffect->getDimColor() >>= nColor; 985 break; 986 } 987 } 988 } 989 } 990 991 return nColor; 992 } 993 994 // -------------------------------------------------------------------- 995 996 997 void EffectMigration::SetDimHide( SvxShape* pShape, sal_Bool bDimHide ) 998 { 999 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 1000 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 1001 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 1002 return; 1003 1004 SdrObject* pObj = pShape->GetSdrObject(); 1005 if( implIsInsideGroup( pObj ) ) 1006 return; 1007 1008 Any aEmpty; 1009 1010 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1011 1012 const Reference< XShape > xShape( pShape ); 1013 1014 EffectSequence::iterator aIter; 1015 bool bNeedRebuild = false; 1016 1017 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 1018 { 1019 CustomAnimationEffectPtr pEffect( (*aIter) ); 1020 if( pEffect->getTargetShape() == xShape ) 1021 { 1022 pEffect->setHasAfterEffect( bDimHide ? true : false ); 1023 if( bDimHide ) 1024 pEffect->setDimColor( aEmpty ); 1025 pEffect->setAfterEffectOnNext( false ); 1026 bNeedRebuild = true; 1027 } 1028 } 1029 1030 if( bNeedRebuild ) 1031 pMainSequence->rebuild(); 1032 } 1033 1034 // -------------------------------------------------------------------- 1035 1036 sal_Bool EffectMigration::GetDimHide( SvxShape* pShape ) 1037 { 1038 sal_Bool bRet = sal_False; 1039 if( pShape ) 1040 { 1041 SdrObject* pObj = pShape->GetSdrObject(); 1042 if( pObj && pObj->GetPage() ) 1043 { 1044 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1045 1046 const Reference< XShape > xShape( pShape ); 1047 1048 EffectSequence::iterator aIter; 1049 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 1050 { 1051 CustomAnimationEffectPtr pEffect( (*aIter) ); 1052 if( pEffect->getTargetShape() == xShape ) 1053 { 1054 bRet = pEffect->hasAfterEffect() && 1055 !pEffect->getDimColor().hasValue() && 1056 (!pEffect->IsAfterEffectOnNext()); 1057 break; 1058 } 1059 } 1060 } 1061 } 1062 1063 return bRet; 1064 } 1065 1066 // -------------------------------------------------------------------- 1067 1068 void EffectMigration::SetDimPrevious( SvxShape* pShape, sal_Bool bDimPrevious ) 1069 { 1070 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(), 1071 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" ); 1072 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 1073 return; 1074 1075 SdrObject* pObj = pShape->GetSdrObject(); 1076 if( implIsInsideGroup( pObj ) ) 1077 return; 1078 1079 Any aColor; 1080 1081 if( bDimPrevious ) 1082 aColor <<= (sal_Int32)COL_LIGHTGRAY; 1083 1084 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1085 1086 const Reference< XShape > xShape( pShape ); 1087 1088 EffectSequence::iterator aIter; 1089 bool bNeedRebuild = false; 1090 1091 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 1092 { 1093 CustomAnimationEffectPtr pEffect( (*aIter) ); 1094 if( pEffect->getTargetShape() == xShape ) 1095 { 1096 pEffect->setHasAfterEffect( bDimPrevious ); 1097 if( !bDimPrevious || !pEffect->getDimColor().hasValue() ) 1098 pEffect->setDimColor( aColor ); 1099 pEffect->setAfterEffectOnNext( true ); 1100 bNeedRebuild = true; 1101 } 1102 } 1103 1104 if( bNeedRebuild ) 1105 pMainSequence->rebuild(); 1106 } 1107 1108 // -------------------------------------------------------------------- 1109 1110 sal_Bool EffectMigration::GetDimPrevious( SvxShape* pShape ) 1111 { 1112 sal_Bool bRet = sal_False; 1113 if( pShape ) 1114 { 1115 SdrObject* pObj = pShape->GetSdrObject(); 1116 if( pObj && pObj->GetPage() ) 1117 { 1118 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1119 1120 const Reference< XShape > xShape( pShape ); 1121 1122 EffectSequence::iterator aIter; 1123 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 1124 { 1125 CustomAnimationEffectPtr pEffect( (*aIter) ); 1126 if( pEffect->getTargetShape() == xShape ) 1127 { 1128 bRet = pEffect->hasAfterEffect() && 1129 pEffect->getDimColor().hasValue() && 1130 pEffect->IsAfterEffectOnNext(); 1131 break; 1132 } 1133 } 1134 } 1135 } 1136 1137 return bRet; 1138 } 1139 1140 // -------------------------------------------------------------------- 1141 1142 void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos ) 1143 { 1144 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() ) 1145 return; 1146 1147 SdrObject* pObj = pShape->GetSdrObject(); 1148 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1149 1150 EffectSequence& rSequence = pMainSequence->getSequence(); 1151 sal_Int32 nPos; 1152 sal_Int32 nCurrentPos = -1; 1153 std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1); 1154 1155 if( !rSequence.empty() ) 1156 { 1157 Reference< XShape > xThis( pShape ); 1158 Reference< XShape > xCurrent; 1159 1160 EffectSequence::iterator aIter( rSequence.begin() ); 1161 EffectSequence::iterator aEnd( rSequence.end() ); 1162 for( nPos = 0; aIter != aEnd; aIter++ ) 1163 { 1164 CustomAnimationEffectPtr pEffect = (*aIter); 1165 1166 if( !xCurrent.is() ) 1167 { 1168 xCurrent = pEffect->getTargetShape(); 1169 } 1170 else if( pEffect->getTargetShape() != xCurrent ) 1171 { 1172 nPos++; 1173 xCurrent = pEffect->getTargetShape(); 1174 aEffectVector.resize( nPos+1 ); 1175 } 1176 1177 // is this the first effect for xThis shape? 1178 if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) ) 1179 { 1180 nCurrentPos = nPos; 1181 } 1182 1183 aEffectVector[nPos].push_back( aIter ); 1184 } 1185 } 1186 1187 // check if there is at least one effect for xThis 1188 if( nCurrentPos == -1 ) 1189 { 1190 DBG_ERROR("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" ); 1191 return; 1192 } 1193 1194 // check trivial case 1195 if( nCurrentPos != nNewPos ) 1196 { 1197 std::vector< CustomAnimationEffectPtr > aEffects; 1198 1199 std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() ); 1200 std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() ); 1201 while( aIter != aEnd ) 1202 { 1203 aEffects.push_back( (*(*aIter)) ); 1204 rSequence.erase( (*aIter++) ); 1205 } 1206 1207 if( nNewPos > nCurrentPos ) 1208 nNewPos++; 1209 1210 std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() ); 1211 std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() ); 1212 1213 if( nNewPos == (sal_Int32)aEffectVector.size() ) 1214 { 1215 while( aTempIter != aTempEnd ) 1216 { 1217 rSequence.push_back( (*aTempIter++) ); 1218 } 1219 } 1220 else 1221 { 1222 EffectSequence::iterator aPos( aEffectVector[nNewPos][0] ); 1223 while( aTempIter != aTempEnd ) 1224 { 1225 rSequence.insert( aPos, (*aTempIter++) ); 1226 } 1227 } 1228 } 1229 } 1230 1231 // -------------------------------------------------------------------- 1232 1233 /** Returns the position of the given SdrObject in the Presentation order. 1234 * This function returns -1 if the SdrObject is not in the Presentation order 1235 * or if its the path-object. 1236 */ 1237 sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape ) 1238 { 1239 sal_Int32 nPos = -1, nFound = -1; 1240 1241 SdrObject* pObj = pShape->GetSdrObject(); 1242 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1243 1244 EffectSequence& rSequence = pMainSequence->getSequence(); 1245 1246 Reference< XShape > xThis( pShape ); 1247 Reference< XShape > xCurrent; 1248 1249 EffectSequence::iterator aIter( rSequence.begin() ); 1250 EffectSequence::iterator aEnd( rSequence.end() ); 1251 for( ; aIter != aEnd; aIter++ ) 1252 { 1253 CustomAnimationEffectPtr pEffect = (*aIter); 1254 1255 if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent ) 1256 { 1257 nPos++; 1258 xCurrent = pEffect->getTargetShape(); 1259 1260 // is this the first effect for xThis shape? 1261 if( xCurrent == xThis ) 1262 { 1263 nFound = nPos; 1264 break; 1265 } 1266 } 1267 } 1268 1269 return nFound; 1270 } 1271 1272 // -------------------------------------------------------------------- 1273 1274 void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo* pInfo ) 1275 { 1276 if( pInfo ) 1277 { 1278 SdrObject* pObj = pShape->GetSdrObject(); 1279 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1280 1281 const Reference< XShape > xShape( pShape ); 1282 1283 EffectSequence::iterator aIter; 1284 bool bNeedRebuild = false; 1285 1286 OUString aSoundFile; 1287 if( pInfo->mbSoundOn ) 1288 aSoundFile = pInfo->maSoundFile; 1289 1290 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ ) 1291 { 1292 CustomAnimationEffectPtr pEffect( (*aIter) ); 1293 if( pEffect->getTargetShape() == xShape ) 1294 { 1295 if( aSoundFile.getLength() ) 1296 { 1297 pEffect->createAudio( makeAny( aSoundFile ) ); 1298 } 1299 else 1300 { 1301 pEffect->removeAudio(); 1302 } 1303 bNeedRebuild = true; 1304 } 1305 } 1306 1307 if( bNeedRebuild ) 1308 pMainSequence->rebuild(); 1309 } 1310 } 1311 1312 // -------------------------------------------------------------------- 1313 1314 OUString EffectMigration::GetSoundFile( SvxShape* pShape ) 1315 { 1316 OUString aSoundFile; 1317 1318 if( pShape ) 1319 { 1320 SdrObject* pObj = pShape->GetSdrObject(); 1321 if( pObj && pObj->GetPage() ) 1322 { 1323 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1324 1325 const Reference< XShape > xShape( pShape ); 1326 1327 EffectSequence::iterator aIter; 1328 1329 for( aIter = pMainSequence->getBegin(); 1330 (aSoundFile.getLength() == 0) && (aIter != pMainSequence->getEnd()); 1331 aIter++ ) 1332 { 1333 CustomAnimationEffectPtr pEffect( (*aIter) ); 1334 if( pEffect->getTargetShape() == xShape ) 1335 { 1336 if( pEffect->getAudio().is() ) 1337 pEffect->getAudio()->getSource() >>= aSoundFile; 1338 } 1339 } 1340 } 1341 } 1342 return aSoundFile; 1343 } 1344 1345 // -------------------------------------------------------------------- 1346 1347 sal_Bool EffectMigration::GetSoundOn( SvxShape* pShape ) 1348 { 1349 return GetSoundFile( pShape ).getLength() != 0; 1350 } 1351 1352 // -------------------------------------------------------------------- 1353 1354 void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj* pPathObj ) 1355 { 1356 if( pShape && pPathObj ) 1357 { 1358 SdrObject* pObj = pShape->GetSdrObject(); 1359 1360 if( pObj ) 1361 { 1362 //sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence(); 1363 1364 const Reference< XShape > xShape( pShape ); 1365 SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->GetPage() : 0 ); 1366 if( pPage ) 1367 { 1368 boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() ); 1369 if( pMainSequence.get() ) 1370 CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) ); 1371 } 1372 } 1373 } 1374 } 1375 1376 // -------------------------------------------------------------------- 1377 1378 static const OUString aServiceNameParallelTimeContainer(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.ParallelTimeContainer")); 1379 static const OUString aServiceNameAnimateSet(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.AnimateSet")); 1380 1381 // #42894# helper which creates the needed XAnimate for changing visibility and all the (currently) needed embeddings 1382 void createVisibilityOnOffNode(Reference< XTimeContainer >& rxParentContainer, SdrObject& rCandidate, bool bVisible, bool bOnClick, double fDuration) 1383 { 1384 Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory()); 1385 Any aAny; 1386 1387 // create par container node 1388 Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance(aServiceNameParallelTimeContainer), UNO_QUERY_THROW); 1389 1390 // set begin 1391 aAny <<= (double)(0.0); 1392 xOuterSeqTimeContainer->setBegin(aAny); 1393 1394 // set fill 1395 xOuterSeqTimeContainer->setFill(AnimationFill::HOLD); 1396 1397 // set named values 1398 Sequence< NamedValue > aUserDataSequence; 1399 aUserDataSequence.realloc(1); 1400 1401 aUserDataSequence[0].Name = OUString(RTL_CONSTASCII_USTRINGPARAM("node-type")); 1402 aUserDataSequence[0].Value <<= bOnClick ? EffectNodeType::ON_CLICK : EffectNodeType::AFTER_PREVIOUS; 1403 1404 xOuterSeqTimeContainer->setUserData(aUserDataSequence); 1405 1406 // create animate set to change visibility for rCandidate 1407 Reference< XAnimationNode > xAnimateSetForLast(xMsf->createInstance(aServiceNameAnimateSet), UNO_QUERY_THROW); 1408 1409 // set begin 1410 aAny <<= (double)(0.0); 1411 xAnimateSetForLast->setBegin(aAny); 1412 1413 // set duration 1414 aAny <<= fDuration; 1415 xAnimateSetForLast->setDuration(aAny); 1416 1417 // set fill 1418 xAnimateSetForLast->setFill(AnimationFill::HOLD); 1419 1420 // set target 1421 Reference< XAnimate > xAnimate(xAnimateSetForLast, UNO_QUERY); 1422 Reference< XShape > xTargetShape(rCandidate.getUnoShape(), UNO_QUERY); 1423 aAny <<= xTargetShape; 1424 xAnimate->setTarget(aAny); 1425 1426 // set AttributeName 1427 xAnimate->setAttributeName(OUString(RTL_CONSTASCII_USTRINGPARAM("Visibility"))); 1428 1429 // set attribute value 1430 aAny <<= bVisible ? sal_True : sal_False; 1431 xAnimate->setTo(aAny); 1432 1433 // ad set node to par node 1434 Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW); 1435 xParentContainer->appendChild(xAnimateSetForLast); 1436 1437 // add node 1438 rxParentContainer->appendChild(xOuterSeqTimeContainer); 1439 } 1440 1441 // #42894# older AOO formats supported animated group objects, that means all members of the group 1442 // were shown animated by showing one after the other. This is no longer supported, but the following 1443 // fallback will create the needed SMIL animation stuff. Unfortunately the members of the group 1444 // have to be moved directly to the page, else the (explained to be generic, thus I expected this to 1445 // work) animations will not work in slideshow 1446 void EffectMigration::CreateAnimatedGroup(SdrObjGroup& rGroupObj, SdPage& rPage) 1447 { 1448 // aw080 will give a vector immeditately 1449 SdrObjListIter aIter(rGroupObj); 1450 1451 if(aIter.Count()) 1452 { 1453 boost::shared_ptr< sd::MainSequence > pMainSequence(rPage.getMainSequence()); 1454 1455 if(pMainSequence.get()) 1456 { 1457 std::vector< SdrObject* > aObjects; 1458 aObjects.reserve(aIter.Count()); 1459 1460 while(aIter.IsMore()) 1461 { 1462 // do move to page rough with old/current stuff, will be different in aw080 anyways 1463 SdrObject* pCandidate = aIter.Next(); 1464 rGroupObj.GetSubList()->NbcRemoveObject(pCandidate->GetOrdNum()); 1465 rPage.NbcInsertObject(pCandidate); 1466 aObjects.push_back(pCandidate); 1467 } 1468 1469 // create main node 1470 Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory()); 1471 Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance(aServiceNameParallelTimeContainer), UNO_QUERY_THROW); 1472 Any aAny; 1473 1474 // set begin 1475 aAny <<= (double)(0.0); 1476 xOuterSeqTimeContainer->setBegin(aAny); 1477 1478 // prepare parent container 1479 Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW); 1480 1481 // prepare loop over objects 1482 SdrObject* pLast = 0; 1483 SdrObject* pNext = 0; 1484 const double fDurationShow(0.2); 1485 const double fDurationHide(0.001); 1486 1487 for(sal_uInt32 a(0); a < aObjects.size(); a++) 1488 { 1489 pLast = pNext; 1490 pNext = aObjects[a]; 1491 1492 // create node 1493 if(pLast) 1494 { 1495 createVisibilityOnOffNode(xParentContainer, *pLast, false, false, fDurationHide); 1496 } 1497 1498 if(pNext) 1499 { 1500 createVisibilityOnOffNode(xParentContainer, *pNext, true, !a, fDurationShow); 1501 } 1502 } 1503 1504 // create end node 1505 if(pNext) 1506 { 1507 createVisibilityOnOffNode(xParentContainer, *pNext, false, false, fDurationHide); 1508 } 1509 1510 // add to main sequence and rebuild 1511 pMainSequence->createEffects(xOuterSeqTimeContainer); 1512 pMainSequence->rebuild(); 1513 } 1514 } 1515 } 1516 1517 // eof 1518