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> /// Generate slide images from a CP3 file /// </summary> /// <param name="g"></param> /// <param name="fileInfo"></param> private void processCp3(Guid g, FileInfo fileInfo) { if (stopNow) { return; } String tempDirName = Utility.GetTempDir(); try { DeckModel deck = UW.ClassroomPresenter.Decks.PPTDeckIO.OpenCP3(fileInfo); SlideDeckTraversalModel dtm = new SlideDeckTraversalModel(Guid.NewGuid(), deck); if (stopNow) { return; } UW.ClassroomPresenter.Decks.PPTDeckIO.ExportDeck(dtm, tempDirName, ImageFormat.Jpeg); dtm.Dispose(); } catch (Exception e) { log.WriteLine("Failed to open CP3 file: " + fileInfo.FullName + " Exception: " + e.ToString()); log.ErrorLevel = 5; return; } //Make conformant file names tempDirName = translateCP3ImageNames(tempDirName); this.outputDirs.Add(g, tempDirName); }
/// <summary> /// Creates the student submissions deck and deck traversal if one doesn't already exist. /// Otherwise returns the existing student submission deck /// </summary> /// <returns>The student submissions deck for this presentation, if one does not /// already exist this function creates one</returns> protected DeckModel GetPresentationStudentSubmissionsDeck() { // Sanity Checks to ensure that the message hierarchy is as we expect if (this.Parent.Parent != null && this.Parent.Parent.Target != null && this.Parent.Parent.Target is PresentationModel) { // Try to get an existing student submissions deck PresentationModel pres = this.Parent.Parent.Target as PresentationModel; DeckModel deck = pres.GetStudentSubmissionDeck(); if (deck != null) { return(deck); } else { // Create the student submissions deck // TODO CMPRINCE: We currently hardcode values for the student submissions deck and // deck traversal. Is there a better way to do this? // Natalie - Apparently the reason that these are hardcoded has to do with the //public display of student submissions - when I switched these guids to normally //generated guids the public display lost the ability to display student submissions. Guid ssGuid = new Guid("{78696D29-AA11-4c5b-BCF8-8E6406077FD4}"); Guid ssTraversalGuid = new Guid("{4884044B-DAE1-4249-AEF2-3A2304F52E97}"); deck = new DeckModel(ssGuid, DeckDisposition.StudentSubmission, "Student Submissions"); deck.Group = Groups.Group.Submissions; deck.current_subs = true; AddLocalRef(ssGuid, deck); DeckTraversalModel traversal = new SlideDeckTraversalModel(ssTraversalGuid, deck); AddLocalRef(ssTraversalGuid, traversal); // Add the new student submission deck to the presentation using (Synchronizer.Lock(pres.SyncRoot)) { pres.DeckTraversals.Add(traversal); } return(deck); } } return(null); }
/// <summary> /// Open the file with CP3, then use CP3's export function to create slide images. /// </summary> /// <param name="g"></param> /// <param name="fileInfo"></param> private void processPptWithCp3(Guid g, FileInfo fileInfo) { if (stopNow) { return; } //TODO: can we do anything with progress tracker here? try { DeckModel deck; deck = UW.ClassroomPresenter.Decks.PPTDeckIO.OpenPPT(fileInfo); String tempDirName = Utility.GetTempDir(); DefaultDeckTraversalModel traversal = new SlideDeckTraversalModel(Guid.NewGuid(), deck); if (stopNow) { return; } List <string> imageNames; if (this.useDefaultSize) { imageNames = UW.ClassroomPresenter.Decks.PPTDeckIO.ExportDeck(traversal, tempDirName, ImageFormat.Jpeg); } else { Console.WriteLine("Exporting deck with custom size: " + this.imageWidth.ToString() + "x" + this.imageHeight.ToString()); imageNames = UW.ClassroomPresenter.Decks.PPTDeckIO.ExportDeck(traversal, tempDirName, ImageFormat.Jpeg, this.imageWidth, this.imageHeight, 1.0f); } fixSlideImageNames(tempDirName); this.outputDirs.Add(g, tempDirName); } catch (Exception ex) { log.WriteLine(ex.ToString()); log.ErrorLevel = 6; } }
/// <summary> /// Creates the student submissions deck and deck traversal if one doesn't already exist. /// Otherwise returns the existing student submission deck /// </summary> /// <returns>The student submissions deck for this presentation, if one does not /// already exist this function creates one</returns> protected DeckModel GetPublicSubmissionDeck() { PresentationModel pm; using (Synchronizer.Lock(this.m_Model.Workspace.CurrentPresentation.SyncRoot)) { pm = this.m_Model.Workspace.CurrentPresentation; } if (pm != null) { DeckModel deck = pm.GetPublicSubmissionDeck(); if (deck != null) { return(deck); } else { // Create the public submissions deck - copy from student sub code. // TODO CMPRINCE: We currently hardcode values for the student submissions deck and // deck traversal. Is there a better way to do this? // Natalie - Apparently the reason that these are hardcoded has to do with the //public display of student submissions - when I switched these guids to normally //generated guids the public display lost the ability to display student submissions. Guid psGuid = new Guid("{EFC46492-5865-430d-962F-8D39038E2C6F}"); Guid psTraversalGuid = new Guid("{18C3CD05-EDCE-4018-AC8B-64E618EB9804}"); deck = new DeckModel(psGuid, DeckDisposition.PublicSubmission, "Public Submissions"); deck.Group = UW.ClassroomPresenter.Network.Groups.Group.AllParticipant; UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(psGuid, deck); DeckTraversalModel traversal = new SlideDeckTraversalModel(psTraversalGuid, deck); UW.ClassroomPresenter.Network.Messages.Message.AddLocalRef(psTraversalGuid, traversal); // Add the new student submission deck to the presentation using (Synchronizer.Lock(pm.SyncRoot)) { pm.DeckTraversals.Add(traversal); } return(deck); } } return(null); }
protected override bool UpdateTarget(ReceiveContext context) { DeckModel deck = this.Parent != null ? this.Parent.Target as DeckModel : null; if (deck == null) { return(false); } SlideDeckTraversalModel traversal = this.Target as SlideDeckTraversalModel; if (traversal == null) { this.Target = traversal = new SlideDeckTraversalModel(((Guid)this.TargetId), deck); } base.UpdateTarget(context); return(true); }
private void OpenXps(FileInfo file) { DeckModel deck = this.m_Marshal.ReadDeckAsync(file, null, null); if (deck != null) { using (Synchronizer.Lock(deck)) { string fileName = file_to_open_.Name; if (file_to_open_.Name.EndsWith(".xps")) { fileName = fileName.Remove(fileName.Length - 4); } else { return; } deck.HumanName = fileName; deck.Dirty = false; if (deck.Disposition == DeckDisposition.StudentSubmission) { deck.Group = Network.Groups.Group.Submissions; } } 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> /// Creates a new QuickPoll and the associated slide (and deck) /// </summary> /// <param name="model">The PresenterModel</param> /// <param name="role">The RoleModel</param> public static void CreateNewQuickPoll(PresenterModel model, RoleModel role) { // Create the quickpoll QuickPollModel newQuickPoll = null; using (Synchronizer.Lock(model.ViewerState.SyncRoot)) { newQuickPoll = new QuickPollModel(Guid.NewGuid(), Guid.NewGuid(), model.ViewerState.PollStyle); } // Get the Current Slide SlideModel oldSlide; using (Synchronizer.Lock(role.SyncRoot)) { using (Synchronizer.Lock(((InstructorModel)role).CurrentDeckTraversal.SyncRoot)) { using (Synchronizer.Lock(((InstructorModel)role).CurrentDeckTraversal.Current.SyncRoot)) { oldSlide = ((InstructorModel)role).CurrentDeckTraversal.Current.Slide; } } } // Add a new QuickPoll to the model // NOTE: This should trigger a network message about the new QuickPoll // NOTE: Need to do this first before adding the sheet otherwise the // public display will not be able to associate the sheet with // this quick poll. using (model.Workspace.Lock()) { using (Synchronizer.Lock((~model.Workspace.CurrentPresentation).SyncRoot)) { (~model.Workspace.CurrentPresentation).QuickPoll = newQuickPoll; } } // Add the quickpoll slide to the quickpoll using (model.Workspace.Lock()) { using (Synchronizer.Lock(model.Participant.SyncRoot)) { DeckTraversalModel qpTraversal = null; DeckModel qpDeck = null; // Find the first quickpoll slidedeck. foreach (DeckTraversalModel candidate in model.Workspace.DeckTraversals) { if ((candidate.Deck.Disposition & DeckDisposition.QuickPoll) != 0) { qpTraversal = candidate; using (Synchronizer.Lock(qpTraversal.SyncRoot)) { qpDeck = qpTraversal.Deck; } break; } } // If there is no existing quickpoll deck, create one. if (qpTraversal == null) { // Change the name of quickpoll according to the number of it string qpName = "QuickPoll"; // NOTE: This code is duplicated in DecksMenu.CreateBlankWhiteboardDeckMenuItem. qpDeck = new DeckModel(Guid.NewGuid(), DeckDisposition.QuickPoll, qpName); qpDeck.Group = Network.Groups.Group.Submissions; qpTraversal = new SlideDeckTraversalModel(Guid.NewGuid(), qpDeck); if (model.Workspace.CurrentPresentation.Value != null) { using (Synchronizer.Lock((~model.Workspace.CurrentPresentation).SyncRoot)) { (~model.Workspace.CurrentPresentation).DeckTraversals.Add(qpTraversal); } } else { model.Workspace.DeckTraversals.Add(qpTraversal); } } // Add the slide // TODO CMPRINCE: Associate the quickpoll with this slide using (Synchronizer.Lock(qpDeck.SyncRoot)) { // Copy the values and sheets from the old slide to the new slide // Get oldSlide's Guid Guid oldId = Guid.Empty; using (Synchronizer.Lock(oldSlide.SyncRoot)) { oldId = oldSlide.Id; } // Create the new slide to add SlideModel newSlide = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Remote | SlideDisposition.StudentSubmission, DEFAULT_SLIDE_BOUNDS, oldId); // Make a list of image content sheets that need to be added to the deck. List <ImageSheetModel> images = new List <ImageSheetModel>(); // Update the fields of the slide using (Synchronizer.Lock(oldSlide.SyncRoot)) { using (Synchronizer.Lock(newSlide.SyncRoot)) { newSlide.Title = oldSlide.Title; newSlide.Bounds = oldSlide.Bounds; newSlide.Zoom = oldSlide.Zoom; newSlide.BackgroundColor = oldSlide.BackgroundColor; newSlide.SubmissionSlideGuid = oldSlide.SubmissionSlideGuid; newSlide.SubmissionStyle = oldSlide.SubmissionStyle; // Copy all of the content sheets. // Because ContentSheets do not change, there is no // need to do a deep copy (special case for ImageSheetModels). foreach (SheetModel s in oldSlide.ContentSheets) { newSlide.ContentSheets.Add(s); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } // Add the QuickPollSheet newSlide.ContentSheets.Add(new QuickPollSheetModel(Guid.NewGuid(), newQuickPoll)); // Make a deep copy of all the ink sheets foreach (SheetModel s in oldSlide.AnnotationSheets) { SheetModel newSheet = SheetModel.SheetDeepCopyHelper(s); newSlide.AnnotationSheets.Add(newSheet); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } } } // Add the slide content to the deck. foreach (ImageSheetModel ism in images) { System.Drawing.Image image = ism.Image; if (image == null) { using (Synchronizer.Lock(ism.Deck.SyncRoot)) using (Synchronizer.Lock(ism.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); } if (image != null) { qpDeck.AddSlideContent(ism.MD5, image); } } // Add the slide to the deck. qpDeck.InsertSlide(newSlide); // Add an entry to the deck traversal so that we can navigate to the slide using (Synchronizer.Lock(qpDeck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(Guid.NewGuid(), qpDeck.TableOfContents, newSlide); qpDeck.TableOfContents.Entries.Add(e); } } } } }
/// <summary> /// /// </summary> /// <param name="server"></param> /// <param name="deckIndex"></param> /// <param name="slideIndex"></param> /// <param name="strokes">SimpleWebInk objects that make up the strokes.</param> public void HandleStudentSubmission(object server, int deckIndex, int slideIndex, ArrayList strokes) { SlideModel slide = null; DeckModel deck = null; using (Synchronizer.Lock(this.m_Presentation.SyncRoot)) { using (Synchronizer.Lock(this.m_Presentation.DeckTraversals[deckIndex].SyncRoot)) { using (Synchronizer.Lock(this.m_Presentation.DeckTraversals[deckIndex].Current.SyncRoot)) { // Get the slide model slide = this.m_Presentation.DeckTraversals[deckIndex].Current.Slide; } deck = this.m_Presentation.DeckTraversals[deckIndex].Deck; } } // Get the student submissions deck or create it if it doesn't exist DeckModel ssDeck = this.m_Presentation.GetStudentSubmissionDeck(); if (ssDeck == null) { // Create the student submissions deck Guid ssGuid = new Guid("{78696D29-AA11-4c5b-BCF8-8E6406077FD4}"); Guid ssTraversalGuid = new Guid("{4884044B-DAE1-4249-AEF2-3A2304F52E97}"); ssDeck = new DeckModel(ssGuid, DeckDisposition.StudentSubmission, "Student Submissions"); ssDeck.Group = Group.Submissions; ssDeck.current_subs = true; // AddLocalRef(ssGuid, ssDeck); DeckTraversalModel traversal = new SlideDeckTraversalModel(ssTraversalGuid, ssDeck); // AddLocalRef(ssTraversalGuid, traversal); // Add the new student submission deck to the presentation using (Synchronizer.Lock(this.m_Presentation.SyncRoot)) { this.m_Presentation.DeckTraversals.Add(traversal); } } // Create the new slide to add SlideModel newSlide = new SlideModel(new Guid(), new LocalId(), SlideDisposition.Remote | SlideDisposition.StudentSubmission); // Make a list of image content sheets that need to be added to the deck. List <ImageSheetModel> images = new List <ImageSheetModel>(); // Update the fields of the slide using (Synchronizer.Lock(newSlide.SyncRoot)) { using (Synchronizer.Lock(slide.SyncRoot)) { newSlide.Title = slide.Title; newSlide.Bounds = slide.Bounds; newSlide.Zoom = slide.Zoom; newSlide.BackgroundColor = slide.BackgroundColor; newSlide.BackgroundTemplate = slide.BackgroundTemplate; newSlide.SubmissionSlideGuid = slide.SubmissionSlideGuid; newSlide.SubmissionStyle = slide.SubmissionStyle; //If the slide background is null, then update the slide background with deck setting using (Synchronizer.Lock(deck.SyncRoot)) { if (slide.BackgroundColor == System.Drawing.Color.Empty) { newSlide.BackgroundColor = deck.DeckBackgroundColor; } if (slide.BackgroundTemplate == null) { newSlide.BackgroundTemplate = deck.DeckBackgroundTemplate; } } // Copy all of the content sheets. // Because ContentSheets do not change, there is no // need to do a deep copy (special case for ImageSheetModels). foreach (SheetModel s in slide.ContentSheets) { newSlide.ContentSheets.Add(s); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } // Make a deep copy of all the ink sheets foreach (SheetModel s in slide.AnnotationSheets) { SheetModel newSheet = UW.ClassroomPresenter.Model.Presentation.SheetModel.SheetDeepRemoteCopyHelper(s); newSlide.AnnotationSheets.Add(newSheet); // Queue up any image content to be added the deck below. ImageSheetModel ism = s as ImageSheetModel; if (ism != null) { images.Add(ism); } } } } // Add the slide content to the deck. using (Synchronizer.Lock(ssDeck.SyncRoot)) { foreach (ImageSheetModel ism in images) { System.Drawing.Image image = ism.Image; if (image == null) { using (Synchronizer.Lock(ism.Deck.SyncRoot)) using (Synchronizer.Lock(ism.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); } if (image != null) { ssDeck.AddSlideContent(ism.MD5, image); } } // Add the slide to the deck. ssDeck.InsertSlide(newSlide); } // Add an entry to the deck traversal so that we can navigate to the slide using (Synchronizer.Lock(ssDeck.TableOfContents.SyncRoot)) { TableOfContentsModel.Entry e = new TableOfContentsModel.Entry(new Guid(), ssDeck.TableOfContents, newSlide); ssDeck.TableOfContents.Entries.Add(e); } // Add the ink to the slide now using (Synchronizer.Lock(newSlide.SyncRoot)) { RealTimeInkSheetModel sheet = new RealTimeInkSheetModel(new Guid(), SheetDisposition.All | SheetDisposition.Remote, newSlide.Bounds); // Add the sheet newSlide.AnnotationSheets.Add(sheet); // Now add the ink using (Synchronizer.Lock(sheet.Ink.Strokes.SyncRoot)) { foreach (SimpleWebInk stroke in strokes) { Microsoft.Ink.Stroke s = sheet.Ink.CreateStroke(stroke.Pts); s.DrawingAttributes.Color = System.Drawing.Color.FromArgb(stroke.R, stroke.G, stroke.B); s.DrawingAttributes.RasterOperation = (stroke.Opacity < 255) ? Microsoft.Ink.RasterOperation.MaskPen : Microsoft.Ink.RasterOperation.CopyPen; s.DrawingAttributes.Width = stroke.Width * 30.00f; } } } }
public SlideDeckTraversalMessage(SlideDeckTraversalModel traversal) : base(traversal) { }
/// <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); }
private void RunWorker(object sender, DoWorkEventArgs progress) { DeckModel deck = this.m_Marshal.ReadDeckAsync(((FileInfo)progress.Argument), ((BackgroundWorker)sender), progress); // Failure is indicated by a null deck - not clear if this is the best way to handle things if (deck != null) { using (Synchronizer.Lock(deck)) { ///in order to have the tabbed files display correctly, we need to set their ///'HumanName' property. Since most people don't want to see the '.cp3' or '.ppt'part ///we'll just erase this. BUG 961 fixed ///Also erase '.pptx', BUG 1130 fixed string fileName = file_to_open_.Name; if (file_to_open_.Name.EndsWith(".cp3") || file_to_open_.Name.EndsWith(".ppt")) { fileName = fileName.Remove(fileName.Length - 4); } if (file_to_open_.Name.EndsWith(".pptx")) { fileName = fileName.Remove(fileName.Length - 5); } deck.HumanName = fileName; //Since opened from a file, the dirty bit should be false, even if //it's a student submission deck. deck.Dirty = false; if (deck.Disposition == DeckDisposition.StudentSubmission) { deck.Group = Network.Groups.Group.Submissions; } } DeckTraversalModel traversal = new SlideDeckTraversalModel(Guid.NewGuid(), deck); #if WEBSERVER // TODO CMPRINCE WEBSERVER: This isn't an ideal solution // Export the deck now as images for the web server using (Synchronizer.Lock(traversal.SyncRoot)) { using (Synchronizer.Lock(traversal.Deck.SyncRoot)) { string imagePath = Path.Combine(Web.WebService.WebRoot, "images\\decks\\" + traversal.Deck.HumanName + "\\" + traversal.Deck.HumanName + "\\"); PPTDeckIO.ExportDeck((DefaultDeckTraversalModel)traversal, imagePath, System.Drawing.Imaging.ImageFormat.Png); string imagePath2 = Path.Combine(Web.WebService.WebRoot, "images\\decks\\" + traversal.Deck.HumanName + "\\" + traversal.Deck.HumanName + "\\thumbnails\\"); PPTDeckIO.ExportDeck((DefaultDeckTraversalModel)traversal, imagePath2, System.Drawing.Imaging.ImageFormat.Png, 0, 0, 0.5f); } } #endif 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); } } } }