public const int PPT_SAVE_AS_ID = 748; // Determined by experimentation; should hold regardless of language.

		/// <summary>
		/// Creates the PPT automation component which handles exporting CSD decks from PPT.
		/// </summary>
		/// <param name="ppt">non-null ppt library accessor</param>
		/// <param name="paneManager">pane manager or null if no pane management is to be used</param>
		public PPTDeckBuilder(PPTLibrary.PPT ppt, PPTPaneManagement.PPTPaneManager paneManager)
#endif
		{
			if (ppt == null) throw new ArgumentNullException("ppt");

			// Hook up to arguments.
			this.myPPT = ppt;

			// Prepare the loader.
			this.myLoader = new PPTSlideLoader(DEFAULT_SIZE, DEFAULT_COMMENT_TYPE, this.myPPT, paneManager
#if SIP_MODE
				, propertyManager
#endif
				);

			// Find the menubar. 
			Core.CommandBar menu = null;
			foreach (Core.CommandBar cb in this.myPPT.App.CommandBars)
				if (cb.Id == PPT_MENU_BAR_ID)
				{
					menu = cb;
					break;
				}
			if (menu == null) 
				throw new Exception("PPTDeckBuilderAddin: Unable to find the PowerPoint menu bar.");

			// Find the file menu.
			Core.CommandBarPopup fileMenu = null;
			foreach (Core.CommandBarControl bar in menu.Controls)
				if (bar.Id == PPT_FILE_ID)
				{
					fileMenu = (Core.CommandBarPopup)bar;
					break;
				}
			if (fileMenu == null) 
				throw new Exception("PPTDeckBuilderAddin: Unable to find the PowerPoint file menu.");

			// Find the Save As.. button.
			// And see if the export to CSD button is already there.
			Core.CommandBarControl saveAs = null;
			foreach (Core.CommandBarControl control in fileMenu.Controls)
			{
				if (control.Id == PPT_SAVE_AS_ID)
					saveAs = control;
				if (control.Caption == "&Export to CSD...")
					control.Delete(false); // Delete permanently.
				if (control.Caption == "Load &Feedback Menu...")
					control.Delete(false);
			}

			// Add and configure the export to CSD button...
			this.myExportButton = (Core.CommandBarButton)fileMenu.Controls.Add(
				Core.MsoControlType.msoControlButton, 
				System.Reflection.Missing.Value,                // Not a built in button: no ID.
				System.Reflection.Missing.Value,                // No parameters used.
				(saveAs == null) ? (object)System.Reflection.Missing.Value : (object)(saveAs.Index + 1), // Place just after Save As... if possible.
				true);                                          // Temporary (disappear on closing PPT).
			this.myExportButton.Caption = "&Export to CSD...";
			this.myExportButton.DescriptionText = "Export the current presentation to the Conferencing Slide Deck format.";
			this.myExportButton.TooltipText = this.myExportButton.DescriptionText;
			this.myExportButton.Click += new Core._CommandBarButtonEvents_ClickEventHandler(this.HandleCSDButtonClick);
			this.myExportButton.Visible = true;
			this.ConfigureButton();

			// Add and configure the load feedback menu button...
			this.myFeedbackButton = (Core.CommandBarButton)fileMenu.Controls.Add(
				Core.MsoControlType.msoControlButton, 
				System.Reflection.Missing.Value,                // Not a built in button: no ID.
				System.Reflection.Missing.Value,                // No parameters used.
				(object)(this.myExportButton.Index + 1), // Place just after Export to CSD
				true);                                          // Temporary (disappear on closing PPT).
			this.myFeedbackButton.Caption = "Load &Feedback Menu...";
			this.myFeedbackButton.DescriptionText = "Load a feedback menu to associate with this deck.";
			this.myFeedbackButton.TooltipText = this.myFeedbackButton.DescriptionText;
			this.myFeedbackButton.Click += new Core._CommandBarButtonEvents_ClickEventHandler(this.HandleFeedbackButtonClick);
			this.myFeedbackButton.Visible = true;
			this.ConfigureButton();

			// Hook up to events to enable/disable the export button.
			this.myPPT.App.PresentationClose += new PowerPoint.EApplication_PresentationCloseEventHandler(this.HandlePresentation);
			this.myPPT.App.PresentationOpen += new PowerPoint.EApplication_PresentationOpenEventHandler(this.HandlePresentation);
			this.myPPT.App.WindowActivate += new PowerPoint.EApplication_WindowActivateEventHandler(this.HandleWindow);
			this.myPPT.App.WindowDeactivate += new PowerPoint.EApplication_WindowDeactivateEventHandler(this.HandleWindow);
		}
