public static RTDocument PPT2RTDocument(string pptFilename) { //Pri2: Investigate where BasePath is and where we should be putting it in more depth. // Concerned that we're creating directories there that never get cleaned up... if (!Directory.Exists(tfc.BasePath)) { Directory.CreateDirectory(tfc.BasePath); } // Initialize PowerPoint app ApplicationClass ppt = new ApplicationClass(); // Open the PPT file Presentation presentation = ppt.Presentations.Open(pptFilename, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse); Slides slides = presentation.Slides; // Set up the document RTDocument rtDoc = new RTDocument(); rtDoc.Identifier = Guid.NewGuid(); rtDoc.Metadata.Title = GetPresentationProperty(presentation, "Title"); rtDoc.Metadata.Creator = GetPresentationProperty(presentation, "Author"); // Create shared MemoryStream to minimize mem usage MemoryStream ms = new MemoryStream(); //Iterate through the pages int i = 0; foreach (Slide s in slides) { // Set the page properties Page p = new Page(); p.Identifier = Guid.NewGuid(); p.Image = GetSlideImage(s, ms); if (p.Image is Metafile) { p.MimeType = "image/x-wmf"; } if (p.Image is Bitmap) { p.MimeType = "image/png"; } rtDoc.Resources.Pages.Add(p.Identifier, p); // TODO, slice in RegionBuilder code from Presenter work... // Set the TOCNode properties for the page TOCNode tn = new TOCNode(); tn.Title = GetSlideTitle(s); tn.Resource = p; tn.ResourceIdentifier = p.Identifier; //Pri2: Shouldn't this be a byte[] containing the PNG stream instead of a System.Drawing.Image? tn.Thumbnail = RTDocumentHelper.GetThumbnailFromImage(p.Image); rtDoc.Organization.TableOfContents.Add(tn); i++; } // Close PPT presentation.Close(); if (ppt.Presentations.Count == 0) { ppt.Quit(); } ppt = null; tfc.Delete(); return(rtDoc); }
public override void AddCapability(ICapability capability) { base.AddCapability (capability); if(presentationCapability == null) { presentationCapability = (PresentationCapability)capability; presentationCapability.ObjectReceived += new CapabilityObjectReceivedEventHandler(ObjectReceived); // Init StatusBar statusBar.SetBusyStatusMessage(Strings.Loading); // Init ThumbnailsListView this.thumbnailsView.ImageSelected += new System.EventHandler(this.thumbnailsView_SelectedImageChanged); this.thumbnailsView.ImageMouseEnter += new EventHandler(thumbnailsView_ImageMouseEnter); this.thumbnailsView.ImageMouseLeave +=new EventHandler(thumbnailsView_ImageMouseLeave); Size pbSize = new Size(thumbnailsView.ClientRectangle.Width - 55, 0); pbSize.Height = (int)( ((float)pbSize.Width)*(3F/4F) ); // Create blank RTDocument this.rtDocument = new RTDocument(); rtDocument.Identifier = new Guid(constWhiteboardGuid); rtDocument.Metadata.Title = Strings.WhiteboardSession; rtDocument.Metadata.Creator = Conference.LocalParticipant.Name; // Add a blank page Page pg = new Page(); pg.Identifier = new Guid(constWhiteboardGuid); TOCNode tn = new TOCNode(); tn.Title = Strings.Whiteboard1; tn.Resource = pg; tn.ResourceIdentifier = pg.Identifier; tn.Identifier = new Guid(constWhiteboardGuid); rtDocument.Organization.TableOfContents.Add(tn); rtDocument.Resources.Pages.Add(pg.Identifier, pg); // Wrap the RTD with a helper & init vars rtDocumentHelper = new RTDocumentHelper( presentationCapability, rtDocument ); rtDocumentHelper.CurrentOrganizationNodeIdentifier = tn.Identifier; statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); thumbnailsView.InsertThumbnail(null, tn.Title, 0, tn.Identifier); thumbnailsView.SelectedIndex = 0; this.pageShowing = pg.Identifier; } }
/// <summary> /// Open a file in local rtd file name. /// </summary> /// <param name="fileName">filename (path + filename)</param> // Pri3: There is a lot of duplication of code between openLocalFile // and miOpenRemote_Click method that could be written just once // If this code is going to stay in long term we should change that private void openLocalFile(string fileName) { try { // Open a RTD file lock(this) { rtDocument = LoadRtdFile(fileName); } if (rtDocument == null) { return; } // Update the title bar of the form // with the document name followed by the capability name this.Text = rtDocument.Metadata.Title + " - " + this.presentationCapability.Name; DisplayRTDocumentOnlyStructureInfo(); rtDocumentHelper = new RTDocumentHelper(this.presentationCapability, rtDocument); DisplayRTDocumentStructureInfo(); #region Populate thumbnails ArrayList thumbnails = new ArrayList(); using (Bitmap bp = new Bitmap( thumbnailsView.ImageSize.Width, thumbnailsView.ImageSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) { using (Graphics g = Graphics.FromImage(bp)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; foreach( TOCNode tn in rtDocument.Organization.TableOfContents ) { Page p = (Page)tn.Resource; ThumbnailListView.CreateSlideThumbnail( thumbnailsView.ImageSize, p.Image, g, tn.Title ); ThumbnailListViewItem item = new ThumbnailListViewItem(); item.thumbnail = ((Bitmap)bp.Clone()); item.tag = tn.Identifier; thumbnails.Add(item); } } } thumbnailsView.Items = (ThumbnailListViewItem[])thumbnails.ToArray(typeof(ThumbnailListViewItem)); #endregion // Initialize the index on the first slide index = 0; // Show the current page statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); ShowPage(rtDocument.Organization.TableOfContents[index].Identifier); // Display the current page on the sender and viewer UpdateCurrentPage(); UpdateNavigationButtonState(); } catch(Exception ex) { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpening, fileName,ex.Message.ToString()), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } }
// Pri2: All the code in this region is temporary // The code in this region allows to request remote capability to open a // rtd file located in the same place than the one open by the initiator // The Open Remote menu has to be explicitely activated using the // application configuration key // MSR.LST.ConferenceXP.Capability.Presentation.OpenRemote /// <summary> /// Menu item miOpenRemote_Click event handler. Open a remote rtd file. /// When you open a file using this menu, the exact same rtd file has to be /// at at the same location on every remote machine /// </summary> /// <param name="sender">The event sender object</param> /// <param name="e">The event arguments</param> private void miOpenRemote_Click(object sender, System.EventArgs e) { System.Windows.Forms.OpenFileDialog cdlg = new OpenFileDialog(); cdlg.Filter = "RTDocument files (*.rtd)|*.rtd" ; DialogResult dr = cdlg.ShowDialog(); try { if (dr == DialogResult.OK) { string fileName = cdlg.FileName; if (System.IO.Path.GetExtension(fileName).ToLower(CultureInfo.InvariantCulture) == ".rtd") { // Open a RTD file lock(this) { rtDocument = LoadRtdFile(fileName); } if (rtDocument == null) { return; } } else { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpeningFileType, fileName), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } Log(string.Format(CultureInfo.CurrentCulture, "rtDocID = {0}", rtDocument.Identifier.ToString())); // Update the title bar of the form // with the document name followed by the capability name this.Text = rtDocument.Metadata.Title + " - " + this.presentationCapability.Name; // Clean up the screen DeleteAllStrokes(); Log("On open doc: info before creating RTDocHelper,"); DisplayRTDocumentOnlyStructureInfo(); rtDocumentHelper = new RTDocumentHelper(this.presentationCapability, rtDocument); Log("Structure Info on open after creating RTDocHelper,"); DisplayRTDocumentStructureInfo(); #region Populate thumbnails ArrayList thumbnails = new ArrayList(); using (Bitmap bp = new Bitmap( thumbnailsView.ImageSize.Width, thumbnailsView.ImageSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) { using (Graphics g = Graphics.FromImage(bp)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; foreach( TOCNode tn in rtDocument.Organization.TableOfContents ) { Page p = (Page)tn.Resource; ThumbnailListView.CreateSlideThumbnail( thumbnailsView.ImageSize, p.Image, g, tn.Title ); ThumbnailListViewItem item = new ThumbnailListViewItem(); item.thumbnail = ((Bitmap)bp.Clone()); item.tag = tn.Identifier; thumbnails.Add(item); } } } thumbnailsView.Items = (ThumbnailListViewItem[])thumbnails.ToArray(typeof(ThumbnailListViewItem)); #endregion // Initialize the index on the first slide index = 0; // Show the current page statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); ShowPage(rtDocument.Organization.TableOfContents[index].Identifier); // Send a message to request the remote users to open the rtd file // fileName SendRemoteFileOpen(fileName); // Update the Backward/Forward buttons (push the navigation button in the // direction(s)that you cannot move anymore) UpdateNavigationButtonState(); // Display the current page on the sender and viewer UpdateCurrentPage(); } } catch(Exception ex) { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpening, cdlg.FileName, ex.Message.ToString()), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } }
/// <summary> /// This method allows the initiator to open a .ppt or .rtd file. /// After the file is open, all the slides are sent to the client(s) and the /// client(s) are positionned to the same page than the initiator. /// </summary> /// <remarks>If you open a .ppt file, a corresponding .rtd file is automatically /// created with the same name and saved in the same folder. If there is an /// existing .rtd file with the same name in this folder, it will be overwrited</remarks> /// <param name="fileMenu">This parameter is for extensibility. The only value so far /// is OpenSlideDeck</param> private void openFile() { System.Windows.Forms.OpenFileDialog cdlg = new OpenFileDialog(); cdlg.Filter = "All Presentation Documents (*.ppt, *.pptx, *.rtd)|" + "*.ppt;*.pptx;*.rtd|PowerPoint document files (*.ppt,*.pptx)|*.ppt;*.pptx|RTDocument files (*.rtd)|*.rtd" ; DialogResult dr = cdlg.ShowDialog(); try { if (dr == DialogResult.OK) { string fileName = cdlg.FileName; string extension = System.IO.Path.GetExtension(fileName).ToLower(CultureInfo.InvariantCulture); if (extension == ".ppt" || extension == ".pptx") { #region Open a PPT file lock(this) { statusBar.SetWaitStatusMessage(Strings.ImportingPowerpointDocument); rtDocument = PPTConversion.PPT2RTDocument(fileName); // Autosave the PPT document a RTD document in the same directory as PPT string outFileName = fileName.Substring(0, fileName.Length - extension.Length) + ".rtd"; FileStream fs = new FileStream(outFileName, FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, rtDocument); fs.Close(); statusBar.SetReadyStatusMessage(); } #endregion } else if (extension == ".rtd") { #region Open a RTD file lock(this) { BinaryFormatter myBinaryFormat = new BinaryFormatter(); try { FileStream myInputStream = System.IO.File.OpenRead(fileName); rtDocument = (RTDocument) myBinaryFormat.Deserialize(myInputStream); } catch (Exception) { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpeningVersion, fileName), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } } #endregion } else { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpeningFileType, fileName), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } Log(string.Format(CultureInfo.CurrentCulture, "rtDocID = {0}", rtDocument.Identifier.ToString())); // Update the title bar of the form // with the document name followed by the capability name this.Text = rtDocument.Metadata.Title + " - " + this.presentationCapability.Name; // Clean up the screen DeleteAllStrokes(); Log("On open doc: info before creating RTDocHelper,"); DisplayRTDocumentOnlyStructureInfo(); rtDocumentHelper = new RTDocumentHelper(this.presentationCapability, rtDocument); Log("Structure Info on open after creating RTDocHelper,"); DisplayRTDocumentStructureInfo(); #region Populate thumbnails ArrayList thumbnails = new ArrayList(); using (Bitmap bp = new Bitmap( thumbnailsView.ImageSize.Width, thumbnailsView.ImageSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)) { using (Graphics g = Graphics.FromImage(bp)) { g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; foreach( TOCNode tn in rtDocument.Organization.TableOfContents ) { Page p = (Page)tn.Resource; ThumbnailListView.CreateSlideThumbnail( thumbnailsView.ImageSize, p.Image, g, tn.Title ); ThumbnailListViewItem item = new ThumbnailListViewItem(); item.thumbnail = ((Bitmap)bp.Clone()); item.tag = tn.Identifier; thumbnails.Add(item); } } } thumbnailsView.Items = (ThumbnailListViewItem[])thumbnails.ToArray(typeof(ThumbnailListViewItem)); #endregion // Initialize the index on the first slide index = 0; // Show the current page statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); ShowPage(rtDocument.Organization.TableOfContents[index].Identifier); if( presentationCapability.IsSender ) { EnableSlideSend(false); statusBar.StatusMessage = Strings.SendingSlides; rtDocumentHelper.BeginSendAllSlides(new AsyncCallback(SlidesSent), null); } // Update the Backward/Forward buttons (push the navigation button in the // direction(s)that you cannot move anymore) UpdateNavigationButtonState(); } } catch(Exception ex) { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.ErrorInOpening, cdlg.FileName, ex.Message.ToString()), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } }
/// <summary> /// Handle the reception of an RTDocument object. The rtDocument received /// does not contain the actual pages (the pages are received separately), /// so this function mainly handles the reception of the document structure /// (TOC, number of pages, guid of pages, etc.) on the client(s). /// </summary> /// <param name="rtDocReceived">rtDocument structure received</param> private void RTDocumentReceived(RTDocument rtDocReceived) { Log("It's an RTDocument object,"); // Set the rtDocument only if you receive a new document (not a repeat) if( (rtDocument == null) || (!rtDocReceived.Identifier.Equals(rtDocument.Identifier)) ) { // Clean up the screen DeleteAllStrokes(); Image tempImg = pbRTDoc.Image; pbRTDoc.Image = null; if( tempImg != null ) tempImg.Dispose(); Log("The document received is different than the one already open!"); rtDocument = rtDocReceived; Log(string.Format(CultureInfo.CurrentCulture, "rtDocID in RTDocumentReceived method: {0}", rtDocument.Identifier.ToString())); Log("Info before creating RTDocHelper,"); DisplayRTDocumentOnlyStructureInfo(); rtDocumentHelper = new RTDocumentHelper( presentationCapability, rtDocument ); // Pri2: is crntPage == 0 correct?? statusBar.SetMaxPage( 0, rtDocument.Organization.TableOfContents.Count ); statusBar.StatusMessage = string.Format(CultureInfo.CurrentCulture, Strings.ReceivingPage_of_, rtDocument.Organization.TableOfContents.Count.ToString(CultureInfo.InvariantCulture)); thumbnailsView.Items = new ThumbnailListViewItem[0]; // Update the title bar of the form this.Text = rtDocument.Metadata.Title + " - " + presentationCapability.Name; Log("Doc organization received:"); DisplayRTDocumentStructureInfo(); // Initialize the received page counter pageReceivedCounter = 0; if( this.cachedPages != null ) { // In the odd case that we have pages waiting, and the wrong TOC is received, // we'll try to add all the pages, fail, and then just discard them all. for( int cnt = cachedPages.Count; cnt > 0; --cnt ) { this.PageReceived( (Page)cachedPages.Dequeue() ); } this.cachedPages = null; } } }