Пример #1
0
        private void HandleEntriesChangedHelper()
        {
            using (Synchronizer.Lock(this.SyncRoot)) {
                using (Synchronizer.Lock(this.Deck.TableOfContents.SyncRoot)) {
                    if (this.Current == null)
                    {
                        // We don't have a current entry to start from, so start from the beginning.
                        this.Reset();
                    }

                    if (this.Current != null && !this.m_Filter(this.Current))
                    {
                        // The current entry is no longer be accepted by the filter.
                        // Find the next entry relative to the current, or the previous entry if there is no next.
                        TableOfContentsModel.Entry replacement = this.FindNext(this.Current);
                        this.Current = (replacement != null) ? replacement : this.FindPrevious(this.Current);

                        // Setting the current entry will have updated the Next and Previous properties,
                        // so there's nothing more to do.
                        return;
                    }

                    // Update the Next and Previous entries, in case the current Next or Previous
                    // entries changed so that they are no longer accepted by the filter.
                    // TODO: Only try to update Next and Previous if the changed entries are adjacent
                    //   to the current entry or one of its parents.  This may be beneficial if the
                    //   tree is very broad.
                    this.UpdateEntries();
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Sets the <see cref="Current">current entry</see> to the first applicable entry
 /// in the deck's table of contents, or <c>null</c> if the table of contents is empty.
 /// </summary>
 /// <remarks>
 /// The caller is required to aquire a reader lock on the <see cref="DeckModel#TableOfContents"/>.
 /// </remarks>
 private void Reset()
 {
     if (this.Deck.TableOfContents.Entries.Count > 0)
     {
         TableOfContentsModel.Entry entry = this.Deck.TableOfContents[0];
         this.Current = this.m_Filter(entry) ? entry : this.FindNext(entry);
     }
 }
Пример #3
0
        public static DeckModel OpenXPS(string file)
        {
            try
            {
                Misc.ProgressBarForm progressForm = new UW.ClassroomPresenter.Misc.ProgressBarForm("Opening \"" + file + "\"...");
                progressForm.Show();

                //Open Xps Document
                XpsDocument xpsDocument = null;

                xpsDocument = new XpsDocument(file, FileAccess.Read);

                //Create two DocumentPaginators for the XPS document. One is for local display, the other one is for the delivery to students.
                DocumentPaginator paginator = xpsDocument.GetFixedDocumentSequence().DocumentPaginator;

                //Create Deck Model
                Guid deckGuid = Guid.NewGuid();
                DeckModel deck = new DeckModel(deckGuid, DeckDisposition.Empty, file);

                using (Synchronizer.Lock(deck.SyncRoot))
                {
                    deck.IsXpsDeck = true;

                    //Iterate over all pages
                    for (int i = 0; i < paginator.PageCount; i++)
                    {
                        DocumentPage page = paginator.GetPage(i);

                        SlideModel newSlideModel = CreateSlide(page, deck);

                        //Create a new Entry + reference SlideModel
                        TableOfContentsModel.Entry newEntry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, newSlideModel);
                        //Lock the TOC
                        using (Synchronizer.Lock(deck.TableOfContents.SyncRoot))
                        {
                            //Add Entry to TOC
                            deck.TableOfContents.Entries.Add(newEntry);
                        }

                        //Update the Progress Bar
                        progressForm.UpdateProgress(0, paginator.PageCount , i+1);
                    }
                }

                //Close Progress Bar
                progressForm.Close();

                return deck;
            }
            catch (Exception e)
            {
                System.Diagnostics.Trace.WriteLine(e.ToString());
            }
            GC.Collect();

            return null;
        }
        public FilmStripSlideViewer(MultiColumnFilmStrip parent, PresenterModel model, DeckTraversalModel traversal, DeckTraversalModel previewTraversal, TableOfContentsModel.Entry entry)
        {
            this.m_Model = model;
            this.m_Parent = parent;
            this.m_DeckTraversal = traversal;
            this.m_Entry = entry;

            this.m_PreviewDeckTraversal = previewTraversal;

            this.BorderStyle = BorderStyle.FixedSingle;

            this.m_CurrentEntryChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, new PropertyEventHandler(this.HandleCurrentEntryChanged));
            this.m_EntriesChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, new PropertyEventHandler(this.HandleEntriesChanged));
            this.m_DeckBackgroundColorChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, new PropertyEventHandler(this.HandleDeckBackgroundColorChanged));
            this.m_DeckBackgroundTemplateChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, new PropertyEventHandler(this.HandleDeckBackgroundTemplateChanged));

            this.m_DeckTraversal.Changed["Current"].Add(this.m_CurrentEntryChangedDispatcher.Dispatcher);
            this.m_Entry.TableOfContents.Changed["Entries"].Add(this.m_EntriesChangedDispatcher.Dispatcher);
            using (Synchronizer.Lock(this.m_DeckTraversal.Deck.SyncRoot)) {
                this.m_DeckTraversal.Deck.Changed["DeckBackgroundColor"].Add(this.m_DeckBackgroundColorChangedDispatcher.Dispatcher);
                this.m_DeckTraversal.Deck.Changed["DeckBackgroundTemplate"].Add(this.m_DeckBackgroundTemplateChangedDispatcher.Dispatcher);
                this.DefaultDeckBGColor = this.m_DeckTraversal.Deck.DeckBackgroundColor;
                this.DefaultDeckBGTemplate = this.m_DeckTraversal.Deck.DeckBackgroundTemplate;
            }

            this.m_EntriesChangedDispatcher.Dispatcher(this.m_Entry, null);
            this.m_CurrentEntryChangedDispatcher.Dispatcher(this.m_DeckTraversal, null);

            this.m_CurrentDeckTraversalChangedDispatcher =
                this.m_Model.Workspace.CurrentDeckTraversal.ListenAndInitialize(this.SlideDisplay.EventQueue,
                delegate(Property<DeckTraversalModel>.EventArgs args) {
                    bool old = this.m_IsCurrentDeckTraversal;

                    using (this.m_Model.Workspace.Lock()) {
                        this.m_IsCurrentDeckTraversal = (~this.m_Model.Workspace.CurrentDeckTraversal == this.m_DeckTraversal);
                    }

                    if (old != this.m_IsCurrentDeckTraversal) {
                        // Invalidate the display to draw the new selection border.
                        this.UpdateSelection();
                    }
                });
        }
