/// <summary> /// Clone slide and sheets - copy a slide with all of the sheets. Care must be taken in setting the SlideDisposition /// </summary> /// <param name="slide">Slide to Copy</param> /// <returns></returns> protected static SlideModel CloneSlideAndSheets(SlideModel slide) { // Create the new slide to add SlideModel newSlide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS); // 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; // 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); } // Make a deep copy of all the ink sheets foreach (SheetModel s in slide.AnnotationSheets) { SheetModel newSheet = UW.ClassroomPresenter.Model.Presentation.SheetModel.SheetDeepCopyHelper(s); newSlide.AnnotationSheets.Add(newSheet); } } } return newSlide; }
public Entry(Guid id, TableOfContentsModel toc, SlideModel slide) : base(toc) { this.m_Id = id; this.m_Children = new EntryCollection(this, "Entries"); this.m_TOC = toc; this.m_Slide = slide; }
public TextSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, TextSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.sheet_ = sheet; this.sheet_.Changed["Text"].Add(new PropertyEventHandler(this.SendText)); this.sheet_.Changed["Color"].Add(new PropertyEventHandler(this.SendText)); this.sheet_.Changed["IsPublic"].Add(new PropertyEventHandler(this.SendPublic)); }
public SSSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Selector = selector; }
protected SheetUndoService(UndoModel undo, DeckModel deck, SlideModel slide, SheetModel sheet) { this.m_Undo = undo; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Sheet.Changed["Bounds"].Add(new PropertyEventHandler(this.HandleSheetChanged)); }
public SSInkSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, InkSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.m_Sheet = sheet; this.m_Sheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded); this.m_Sheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting); this.SendExistingInk(); }
/// <summary> /// Remove the label from the slide. Note that we prefer to do this instead of setting the lable to empty string /// so that the lable does not become a permanent part of the deck. /// </summary> /// <param name="slide"></param> public static void RemoveLabelForSlide(SlideModel slide) { if ((dictionary_ != null) && (dictionary_.ContainsKey(slide))) { using (Synchronizer.Lock(slide.SyncRoot)) { slide.AnnotationSheets.Remove(dictionary_[slide]); } dictionary_.Remove(slide); } }
public SSSlideNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_SubmissionStyleChangeDispatcher = new EventQueue.PropertyEventDispatcher( this.m_Sender, new PropertyEventHandler( this.HandleChange ) ); this.m_Slide.Changed["SubmissionStyle"].Add( this.m_SubmissionStyleChangeDispatcher.Dispatcher ); this.m_AnnotationSheetsCollectionHelper = new SSSheetsCollectionHelper(this, "AnnotationSheets", SheetMessage.SheetCollection.AnnotationSheets); }
/// <summary> /// Construct a listener for a generic sheet /// </summary> /// <param name="sender">The event queue</param> /// <param name="presentation">The presentation</param> /// <param name="deck">The deck</param> /// <param name="slide">The slide</param> /// <param name="sheet">The sheet</param> /// <param name="selector">The collection that this is part of</param> public SheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_Sheet = sheet; this.m_Selector = selector; // this.m_BoundsChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleBoundsChanged)); // this.m_Sheet.Changed["Bounds"].Add(this.m_BoundsChangedDispatcher.Dispatcher); }
public TextSheetUndoService(EventQueue dispatcher, UndoModel undo, DeckModel deck, SlideModel slide, TextSheetModel sheet) : base(undo, deck, slide, sheet) { this.m_EventQueue = dispatcher; this.m_SheetChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleSheetChanged)); //Ignore any sheets with the Remote flag if ((sheet.Disposition & SheetDisposition.Remote) == 0) { this.Sheet.Changed["Text"].Add(this.m_SheetChangedDispatcher.Dispatcher); this.Sheet.Changed["Font"].Add(this.m_SheetChangedDispatcher.Dispatcher); } }
/// <summary> /// Construct the InkSheetWebService, this class listens for strokes to finish /// and sends them across the network /// </summary> /// <param name="sender">The queue to use</param> /// <param name="presentation">The presentation model</param> /// <param name="deck">The deck model</param> /// <param name="slide">The slide model</param> /// <param name="sheet">The sheet model</param> /// <param name="selector">The sheet collection we are part of</param> public InkSheetWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { // Keep track of our sheet this.m_Sheet = (InkSheetModel)sheet; // Get the slide ID using (Synchronizer.Lock(slide.SyncRoot)) { m_SlideID = slide.Id; } // Set Events this.m_Sheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded); // this.m_Sheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting); }
public InkSheetUndoService(EventQueue dispatcher, UndoModel undo, DeckModel deck, SlideModel slide, InkSheetModel sheet) : base(undo, deck, slide, sheet) { this.m_EventQueue = dispatcher; this.m_InkSheet = sheet; this.m_Ignore = new ArrayList(); //Ignore any sheets with the Remote flag if ((this.m_InkSheet.Disposition & SheetDisposition.Remote) == 0) { this.m_HandleInkChangedDelegate = new HandleInkChangedDelegate(this.HandleInkChanged); this.m_InkSheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded); this.m_InkSheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting); } }
/// <summary> /// Construct the service /// </summary> /// <param name="sender">The event queue</param> /// <param name="presentation">The presentation</param> /// <param name="deck">The deck</param> /// <param name="slide">The slide</param> public SlideWebService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide) { this.m_Sender = sender; this.m_Presentation = presentation; this.m_Deck = deck; this.m_Slide = slide; this.m_ChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleChange)); this.m_Slide.Changed["Bounds"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_Slide.Changed["Zoom"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_Slide.Changed["BackgroundColor"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_Slide.Changed["BackgroundTemplate"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_ContentSheetsCollectionHelper = new SheetsCollectionHelper(this, "ContentSheets", SheetMessage.SheetCollection.ContentSheets); this.m_AnnotationSheetsCollectionHelper = new SheetsCollectionHelper(this, "AnnotationSheets", SheetMessage.SheetCollection.AnnotationSheets); }
public SlideUndoService(EventQueue dispatcher, UndoModel undo, DeckModel deck, SlideModel slide) { this.m_EventQueue = dispatcher; this.m_Undo = undo; this.m_Deck = deck; this.m_Slide = slide; this.m_SlideChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleSlideChanged)); this.m_Slide.Changed["Title"].Add(this.m_SlideChangedDispatcher.Dispatcher); this.m_Slide.Changed["Bounds"].Add(this.m_SlideChangedDispatcher.Dispatcher); this.m_Slide.Changed["ContentSheets"].Add(this.m_SlideChangedDispatcher.Dispatcher); this.m_Slide.Changed["AnnotationSheets"].Add(this.m_SlideChangedDispatcher.Dispatcher); this.m_ContentSheetsCollectionHelper = new SheetsCollectionHelper(this, "ContentSheets"); this.m_AnnotationSheetsCollectionHelper = new SheetsCollectionHelper(this, "AnnotationSheets"); }
/// <summary> /// Adds a slide to the deck. /// NOTE: slides have no natural ordering /// </summary> /// <param name="slide">The slide to insert</param> public void InsertSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (m_ContentToSlideLookup == null) { BuildContentToSlideLookup(); } using (Synchronizer.Lock(this)) { // Prevent events from being registered or unregistered. if (this.m_Slides[slide.LocalId] == null || ((SlideModel)this.m_Slides[slide.LocalId]).Id != slide.Id) { this.m_Slides[slide.LocalId] = slide; using (Synchronizer.Lock(slide.SyncRoot)) { foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) { continue; } ImageSheetModel ism = ((ImageSheetModel)sm); Image image = ism.Image; if (image == null) { using (Synchronizer.Lock(ism.Deck.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); } if (image != null) { this.AddSlideContent(ism.MD5, image); } if (!m_ContentToSlideLookup.ContainsKey(ism.MD5)) { m_ContentToSlideLookup.Add(ism.MD5, slide); } } } if (this.m_SlideAddedDelegate != null) { this.m_SlideAddedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, null, slide)); } } } }
public RealTimeInkSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, RealTimeInkSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.m_Sheet = sheet; using (Synchronizer.Lock(slide.SyncRoot)) { m_SlideID = slide.Id; } this.PacketBuffers = new Dictionary<int, List<int>>(); this.PacketFlushTimes = new Dictionary<int, long>(); this.m_CurrentDrawingAttributesChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.Sender, new PropertyEventHandler(this.HandleCurrentDrawingAttributesChanged)); this.m_Sheet.Changed["CurrentDrawingAttributes"].Add(this.m_CurrentDrawingAttributesChangedDispatcher.Dispatcher); this.m_Sheet.StylusUp += new RealTimeInkSheetModel.StylusUpEventHandler(this.HandleStylusUp); this.m_Sheet.Packets += new RealTimeInkSheetModel.PacketsEventHandler(this.HandlePackets); this.m_Sheet.StylusDown += new RealTimeInkSheetModel.StylusDownEventHandler(this.HandleStylusDown); }
public InkSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, InkSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.m_Sheet = sheet; using (Synchronizer.Lock(slide.SyncRoot)) { m_SlideID = slide.Id; } this.m_Sheet.InkAdded += new StrokesEventHandler(this.HandleInkAdded); this.m_Sheet.InkDeleting += new StrokesEventHandler(this.HandleInkDeleting); Group receivers = Group.AllParticipant; if( (deck.Disposition & (DeckDisposition.StudentSubmission | DeckDisposition.QuickPoll)) != 0 ) { receivers = Group.Submissions; } this.SendExistingInk(receivers); }
/// <summary> /// Construct a slide match between two slides /// </summary> /// <param name="sender">The event queue for async calls</param> /// <param name="srcSlide">The source slide</param> /// <param name="destSlide">The destination slide</param> public SlideMatch( EventQueue sender, SlideModel srcSlide, SlideModel destSlide ) { this.m_Sender = sender; this.m_SrcSlide = srcSlide; this.m_DestSlide = destSlide; // Listen for changes this.m_ChangeDispatcher = new EventQueue.PropertyEventDispatcher(this.m_Sender, new PropertyEventHandler(this.HandleChange)); this.m_Sender.Post(delegate() { this.m_ChangeDispatcher.Dispatcher(this, null); }); this.m_SrcSlide.Changed["Bounds"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_SrcSlide.Changed["Zoom"].Add(this.m_ChangeDispatcher.Dispatcher); this.m_SrcSlide.Changed["SubmissionSlideGuid"].Add( this.m_ChangeDispatcher.Dispatcher ); this.m_SrcSlide.Changed["SubmissionStyle"].Add( this.m_ChangeDispatcher.Dispatcher ); // Listen for changes to the sheets // NOTE: Content sheets cannot change, so we don't need to listen to changes in them // this.m_ContentSheetsCollectionHelper = new SheetsCollectionHelper(this, "ContentSheets"); this.m_AnnotationSheetsCollectionHelper = new SheetsCollectionHelper(this, "AnnotationSheets"); }
public static void ChangeLabelForSlide(SlideModel slide, string text) { if (dictionary_ == null) { dictionary_ = new Dictionary <SlideModel, StatusLabel>(); } if (!dictionary_.ContainsKey(slide)) { StatusLabel label = new StatusLabel(slide, text); dictionary_[slide] = label; using (Synchronizer.Lock(slide.SyncRoot)) { slide.AnnotationSheets.Add(label); } } else { StatusLabel label = dictionary_[slide]; using (Synchronizer.Lock(label.SyncRoot)) { label.Text = text; } } }
public PresentItBox(SheetModel sheet, MainSlideViewer viewer) { InitializeComponent(); slide_display_ = viewer.SlideDisplay; slide_ = viewer.Slide; viewer_ = viewer; sheet_ = sheet; ///add event listeners ///we need to change how we transform our textbox every time the slidedisplay transform changes. pixel_transform_listener_ = new EventQueue.PropertyEventDispatcher(slide_display_.EventQueue, new PropertyEventHandler(this.HandleTransformChanged)); ///add the dispatcher, not the actual method we want to execute slide_display_.Changed["PixelTransform"].Add(pixel_transform_listener_.Dispatcher); ///set the location and size of our controls relative to the slide by ///using the sheet information. using (Synchronizer.Lock(sheet_.SyncRoot)) { slide_coordinates_ = new Point(sheet.Bounds.Location.X, sheet.Bounds.Location.Y); slide_size_ = sheet.Bounds.Size; } }
/// <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; } } } }
/// <summary> /// Checks for the existance of a slide in the deck /// </summary> /// <param name="slide">The slide to check for</param> /// <returns>True if the given slide exists, false otherwise</returns> public bool ContainsSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); return(this.m_Slides.ContainsKey(slide.LocalId)); }
/// <summary> /// Construct the appropriate sheet web service /// </summary> /// <param name="sender">The queue</param> /// <param name="presentation">The presentation</param> /// <param name="deck">The deck</param> /// <param name="slide">The slide</param> /// <param name="sheet">The sheet</param> /// <param name="selector">The sheet collection type</param> /// <returns>A sheet web service appropriate for the sheet model</returns> public static SheetWebService ForSheet(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { if (sheet is InkSheetModel) { return new InkSheetWebService( sender, presentation, deck, slide, sheet, selector ); } else { return new SheetWebService( sender, presentation, deck, slide, sheet, selector ); } }
//, Viewer.Slides.MainSlideViewer m) public CaptureGraphForm(SlideModel slide, ViewerStateModel viewerstate) { this.m_ViewerState = viewerstate; using (Synchronizer.Lock(this.m_ViewerState.SyncRoot)) { this.m_DeviceName = this.m_ViewerState.DeviceName; this.m_OutPutSize = this.m_ViewerState.OutPutSize; } this.m_Slide = slide; InitializeComponent(); }
public static SheetNetworkService ForSheet(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, SheetModel sheet, SheetMessage.SheetCollection selector) { if(sheet is RealTimeInkSheetModel) { return new RealTimeInkSheetNetworkService(sender, presentation, deck, slide, ((RealTimeInkSheetModel) sheet), selector); } else if(sheet is InkSheetModel) { return new InkSheetNetworkService(sender, presentation, deck, slide, ((InkSheetModel) sheet), selector); } else if(sheet is ImageSheetModel) { return new ImageSheetNetworkService(sender, presentation, deck, slide, ((ImageSheetModel)sheet), selector); } else if(sheet is TextSheetModel) { return new TextSheetNetworkService(sender, presentation, deck, slide, ((TextSheetModel)sheet), selector); } else if(sheet is QuickPollSheetModel) { return new QuickPollSheetNetworkService( sender, presentation, deck, slide, ((QuickPollSheetModel)sheet), selector ); } else { return null; } }
public SheetsCollectionHelper(SlideRenderer parent, SlideModel publisher, string property) : base(parent.m_SlideDisplay.EventQueue, publisher, property) { this.m_Parent = parent; base.Initialize(); }
private void HandleSlideChanged(object sender, PropertyEventArgs args) { using(Synchronizer.Lock(this.m_SlideDisplay.SyncRoot)) { this.Slide = this.m_SlideDisplay.Slide; } }
protected virtual void Dispose(bool disposing) { if(this.m_Disposed) return; if(disposing) { this.m_SlideDisplay.Changed["Slide"].Remove(this.m_SlideChangedDispatcher.Dispatcher); this.m_SlideDisplay.Changed["SheetDisposition"].Remove(this.m_SheetDispositionChangedDispatcher.Dispatcher); // Unregister event listeners via the Slide setter. this.Slide = null; } this.m_Disposed = 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); } } } }
/// <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 ); } // 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 ) ) { // 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; } } } // Copy the values and sheets from the old slide to the new slide using( Synchronizer.Lock( oldSlide.SyncRoot ) ) { // Create the new slide to add SlideModel newSlide = new SlideModel( Guid.NewGuid(), new LocalId(), SlideDisposition.Remote | SlideDisposition.StudentSubmission, DEFAULT_SLIDE_BOUNDS, oldSlide.Id ); // 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 ) ) { 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 = InkSheetModel.InkSheetDeepCopyHelper( 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 ); } } } } } }
private void SendSlideInformation(SlideModel slide, Group receivers) { Message message, deck; message = new PresentationInformationMessage(this.m_Presentation); message.Group = receivers; message.InsertChild(deck = new DeckInformationMessage(this.m_Deck)); // Ensure that nothing about the slide can change between sending the slide's information // and creating the SlideNetworkService to listen for changes. // TODO: Find a way to also ensure that nothing about the SheetModels change either, but this is less of a concern. using (Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) { using (Synchronizer.Lock(slide.SyncRoot)) { deck.InsertChild(new SlideInformationMessage(slide)); message.Tags = new MessageTags(); message.Tags.SlideID = slide.Id; this.m_Sender.Send(message); if (!this.m_SlideNetworkServices.ContainsKey(slide)) { SlideNetworkService service = new SlideNetworkService(this.m_Sender, this.m_Presentation, this.m_Deck, slide); this.m_SlideNetworkServices.Add(slide, service); } } } }
/// <summary> /// Removes a slide and its content (if used nowhere else) from the deck /// </summary> /// <param name="slide">The slide to remove</param> public void DeleteSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (!this.m_Slides.Contains(slide.LocalId)) { throw new ArgumentException("The specified slide is not a member of this deck.", "slide"); } else { //Remove the slide from the deck this.m_Slides.Remove(slide.LocalId); //Lock the slide using (Synchronizer.Lock(slide.SyncRoot)) { //Get all the ImageSheets // FIXME: Also get ImageSheetModels from the slide's AnnotationSheets foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) { continue; } ImageSheetModel ism = ((ImageSheetModel)sm); //Get the MD5 and remove it from the SlideContent if it is not used anywhere else int slideCount = 0; SlideModel uniqueSlide = null; foreach (SlideModel sdm in this.m_Slides.Values) { using (Synchronizer.Lock(sdm.SyncRoot)) { if (sdm.HasHash(ism.MD5)) { //don't remove this sheet slideCount++; uniqueSlide = sdm; } } } if (slideCount == 0) { this.m_SlideContent.Remove(ism.MD5); } if (m_ContentToSlideLookup != null) { if (slideCount == 0) { this.m_ContentToSlideLookup.Remove(ism.MD5); } if (slideCount == 1) { this.m_ContentToSlideLookup[ism.MD5] = uniqueSlide; } } } } using (Synchronizer.Lock(this)) { // Prevent event listeners from being registered or unregistered. if (this.m_SlideRemovedDelegate != null) { this.m_SlideRemovedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, slide, null)); } } } }
/// <summary> /// Removes a slide and its content (if used nowhere else) from the deck /// </summary> /// <param name="slide">The slide to remove</param> public void DeleteSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (!this.m_Slides.Contains(slide.LocalId)) { throw new ArgumentException("The specified slide is not a member of this deck.", "slide"); } else { //Remove the slide from the deck this.m_Slides.Remove(slide.LocalId); //Lock the slide using(Synchronizer.Lock(slide.SyncRoot)) { //Get all the ImageSheets // FIXME: Also get ImageSheetModels from the slide's AnnotationSheets foreach(SheetModel sm in slide.ContentSheets) { if(!(sm is ImageSheetModel)) continue; ImageSheetModel ism = ((ImageSheetModel) sm); //Get the MD5 and remove it from the SlideContent if it is not used anywhere else int slideCount = 0; SlideModel uniqueSlide = null; foreach (SlideModel sdm in this.m_Slides.Values) { using(Synchronizer.Lock(sdm.SyncRoot)) { if (sdm.HasHash(ism.MD5)) { //don't remove this sheet slideCount++; uniqueSlide = sdm; } } } if (slideCount == 0) { this.m_SlideContent.Remove(ism.MD5); } if (m_ContentToSlideLookup != null) { if (slideCount == 0) { this.m_ContentToSlideLookup.Remove(ism.MD5); } if (slideCount == 1) { this.m_ContentToSlideLookup[ism.MD5] = uniqueSlide; } } } } using(Synchronizer.Lock(this)) { // Prevent event listeners from being registered or unregistered. if(this.m_SlideRemovedDelegate != null) this.m_SlideRemovedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, slide, null)); } } }
/// <summary> /// Checks for the existance of a slide in the deck /// </summary> /// <param name="slide">The slide to check for</param> /// <returns>True if the given slide exists, false otherwise</returns> public bool ContainsSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); return this.m_Slides.ContainsKey(slide.LocalId); }
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); } } }
/// <summary> /// Adds a slide to the deck. /// NOTE: slides have no natural ordering /// </summary> /// <param name="slide">The slide to insert</param> public void InsertSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (m_ContentToSlideLookup == null) { BuildContentToSlideLookup(); } using(Synchronizer.Lock(this)) { // Prevent events from being registered or unregistered. if( this.m_Slides[slide.LocalId] == null || ((SlideModel)this.m_Slides[slide.LocalId]).Id != slide.Id ) { this.m_Slides[slide.LocalId] = slide; using (Synchronizer.Lock(slide.SyncRoot)) { foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) continue; ImageSheetModel ism = ((ImageSheetModel)sm); Image image = ism.Image; if (image == null) using (Synchronizer.Lock(ism.Deck.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); if (image != null) this.AddSlideContent(ism.MD5, image); if (!m_ContentToSlideLookup.ContainsKey(ism.MD5)) { m_ContentToSlideLookup.Add(ism.MD5, slide); } } } if(this.m_SlideAddedDelegate != null) { this.m_SlideAddedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, null, slide)); } } } }
private StatusLabel(SlideModel slide, string text) : base(Guid.NewGuid(), text, SheetDisposition.All, false, true, new Rectangle(10, 0, text.Length * 20, 20), Color.Red, new Font("Arial", 12)) { }