Example #1
0
        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);
                    }
                }
            }
        }
 private void SendImageHelper(Group receivers)
 {
     //Don't send message if it's an instructor note.
     if (this.sheet_.Disposition != SheetDisposition.Instructor)
     {
         Message message, deck, slide;
         message                  = new PresentationInformationMessage(this.Presentation);
         message.Group            = receivers;
         message.InsertChild(deck = new DeckInformationMessage(this.Deck));
         deck.InsertChild(slide   = new SlideInformationMessage(this.Slide));
         slide.InsertChild(new ImageSheetMessage(this.sheet_, this.SheetCollectionSelector));
         using (Synchronizer.Lock(m_SlideModel.SyncRoot)) {
             message.Tags         = new MessageTags();
             message.Tags.SlideID = m_SlideModel.Id;
         }
         if (this.sheet_.Image != null)
         {
             using (Synchronizer.Lock(this.sheet_.SyncRoot)) {
                 this.Sender.Send(message);
             }
         }
         else
         {
             this.Sender.Send(message);
         }
     }
 }
Example #3
0
        /// <summary>
        /// The only thing in this message that we might care about is the background color.
        /// If the color changed and the current slide has no explicit background color set,
        /// then we want to send a RTUpdate.  Otherwise, just note the new background color.
        /// </summary>
        /// <param name="dim"></param>
        /// <returns></returns>
        internal object UpdateDeckInformation(CP3Msgs.DeckInformationMessage dim)
        {
            bool sendRTUpdate = false;

            if (!toc.DeckBackgroundColors.ContainsKey((Guid)dim.TargetId))
            {
                toc.DeckBackgroundColors.Add((Guid)dim.TargetId, dim.DeckBackgroundColor);
                //If set and non-white we need to issue a RTUpdate for the current slide.
                if ((!dim.DeckBackgroundColor.Equals(Color.White)) &&
                    (!dim.DeckBackgroundColor.Equals(Color.Empty)))
                {
                    sendRTUpdate = true;
                }
            }
            else
            {
                if (!toc.DeckBackgroundColors[(Guid)dim.TargetId].Equals(dim.DeckBackgroundColor))
                {
                    toc.DeckBackgroundColors[(Guid)dim.TargetId] = dim.DeckBackgroundColor;
                    //Color change, issue a RTUpdate for current slide.
                    sendRTUpdate = true;
                }
            }
            if (sendRTUpdate)
            {
                return(toc.GetRtUpdateForSlideId(this.currentSlideId));
            }
            return(null);
        }
Example #4
0
        private void HandleSlideContentAdded(object sender, PropertyEventArgs args_)
        {
            PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs)args_);
            ByteArray hash = ((ByteArray)args.Added);

            // For the purposes of ForceUpdate, this information is sent by SendAllSlidesAndContent.

            Message message, deck;

            message = new PresentationInformationMessage(this.m_Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash));

            if ((this.m_Deck.Disposition & (DeckDisposition.StudentSubmission | DeckDisposition.QuickPoll)) != 0)
            {
                // If we get here in response to a new student submission received
                // we don't need to send anything because we can assume the public display
                // already has the slide, however if the instructor manually adds new
                // slides to a student submission deck, the public display may not have them.
                // For now we send in both cases, but that could be improved.
                // In any case we only send slides from a Student Submission deck to Public nodes.
                message.Group = Group.Submissions;
            }
            this.m_Sender.Send(message, MessagePriority.Low);
        }
Example #5
0
        private void SendAllSlidesAndContent(Group receivers)
        {
            using (Synchronizer.Lock(this.m_Deck.SyncRoot)) {
                foreach (SlideModel slide in this.m_Deck.Slides)
                {
                    this.SendSlideInformation(slide, receivers);
                }

                foreach (ByteArray hash in this.m_Deck.SlideContentKeys)
                {
                    Message message, deck;
                    message                  = new PresentationInformationMessage(this.m_Presentation);
                    message.Group            = receivers;
                    message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
                    deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash));

                    message.Tags = new MessageTags();
                    message.Tags.BridgePriority = MessagePriority.Lowest;
                    SlideModel slide = this.m_Deck.GetSlideFromContent(hash);
                    if (slide != null)
                    {
                        using (Synchronizer.Lock(slide.SyncRoot)) {
                            message.Tags.SlideID = slide.Id;
                        }
                    }

                    this.m_Sender.Send(message, MessagePriority.Low);
                }
            }
        }