Пример #5
0
        public SlideModel(Guid id, LocalId localId, SlideDisposition disposition, Rectangle bounds, Guid associationId)
            : this(id, localId, disposition, bounds)
        {
            this.m_AssociationId = associationId;

            //If this is a student submission, the associationID should be set.  In this case we
            //gather some extra information about the association slide and deck.
            if (!m_AssociationId.Equals(Guid.Empty))
            {
                PresentationModel pres = PresentationModel.CurrentPresentation;
                if (pres != null)
                {
                    PresentationModel.DeckTraversalCollection traversals;
                    traversals = pres.DeckTraversals;
                    foreach (DeckTraversalModel dtm in traversals)
                    {
                        DeckModel deck;
                        using (Synchronizer.Lock(dtm.SyncRoot)) {
                            deck = dtm.Deck;
                        }
                        Guid                 deckId;
                        DeckDisposition      deckDisp;
                        TableOfContentsModel toc;
                        using (Synchronizer.Lock(deck.SyncRoot)) {
                            deckId   = deck.Id;
                            deckDisp = deck.Disposition;
                            toc      = deck.TableOfContents;
                        }
                        TableOfContentsModel.Entry tocEntry = toc.GetEntryBySlideId(m_AssociationId);
                        if (tocEntry != null)
                        {
                            using (Synchronizer.Lock(tocEntry.SyncRoot)) {
                                m_AssociationSlideIndex = tocEntry.IndexInParent;
                            }
                            m_AssociationDeckDispostion = deckDisp;
                            m_AssociationDeckId         = deckId;
                            break;
                        }
                    }
                }
            }
        }
            private void InsertSlide()
            {
                ///get the index of the current slide that's selected,
                ///so that we can insert our blank slide there
                int current_slide_index;
                using (Synchronizer.Lock(traversal_.SyncRoot)) {
                    current_slide_index = traversal_.AbsoluteCurrentSlideIndex;
                }

                ///if current_slide_index == -1, this means there are no slides in current deck.
                ///This new slide we try to insert is the first slide.
                if (current_slide_index < 0) {
                    current_slide_index = 0;
                }

                // Create a blank slide
                SlideModel slide;
                using (Synchronizer.Lock(this.m_Deck.SyncRoot)) {
                    slide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS);
                    this.m_Deck.Dirty = true;
                    this.m_Deck.InsertSlide(slide);
                }

                ///Insert our blank slide after the current index. This is modeled after the powerpoint
                ///UI
                using (Synchronizer.Lock(this.m_Deck.TableOfContents.SyncRoot)) {
                    TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.m_Deck.TableOfContents, slide);
                    this.m_WhereTheEntriesGo.Insert(current_slide_index, entry);
                }
            }
            private void InsertDeck(FileInfo file)
            {
                ///get the index of the current slide that's selected,
                ///so that we can insert our deck there
                int current_slide_index;
                using (Synchronizer.Lock(deck_traversal_.SyncRoot)) {
                    current_slide_index = deck_traversal_.AbsoluteCurrentSlideIndex;
                }

                ///if current_slide_index == -1, this means there are no slides in current deck.
                ///This new slide we try to insert is the first slide.
                if (current_slide_index < 0) {
                    current_slide_index = 0;
                }

                /// get the deck of slides to insert
                DeckModel deck = null;
                if (file.Extension == ".cp3") {
                    deck = Decks.PPTDeckIO.OpenCP3(file);

                }
                else if (file.Extension == ".ppt") {
                    deck = Decks.PPTDeckIO.OpenPPT(file);
                }
                else if (file.Extension == ".pptx") {
                    deck = Decks.PPTDeckIO.OpenPPT(file);
                }
                else if (file.Extension == ".xps") {
                    deck = Decks.XPSDeckIO.OpenXPS(file);
                }
                if (deck == null) {     // This should never happen,  since we have filtered on extension
                    throw new Exception("Wrong file extension");
                }
                else {
                    deck_.InsertDeck(deck);
                }

                using (Synchronizer.Lock(deck.TableOfContents.SyncRoot)) {
                    using (Synchronizer.Lock(deck_.TableOfContents.SyncRoot)) {
                        ///insert each slide from the deck into our current deck.
                        for (int i = 0; i < deck.TableOfContents.Entries.Count; i++) {
                            ///create our TOC entry
                            TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck_.TableOfContents, deck.TableOfContents.Entries[i].Slide);
                            ///insert it into our TOC
                            this.m_WhereTheEntriesGo.Insert(current_slide_index + i, entry);//Natalie - should it be +1?
                        }
                    }
                }
            }