Example #2
0
        /// <summary>
        /// Create a slide model from a powerpoint slide
        /// </summary>
        /// <param name="pageSetup"></param>
        /// <param name="pptpm"></param>
        /// <param name="deck"></param>
        /// <param name="tempFileCollection"></param>
        /// <param name="dirpath"></param>
        /// <param name="currentSlide"></param>
        /// <returns></returns>
        private static SlideModel CreateSlide(PowerPoint.PageSetup pageSetup, PPTPaneManagement.PPTPaneManager pptpm, DeckModel deck, TempFileCollection tempFileCollection, string dirpath, PowerPoint._Slide currentSlide)
        {
            int slideWidth = (int)pageSetup.SlideWidth;     //Standard = 720  => 6000
            int slideHeight = (int)pageSetup.SlideHeight;   //Standard = 540  => 4500
            float emfWidth = slideWidth * 25 / 3;
            float emfHeight = slideHeight * 25 / 3;

            // Adding an empty textbox in the upper left corner of the the
            // slide before layers are exported works around a common
            // issue with shape positioning.  Without this, text shapes often get pushed too far
            // to the right and down due to some extra padding that PPT inserts on
            // the top and left of the exported images.  It doesn't pad the top left of an
            // empty text box, so the positioning is corrected.
            // This isn't perfect since the workaround should probably be applied to
            // every layer with text boxes.
            currentSlide.Shapes.AddTextbox(Core.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 1, 1);

            PowerPoint.Shapes currentShapes = currentSlide.Shapes;

            List<TaggedShape> taggedShapeList = PPTDeckIO.BuildTaggedShapeList(currentShapes, pptpm);

            //Create a new SlideModel
            SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, slideWidth, slideHeight));
            //Lock it
            using (Synchronizer.Lock(newSlideModel.SyncRoot)) {
                //Set the slide's title
                newSlideModel.Title = PPTDeckIO.FindSlideTitle(taggedShapeList, currentSlide);

                PPTDeckIO.MakeShapesInvisible(currentShapes);

                //Create the Background image
                //Generate a new filename
                string filename = PPTDeckIO.GenerateFilename();
                bool bitmapMode = true;
                if (bitmapMode) {
                    filename = dirpath + "\\" + filename + ".png";
                    currentSlide.Export(filename, "PNG", 0, 0);

                    // Need to also export as EMF to get the size of the slide in inches
                    currentSlide.Export(filename + "_TEMP", "EMF", 0, 0);
                    tempFileCollection.AddFile( filename + "_TEMP", false );
                }
                else {
                    filename = dirpath + "\\" + filename + ".emf";
                    currentSlide.Export(filename, "EMF", 0, 0);
                }
                tempFileCollection.AddFile(filename, false);

                //Compute the MD5 of the BG
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                MD5 md5Provider = new MD5CryptoServiceProvider();
                byte[] md5 = md5Provider.ComputeHash(fs);
                fs.Seek(0, SeekOrigin.Begin);
                Image image = Image.FromStream(fs);
                if (bitmapMode) {
                    image = DisassociateBitmap(image);
                }
                fs.Close();

                // Open the EMF version if we used a bitmap to get the conversion
                if( bitmapMode ) {
                    FileStream fsEMF = new FileStream( filename + "_TEMP", FileMode.Open, FileAccess.Read );
                    Image image_emf = Image.FromStream( fsEMF );
                    emfWidth = image_emf.Width;
                    emfHeight = image_emf.Height;
                    fsEMF.Close();
                    image_emf.Dispose();
                } else {
                    emfWidth = image.Width;
                    emfHeight = image.Height;
                }

                //Create the ImageSheet
                ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), Model.Presentation.SheetDisposition.Background,
                    new Rectangle(0, 0, slideWidth, slideHeight), (ByteArray)md5, 1);
                //Add the ImageSheet to the Slide
                newSlideModel.ContentSheets.Add(sheet);
                //Add the Image+MD5 to the deck
                deck.AddSlideContent((ByteArray)md5, image);

                                                // Restore visibility - this makes everything visible - a bug?
                PPTDeckIO.MakeShapesVisible(currentShapes);

                List<List<TaggedShape>> layerList = PPTDeckIO.SeparateIntoLayers(taggedShapeList);

                int startHeight = 2;
                foreach (List<TaggedShape> layer in layerList)
                    PPTDeckIO.ProcessLayer( layer, tempFileCollection, currentShapes, deck, newSlideModel,
                                            slideWidth/emfWidth, slideHeight/emfHeight, startHeight++ );

                //Add SlideModel to the deck
                deck.InsertSlide(newSlideModel);
            }
            return newSlideModel;
        }
		/// <summary>
		/// Creates the PPT automation component which handles exporting CSD decks from PPT.
		/// </summary>
		/// <param name="ppt">non-null ppt library accessor</param>
		/// <param name="paneManager">pane manager or null if no pane management is to be used</param>
		/// <param name="propertyManager">widget property manager or null if the builder should assume no widgets exist</param>
		public PPTDeckBuilder(PPTLibrary.PPT ppt, PPTPaneManagement.PPTPaneManager paneManager,
			PPTPropertyManagement.PPTPropertyManager propertyManager)