Example #6
0
        public void SendSheetInformation(SheetModel sheet, SheetMessage.SheetCollection selector, Group receivers)
        {
            // TODO: Also pass the index so the sheet can be inserted into the correct index on the remote side.
            Message message, deck, slide;

            message                  = new PresentationInformationMessage(this.m_Presentation);
            message.Group            = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(this.m_Slide));
            Message sm = SheetMessage.RemoteForSheet(sheet, selector);

            //if sm is null that means that the sheet is an instructor note and shouldn't be sent.
            if (sm != null)
            {
                slide.InsertChild(sm);
            }
            using (Synchronizer.Lock(this.m_Slide.SyncRoot)) {
                message.Tags         = new MessageTags();
                message.Tags.SlideID = this.m_Slide.Id;
            }
            if (sheet is ImageSheetModel && ((ImageSheetModel)sheet).Image != null)
            {
                using (Synchronizer.Lock(sheet.SyncRoot)) {
                    this.m_Sender.Send(message);
                }
            }
            else
            {
                this.m_Sender.Send(message);
            }
        }
        /// <summary>
        /// This is similar to the texthelpermethod, but here we send a removal message
        /// if the message is private. I am having two different methods for the sake of seperating
        /// the two different types of messages.
        /// </summary>
        /// <param name="receivers"></param>
        private void SendPublicHelper(Group receivers)
        {
            Message message, deck, slide;
            message = new PresentationInformationMessage(this.Presentation);
            message.Group = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide = new SlideInformationMessage(this.Slide));

            ///send the text message
            bool sheet_is_public;
            using (Synchronizer.Lock(sheet_.SyncRoot)) {
                sheet_is_public = sheet_.IsPublic;
            }
            ///if the sheet is private, the users should not be able to see any part of the sheet,
            ///so we should just remove a private sheet.
            if (sheet_is_public) {
                slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector));
            } else {
                slide.InsertChild(new SheetRemovedMessage(this.sheet_, this.SheetCollectionSelector));
            }

            using (Synchronizer.Lock(this.Slide.SyncRoot)) {
                message.Tags = new MessageTags();
                message.Tags.SlideID = this.Slide.Id;
            }

            this.Sender.Send(message);
        }
Example #8
0
            protected override void TearDownMember(int index, object member, object tag)
            {
                if (tag == null)
                {
                    return;
                }

                SheetModel sheet = ((SheetModel)member);

                Message message, deck, slide;

                message = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
                deck.InsertChild(slide   = new SlideInformationMessage(this.m_Service.m_Slide));
                slide.InsertChild(new SheetRemovedMessage(sheet, this.m_Selector));

                using (Synchronizer.Lock(this.m_Service.m_Slide.SyncRoot)) {
                    message.Tags         = new MessageTags();
                    message.Tags.SlideID = this.m_Service.m_Slide.Id;
                }

                this.m_Service.m_Sender.Send(message);

                ((SheetNetworkService)tag).Dispose();
            }
Example #9
0
        /// <summary>
        /// This is similar to the texthelpermethod, but here we send a removal message
        /// if the message is private. I am having two different methods for the sake of seperating
        /// the two different types of messages.
        /// </summary>
        /// <param name="receivers"></param>
        private void SendPublicHelper(Group receivers)
        {
            Message message, deck, slide;

            message                  = new PresentationInformationMessage(this.Presentation);
            message.Group            = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(this.Slide));

            ///send the text message
            bool sheet_is_public;

            using (Synchronizer.Lock(sheet_.SyncRoot)) {
                sheet_is_public = sheet_.IsPublic;
            }
            ///if the sheet is private, the users should not be able to see any part of the sheet,
            ///so we should just remove a private sheet.
            if (sheet_is_public)
            {
                slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector));
            }
            else
            {
                slide.InsertChild(new SheetRemovedMessage(this.sheet_, this.SheetCollectionSelector));
            }

            using (Synchronizer.Lock(this.Slide.SyncRoot)) {
                message.Tags         = new MessageTags();
                message.Tags.SlideID = this.Slide.Id;
            }

            this.Sender.Send(message);
        }
        private void HandleInkDeletingHelper(string[] ids)
        {
            Message message, deck, slide, sheet;

            message = new PresentationInformationMessage(this.Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(GetSubmissionSlideModel(), false));
            slide.InsertChild(sheet  = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids));
            this.Sender.Send(message);
        }
        private void HandleCurrentDrawingAttributesChanged(object sender, PropertyEventArgs args)
        {
            Message message, deck, slide, sheet;

            message = new PresentationInformationMessage(this.Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(GetSubmissionSlideModel(), false));
            slide.InsertChild(sheet  = SheetMessage.RemoteForSheet(this.Sheet, this.SheetCollectionSelector));
            this.Sender.Send(message);
        }