Пример #8
0
        private TableOfContentsModel.Entry insertImageHelper(int index, string filename)
        {
            //Assume that traversal is already locked!
            using(Synchronizer.Lock(this.deck.SyncRoot)) {
                using(Synchronizer.Lock(this.deck.TableOfContents.SyncRoot)) {
                    //Create a new Background layer
                    //Compute the MD5 of the BG
                    FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
                    MD5 md5Provider = new MD5CryptoServiceProvider();
                    byte[] md5 = md5Provider.ComputeHash(fs);
               //                 fs.Seek(0, SeekOrigin.Begin);
               //                 Image imageFile = Image.FromStream(fs);
               //                 fs.Close();
                    fs.Close();
                    Image imageFile;
                    try {
                        imageFile = Image.FromFile(filename);
                    }
                    catch (Exception e) {
                        MessageBox.Show("Error reading in file:\r\n" + filename + "\r\n" + e.Message);
                        imageFile = new Bitmap(10, 10);

                    }

                    //Create a new SlideModel
                    SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(new Point(0, 0), imageFile.Size));
                    using(Synchronizer.Lock(newSlideModel.SyncRoot)) {
                        //Set the slide's title
                        newSlideModel.Title = filename;

                        //Create the ImageSheet
                        ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), Model.Presentation.SheetDisposition.Background,
                            new Rectangle(new Point(0, 0), imageFile.Size), (ByteArray)md5, 1);
                        //Add the ImageSheet to the Slide
                        newSlideModel.ContentSheets.Add(sheet);
                        TableOfContentsModel.Entry newEntry;

                        //Add the Image+MD5 to the deck
                        this.deck.AddSlideContent((ByteArray)md5, imageFile);
                        //Add SlideModel to the deck
                        this.deck.InsertSlide(newSlideModel);
                        //Create a new Entry + reference SlideModel
                        newEntry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, newSlideModel);
                        //Add Entry to TOC
                        this.deck.TableOfContents.Entries.Insert(index, newEntry);
                        this.isDirty = true;

                        //Return the entry so we can navigate to it, if we wish
                        return newEntry;
                    }
                }
            }
        }
            private void DuplicateSlide()
            {
                ///get the index of the current slide that's selected,
                ///so that we can insert our blank slide there
                int current_slide_index;
                using (Synchronizer.Lock(traversal_.SyncRoot)) {
                    current_slide_index = traversal_.AbsoluteCurrentSlideIndex - 1;
                }

                ///don't do anything if no object is selected
                if (current_slide_index < 0) {
                    return;
                }

                // Copy slide
                SlideModel newSlide;
                using (Synchronizer.Lock(this.m_Deck.SyncRoot)) {
                    SlideModel currentSlide = this.m_Deck.TableOfContents.Entries[current_slide_index].Slide;
                    newSlide = CloneSlideAndSheets(currentSlide);
                    //remove remote disposition for student submission slide; The removal may be not necessary for non-student submission slide.
                    //If current role is non-instructor,the sheet models in slide should contain remote disposition
                    if ((currentSlide.Disposition & SlideDisposition.StudentSubmission)!=0) {
                        newSlide.RemoveRemoteDisposition();
                    }
                    this.m_Deck.Dirty = true;
                    this.m_Deck.InsertSlide(newSlide);
                }

                ///Insert our current slide after the current index. This is modeled after the powerpoint
                ///UI
                using (Synchronizer.Lock(this.m_Deck.TableOfContents.SyncRoot)) {
                    TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.m_Deck.TableOfContents, newSlide);
                    this.m_WhereTheEntriesGo.Insert(current_slide_index + 1, entry);
                }
            }
Пример #10
0
 /// <summary>
 /// Construct the matching between two entries
 /// </summary>
 /// <param name="srcEntry">The source entry</param>
 /// <param name="dstEntry">The destination entry</param>
 public TableOfContentsEntryMatch( TableOfContentsModel.Entry srcEntry, TableOfContentsModel.Entry dstEntry )
 {
     this.m_SourceEntry = srcEntry;
     this.m_DestEntry = dstEntry;
 }
