protected override void OnClick(EventArgs e) { base.OnClick(e); // Change the name of whiteboard according to the number of it string wbname = "WhiteBoard " + (++UW.ClassroomPresenter.Viewer.ViewerForm.white_board_num).ToString(); // NOTE: This code is duplicated in DeckNavigationToolBarButtons.WhiteboardToolBarButton and DeckMessage.UpdateContext DeckModel deck = new DeckModel(Guid.NewGuid(), DeckDisposition.Whiteboard, wbname); using (Synchronizer.Lock(deck.SyncRoot)) { SlideModel slide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS); deck.InsertSlide(slide); using (Synchronizer.Lock(deck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, slide); deck.TableOfContents.Entries.Add(entry); } } DeckTraversalModel traversal = new SlideDeckTraversalModel(Guid.NewGuid(), deck); using (this.m_Model.Workspace.Lock()) { if ((~this.m_Model.Workspace.CurrentPresentation) != null) { using (Synchronizer.Lock((~this.m_Model.Workspace.CurrentPresentation).SyncRoot)) { (~this.m_Model.Workspace.CurrentPresentation).DeckTraversals.Add(traversal); } } else { this.m_Model.Workspace.DeckTraversals.Add(traversal); } } }
private void CopySlideToPublicDeck() { ///get the index of the current slide that's selected, ///so that we can insert our blank slide there int current_slide_index; using (Synchronizer.Lock(traversal_.SyncRoot)) { current_slide_index = traversal_.AbsoluteCurrentSlideIndex - 1; } ///don't do anything if no object is selected if (current_slide_index < 0) { return; } DeckModel publicDeck = GetPublicSubmissionDeck(); // Copy slide SlideModel newSlide; using (Synchronizer.Lock(this.m_Deck.SyncRoot)) { SlideModel currentSlide = this.m_Deck.TableOfContents.Entries[current_slide_index].Slide; newSlide = CloneSlideAndSheets(currentSlide); using (Synchronizer.Lock(newSlide.SyncRoot)) { using (Synchronizer.Lock(currentSlide.SyncRoot)) { if (currentSlide.BackgroundTemplate == null) { newSlide.BackgroundTemplate = this.m_Deck.DeckBackgroundTemplate; } if (currentSlide.BackgroundColor == Color.Empty) { newSlide.BackgroundColor = this.m_Deck.DeckBackgroundColor; } } } newSlide.RemoveRemoteDisposition(); } using (Synchronizer.Lock(publicDeck.SyncRoot)) { publicDeck.Dirty = true; publicDeck.InsertSlide(newSlide); UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(newSlide.Id, newSlide); } using (Synchronizer.Lock(publicDeck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(Guid.NewGuid(), publicDeck.TableOfContents, newSlide); publicDeck.TableOfContents.Entries.Add(e); UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(e.Id, e); } ///Insert our current slide after the current index. This is modeled after the powerpoint ///UI // using (Synchronizer.Lock(this.m_Deck.TableOfContents.SyncRoot)) { // TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.m_Deck.TableOfContents, newSlide); // this.m_WhereTheEntriesGo.Insert(current_slide_index + 1, entry); // } }
protected override bool UpdateTarget(ReceiveContext context) { SlideModel slide = this.Target as SlideModel; if (slide == null) { this.Target = slide = new SlideModel(((Guid)this.TargetId), this.LocalId, this.Disposition | SlideDisposition.Remote, this.Bounds); } using (Synchronizer.Lock(slide.SyncRoot)) { slide.Title = this.Title; slide.Bounds = this.Bounds; slide.Zoom = this.Zoom; slide.BackgroundColor = this.SlideBackgroundColor; slide.BackgroundTemplate = this.SlideBackgroundTemplate; //Force the FilmStrip refresh, when slide.Visited change from false to true. if (slide.Visited == false && this.Visited == true) { slide.Visited = this.Visited; using (Synchronizer.Lock(PresenterModel.TheInstance.ViewerState.SyncRoot)) { if (PresenterModel.TheInstance.ViewerState.StudentNavigationType == LinkedDeckTraversalModel.NavigationSelector.Visited && PresenterModel.TheInstance.ViewerState.FilmStripEnabled == true) { PresenterModel.TheInstance.ViewerState.FilmStripEnabled = false; PresenterModel.TheInstance.ViewerState.FilmStripEnabled = true; } } } slide.Visited = this.Visited; slide.SubmissionSlideGuid = this.SubmissionSlideGuid; if (slide.SubmissionStyle != this.SubmissionStyle) { slide.SubmissionStyle = this.SubmissionStyle; } } DeckModel deck = this.Parent != null ? this.Parent.Target as DeckModel : null; if (deck != null) { using (Synchronizer.Lock(deck.SyncRoot)) { deck.InsertSlide(slide); } } //if the background template is not exist in BackgroundTemplate.xml, then save it to the xml file if (this.SlideBackgroundTemplate != null) { BackgroundTemplateXmlService xmlservice = new BackgroundTemplateXmlService(); if (!xmlservice.IsTemplateExist(this.SlideBackgroundTemplate.Name)) { xmlservice.SaveTemplate(this.SlideBackgroundTemplate); } } return(true); }
protected void LocalAddStudentSubmission(Guid g, Guid TOCEntryGuid) { using (Synchronizer.Lock(this.m_Slide.SyncRoot)) { // Only create student submissions from slides that exist on the client machine SlideModel newSlide = new SlideModel(g, new LocalId(), SlideDisposition.Remote, new Rectangle(0, 0, 0, 0)); // Update the fields of the slide using (Synchronizer.Lock(newSlide.SyncRoot)) { using (Synchronizer.Lock(this.m_Slide.SyncRoot)) { newSlide.Title = this.m_Slide.Title; newSlide.Bounds = new Rectangle(this.m_Slide.Bounds.Location, this.m_Slide.Bounds.Size); newSlide.Zoom = this.m_Slide.Zoom; newSlide.BackgroundColor = this.m_Slide.BackgroundColor; newSlide.BackgroundTemplate = this.m_Slide.BackgroundTemplate; newSlide.SubmissionSlideGuid = this.m_Slide.SubmissionSlideGuid; newSlide.SubmissionStyle = this.m_Slide.SubmissionStyle; // TODO CMPRINCE: Copy all the sheets over (Do a deep copy?) foreach (SheetModel s in this.m_Slide.ContentSheets) { newSlide.ContentSheets.Add(s); } // Make a deep copy of all the ink sheets foreach (SheetModel s in this.m_Slide.AnnotationSheets) { newSlide.AnnotationSheets.Add(UW.ClassroomPresenter.Model.Presentation.SheetModel.SheetDeepCopyHelper(s)); } } } // Add the slide to the deck DeckModel ssDeck = GetPresentationStudentSubmissionsDeck(); if (ssDeck != null) { // Add the slide itself using (Synchronizer.Lock(ssDeck.SyncRoot)) { ssDeck.InsertSlide(newSlide); Message.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(TOCEntryGuid, ssDeck.TableOfContents, newSlide); ssDeck.TableOfContents.Entries.Add(e); Message.AddLocalRef(e.Id, e); } } } }
private static SlideModel CreateSlide(DocumentPage page, DeckModel deck) { int slideWidth = (int)page.Size.Width; int slideHeight = (int)page.Size.Height; //Create a new SlideModel SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, slideWidth, slideHeight)); //Create a XPSPageSheetModel for each XPS Page XPSPageSheetModel sheet = new XPSPageSheetModel(page, new XPSDocumentPageWrapper(page), Guid.NewGuid(), SheetDisposition.All, new Rectangle(0, 0, slideWidth, slideHeight), slideHeight); //Add XPSPageSheetModel into SlideModel using (Synchronizer.Lock(newSlideModel.SyncRoot)) { newSlideModel.ContentSheets.Add(sheet); } deck.InsertSlide(newSlideModel); return(newSlideModel); }
/// <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); }
/// <summary> /// Handle clicking of this button (switch between whiteboard and normal deck) /// </summary> /// <param name="args">The event arguments</param> protected override void OnClick(EventArgs args) { using (this.m_Model.Workspace.Lock()) { using (Synchronizer.Lock(this.m_Model.Participant.SyncRoot)) { DeckTraversalModel traversal; if (this.CurrentDeckTraversal == null || (this.CurrentDeckTraversal.Deck.Disposition & DeckDisposition.Whiteboard) == 0) { traversal = this.m_PreviousWhiteboard; // Make sure the deck hasn't been closed. if (!this.m_Model.Workspace.DeckTraversals.Contains(traversal)) { traversal = this.m_PreviousWhiteboard = null; } // If there is no previous whiteboard traversal, find one or create one. if (traversal == null) { // TODO: If the participant is an instructor, *only* search the whiteboards in the active presentation. // Then, when changing the current deck, also change the current presentation if necessary. foreach (DeckTraversalModel candidate in this.m_Model.Workspace.DeckTraversals) { if ((candidate.Deck.Disposition & DeckDisposition.Whiteboard) != 0) { traversal = candidate; break; } } // If there is no existing whiteboard deck, create one. if (traversal == null) { // Change the name of whiteboard according to the number of it string wbname = "WhiteBoard " + (++UW.ClassroomPresenter.Viewer.ViewerForm.white_board_num).ToString(); // NOTE: This code is duplicated in DecksMenu.CreateBlankWhiteboardDeckMenuItem. DeckModel deck = new DeckModel(Guid.NewGuid(), DeckDisposition.Whiteboard, wbname); using (Synchronizer.Lock(deck.SyncRoot)) { SlideModel slide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS); deck.InsertSlide(slide); using (Synchronizer.Lock(deck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, slide); deck.TableOfContents.Entries.Add(entry); } } traversal = new SlideDeckTraversalModel(Guid.NewGuid(), deck); if (this.m_Model.Workspace.CurrentPresentation.Value != null) { using (Synchronizer.Lock((~this.m_Model.Workspace.CurrentPresentation).SyncRoot)) { (~this.m_Model.Workspace.CurrentPresentation).DeckTraversals.Add(traversal); } } else { this.m_Model.Workspace.DeckTraversals.Add(traversal); } } } } else { traversal = this.m_PreviousNormal; // Make sure the deck hasn't been closed. if (!this.m_Model.Workspace.DeckTraversals.Contains(traversal)) { traversal = this.m_PreviousNormal = null; } // Search the workspace for a non-whiteboard deck if we haven't encountered one before. if (traversal == null) { // TODO: If the participant is an instructor, *only* search the whiteboards in the active presentation. foreach (DeckTraversalModel candidate in this.m_Model.Workspace.DeckTraversals) { if ((candidate.Deck.Disposition & DeckDisposition.Whiteboard) == 0) { traversal = candidate; break; } } // If we still haven't found a non-whiteboard deck, do nothing. if (traversal == null) { return; } } } // If the user's role is an InstructorModel, set the InstructorModel's CurrentDeckTraversal. // The NetworkAssociationService will then use this to set the WorkspaceModel's CurrentDeckTraversal, // and the new deck traversal will also be broadcast. InstructorModel instructor = this.m_Model.Participant.Role as InstructorModel; if (instructor != null) { using (Synchronizer.Lock(instructor.SyncRoot)) { instructor.CurrentDeckTraversal = traversal; } } else { // Otherwise, we must set the CurrentDeckTraversal on the WorkspaceModel directly. using (this.m_Model.Workspace.Lock()) { this.m_Model.Workspace.CurrentDeckTraversal.Value = traversal; } } } } base.OnClick(args); }