Example #12
0
            private void SendEntryAdded(TableOfContentsModel.Entry entry, Group receivers)
            {
                Message message, deck, slide;

                message                  = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.Group            = receivers;
                message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
                deck.InsertChild(slide   = new SlideInformationMessage(entry.Slide));
                slide.InsertChild(new TableOfContentsEntryMessage(entry));
                this.m_Service.m_Sender.Send(message);
            }
        private void HandleInkAddedHelper(Ink extracted)
        {
            Message message, deck, slide, sheet;

            message = new PresentationInformationMessage(this.Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(GetSubmissionSlideModel(), false));
            slide.InsertChild(sheet  = new InkSheetStrokesAddedMessage(this.m_Sheet, (Guid)slide.TargetId, this.SheetCollectionSelector, extracted));
            sheet.AddOldestPredecessor(SheetMessage.RemoteForSheet(this.m_Sheet, this.SheetCollectionSelector));
            this.Sender.Send(message);
        }
Example #14
0
            private void SendTraversalInformation(DeckTraversalModel traversal, Group receivers)
            {
                Message message, deck;

                message                  = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.Group            = receivers;
                message.InsertChild(deck = new DeckInformationMessage(traversal.Deck));
                deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(traversal));

                this.m_Service.m_Sender.Send(message);
            }
Example #15
0
        private void SendGenericChange(Group receivers)
        {
            // Send a generic update with information about the slide (including the new bounds/zoom).
            Message message, deck;

            message                  = new PresentationInformationMessage(this.m_Presentation);
            message.Group            = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new SlideInformationMessage(this.m_Slide));
            this.m_Sender.Send(message);
        }
        private void HandleInkDeletingHelper(string[] ids)
        {
            Message message, deck, slide, sheet;

            message = new PresentationInformationMessage(this.Presentation);
            message.InsertChild(deck    = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide      = new SlideInformationMessage(this.Slide));
            slide.InsertChild(sheet     = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids));
            message.Tags                = new MessageTags();
            message.Tags.SlideID        = m_SlideID;
            message.Tags.BridgePriority = MessagePriority.Higher;
            this.Sender.Send(message);
        }
Example #17
0
        protected virtual void HandleBoundsChanged(object sender, PropertyEventArgs args)
        {
            // Send a generic update with information about the sheet (including the new bounds).
            Message message, deck, slide, sheet;

            message = new PresentationInformationMessage(this.Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(this.Slide));
            slide.InsertChild(sheet  = SheetMessage.RemoteForSheet(this.Sheet, this.SheetCollectionSelector));
            using (Synchronizer.Lock(this.m_Slide.SyncRoot)) {
                message.Tags         = new MessageTags();
                message.Tags.SlideID = this.m_Slide.Id;
            }
            this.Sender.Send(message);
        }
Example #18
0
            protected override void TearDownMember(int index, object member, object tag)
            {
                if (tag == null)
                {
                    return;
                }

                TableOfContentsModel.Entry entry = ((TableOfContentsModel.Entry)member);

                Message message, deck, slide;

                message = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
                deck.InsertChild(slide   = new SlideInformationMessage(entry.Slide));
                slide.InsertChild(new TableOfContentsEntryRemovedMessage(entry));

                this.m_Service.m_Sender.Send(message);
            }
Example #19
0
        private void SendTextHelper(Group receivers)
        {
            Message message, deck, slide;

            message                  = new PresentationInformationMessage(this.Presentation);
            message.Group            = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide   = new SlideInformationMessage(this.Slide));

            ///send the text message
            slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector));

            using (Synchronizer.Lock(this.Slide.SyncRoot)) {
                message.Tags         = new MessageTags();
                message.Tags.SlideID = this.Slide.Id;
            }

            this.Sender.Send(message);
        }
Example #20
0
        private void SendCurrentChanged(Group receivers)
        {
            Message message, deck;

            message                  = new PresentationInformationMessage(this.m_Presentation);
            message.Group            = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.m_DeckTraversal.Deck));
            deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(this.m_DeckTraversal));

#if DEBUG
            // Add logging of slide change events
            string pres_name = "";
            using (Synchronizer.Lock(this.m_Presentation.SyncRoot))
                pres_name = this.m_Presentation.HumanName;

            string deck_name = "";
            using (Synchronizer.Lock(this.m_DeckTraversal.Deck.SyncRoot))
                deck_name = this.m_DeckTraversal.Deck.HumanName;

            int  slide_index = 0;
            Guid slide_guid  = Guid.Empty;
            using (Synchronizer.Lock(this.m_DeckTraversal.SyncRoot)) {
                if (this.m_DeckTraversal.Current != null)
                {
                    using (Synchronizer.Lock(this.m_DeckTraversal.Current.SyncRoot)) {
                        slide_index = this.m_DeckTraversal.Current.IndexInParent;
                        using (Synchronizer.Lock(this.m_DeckTraversal.Current.Slide.SyncRoot)) {
                            slide_guid = this.m_DeckTraversal.Current.Slide.Id;
                        }
                    }
                }
            }

            Debug.WriteLine(string.Format("SLIDE CHANGE ({0}): Pres -- {1}, Deck -- {2}, Slide -- {3}, Guid -- {4}",
                                          System.DateTime.Now.Ticks, pres_name, deck_name, slide_index, slide_guid));