Пример #11
0
        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);
                    }
                }
            }
        }
Пример #12
0
 private static bool TestEntry(TableOfContentsModel.Entry entry)
 {
     return(entry.Slide != null);
 }
Пример #13
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="i">The index of this entry</param>
            /// <param name="e">The entry this control represents</param>
            /// <param name="deckColor">The background color for the deck
            /// containing this entry</param>
            /// <param name="location">The location for this control</param>
            /// <param name="size">The size of this control</param>
            public SSOrganizerEntry(int i, TableOfContentsModel.Entry e,
                Color deckColor, PointF location, SizeF size)
            {
                this.entry = e;
                this.location = location;
                this.size = size;

                this.SuspendLayout();

                // Create the background image
                this.cachedImage = this.CacheSlideImage(deckColor);
                this.BackgroundImage = this.cachedImage;
                this.BackgroundImageLayout = ImageLayout.Stretch;
                this.BackColor = Color.White;
                this.BorderStyle = BorderStyle.FixedSingle;
                this.ClientSize = new Size(200, 150);
                this.Location = new Point(i * this.Size.Width, 0);
                this.Anchor = AnchorStyles.Left | AnchorStyles.Top;

                this.ResumeLayout();
            }
Пример #14
0
        /// <summary>
        /// Finds the next entry, in pre-order relative to the specified entry, which is accepted by the entry filter.
        /// </summary>
        /// <remarks>
        /// The caller is required to hold a reader lock on the entry's <see cref="TableOfContentsModel"/>.
        /// </remarks>
        public TableOfContentsModel.Entry FindNext(TableOfContentsModel.Entry entry)
        {
            if (entry == null)
            {
                return(null);
            }

            using (Synchronizer.Lock(entry.SyncRoot)) {
                // Pre-order traversal: we've already visited the "current" entry, so visit it's children next.
                if (entry.Children.Count > 0)
                {
                    TableOfContentsModel.Entry child = entry.Children[0];
                    if (this.m_Filter(child))
                    {
                        return(child);
                    }
                    else
                    {
                        return(this.FindNext(child));
                    }
                }

                // If there are no children, look for a next sibling, parent's sibling, etc.
                else
                {
                    TableOfContentsModel.Entry           parent   = entry.Parent;
                    TableOfContentsModel.EntryCollection siblings = (parent == null)
                        ? entry.TableOfContents.Entries
                        : parent.Children;

                    while (siblings != null)
                    {
                        int index = siblings.IndexOf(entry);

                        // Use the entry's sibling within the parent, if possible.
                        if (index >= 0 && index < siblings.Count - 1)
                        {
                            TableOfContentsModel.Entry sibling = siblings[index + 1];
                            if (this.m_Filter(sibling))
                            {
                                return(sibling);
                            }
                            else
                            {
                                return(this.FindNext(sibling));
                            }
                        }

                        // If there is no sibling in the parent, go up another level.
                        // Do not consider parent nodes in the pre-order traversal.
                        else
                        {
                            entry    = parent;
                            parent   = (entry == null) ? null : entry.Parent;
                            siblings = (parent == null) ? null : parent.Children;
                        }
                    }

                    // If we get here, then we've run out of parents and there is no next entry!
                    return(null);
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Finds the next entry, relative to the specified entry, which is accepted by the entry filter.
        /// </summary>
        /// <remarks>
        /// The caller is required to hold a reader lock on the entry's <see cref="TableOfContentsModel"/>.
        /// </remarks>
        public TableOfContentsModel.Entry FindPrevious(TableOfContentsModel.Entry entry)
        {
            if (entry == null)
            {
                return(null);
            }

            // Pre-order traversal: we start with the last descendent of the entry's previous sibling.
            using (Synchronizer.Lock(entry.SyncRoot)) {
                TableOfContentsModel.Entry           parent   = entry.Parent;
                TableOfContentsModel.EntryCollection siblings = (parent == null)
                    ? entry.TableOfContents.Entries
                    : parent.Children;

                int index = siblings.IndexOf(entry);

                // If there exists a previous sibling, we're in good shape.
                // (This also handles the case when the given entry is not a child of its parent,
                // which can happen when entries are received over the network in a strange order.)
                if (index > 0)
                {
                    entry = siblings[index - 1];

                    // Find the *last* descendent of the sibling by going down as far as possible.
                    siblings = entry.Children;
                    while (siblings.Count > 0)
                    {
                        entry    = siblings[siblings.Count - 1];
                        siblings = entry.Children;
                    }

                    // Now, we've either got the original sibling or the last descendent of it.
                    // Use this as the previous entry, or start here if it's not accepted by the filter.
                    if (this.m_Filter(entry))
                    {
                        return(entry);
                    }
                    else
                    {
                        return(this.FindPrevious(entry));
                    }
                }

                // If there's no previous sibling and no parent, we're screwed.
                else if (parent == null)
                {
                    return(null);
                }

                // Otherwise, if there's no previous sibling, use the parent.
                else
                {
                    if (this.m_Filter(parent))
                    {
                        return(parent);
                    }
                    else
                    {
                        return(this.FindPrevious(parent));
                    }
                }
            }
        }
Пример #16
0
        private void insertBlankSlide()
        {
            //If we have nothing open, create a new deck and traversal
            bool newDeck = this.blankDeckPreCheck();

            using(Synchronizer.Lock(this.traversal.SyncRoot)) {
                using(Synchronizer.Lock(this.deck.SyncRoot)) {
                    using(Synchronizer.Lock(this.deck.TableOfContents.SyncRoot)) {
                        //TODO: The slide bounds should not be hardcoded...
                        SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, 720, 540));
                        this.deck.InsertSlide(newSlideModel);
                        TableOfContentsModel.Entry newEntry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.deck.TableOfContents, newSlideModel);
                        if (newDeck) {
                            this.deck.TableOfContents.Entries.Add(newEntry);
                        } else {
                            int index = this.traversal.AbsoluteCurrentSlideIndex;
                            if (this.insertBefore) {
                                index--;
                            }
                            this.deck.TableOfContents.Entries.Insert(index, newEntry);
                        }
                        //Navigate to that blank slide
                        this.traversal.Current = newEntry;
                    }
                }
            }
            this.isDirty = true;

            //Add event listeners for new decks
            this.blankDeckPostCheck(newDeck);
        }
