/* * public DeckSlideContentMessage( DeckModel deck, ByteArray hash ) * : this( deck, hash, 320, 240, 32, System.Drawing.Imaging.ImageFormat.Png ) { * } * * private bool Stub() { * return true; * } * * public DeckSlideContentMessage( DeckModel deck, ByteArray hash, int width, int height, int depth, System.Drawing.Imaging.ImageFormat fmt ) : base( hash ) { * using( Synchronizer.Lock( deck.SyncRoot ) ) { * Image image = deck.GetSlideContent( hash ); * * if( image == null ) * throw new ArgumentException( "The specified ByteArray does not map to slide content in the specified deck.", "hash" ); * * Image.GetThumbnailImageAbort callback = new Image.GetThumbnailImageAbort( Stub ); * Image small = image.GetThumbnailImage( width, height, callback, System.IntPtr.Zero ); * string tempFile = System.IO.Path.GetTempFileName(); * small.Save( tempFile, fmt ); * byte[] smallData = System.IO.File.ReadAllBytes( tempFile ); * System.IO.MemoryStream ms = new System.IO.MemoryStream( smallData ); * Image newSmall = Image.FromStream( ms ); * * // Cleanup Temp File * this.Target = this.Content = new ImageHashtable.ImageHashTableItem( hash, newSmall ); * this.AddLocalRef( this.Target ); * } * } */ protected override bool UpdateTarget(ReceiveContext context) { #if GENERIC_SERIALIZATION if (this.Content == null) { return(true); } #else Debug.Assert(this.Content != null); #endif if (this.Content.image == null) { throw new ArgumentException("The deserialized content image is null.", "Content"); } this.Target = this.Content; DeckModel deck = this.Parent != null ? this.Parent.Target as DeckModel : null; if (deck != null) { using (Synchronizer.Lock(deck.SyncRoot)) { // Note: If the deck already has content with this hash, nothing will happen. deck.AddSlideContent(this.Content.key, this.Content.image); } } return(true); }
/// <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); }
/// <summary> /// Handle the receipt of this message /// </summary> /// <param name="context">The context of the receiver from which the message was sent</param> protected override bool UpdateTarget(ReceiveContext context) { #if DEBUG // Add logging of slide change events string machine_name = ""; string machine_guid = ""; using (Synchronizer.Lock(context.Participant.SyncRoot)) { machine_name = context.Participant.HumanName; machine_guid = context.Participant.Guid.ToString(); } Debug.WriteLine(string.Format("SUBMISSION RCVD ({0}): Machine -- {1}, GUID -- {2}", System.DateTime.Now.Ticks, machine_name, machine_guid)); #endif SlideModel slide = this.Target as SlideModel; // Only create student submissions from slides that exist on the client machine // TODO CMPRINCE: Should we create these anyway??? if (slide != null) { // Get the student submissions deck DeckModel ssDeck = GetPresentationStudentSubmissionsDeck(); if (ssDeck != null) { // Check if this entry already exists using (Synchronizer.Lock(ssDeck.TableOfContents.SyncRoot)) { foreach (TableOfContentsModel.Entry ent in ssDeck.TableOfContents.Entries) { if (ent.Id == this.TOCEntryGuid) { this.Target = ent.Slide; return(false); } } } // Create the new slide to add SlideModel newSlide = new SlideModel(this.SlideGuid, this.LocalId, SlideDisposition.Remote | SlideDisposition.StudentSubmission, this.Bounds, (Guid)this.TargetId); this.Target = newSlide; // Make a list of image content sheets that need to be added to the deck. List <ImageSheetModel> images = new List <ImageSheetModel>(); // Update the fields of the slide using (Synchronizer.Lock(newSlide.SyncRoot)) { using (Synchronizer.Lock(slide.SyncRoot)) { newSlide.Title = this.Title; newSlide.Bounds = this.Bounds; newSlide.Zoom = this.Zoom; newSlide.BackgroundColor = this.SlideBackgroundColor; newSlide.BackgroundTemplate = this.SlideBackgroundTemplate; newSlide.SubmissionSlideGuid = this.SubmissionSlideGuid; newSlide.SubmissionStyle = this.SubmissionStyle; //If the slide background is null, then update the slide background with deck setting if (this.SlideBackgroundColor == Color.Empty && this.Parent is DeckInformationMessage) { newSlide.BackgroundColor = ((DeckInformationMessage)this.Parent).DeckBackgroundColor; } if (this.SlideBackgroundTemplate == null && this.Parent is DeckInformationMessage) { newSlide.BackgroundTemplate = ((DeckInformationMessage)this.Parent).DeckBackgroundTemplate; } // Copy all of the content sheets. // Because ContentSheets do not change, there is no // need to do a deep copy (special case for ImageSheetModels). foreach (SheetModel s in slide.ContentSheets) { newSlide.ContentSheets.Add(s); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } // Make a deep copy of all the ink sheets foreach (SheetModel s in slide.AnnotationSheets) { SheetModel newSheet = UW.ClassroomPresenter.Model.Presentation.SheetModel.SheetDeepRemoteCopyHelper(s); newSlide.AnnotationSheets.Add(newSheet); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } } } using (Synchronizer.Lock(ssDeck.SyncRoot)) { // Add the slide content to the deck. foreach (ImageSheetModel ism in images) { Image image = ism.Image; if (image == null) { using (Synchronizer.Lock(ism.Deck.SyncRoot)) using (Synchronizer.Lock(ism.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); } if (image != null) { ssDeck.AddSlideContent(ism.MD5, image); } } // Add the slide to the deck. ssDeck.InsertSlide(newSlide); AddLocalRef(newSlide.Id, newSlide); } // Add an entry to the deck traversal so that we can navigate to the slide using (Synchronizer.Lock(ssDeck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(this.TOCEntryGuid, ssDeck.TableOfContents, newSlide); ssDeck.TableOfContents.Entries.Add(e); AddLocalRef(e.Id, e); } } } // Fix Bug 803: "Erased ink and text still shows up in student submissions". // We've updated our target with 'newSheet', which is NOT the real target! // Child messages should be able to access this target, but we don't want to // save the 'newSheet' in the targets table. We want to keep the original sheet. return(false); }