예제 #1
0
        // before we embed we need to check if we have any old shape on the slide. If
        // we have, we need to delete it AFTER the new shape is inserted to preserve
        // the original timeline.
        public void EmbedOnSlide(PowerPointSlide slide, int clickNumber)
        {
            var isOnClick = clickNumber > 0;
            var shapeName = Name;

            if (slide != null)
            {
                // embed new shape using two-turn method. In the first turn, embed the shape, name it to
                // something special to distinguish from the old shape; in the second turn, delete the
                // old shape using timeline invariant deletion, and rename the new shape to the correct
                // name.
                try
                {
                    var audioShape = AudioHelper.InsertAudioFileOnSlide(slide, SaveName);
                    audioShape.Name = "#";
                    slide.RemoveAnimationsForShape(audioShape);

                    if (isOnClick)
                    {
                        slide.SetShapeAsClickTriggered(audioShape, clickNumber, MsoAnimEffect.msoAnimEffectMediaPlay);
                    }
                    else
                    {
                        slide.SetAudioAsAutoplay(audioShape);
                    }

                    // delete old shape
                    slide.DeleteShapesWithPrefixTimelineInvariant(Name);

                    audioShape.Name = shapeName;
                }
                catch (COMException)
                {
                    // Adding the file failed for one reason or another - probably cancelled by the user.
                }
            }
            else
            {
                MessageBox.Show("Slide selection error");
            }
        }