Пример #17
0
 protected void SetPrevious(TableOfContentsModel.Entry value)
 {
     this.SetPublishedProperty("Previous", ref this.m_Previous, value);
 }
Пример #18
0
 protected void SetNext(TableOfContentsModel.Entry value)
 {
     this.SetPublishedProperty("Next", ref this.m_Next, value);
 }
Пример #19
0
            private void CopySlideToPublicDeck()
            {
                ///get the index of the current slide that's selected,
                ///so that we can insert our blank slide there
                int current_slide_index;
                using (Synchronizer.Lock(traversal_.SyncRoot)) {
                    current_slide_index = traversal_.AbsoluteCurrentSlideIndex - 1;
                }

                ///don't do anything if no object is selected
                if (current_slide_index < 0) {
                    return;
                }

                DeckModel publicDeck = GetPublicSubmissionDeck();

                // Copy slide
                SlideModel newSlide;
                using (Synchronizer.Lock(this.m_Deck.SyncRoot)) {
                    SlideModel currentSlide = this.m_Deck.TableOfContents.Entries[current_slide_index].Slide;
                    newSlide = CloneSlideAndSheets(currentSlide);
                    using (Synchronizer.Lock(newSlide.SyncRoot)) {
                        using (Synchronizer.Lock(currentSlide.SyncRoot)) {
                            if (currentSlide.BackgroundTemplate == null)
                                newSlide.BackgroundTemplate = this.m_Deck.DeckBackgroundTemplate;
                            if (currentSlide.BackgroundColor == Color.Empty)
                                newSlide.BackgroundColor = this.m_Deck.DeckBackgroundColor;
                        }
                    }
                    newSlide.RemoveRemoteDisposition();
                }

                using (Synchronizer.Lock(publicDeck.SyncRoot)) {
                    publicDeck.Dirty = true;
                    publicDeck.InsertSlide(newSlide);
                    UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(newSlide.Id, newSlide);

                }

                using (Synchronizer.Lock(publicDeck.TableOfContents.SyncRoot)) {
                    TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(Guid.NewGuid(), publicDeck.TableOfContents, newSlide);
                    publicDeck.TableOfContents.Entries.Add(e);
                    UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(e.Id, e);
                }

                ///Insert our current slide after the current index. This is modeled after the powerpoint
                ///UI
                //         using (Synchronizer.Lock(this.m_Deck.TableOfContents.SyncRoot)) {
                //             TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.m_Deck.TableOfContents, newSlide);
                //              this.m_WhereTheEntriesGo.Insert(current_slide_index + 1, entry);
                //         }
            }