#endif

            message.Tags = new MessageTags();
            message.Tags.BridgePriority = MessagePriority.Higher;

            this.m_Sender.Send(message);
        }
 private void SendQuickPollSheetHelper( Group receivers )
 {
     //Don't send message if it's an instructor note.
     if( this.sheet.Disposition != SheetDisposition.Instructor ) {
         Message message, deck, poll, slide;
         message = new PresentationInformationMessage( this.Presentation );
         message.Group = receivers;
         message.InsertChild( deck = new DeckInformationMessage( this.Deck ) );
         deck.InsertChild( slide = new SlideInformationMessage( this.Slide ) );
         using( Synchronizer.Lock( this.Sheet.SyncRoot ) ) {
             slide.InsertChild( poll = new QuickPollInformationMessage( this.sheet.QuickPoll ) );
         }
         poll.InsertChild( new QuickPollSheetMessage( this.sheet, this.SheetCollectionSelector ) );
         using( Synchronizer.Lock( m_SlideModel.SyncRoot ) ) {
             message.Tags = new MessageTags();
             message.Tags.SlideID = m_SlideModel.Id;
         }
         this.Sender.Send( message );
     }
 }
Example #22
0
        protected void HandleSubmissionStyleChange(object sender, PropertyEventArgs args)
        {
            // Send the Student Submission Message
            using (Synchronizer.Lock(this.m_Slide.SyncRoot)){
                if (this.m_Slide.SubmissionStyle == SlideModel.StudentSubmissionStyle.Shared)
                {
                    Guid TOCEntryGuid = Guid.NewGuid();
                    this.m_Slide.SubmissionSlideGuid = SendStudentSubmission(TOCEntryGuid);
                    LocalAddStudentSubmission(this.m_Slide.SubmissionSlideGuid, TOCEntryGuid);
                }
            }

            // Send a generic update with information about the slide (including the new bounds/zoom).
            Message message, deck;

            message = new PresentationInformationMessage(this.m_Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new SlideInformationMessage(this.m_Slide));
            this.m_Sender.Send(message);
        }
Example #23
0
        private void HandleSlideRemoved(object sender, PropertyEventArgs args_)
        {
            PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs)args_);
            SlideModel slide = ((SlideModel)args.Removed);

            using (Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) {
                SlideNetworkService service = ((SlideNetworkService)this.m_SlideNetworkServices[slide]);
                if (service != null)
                {
                    this.m_SlideNetworkServices.Remove(service);
                    service.Dispose();
                }
            }

            Message message, deck;

            message = new PresentationInformationMessage(this.m_Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new SlideDeletedMessage(slide));
            this.m_Sender.Send(message);
        }
 private void SendQuickPollSheetHelper(Group receivers)
 {
     //Don't send message if it's an instructor note.
     if (this.sheet.Disposition != SheetDisposition.Instructor)
     {
         Message message, deck, poll, slide;
         message                  = new PresentationInformationMessage(this.Presentation);
         message.Group            = receivers;
         message.InsertChild(deck = new DeckInformationMessage(this.Deck));
         deck.InsertChild(slide   = new SlideInformationMessage(this.Slide));
         using (Synchronizer.Lock(this.Sheet.SyncRoot)) {
             slide.InsertChild(poll = new QuickPollInformationMessage(this.sheet.QuickPoll));
         }
         poll.InsertChild(new QuickPollSheetMessage(this.sheet, this.SheetCollectionSelector));
         using (Synchronizer.Lock(m_SlideModel.SyncRoot)) {
             message.Tags         = new MessageTags();
             message.Tags.SlideID = m_SlideModel.Id;
         }
         this.Sender.Send(message);
     }
 }