Example #4
0
        /// <summary>
        /// Tag all the shapes with their visibility mode, index, and whether or not they are a picture
        /// </summary>
        /// <param name="shapes"></param>
        /// <param name="pptpm"></param>
        /// <returns></returns>
        private static List<TaggedShape> BuildTaggedShapeList(PowerPoint.Shapes shapes, PPTPaneManagement.PPTPaneManager pptpm)
        {
            List<TaggedShape> tsList = new List<TaggedShape>();
            int index = 1;

            double version;
            if (!double.TryParse(((PowerPoint.Application)shapes.Application).Version,out version)) {
                version = 0.0;
            }

            for (int i = 1; i <= shapes.Count; i++) {
                PowerPoint.Shape shape = shapes[i];

                if(version >= 12.0)
                    Scrub2007EffectsFromShape(shape);

                if( shape.Type == Microsoft.Office.Core.MsoShapeType.msoGroup && (version < 12.0)) {
                    shape.Ungroup();
                    i--;
                    continue;
                } else
                    AddTaggedShapeToList( tsList, ref index, shape, pptpm );
            }

            return tsList;
        }
Example #5
0
        private static void AddTaggedShapeToList( List<TaggedShape> tsList, ref int index, PowerPoint.Shape shape, PPTPaneManagement.PPTPaneManager pptpm )
        {
            TaggedShape ts;
            ts.shape = shape;
            ts.index = index;
            index++;
            ts.isImage = (shape.Name.StartsWith( "Picture" ));      // A shape is an image if its called a picture!
            string[] modes = pptpm.GetModes( shape );

            if( modes.Length == 0 ) {
                ts.disp = SheetDisposition.All;
                tsList.Add( ts );
            } else {
                foreach( string mode in modes ) {
                    ts.disp = PPTDeckIO.Disposition( mode );          // Make a copy for each mode, and add to the list
                    tsList.Add( ts );
                }
            }
        }
		/// <param name="ppt">non-null ppt library accessor</param>
		/// <param name="paneManager">pane manager or null if no pane management is to be used</param>
		public PPTSlideLoader(Size viewerSize, int commentMenuType, PPTLibrary.PPT ppt, PPTPaneManagement.PPTPaneManager paneManager) 
#endif
		{
			if (ppt == null) throw new ArgumentNullException("ppt");

			this.myPPT = ppt;
			this.myPaneManager = paneManager;
#if SIP_MODE
			this.myPropertyManager = propertyManager;
#endif

			this.myViewerSize = viewerSize;
			this.myDefaultCommentMenuType = commentMenuType;

			this.myFilesLoaded = 0;

			this.myTemporaryDirectoryPath =  Path.GetTempPath() + "\\DeckBuilderTempFiles";
			try 
			{
				if (Directory.Exists(this.myTemporaryDirectoryPath))
					Directory.Delete(this.myTemporaryDirectoryPath, true);		// Delete directory to clean up old files
				Directory.CreateDirectory(this.myTemporaryDirectoryPath);

			}
			catch (IOException e)
			{
				Console.WriteLine(e.Message);
			}

		}