Пример #20
0
        //TODO: Image type needs to be more dynamically chosen...
        public static DeckModel OpenPPT(FileInfo file, BackgroundWorker worker, DoWorkEventArgs progress)
        {
            //Start the progress bar
            if (worker != null) {
                worker.ReportProgress(0, "  Initializing...");
            }

            //Make the default flat tree representation of the PPT
            //Try to detect if powerpoint is already running (powerpnt.exe)
            bool pptAlreadyRunning = false;
            Process[] processes = Process.GetProcesses();
            for (int i = 0; i < processes.Length; i++) {
                string currentProcess = processes[i].ProcessName.ToLower();
                if (currentProcess == "powerpnt") {
                    pptAlreadyRunning = true;
                    break;
                }
            }
            //Open PowerPoint + open file
            PowerPoint.Application pptapp = null;
            try {
                pptapp = new PowerPoint.Application();
            }
            catch (Exception e) {
                throw new PPTNotInstalledException("Failed to create PowerPoint Application.  See InnerException for details.", e);
            }

            PowerPoint._Presentation presentation;
            try {
                presentation = pptapp.Presentations.Open(file.FullName, Core.MsoTriState.msoTrue, Core.MsoTriState.msoFalse, Core.MsoTriState.msoFalse);
            }
            catch (Exception e) {
                throw new PPTFileOpenException("Failed to open PowerPoint file.  See InnerException for details.", e);
            }

            //Initialize the PPT Shape tag reader
            PPTPaneManagement.PPTPaneManager pptpm = new PPTPaneManagement.PPTPaneManager();
            //Create a new DeckModel

            Guid deckGuid = Guid.Empty;
            try {
                string g = presentation.Tags["WEBEXPORTGUID"];
                if (g == "") {
                    deckGuid = Guid.NewGuid();
                }
                else {
                    deckGuid = new Guid(g);
                }
            }
            catch {
                deckGuid = Guid.NewGuid();
            }

            DeckModel deck = new DeckModel(deckGuid, DeckDisposition.Empty, file.Name);

            //Initialize a temporary file collection that will be where slide images are exported to
            TempFileCollection tempFileCollection = new TempFileCollection();
            string dirpath = tempFileCollection.BasePath;
            if (!Directory.Exists(dirpath)) {
                Directory.CreateDirectory(dirpath);
            } else {
                Directory.Delete(dirpath, true);
                Directory.CreateDirectory(dirpath);
            }

            //Lock it
            using(Synchronizer.Lock(deck.SyncRoot)) {
                //Iterate over all slides
                for (int i = 1;  i <= presentation.Slides.Count; i++) {
                    if (progress != null && progress.Cancel)
                        break;

                    //Get the slide
                    PowerPoint._Slide currentSlide= presentation.Slides[i];

                    if (currentSlide.SlideShowTransition.Hidden == Core.MsoTriState.msoTrue)
                        continue;

                    SlideModel newSlideModel = CreateSlide(presentation.PageSetup, pptpm, deck, tempFileCollection, dirpath, currentSlide);

                    //Create a new Entry + reference SlideModel
                    TableOfContentsModel.Entry newEntry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, newSlideModel);
                    //Lock the TOC
                    using(Synchronizer.Lock(deck.TableOfContents.SyncRoot)) {
                        //Add Entry to TOC
                        deck.TableOfContents.Entries.Add(newEntry);
                    }
                    //Increment the ProgressBarForm
                    if (worker != null) {
                        worker.ReportProgress((i * 100) / presentation.Slides.Count, "  Reading slide " + i + " of " + presentation.Slides.Count);
                    }
                }
            }
            //Close the presentation
            presentation.Close();
            presentation = null;
            //If PowerPoint was not open before, close PowerPoint
            if (!pptAlreadyRunning) {
                pptapp.Quit();
                pptapp = null;
            }
            GC.Collect();
            //Delete temp directory
            tempFileCollection.Delete();
            Directory.Delete(dirpath);

            if (worker != null)
                worker.ReportProgress(100, " Done!");

            //Return the deck
            if (progress != null)
                progress.Result = deck;
            return deck;
        }
        /// <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;
                    }
                }
            }
        }
Пример #22
0
 public SlideMenuItem(TableOfContentsModel.Entry entry, DeckTraversalModel traversal, int slideCount)
 {
     this.Entry = entry;
     this.Traversal = traversal;
     using (Synchronizer.Lock(this.Entry.Slide.SyncRoot)) {
         //Set a 50 char limit on the title
         string toDisplay = this.Entry.Slide.Title;
         if (toDisplay.Length > 50) {
             toDisplay = toDisplay.Substring(0, 50) + "...";
         }
         this.Text = "" + slideCount + ". " + toDisplay;
     }
     using (Synchronizer.Lock(this.Traversal)) {
         this.Traversal.Changed["Current"].Add(new Model.PropertyEventHandler(this.OnUpdate));
     }
     this.OnUpdate(this, null);
 }