Example #25
0
        /// <summary>
        /// When a new quickpoll is started we get this with parents: QuickPollInformationMessage, Slide..,Deck..,Presentation..
        /// The SheetMessage base class has dimensions, but they appear to all be zeros.
        /// </summary>
        /// <param name="quickPollSheetMessage"></param>
        /// <returns></returns>
        internal object AddQuickPollSheet(UW.ClassroomPresenter.Network.Messages.Presentation.QuickPollSheetMessage qpsm)
        {
            if ((qpsm.Parent is CP3Msgs.QuickPollInformationMessage) &&
                (qpsm.Parent.Parent is CP3Msgs.SlideInformationMessage) &&
                (qpsm.Parent.Parent.Parent is CP3Msgs.DeckInformationMessage) &&
                (qpsm.Parent.Parent.Parent.Parent is CP3Msgs.PresentationInformationMessage))
            {
                CP3Msgs.QuickPollInformationMessage qpim = (CP3Msgs.QuickPollInformationMessage)qpsm.Parent;
                CP3Msgs.SlideInformationMessage     sim  = (CP3Msgs.SlideInformationMessage)qpsm.Parent.Parent;
                CP3Msgs.DeckInformationMessage      dim  = (CP3Msgs.DeckInformationMessage)qpsm.Parent.Parent.Parent;
                CP3Msgs.QuickPollMessage            qpm  = (CP3Msgs.QuickPollMessage)qpim;

                // Note: OriginalSlideId is not in the TOC.  What is that??
                //TableOfContents.TocEntry te = toc.LookupBySlideId(qpModel.OriginalSlideId);

                /// sim.TargetID seems to give us a good TOC entry for the quickpoll
                /// slide with association information filled in correctly:
                TableOfContents.TocEntry qptoc = toc.LookupBySlideId((Guid)sim.TargetId);
                if (qptoc == null)
                {
                    Debug.WriteLine("***Failed to find slide for QuickPoll Sheet!");
                    return(null);
                }

                m_QuickPollAggregator.AddQuickPoll(qpm.Model);
                toc.AddQuickPollIdForSlide((Guid)sim.TargetId, qpm.Model.Id);

                //Send the initial RtQuickPoll with empty results
                int[] results = new int[0];
                ArchiveRTNav.RTQuickPoll rtqp = new ArchiveRTNav.RTQuickPoll((ArchiveRTNav.QuickPollStyle)qpm.Model.PollStyle, results, qptoc.DeckId, qptoc.SlideIndex);
                return(rtqp);
            }
            else
            {
                Debug.WriteLine("****Unexpected QuickPollSheetMessage: " + qpsm.ToString());
            }
            return(null);
        }
 private void SendImageHelper(Group receivers)
 {
     //Don't send message if it's an instructor note.
     if (this.sheet_.Disposition != SheetDisposition.Instructor) {
         Message message, deck, slide;
         message = new PresentationInformationMessage(this.Presentation);
         message.Group = receivers;
         message.InsertChild(deck = new DeckInformationMessage(this.Deck));
         deck.InsertChild(slide = new SlideInformationMessage(this.Slide));
         slide.InsertChild(new ImageSheetMessage(this.sheet_, this.SheetCollectionSelector));
         using (Synchronizer.Lock(m_SlideModel.SyncRoot)) {
             message.Tags = new MessageTags();
             message.Tags.SlideID = m_SlideModel.Id;
         }
         if (this.sheet_.Image != null) {
             using (Synchronizer.Lock(this.sheet_.SyncRoot)) {
                 this.Sender.Send(message);
             }
         }
         else
             this.Sender.Send(message);
     }
 }