예제 #2
0
        public static Shape InsertAudioFileOnSlide(PowerPointSlide slide, string fileName)
        {
            float slideWidth = PowerPointPresentation.Current.SlideWidth;

            Shape audioShape = slide.Shapes.AddMediaObject2(fileName, MsoTriState.msoFalse, MsoTriState.msoTrue, slideWidth + 20);
            slide.RemoveAnimationsForShape(audioShape);

            return audioShape;
        }
        /// <summary>
        /// Creates a cover image from a copy of the shape to obstruct the viewer while preloading images in the background.
        /// </summary>
        public static void DuplicateAsCoverImage(PowerPointSlide animationSlide, PowerPoint.Shape shape)
        {
            var coverImage = shape.Duplicate()[1];
            coverImage.Left = shape.Left;
            coverImage.Top = shape.Top;
            animationSlide.RemoveAnimationsForShape(coverImage);

            var sequence = animationSlide.TimeLine.MainSequence;
            var effectDisappear = sequence.AddEffect(coverImage, PowerPoint.MsoAnimEffect.msoAnimEffectFade,
                PowerPoint.MsoAnimateByLevel.msoAnimateLevelNone,
                PowerPoint.MsoAnimTriggerType.msoAnimTriggerWithPrevious);
            effectDisappear.Exit = Office.MsoTriState.msoTrue;
            effectDisappear.Timing.Duration = 0.01f;
            effectDisappear.MoveTo(1);
        }
        /// <summary>
        /// Preloads a shape within the slide to reduce lag. Call after the animations for the shape have been created.
        /// </summary>
        public static void PreloadShape(PowerPointSlide animationSlide, PowerPoint.Shape shape, bool addCoverImage=true)
        {
            // The cover image is used to cover the screen while the preloading happens behind the cover image.
            PowerPoint.Shape coverImage = null;
            if (addCoverImage)
            {
                coverImage = shape.Duplicate()[1];
                coverImage.Left = shape.Left;
                coverImage.Top = shape.Top;
                animationSlide.RemoveAnimationsForShape(coverImage);
            }

            float originalWidth = shape.Width;
            float originalHeight = shape.Height;
            float originalLeft = shape.Left;
            float originalTop = shape.Top;

            // fit the shape exactly in the screen for preloading.
            float scaleRatio = Math.Min(PowerPointPresentation.Current.SlideWidth / shape.Width,
                PowerPointPresentation.Current.SlideHeight / shape.Height);
            animationSlide.RelocateShapeWithoutPath(shape, 0, 0, shape.Width * scaleRatio, shape.Height * scaleRatio);

            var trigger = PowerPoint.MsoAnimTriggerType.msoAnimTriggerWithPrevious;
            var effectMotion = AddMotionAnimation(animationSlide, shape, shape.Left, shape.Top, originalLeft + (originalWidth - shape.Width) / 2, originalTop + (originalHeight - shape.Height) / 2, 0, ref trigger);
            var effectResize = AddResizeAnimation(animationSlide, shape, shape.Width, shape.Height, originalWidth, originalHeight, 0, ref trigger);

            // Make "cover" image disappear after preload.
            PowerPoint.Effect effectDisappear = null;
            if (addCoverImage)
            {
                var sequence = animationSlide.TimeLine.MainSequence;
                effectDisappear = sequence.AddEffect(coverImage, PowerPoint.MsoAnimEffect.msoAnimEffectFade,
                    PowerPoint.MsoAnimateByLevel.msoAnimateLevelNone,
                    PowerPoint.MsoAnimTriggerType.msoAnimTriggerWithPrevious);
                effectDisappear.Exit = Office.MsoTriState.msoTrue;
                effectDisappear.Timing.Duration = 0.01f;
            }


            int firstEffectIndex = animationSlide.IndexOfFirstEffect(shape);
            // Move the animations to just before the index of the first effect.
            if (effectDisappear != null) effectDisappear.MoveTo(firstEffectIndex);
            if (effectResize != null) effectResize.MoveTo(firstEffectIndex);
            if (effectMotion != null) effectMotion.MoveTo(firstEffectIndex);
        }
        /// <summary>
        /// This function will embed the auto generated speech to the current slide.
        /// File names of generated audios will be returned.
        /// </summary>
        /// <param name="slide">Current slide reference.</param>
        /// <returns>An array of auto generated audios' name.</returns>
        private static string[] EmbedSlideNotes(PowerPointSlide slide)
        {
            String folderPath = Path.GetTempPath() + TempFolderName;
            String fileNameSearchPattern = String.Format("Slide {0} Speech", slide.ID);
            
            Directory.CreateDirectory(folderPath);
            
            // TODO:
            // obviously deleting all audios in current slide may not a good idea, some lines of script
            // may still be the same. Check the line first before deleting, if the line has not been
            // changed, leave the audio.

            // to avoid duplicate records, delete all old audios in the current slide
            var audiosInCurrentSlide = Directory.GetFiles(folderPath);
            foreach (var audio in audiosInCurrentSlide)
            {
                if (audio.Contains(fileNameSearchPattern))
                {
                    try
                    {
                        File.Delete(audio);
                    }
                    catch (Exception e)
                    {
                        Logger.LogException(e, "Failed to delete audio, it may be still playing. " + e.Message);
                    }
                }
            }

            bool isSaveSuccessful = OutputSlideNotesToFiles(slide, folderPath);
            string[] audioFiles = null;
            
            if (isSaveSuccessful)
            {
                slide.DeleteShapesWithPrefix(SpeechShapePrefix);

                audioFiles = GetAudioFilePaths(folderPath, fileNameSearchPattern);

                for (int i = 0; i < audioFiles.Length; i++)
                {
                    String fileName = audioFiles[i];
                    bool isOnClick = fileName.Contains("OnClick");

                    try
                    {
                        Shape audioShape = InsertAudioFileOnSlide(slide, fileName);
                        audioShape.Name = String.Format("PowerPointLabs Speech {0}", i);
                        slide.RemoveAnimationsForShape(audioShape);

                        if (isOnClick)
                        {
                            slide.SetShapeAsClickTriggered(audioShape, i, MsoAnimEffect.msoAnimEffectMediaPlay);
                        }
                        else
                        {
                            slide.SetAudioAsAutoplay(audioShape);
                        }
                    }
                    catch (COMException)
                    {
                        // Adding the file failed for one reason or another - probably cancelled by the user.
                    }
                }
            }

            return audioFiles;
        }