Пример #23
0
            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>
        /// Handle the receipt of this message
        /// </summary>
        /// <param name="context">The context of the receiver from which the message was sent</param>
        protected override bool UpdateTarget(ReceiveContext context)
        {
            #if DEBUG
            // Add logging of slide change events
            string machine_name = "";
            string machine_guid = "";
            using( Synchronizer.Lock( context.Participant.SyncRoot ) ) {
                machine_name = context.Participant.HumanName;
                machine_guid = context.Participant.Guid.ToString();
            }

            Debug.WriteLine( string.Format( "SUBMISSION RCVD ({0}): Machine -- {1}, GUID -- {2}", System.DateTime.Now.Ticks, machine_name, machine_guid ) );
            #endif

            SlideModel slide = this.Target as SlideModel;
            // Only create student submissions from slides that exist on the client machine
            // TODO CMPRINCE: Should we create these anyway???
            if (slide != null) {
                // Get the student submissions deck
                DeckModel ssDeck = GetPresentationStudentSubmissionsDeck();
                if (ssDeck != null) {
                    // Check if this entry already exists
                    using (Synchronizer.Lock(ssDeck.TableOfContents.SyncRoot)) {
                        foreach (TableOfContentsModel.Entry ent in ssDeck.TableOfContents.Entries) {
                            if (ent.Id == this.TOCEntryGuid) {
                                this.Target = ent.Slide;
                                return false;
                            }
                        }
                    }

                    // Create the new slide to add
                    SlideModel newSlide = new SlideModel(this.SlideGuid, this.LocalId, SlideDisposition.Remote | SlideDisposition.StudentSubmission, this.Bounds, (Guid)this.TargetId);
                    this.Target = newSlide;

                    // Make a list of image content sheets that need to be added to the deck.
                    List<ImageSheetModel> images = new List<ImageSheetModel>();

                    // Update the fields of the slide
                    using (Synchronizer.Lock(newSlide.SyncRoot)) {
                        using (Synchronizer.Lock(slide.SyncRoot)) {
                            newSlide.Title = this.Title;
                            newSlide.Bounds = this.Bounds;
                            newSlide.Zoom = this.Zoom;
                            newSlide.BackgroundColor = this.SlideBackgroundColor;
                            newSlide.SubmissionSlideGuid = this.SubmissionSlideGuid;
                            newSlide.SubmissionStyle = this.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);

                                // 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 = 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);
                            }
                        }
                    }

                    using (Synchronizer.Lock(ssDeck.SyncRoot)) {
                        // Add the slide content to the deck.
                        foreach (ImageSheetModel ism in images) {
                            Image image = ism.Image;
                            if (image == null)
                                using (Synchronizer.Lock(ism.Deck.SyncRoot))
                                using (Synchronizer.Lock(ism.SyncRoot))
                                    image = ism.Deck.GetSlideContent(ism.MD5);
                            if (image != null)
                                ssDeck.AddSlideContent(ism.MD5, image);
                        }

                        // Add the slide to the deck.
                        ssDeck.InsertSlide(newSlide);
                        AddLocalRef(newSlide.Id, newSlide);
                    }

                    // Add an entry to the deck traversal so that we can navigate to the slide
                    using (Synchronizer.Lock(ssDeck.TableOfContents.SyncRoot)) {
                        TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(this.TOCEntryGuid, ssDeck.TableOfContents, newSlide);
                        ssDeck.TableOfContents.Entries.Add(e);
                        AddLocalRef(e.Id, e);
                    }
                }
            }

            // Fix Bug 803: "Erased ink and text still shows up in student submissions".
            // We've updated our target with 'newSheet', which is NOT the real target!
            // Child messages should be able to access this target, but we don't want to
            // save the 'newSheet' in the targets table.  We want to keep the original sheet.
            return false;
        }
Пример #25
0
        /// <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 );
                            }
                        }
                    }
                }
            }
        }
        protected override bool UpdateTarget(ReceiveContext context)
        {
            SlideModel slide = this.Parent != null ? this.Parent.Target as SlideModel : null;
            if(slide == null)
                return false;

            DeckModel deck = this.Parent.Parent != null ? this.Parent.Parent.Target as DeckModel : null;
            if(deck == null)
                return false;

            TableOfContentsModel.Entry entry = this.Target as TableOfContentsModel.Entry;
            if(entry == null)
                this.Target = entry = new TableOfContentsModel.Entry(((Guid) this.TargetId), deck.TableOfContents, slide);

            this.UpdatePathFromRoot(entry);

            return true;
        }
