public ImageSheetRenderer(SlideDisplayModel display, ImageSheetModel sheet) : base(display, sheet) { this.m_Sheet = sheet; repaint_dispatcher_ = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, this.Repaint); if (m_Sheet.Image == null) { // we are looking at a background image if (this.m_Sheet.Deck != null) { this.m_Sheet.Deck.SlideContentAdded += new PropertyEventHandler(repaint_dispatcher_.Dispatcher); } else { //FIXME: This happened a couple of times. Ignoring it is not the best fix. Trace.WriteLine("Warning: ImageSheetModel.Deck was found to be null when creating ImageSheetRenderer."); } } else { //we're looking at an ImageIt image this.m_Sheet.Changed["Bounds"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); this.m_Sheet.Changed["Image"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); this.SlideDisplay.Changed["Slide"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); } }
public static void InsertImage(Image image, SlideModel slide) { int width = image.Width; int height = image.Height; int w = 0, h = 0; using (Synchronizer.Lock(slide.SyncRoot)) { w = slide.Bounds.Width; h = slide.Bounds.Height - 10; } if (width > w) { height = w * height / width; width = w; } if (height > h) { width = h * width / height; height = h; } /// add 4 to the with of image box as padding height = (width + 4) * height / width; width += 4; Point position = new Point(Math.Max((w - width) / 2, 0), Math.Max((h - height) / 2, 10)); ImageSheetModel imagesheet = new ImageSheetModel(Guid.NewGuid(), image, true, position, new Size(width, height), 0); imagesheet.Visible = true; using (Synchronizer.Lock(slide.SyncRoot)) { slide.AnnotationSheets.Add(imagesheet); } }
protected override bool UpdateTarget(ReceiveContext context) { DeckModel deck = (this.Parent != null && this.Parent.Parent != null) ? this.Parent.Parent.Target as DeckModel : null; ImageSheetModel sheet = this.Target as ImageSheetModel; if (sheet == null) { ///create our imagesheet based on what type of image it is if (image_ != null) { // ImageIt image // RJA - added disposition setting (previously, this was the default) this.Target = sheet = new ImageSheetModel((Guid)this.TargetId, this.image_, this.Disposition | SheetDisposition.Remote, false, this.Bounds.Location, this.Bounds.Size, this.Height); ///make the image visible sheet.Visible = true; } else { // Background image this.Target = sheet = new ImageSheetModel(deck, ((Guid)this.TargetId), this.Disposition | SheetDisposition.Remote, this.Bounds, this.MD5, this.Height); } } if (image_ != null) { using (Synchronizer.Lock(sheet.SyncRoot)) { sheet.Image = this.image_; } } base.UpdateTarget(context); return(true); }
public ImageSheetMessage(ImageSheetModel sheet, SheetCollection collection) : base(sheet, collection) { if (sheet.Deck != null) { // we are in background mode // MD5 is not a Published property of ImageSheetModel. using (Synchronizer.Lock(sheet.SyncRoot)) { this.MD5 = sheet.MD5; } // Do NOT try to serialize the ImageContent. That is done by a separate DeckSlideContentMessage. } else { // we are in ImageIt mode using (Synchronizer.Lock(sheet.SyncRoot)) { this.image_ = sheet.Image; } } }
/// <summary> /// pre: image_sheet is an image that is to be on the slide (not a background image), /// and therefore it's .Image property is not null /// </summary> /// <param name="image_sheet"></param> /// <param name="viewer"></param> /// <param name="image"></param> public ImageIt(ImageSheetModel image_sheet, MainSlideViewer viewer) : base(image_sheet, viewer) { InitializeComponent(); this.Parent = viewer; //HACK: I'm adding a control that doesn't exist on the ImageIt //because imageit has no control Control c = new Control(); actual_control_ = c; using (Synchronizer.Lock(image_sheet.SyncRoot)) { image_sheet_ = image_sheet; c.Size = image_sheet.Bounds.Size; } image_ratio_ = (float)(c.Width) / (float)(c.Height); Transform(); c.Location = new Point(0, pnlTop.Height); PaintSheet(true); }
/// <summary> /// Creates a new QuickPoll and the associated slide (and deck) /// </summary> /// <param name="model">The PresenterModel</param> /// <param name="role">The RoleModel</param> public static void CreateNewQuickPoll(PresenterModel model, RoleModel role) { // Create the quickpoll QuickPollModel newQuickPoll = null; using (Synchronizer.Lock(model.ViewerState.SyncRoot)) { newQuickPoll = new QuickPollModel(Guid.NewGuid(), Guid.NewGuid(), model.ViewerState.PollStyle); } // Get the Current Slide SlideModel oldSlide; using (Synchronizer.Lock(role.SyncRoot)) { using (Synchronizer.Lock(((InstructorModel)role).CurrentDeckTraversal.SyncRoot)) { using (Synchronizer.Lock(((InstructorModel)role).CurrentDeckTraversal.Current.SyncRoot)) { oldSlide = ((InstructorModel)role).CurrentDeckTraversal.Current.Slide; } } } // Add a new QuickPoll to the model // NOTE: This should trigger a network message about the new QuickPoll // NOTE: Need to do this first before adding the sheet otherwise the // public display will not be able to associate the sheet with // this quick poll. using (model.Workspace.Lock()) { using (Synchronizer.Lock((~model.Workspace.CurrentPresentation).SyncRoot)) { (~model.Workspace.CurrentPresentation).QuickPoll = newQuickPoll; } } // Add the quickpoll slide to the quickpoll using (model.Workspace.Lock()) { using (Synchronizer.Lock(model.Participant.SyncRoot)) { DeckTraversalModel qpTraversal = null; DeckModel qpDeck = null; // Find the first quickpoll slidedeck. foreach (DeckTraversalModel candidate in model.Workspace.DeckTraversals) { if ((candidate.Deck.Disposition & DeckDisposition.QuickPoll) != 0) { qpTraversal = candidate; using (Synchronizer.Lock(qpTraversal.SyncRoot)) { qpDeck = qpTraversal.Deck; } break; } } // If there is no existing quickpoll deck, create one. if (qpTraversal == null) { // Change the name of quickpoll according to the number of it string qpName = "QuickPoll"; // NOTE: This code is duplicated in DecksMenu.CreateBlankWhiteboardDeckMenuItem. qpDeck = new DeckModel(Guid.NewGuid(), DeckDisposition.QuickPoll, qpName); qpDeck.Group = Network.Groups.Group.Submissions; qpTraversal = new SlideDeckTraversalModel(Guid.NewGuid(), qpDeck); if (model.Workspace.CurrentPresentation.Value != null) { using (Synchronizer.Lock((~model.Workspace.CurrentPresentation).SyncRoot)) { (~model.Workspace.CurrentPresentation).DeckTraversals.Add(qpTraversal); } } else { model.Workspace.DeckTraversals.Add(qpTraversal); } } // Add the slide // TODO CMPRINCE: Associate the quickpoll with this slide using (Synchronizer.Lock(qpDeck.SyncRoot)) { // Copy the values and sheets from the old slide to the new slide // Get oldSlide's Guid Guid oldId = Guid.Empty; using (Synchronizer.Lock(oldSlide.SyncRoot)) { oldId = oldSlide.Id; } // Create the new slide to add SlideModel newSlide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Remote | SlideDisposition.StudentSubmission, DEFAULT_SLIDE_BOUNDS, oldId); // 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(oldSlide.SyncRoot)) { using (Synchronizer.Lock(newSlide.SyncRoot)) { newSlide.Title = oldSlide.Title; newSlide.Bounds = oldSlide.Bounds; newSlide.Zoom = oldSlide.Zoom; newSlide.BackgroundColor = oldSlide.BackgroundColor; newSlide.SubmissionSlideGuid = oldSlide.SubmissionSlideGuid; newSlide.SubmissionStyle = oldSlide.SubmissionStyle; // 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 oldSlide.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); } } // Add the QuickPollSheet newSlide.ContentSheets.Add(new QuickPollSheetModel(Guid.NewGuid(), newQuickPoll)); // Make a deep copy of all the ink sheets foreach (SheetModel s in oldSlide.AnnotationSheets) { SheetModel newSheet = SheetModel.SheetDeepCopyHelper(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); } } } } // Add the slide content to the deck. foreach (ImageSheetModel ism in images) { System.Drawing.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) { qpDeck.AddSlideContent(ism.MD5, image); } } // Add the slide to the deck. qpDeck.InsertSlide(newSlide); // Add an entry to the deck traversal so that we can navigate to the slide using (Synchronizer.Lock(qpDeck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(Guid.NewGuid(), qpDeck.TableOfContents, newSlide); qpDeck.TableOfContents.Entries.Add(e); } } } } }
/// <summary> /// Send the current ink as a student submission slide /// </summary> /// <param name="sender">The object which sent this event, i.e. this class</param> /// <param name="args">The parameters for the property</param> private void HandleSendSubmission(object sender, PropertyEventArgs args) { if (this.m_SendingLock) { return; } using (Synchronizer.Lock(SubmissionStatusModel.GetInstance().SyncRoot)) { SubmissionStatusModel.GetInstance().SubmissionStatus = SubmissionStatusModel.Status.NotReceived; } ///declare variables we will be using UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet; // Construct the message to send using (this.m_Model.Workspace.Lock()) { // Add the presentation if (this.m_Model.Workspace.CurrentPresentation == null) { return; } ///the presentation message we will be sending pres = new PresentationInformationMessage(this.m_Model.Workspace.CurrentPresentation); pres.Group = Groups.Group.Submissions; //Add the current deck model that corresponds to this slide deck at the remote location if ((~this.m_Model.Workspace.CurrentDeckTraversal) == null) { return; } using (Synchronizer.Lock((~this.m_Model.Workspace.CurrentDeckTraversal).SyncRoot)) { DeckModel dModel = (~this.m_Model.Workspace.CurrentDeckTraversal).Deck; foreach (DeckPairModel match in this.m_Model.Workspace.DeckMatches) { ///check to see if the decks are the same if (match.LocalDeckTraversal.Deck == (~this.m_Model.Workspace.CurrentDeckTraversal).Deck) { dModel = match.RemoteDeckTraversal.Deck; } } ///create the deck message from this matched deck deck = new DeckInformationMessage(dModel); ///make the deck a submission type deck. deck.Group = Groups.Group.Submissions; ///tack this message onto the end. pres.InsertChild(deck); ///add the particular slide we're on the to message. if ((~this.m_Model.Workspace.CurrentDeckTraversal).Current == null) { return; } using (Synchronizer.Lock((~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.SyncRoot)) { // Add the Slide Message slide = new StudentSubmissionSlideInformationMessage((~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide, Guid.NewGuid(), Guid.NewGuid()); slide.Group = Groups.Group.Submissions; deck.InsertChild(slide); // Find the correct user ink layer to send RealTimeInkSheetModel m_Sheet = null; int count = 0; foreach (SheetModel s in (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.AnnotationSheets) { if (s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0) { m_Sheet = (RealTimeInkSheetModel)s; count++; } } // DEBUGGING if (count > 1) { Debug.Assert(true, "Bad Count", "Bad"); } // Find the existing ink on the slide Ink extracted; using (Synchronizer.Lock(m_Sheet.Ink.Strokes.SyncRoot)) { // Ensure that each stroke has a Guid which will uniquely identify it on the remote side foreach (Stroke stroke in m_Sheet.Ink.Strokes) { if (!stroke.ExtendedProperties.DoesPropertyExist(InkSheetMessage.StrokeIdExtendedProperty)) { stroke.ExtendedProperties.Add(InkSheetMessage.StrokeIdExtendedProperty, Guid.NewGuid().ToString()); } } // Extract all of the strokes extracted = m_Sheet.Ink.ExtractStrokes(m_Sheet.Ink.Strokes, ExtractFlags.CopyFromOriginal); } // Find the Realtime ink on the slide RealTimeInkSheetModel newSheet = null; using (Synchronizer.Lock(m_Sheet.SyncRoot)) { newSheet = new RealTimeInkSheetModel(Guid.NewGuid(), m_Sheet.Disposition | SheetDisposition.Remote, m_Sheet.Bounds); using (Synchronizer.Lock(newSheet.SyncRoot)) { newSheet.CurrentDrawingAttributes = m_Sheet.CurrentDrawingAttributes; } } // Add a message to *create* the student's RealTimeInkSheetModel on the instructor client (without any ink). sheet = SheetMessage.ForSheet(newSheet, SheetMessage.SheetCollection.AnnotationSheets); sheet.Group = Groups.Group.Submissions; slide.InsertChild(sheet); //Scale the ink if necessary if (ViewerStateModel.NonStandardDpi) { extracted.Strokes.Transform(ViewerStateModel.DpiNormalizationSendMatrix); } // Add a message to copy the ink from the student's RealTimeInkSheetModel to the just-created sheet on the instructor. sheet = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted); sheet.Group = Groups.Group.Submissions; slide.InsertChild(sheet); ///Add each text and image sheet into the message as children of the ink sheet if it is public foreach (SheetModel s in (~this.m_Model.Workspace.CurrentDeckTraversal).Current.Slide.AnnotationSheets) { if (s is TextSheetModel && !(s is StatusLabel) && (s.Disposition & SheetDisposition.Remote) == 0) { TextSheetModel text_sheet = (TextSheetModel)s; text_sheet = (TextSheetModel)text_sheet.Clone(); ///some ugly code here due to synchronization bool sheet_is_public; using (Synchronizer.Lock(text_sheet.SyncRoot)) { sheet_is_public = text_sheet.IsPublic; } if (sheet_is_public) { TextSheetMessage t_message = new TextSheetMessage(text_sheet, SheetMessage.SheetCollection.AnnotationSheets); t_message.Group = Groups.Group.Submissions; slide.InsertChild(t_message); } } if (s is ImageSheetModel && !(s is StatusLabel) && (s.Disposition & SheetDisposition.Remote) == 0) { ImageSheetModel image_sheet = (ImageSheetModel)s; image_sheet = (ImageSheetModel)image_sheet.Clone(); ImageSheetMessage i_message = new ImageSheetMessage(image_sheet, SheetMessage.SheetCollection.AnnotationSheets); i_message.Group = Groups.Group.Submissions; slide.InsertChild(i_message); } } //Lock the current sending. this.LockSending(); // Send the message this.m_Sender.Send(pres); } } } }
/// <summary> /// /// </summary> /// <param name="tfc"></param> /// <param name="shapes"></param> /// <param name="range"></param> /// <param name="deck"></param> /// <param name="slide"></param> /// <param name="disposition"></param> /// <param name="emfHeight"></param> /// <param name="startHeight">The starting height to place this sheet at</param> private static void ProcessLayer(List <TaggedShape> layer, TempFileCollection tfc, PowerPoint.Shapes shapes, Model.Presentation.DeckModel deck, Model.Presentation.SlideModel slide, float emfWidthRatio, float emfHeightRatio, int startHeight) { if (layer.Count < 1) { return; } //Create the image int[] range = PPTDeckIO.BuildIntRange(layer); PowerPoint.ShapeRange sr = shapes.Range(range); PowerPoint.PpShapeFormat format; string fileExt = ""; bool bitmapMode = layer[0].isImage; if (bitmapMode) { format = PowerPoint.PpShapeFormat.ppShapeFormatJPG; fileExt = "jpg"; } else { format = PowerPoint.PpShapeFormat.ppShapeFormatEMF; fileExt = "emf"; } //Generate a new filename string dirpath = tfc.BasePath; string filename = PPTDeckIO.GenerateFilename(); filename = dirpath + "\\" + filename + "." + fileExt; while (File.Exists(filename)) { filename = PPTDeckIO.GenerateFilename(); filename = dirpath + "\\" + filename + "." + fileExt; } sr.Export(filename, format, 0, 0, PowerPoint.PpExportMode.ppRelativeToSlide); tfc.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(); //Calculate the geometry int xCoord = 0; int yCoord = 0; int width = 0; int height = 0; PPTDeckIO.CalculateGeometry(image, shapes, range, emfWidthRatio, emfHeightRatio, ref xCoord, ref yCoord, ref width, ref height); //Create the ImageSheet ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), layer[0].disp, new Rectangle(xCoord, yCoord, width, height), (ByteArray)md5, startHeight); //Add the ImageSheet to the Slide slide.ContentSheets.Add(sheet); //Add the Image+MD5 to the deck deck.AddSlideContent((ByteArray)md5, image); }
/// <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> /// /// </summary> /// <param name="server"></param> /// <param name="deckIndex"></param> /// <param name="slideIndex"></param> /// <param name="strokes">SimpleWebInk objects that make up the strokes.</param> public void HandleStudentSubmission(object server, int deckIndex, int slideIndex, ArrayList strokes) { SlideModel slide = null; DeckModel deck = null; using (Synchronizer.Lock(this.m_Presentation.SyncRoot)) { using (Synchronizer.Lock(this.m_Presentation.DeckTraversals[deckIndex].SyncRoot)) { using (Synchronizer.Lock(this.m_Presentation.DeckTraversals[deckIndex].Current.SyncRoot)) { // Get the slide model slide = this.m_Presentation.DeckTraversals[deckIndex].Current.Slide; } deck = this.m_Presentation.DeckTraversals[deckIndex].Deck; } } // Get the student submissions deck or create it if it doesn't exist DeckModel ssDeck = this.m_Presentation.GetStudentSubmissionDeck(); if (ssDeck == null) { // Create the student submissions deck Guid ssGuid = new Guid("{78696D29-AA11-4c5b-BCF8-8E6406077FD4}"); Guid ssTraversalGuid = new Guid("{4884044B-DAE1-4249-AEF2-3A2304F52E97}"); ssDeck = new DeckModel(ssGuid, DeckDisposition.StudentSubmission, "Student Submissions"); ssDeck.Group = Group.Submissions; ssDeck.current_subs = true; // AddLocalRef(ssGuid, ssDeck); DeckTraversalModel traversal = new SlideDeckTraversalModel(ssTraversalGuid, ssDeck); // AddLocalRef(ssTraversalGuid, traversal); // Add the new student submission deck to the presentation using (Synchronizer.Lock(this.m_Presentation.SyncRoot)) { this.m_Presentation.DeckTraversals.Add(traversal); } } // Create the new slide to add SlideModel newSlide = new SlideModel(new Guid(), new LocalId(), SlideDisposition.Remote | SlideDisposition.StudentSubmission); // 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 = slide.Title; newSlide.Bounds = slide.Bounds; newSlide.Zoom = slide.Zoom; newSlide.BackgroundColor = slide.BackgroundColor; newSlide.BackgroundTemplate = slide.BackgroundTemplate; newSlide.SubmissionSlideGuid = slide.SubmissionSlideGuid; newSlide.SubmissionStyle = slide.SubmissionStyle; //If the slide background is null, then update the slide background with deck setting using (Synchronizer.Lock(deck.SyncRoot)) { if (slide.BackgroundColor == System.Drawing.Color.Empty) { newSlide.BackgroundColor = deck.DeckBackgroundColor; } if (slide.BackgroundTemplate == null) { newSlide.BackgroundTemplate = deck.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); } } } } // Add the slide content to the deck. using (Synchronizer.Lock(ssDeck.SyncRoot)) { foreach (ImageSheetModel ism in images) { System.Drawing.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); } // 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(new Guid(), ssDeck.TableOfContents, newSlide); ssDeck.TableOfContents.Entries.Add(e); } // Add the ink to the slide now using (Synchronizer.Lock(newSlide.SyncRoot)) { RealTimeInkSheetModel sheet = new RealTimeInkSheetModel(new Guid(), SheetDisposition.All | SheetDisposition.Remote, newSlide.Bounds); // Add the sheet newSlide.AnnotationSheets.Add(sheet); // Now add the ink using (Synchronizer.Lock(sheet.Ink.Strokes.SyncRoot)) { foreach (SimpleWebInk stroke in strokes) { Microsoft.Ink.Stroke s = sheet.Ink.CreateStroke(stroke.Pts); s.DrawingAttributes.Color = System.Drawing.Color.FromArgb(stroke.R, stroke.G, stroke.B); s.DrawingAttributes.RasterOperation = (stroke.Opacity < 255) ? Microsoft.Ink.RasterOperation.MaskPen : Microsoft.Ink.RasterOperation.CopyPen; s.DrawingAttributes.Width = stroke.Width * 30.00f; } } } }
public ImageSheetUndoService(EventQueue dispatcher, UndoModel undo, DeckModel deck, SlideModel slide, ImageSheetModel sheet) : base(undo, deck, slide, sheet) { // There are currently no published properties of ImageSheetModel, other than those handled by the base class. }
/// <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); }
public ImageSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, ImageSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.sheet_ = sheet; this.m_SlideModel = slide; }