Example #7
0
        /// <summary>
        /// Create a slide model from a powerpoint slide
        /// </summary>
        /// <param name="pageSetup"></param>
        /// <param name="pptpm"></param>
        /// <param name="deck"></param>
        /// <param name="tempFileCollection"></param>
        /// <param name="dirpath"></param>
        /// <param name="currentSlide"></param>
        /// <returns></returns>
        private static SlideModel CreateSlide(PowerPoint.PageSetup pageSetup, PPTPaneManagement.PPTPaneManager pptpm, DeckModel deck, TempFileCollection tempFileCollection, string dirpath, PowerPoint._Slide currentSlide)
        {
            int slideWidth = (int)pageSetup.SlideWidth;     //Standard = 720  => 6000
            int slideHeight = (int)pageSetup.SlideHeight;   //Standard = 540  => 4500
            float emfWidth = slideWidth * 25 / 3;
            float emfHeight = slideHeight * 25 / 3;

            PowerPoint.Shapes currentShapes = currentSlide.Shapes;

            List<TaggedShape> taggedShapeList = PPTDeckIO.BuildTaggedShapeList(currentShapes, pptpm);

            //Create a new SlideModel
            SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, slideWidth, slideHeight));
            //Lock it
            using (Synchronizer.Lock(newSlideModel.SyncRoot)) {
                //Set the slide's title
                newSlideModel.Title = PPTDeckIO.FindSlideTitle(taggedShapeList);

                PPTDeckIO.MakeShapesInvisible(currentShapes);

                //Create the Background image
                //Generate a new filename
                string filename = PPTDeckIO.GenerateFilename();
                bool bitmapMode = true;
                if (bitmapMode) {
                    filename = dirpath + "\\" + filename + ".JPG";
                    currentSlide.Export(filename, "JPG", 0, 0);

                    // Need to also export as EMF to get the size of the slide in inches
                    currentSlide.Export(filename + "_TEMP", "EMF", 0, 0);
                    tempFileCollection.AddFile( filename + "_TEMP", false );
                }
                else {
                    filename = dirpath + "\\" + filename + ".emf";
                    currentSlide.Export(filename, "EMF", 0, 0);
                }
                tempFileCollection.AddFile(filename, false);

                //Compute the MD5 of the BG
                FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                MD5 md5Provider = new MD5CryptoServiceProvider();
                byte[] md5 = md5Provider.ComputeHash(fs);
                fs.Seek(0, SeekOrigin.Begin);
                Image image = Image.FromStream(fs);
                if (bitmapMode) {
                    image = DisassociateBitmap(image);
                }
                fs.Close();

                // Open the EMF version if we used a bitmap to get the conversion
                if( bitmapMode ) {
                    FileStream fsEMF = new FileStream( filename + "_TEMP", FileMode.Open, FileAccess.Read );
                    Image image_emf = Image.FromStream( fsEMF );
                    emfWidth = image_emf.Width;
                    emfHeight = image_emf.Height;
                    fsEMF.Close();
                    image_emf.Dispose();
                } else {
                    emfWidth = image.Width;
                    emfHeight = image.Height;
                }

                //Create the ImageSheet
                ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), Model.Presentation.SheetDisposition.Background,
                    new Rectangle(0, 0, slideWidth, slideHeight), (ByteArray)md5, 1);
                //Add the ImageSheet to the Slide
                newSlideModel.ContentSheets.Add(sheet);
                //Add the Image+MD5 to the deck
                deck.AddSlideContent((ByteArray)md5, image);

                                                // Restore visibility - this makes everything visible - a bug?
                PPTDeckIO.MakeShapesVisible(currentShapes);

                List<List<TaggedShape>> layerList = PPTDeckIO.SeparateIntoLayers(taggedShapeList);

                int startHeight = 2;
                foreach (List<TaggedShape> layer in layerList)
                    PPTDeckIO.ProcessLayer( layer, tempFileCollection, currentShapes, deck, newSlideModel,
                                            slideWidth/emfWidth, slideHeight/emfHeight, startHeight++ );

                //Add SlideModel to the deck
                deck.InsertSlide(newSlideModel);
            }
            return newSlideModel;
        }
Example #8
0
        /// <summary>
        /// Tag all the shapes with their visibility mode, index, and whether or not they are a picture
        /// </summary>
        /// <param name="shapes"></param>
        /// <param name="pptpm"></param>
        /// <returns></returns>
        private static List<TaggedShape> BuildTaggedShapeList(PowerPoint.Shapes shapes, PPTPaneManagement.PPTPaneManager pptpm)
        {
            List<TaggedShape> tsList = new List<TaggedShape>();
            int index = 1;

            for (int i = 1; i <= shapes.Count; i++) {
                PowerPoint.Shape shape = shapes[i];

                if( shape.Type == Microsoft.Office.Core.MsoShapeType.msoGroup ) {
                    shape.Ungroup();
                    i--;
                    continue;
                } else
                    AddTaggedShapeToList( tsList, ref index, shape, pptpm );
            }

            return tsList;
        }