Пример #27
0
        /// <summary>
        /// Advance to the next slide
        /// <remarks>
        /// Code taken from the next slide toolbar button
        /// </remarks>
        /// </summary>
        protected void NextSlide()
        {
            using( Synchronizer.Lock( this ) ) {
                if( this.currentDeckTraversal == null ) return;
                using( Synchronizer.Lock( this.currentDeckTraversal.SyncRoot ) ) {
                    if( this.currentDeckTraversal.Next != null )
                        // Advance the slide
                        this.currentDeckTraversal.Current = this.currentDeckTraversal.Next;
                    else {
                        // Add a whiteboard slide if we are at the end of the deck
                        using (Synchronizer.Lock(this.currentDeckTraversal.Deck.SyncRoot)) {
                            if (((this.currentDeckTraversal.Deck.Disposition & DeckDisposition.Whiteboard) != 0) &&
                                ((this.currentDeckTraversal.Deck.Disposition & DeckDisposition.Remote) == 0)) {
                                // Add the new slide
                                SlideModel slide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS);
                                this.currentDeckTraversal.Deck.InsertSlide(slide);
                                using (Synchronizer.Lock(this.currentDeckTraversal.Deck.TableOfContents.SyncRoot)) {
                                    // Add the new table of contents entry
                                    TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), this.currentDeckTraversal.Deck.TableOfContents, slide);
                                    this.currentDeckTraversal.Deck.TableOfContents.Entries.Add(entry);

                                    // Move to the slide
                                    this.currentDeckTraversal.Current = entry;
                                }
                            }
                        }
                    }
                }
            }
        }
            /// <summary>
            /// Handle clicking of this button (switch between whiteboard and normal deck)
            /// </summary>
            /// <param name="args">The event arguments</param>
            protected override void OnClick(EventArgs args)
            {
                using (this.m_Model.Workspace.Lock())
                {
                    using( Synchronizer.Lock( this.m_Model.Participant.SyncRoot ) )
                    {
                        DeckTraversalModel traversal;

                        if (this.CurrentDeckTraversal == null || (this.CurrentDeckTraversal.Deck.Disposition & DeckDisposition.Whiteboard) == 0)
                        {
                            traversal = this.m_PreviousWhiteboard;

                            // Make sure the deck hasn't been closed.
                            if (!this.m_Model.Workspace.DeckTraversals.Contains(traversal))
                                traversal = this.m_PreviousWhiteboard = null;

                            // If there is no previous whiteboard traversal, find one or create one.
                            if (traversal == null)
                            {
                                // TODO: If the participant is an instructor, *only* search the whiteboards in the active presentation.
                                //   Then, when changing the current deck, also change the current presentation if necessary.

                                foreach (DeckTraversalModel candidate in this.m_Model.Workspace.DeckTraversals)
                                {
                                    if ((candidate.Deck.Disposition & DeckDisposition.Whiteboard) != 0)
                                    {
                                        traversal = candidate;
                                        break;
                                    }
                                }

                                // If there is no existing whiteboard deck, create one.
                                if (traversal == null)
                                {
                                    // Change the name of whiteboard according to the number of it
                                    string wbname = "WhiteBoard " + (++UW.ClassroomPresenter.Viewer.ViewerForm.white_board_num).ToString();
                                    // NOTE: This code is duplicated in DecksMenu.CreateBlankWhiteboardDeckMenuItem.
                                    DeckModel deck = new DeckModel(Guid.NewGuid(), DeckDisposition.Whiteboard, wbname);
                                    using (Synchronizer.Lock(deck.SyncRoot))
                                    {
                                        SlideModel slide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, UW.ClassroomPresenter.Viewer.ViewerForm.DEFAULT_SLIDE_BOUNDS);

                                        deck.InsertSlide(slide);

                                        using (Synchronizer.Lock(deck.TableOfContents.SyncRoot))
                                        {
                                            TableOfContentsModel.Entry entry = new TableOfContentsModel.Entry(Guid.NewGuid(), deck.TableOfContents, slide);
                                            deck.TableOfContents.Entries.Add(entry);
                                        }
                                    }

                                    traversal = new SlideDeckTraversalModel(Guid.NewGuid(), deck);

                                    if (this.m_Model.Workspace.CurrentPresentation.Value != null)
                                    {
                                        using (Synchronizer.Lock((~this.m_Model.Workspace.CurrentPresentation).SyncRoot))
                                        {
                                            (~this.m_Model.Workspace.CurrentPresentation).DeckTraversals.Add(traversal);
                                        }
                                    }
                                    else
                                    {
                                        this.m_Model.Workspace.DeckTraversals.Add(traversal);
                                    }
                                }
                            }
                        }
                        else
                        {
                            traversal = this.m_PreviousNormal;

                            // Make sure the deck hasn't been closed.
                            if (!this.m_Model.Workspace.DeckTraversals.Contains(traversal))
                                traversal = this.m_PreviousNormal = null;

                            // Search the workspace for a non-whiteboard deck if we haven't encountered one before.
                            if (traversal == null)
                            {
                                // TODO: If the participant is an instructor, *only* search the whiteboards in the active presentation.
                                foreach (DeckTraversalModel candidate in this.m_Model.Workspace.DeckTraversals)
                                {
                                    if ((candidate.Deck.Disposition & DeckDisposition.Whiteboard) == 0)
                                    {
                                        traversal = candidate;
                                        break;
                                    }
                                }

                                // If we still haven't found a non-whiteboard deck, do nothing.
                                if (traversal == null)
                                    return;
                            }
                        }

                        // If the user's role is an InstructorModel, set the InstructorModel's CurrentDeckTraversal.
                        // The NetworkAssociationService will then use this to set the WorkspaceModel's CurrentDeckTraversal,
                        // and the new deck traversal will also be broadcast.
                        InstructorModel instructor = this.m_Model.Participant.Role as InstructorModel;
                        if (instructor != null)
                        {
                            using (Synchronizer.Lock(instructor.SyncRoot))
                            {
                                instructor.CurrentDeckTraversal = traversal;
                            }
                        }
                        else
                        {
                            // Otherwise, we must set the CurrentDeckTraversal on the WorkspaceModel directly.
                            using (this.m_Model.Workspace.Lock())
                            {
                                this.m_Model.Workspace.CurrentDeckTraversal.Value = traversal;
                            }
                        }
                    }
                }
                base.OnClick(args);
            }