Example #27
0
        protected Guid SendStudentSubmission()
        {
            Guid newSlideGuid = Guid.Empty;

            UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet;
            // Add the presentation
            if (this.Presentation == null)
            {
                return(Guid.Empty);
            }
            pres       = new PresentationInformationMessage(this.Presentation);
            pres.Group = Groups.Group.Submissions;

            //Add the current deck model that corresponds to this slide deck at the remote location
            deck       = new DeckInformationMessage(this.Deck);
            deck.Group = Groups.Group.Submissions;
            pres.InsertChild(deck);

            // Add the Slide Message
            newSlideGuid = Guid.NewGuid();
            slide        = new StudentSubmissionSlideInformationMessage(this.Slide, newSlideGuid, Guid.NewGuid());
            slide.Group  = Groups.Group.Submissions;
            deck.InsertChild(slide);

            // Find the correct user ink layer to send
            RealTimeInkSheetModel m_Sheet = null;

            using (Synchronizer.Lock(this.Slide.SyncRoot)) {
                foreach (SheetModel s in this.Slide.AnnotationSheets)
                {
                    if (s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0)
                    {
                        m_Sheet = (RealTimeInkSheetModel)s;
                        break;
                    }
                }
            }

            // Find the existing ink on the slide
            Microsoft.Ink.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 (Microsoft.Ink.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, Microsoft.Ink.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 the Sheet Message for the existing
            sheet       = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted);
            sheet.Group = Groups.Group.Submissions;
            slide.InsertChild(sheet);

            // Add the Sheet Message for the real-time ink
            sheet       = SheetMessage.ForSheet(newSheet, SheetMessage.SheetCollection.AnnotationSheets);
            sheet.Group = Groups.Group.Submissions;
            slide.AddOldestPredecessor(sheet);

            // Send the message
            this.m_Sender.Send(pres);

            return(newSlideGuid);
        }
        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);
                    }
                }
            }
        }
 private void HandleInkDeletingHelper(string[] ids)
 {
     Message message, deck, slide, sheet;
     message = new PresentationInformationMessage(this.Presentation);
     message.InsertChild(deck = new DeckInformationMessage(this.Deck));
     deck.InsertChild(slide = new SlideInformationMessage(this.Slide));
     slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids));
     message.Tags = new MessageTags();
     message.Tags.SlideID = m_SlideID;
     message.Tags.BridgePriority = MessagePriority.Higher;
     this.Sender.Send(message);
 }
 private void SendGenericChange(Group receivers)
 {
     // Send a generic update with information about the slide (including the new bounds/zoom).
     Message message, deck;
     message = new PresentationInformationMessage( this.m_Presentation );
     message.Group = receivers;
     message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) );
     deck.InsertChild( new SlideInformationMessage( this.m_Slide ) );
     this.m_Sender.Send( message );
 }
        protected void HandleSubmissionStyleChange( object sender, PropertyEventArgs args )
        {
            // Send the Student Submission Message
            using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ){
                if( this.m_Slide.SubmissionStyle == SlideModel.StudentSubmissionStyle.Shared ) {
                    Guid TOCEntryGuid = Guid.NewGuid();
                    this.m_Slide.SubmissionSlideGuid = SendStudentSubmission( TOCEntryGuid );
                    LocalAddStudentSubmission( this.m_Slide.SubmissionSlideGuid, TOCEntryGuid );
                }
            }

            // Send a generic update with information about the slide (including the new bounds/zoom).
            Message message, deck;
            message = new PresentationInformationMessage( this.m_Presentation );
            message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) );
            deck.InsertChild( new SlideInformationMessage( this.m_Slide ) );
            this.m_Sender.Send( message );
        }
 protected virtual void HandleBoundsChanged(object sender, PropertyEventArgs args)
 {
     // Send a generic update with information about the sheet (including the new bounds).
     Message message, deck, slide, sheet;
     message = new PresentationInformationMessage(this.Presentation);
     message.InsertChild(deck = new DeckInformationMessage(this.Deck));
     deck.InsertChild(slide = new SlideInformationMessage(this.Slide));
     slide.InsertChild( sheet = SheetMessage.RemoteForSheet( this.Sheet, this.SheetCollectionSelector ) );
     using (Synchronizer.Lock(this.m_Slide.SyncRoot)) {
         message.Tags = new MessageTags();
         message.Tags.SlideID = this.m_Slide.Id;
     }
     this.Sender.Send(message);
 }
 private void HandleInkAddedHelper(Ink extracted)
 {
     Message message, deck, slide, sheet;
     message = new PresentationInformationMessage(this.Presentation);
     message.InsertChild(deck = new DeckInformationMessage(this.Deck));
     deck.InsertChild(slide = new SlideInformationMessage( GetSubmissionSlideModel(), false ));
     slide.InsertChild(sheet = new InkSheetStrokesAddedMessage(this.m_Sheet, (Guid)slide.TargetId, this.SheetCollectionSelector, extracted));
     sheet.AddOldestPredecessor( SheetMessage.RemoteForSheet( this.m_Sheet, this.SheetCollectionSelector ) );
     this.Sender.Send(message);
 }
 private void HandleInkDeletingHelper(string[] ids)
 {
     Message message, deck, slide, sheet;
     message = new PresentationInformationMessage(this.Presentation);
     message.InsertChild(deck = new DeckInformationMessage(this.Deck));
     deck.InsertChild(slide = new SlideInformationMessage( GetSubmissionSlideModel(), false ));
     slide.InsertChild(sheet = new InkSheetStrokesDeletingMessage(this.m_Sheet, this.SheetCollectionSelector, ids));
     this.Sender.Send(message);
 }
        /// <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);
                    }
                }
            }
        }
 private void HandleCurrentDrawingAttributesChanged(object sender, PropertyEventArgs args)
 {
     Message message, deck, slide, sheet;
     message = new PresentationInformationMessage(this.Presentation);
     message.InsertChild(deck = new DeckInformationMessage(this.Deck));
     deck.InsertChild(slide = new SlideInformationMessage(this.Slide));
     slide.InsertChild( sheet = SheetMessage.RemoteForSheet( this.Sheet, this.SheetCollectionSelector ) );
     message.Tags = new MessageTags();
     message.Tags.SlideID = m_SlideID;
     this.Sender.Send(message);
 }
 private void SendEntryAdded(TableOfContentsModel.Entry entry, Group receivers)
 {
     Message message, deck, slide;
     message = new PresentationInformationMessage(this.m_Service.m_Presentation);
     message.Group = receivers;
     message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
     deck.InsertChild(slide = new SlideInformationMessage(entry.Slide));
     slide.InsertChild(new TableOfContentsEntryMessage(entry));
     this.m_Service.m_Sender.Send(message);
 }
 public void SendSheetInformation( SheetModel sheet, SheetMessage.SheetCollection selector, Group receivers )
 {
     // TODO: Also pass the index so the sheet can be inserted into the correct index on the remote side.
     Message message, deck, slide;
     message = new PresentationInformationMessage( this.m_Presentation );
     message.Group = receivers;
     message.InsertChild( deck = new DeckInformationMessage( this.m_Deck ) );
     deck.InsertChild( slide = new SlideInformationMessage( this.m_Slide ) );
     Message sm = SheetMessage.RemoteForSheet(sheet, selector);
     //if sm is null that means that the sheet is an instructor note and shouldn't be sent.
     if (sm != null) {
         slide.InsertChild(sm);
     }
     using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ) {
         message.Tags = new MessageTags();
         message.Tags.SlideID = this.m_Slide.Id;
     }
     if (sheet is ImageSheetModel && ((ImageSheetModel)sheet).Image != null) {
         using (Synchronizer.Lock(sheet.SyncRoot)) {
             this.m_Sender.Send( message );
         }
     }
     else
         this.m_Sender.Send(message);
 }
            protected override void TearDownMember(int index, object member, object tag)
            {
                if(tag == null) return;

                TableOfContentsModel.Entry entry = ((TableOfContentsModel.Entry) member);

                Message message, deck, slide;
                message = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
                deck.InsertChild(slide = new SlideInformationMessage(entry.Slide));
                slide.InsertChild(new TableOfContentsEntryRemovedMessage(entry));

                this.m_Service.m_Sender.Send(message);
            }
        protected Guid SendStudentSubmission( Guid TOCEntryGuid )
        {
            Guid newSlideGuid = Guid.Empty;

            UW.ClassroomPresenter.Network.Messages.Message pres, deck, slide, sheet;
            // Add the presentation
            if( this.m_Presentation == null )
                return Guid.Empty;
            pres = new PresentationInformationMessage( this.m_Presentation );
            pres.Group = Groups.Group.Submissions;

            //Add the current deck model that corresponds to this slide deck at the remote location
            deck = new DeckInformationMessage( this.m_Deck );
            deck.Group = Groups.Group.Submissions;
            pres.InsertChild( deck );

            // Add the Slide Message
            newSlideGuid = Guid.NewGuid();
            TOCEntryGuid = Guid.NewGuid();
            slide = new StudentSubmissionSlideInformationMessage( this.m_Slide, newSlideGuid, TOCEntryGuid );
            slide.Group = Groups.Group.Submissions;
            deck.InsertChild( slide );

            // Find the correct user ink layer to send
            RealTimeInkSheetModel m_Sheet = null;
            using( Synchronizer.Lock( this.m_Slide.SyncRoot ) ) {
                foreach( SheetModel s in this.m_Slide.AnnotationSheets ) {
                    if( s is RealTimeInkSheetModel && (s.Disposition & SheetDisposition.Remote) == 0 ) {
                        m_Sheet = (RealTimeInkSheetModel)s;
                        break;
                    }
                }
            }

            // Find the existing ink on the slide
            Microsoft.Ink.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( Microsoft.Ink.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, Microsoft.Ink.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 the Sheet Message for the existing ink
            sheet = new InkSheetStrokesAddedMessage(newSheet, (Guid)slide.TargetId, SheetMessage.SheetCollection.AnnotationSheets, extracted);
            sheet.Group = Groups.Group.Submissions;
            slide.InsertChild( sheet );

            // Add the Sheet Message for the real-time ink
            sheet = SheetMessage.ForSheet( newSheet, SheetMessage.SheetCollection.AnnotationSheets );
            sheet.Group = Groups.Group.Submissions;
            slide.AddOldestPredecessor( sheet );

            // Send the message
            this.m_Sender.Send( pres );

            return newSlideGuid;
        }
        private void HandleSlideContentAdded(object sender, PropertyEventArgs args_)
        {
            PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs) args_);
            ByteArray hash = ((ByteArray) args.Added);

            // For the purposes of ForceUpdate, this information is sent by SendAllSlidesAndContent.

            Message message, deck;
            message = new PresentationInformationMessage(this.m_Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash));

            if( ( this.m_Deck.Disposition & (DeckDisposition.StudentSubmission | DeckDisposition.QuickPoll) ) != 0 ) {
                // If we get here in response to a new student submission received
                // we don't need to send anything because we can assume the public display
                // already has the slide, however if the instructor manually adds new
                // slides to a student submission deck, the public display may not have them.
                // For now we send in both cases, but that could be improved.
                // In any case we only send slides from a Student Submission deck to Public nodes.
                message.Group = Group.Submissions;
            }
            this.m_Sender.Send(message, MessagePriority.Low);
        }
            protected override void TearDownMember(int index, object member, object tag)
            {
                if(tag == null) return;

                SheetModel sheet = ((SheetModel) member);

                Message message, deck, slide;
                message = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.InsertChild(deck = new DeckInformationMessage(this.m_Service.m_Deck));
                deck.InsertChild(slide = new SlideInformationMessage(this.m_Service.m_Slide));
                slide.InsertChild(new SheetRemovedMessage(sheet, this.m_Selector));

                using (Synchronizer.Lock(this.m_Service.m_Slide.SyncRoot)) {
                    message.Tags = new MessageTags();
                    message.Tags.SlideID = this.m_Service.m_Slide.Id;
                }

                this.m_Service.m_Sender.Send(message);

                ((SheetNetworkService) tag).Dispose();
            }
        private void HandleSlideRemoved(object sender, PropertyEventArgs args_)
        {
            PropertyCollectionEventArgs args = ((PropertyCollectionEventArgs) args_);
            SlideModel slide = ((SlideModel) args.Removed);

            using(Synchronizer.Lock(this.m_SlideNetworkServices.SyncRoot)) {
                SlideNetworkService service = ((SlideNetworkService) this.m_SlideNetworkServices[slide]);
                if(service != null) {
                    this.m_SlideNetworkServices.Remove(service);
                    service.Dispose();
                }
            }

            Message message, deck;
            message = new PresentationInformationMessage(this.m_Presentation);
            message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
            deck.InsertChild(new SlideDeletedMessage(slide));
            this.m_Sender.Send(message);
        }
            private void SendTraversalInformation(DeckTraversalModel traversal, Group receivers)
            {
                Message message, deck;
                message = new PresentationInformationMessage(this.m_Service.m_Presentation);
                message.Group = receivers;
                message.InsertChild(deck = new DeckInformationMessage(traversal.Deck));
                deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(traversal));

                this.m_Service.m_Sender.Send(message);
            }
        private void SendAllSlidesAndContent(Group receivers)
        {
            using(Synchronizer.Lock(this.m_Deck.SyncRoot)) {

                foreach (SlideModel slide in this.m_Deck.Slides)
                    this.SendSlideInformation(slide, receivers);

                foreach(ByteArray hash in this.m_Deck.SlideContentKeys) {
                    Message message, deck;
                    message = new PresentationInformationMessage(this.m_Presentation);
                    message.Group = receivers;
                    message.InsertChild(deck = new DeckInformationMessage(this.m_Deck));
                    deck.InsertChild(new DeckSlideContentMessage(this.m_Deck, hash));

                    message.Tags = new MessageTags();
                    message.Tags.BridgePriority = MessagePriority.Lowest;
                    SlideModel slide = this.m_Deck.GetSlideFromContent(hash);
                    if (slide != null) {
                        using (Synchronizer.Lock(slide.SyncRoot)) {
                            message.Tags.SlideID = slide.Id;
                        }
                    }

                    this.m_Sender.Send(message, MessagePriority.Low);
                }
            }
        }
        private void SendCurrentChanged(Group receivers)
        {
            Message message, deck;
            message = new PresentationInformationMessage(this.m_Presentation);
            message.Group = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.m_DeckTraversal.Deck));
            deck.InsertChild(DeckTraversalMessage.ForDeckTraversal(this.m_DeckTraversal));

            #if DEBUG
            // Add logging of slide change events
            string pres_name = "";
            using( Synchronizer.Lock( this.m_Presentation.SyncRoot ) )
                pres_name = this.m_Presentation.HumanName;

            string deck_name = "";
            using( Synchronizer.Lock( this.m_DeckTraversal.Deck.SyncRoot ) )
                deck_name = this.m_DeckTraversal.Deck.HumanName;

            int slide_index = 0;
            Guid slide_guid = Guid.Empty;
            using( Synchronizer.Lock( this.m_DeckTraversal.SyncRoot ) ) {
                if( this.m_DeckTraversal.Current != null )
                    using( Synchronizer.Lock( this.m_DeckTraversal.Current.SyncRoot ) ) {
                        slide_index = this.m_DeckTraversal.Current.IndexInParent;
                        using (Synchronizer.Lock(this.m_DeckTraversal.Current.Slide.SyncRoot)) {
                            slide_guid = this.m_DeckTraversal.Current.Slide.Id;
                        }
                    }
            }

            Debug.WriteLine( string.Format("SLIDE CHANGE ({0}): Pres -- {1}, Deck -- {2}, Slide -- {3}, Guid -- {4}",
                System.DateTime.Now.Ticks, pres_name, deck_name, slide_index, slide_guid ) );
            #endif

            message.Tags = new MessageTags();
            message.Tags.BridgePriority = MessagePriority.Higher;

            this.m_Sender.Send(message);
        }
        private void SendTextHelper(Group receivers)
        {
            Message message, deck, slide;
            message = new PresentationInformationMessage(this.Presentation);
            message.Group = receivers;
            message.InsertChild(deck = new DeckInformationMessage(this.Deck));
            deck.InsertChild(slide = new SlideInformationMessage(this.Slide));

            ///send the text message
            slide.InsertChild(new TextSheetMessage(this.sheet_, this.SheetCollectionSelector));

            using (Synchronizer.Lock(this.Slide.SyncRoot)) {
                message.Tags = new MessageTags();
                message.Tags.SlideID = this.Slide.Id;
            }

            this.Sender.Send(message);
        }