public static RTDocument PPT2RTDwithSVG(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(); ppt.Visible = MsoTriState.msoTrue; // Open the PPT file Presentation presentation = ppt.Presentations.Open(pptFilename, MsoTriState.msoFalse, MsoTriState.msoTrue, MsoTriState.msoTrue); PrintOptions po = presentation.PrintOptions; po.ActivePrinter = @"SVGmaker"; System.Threading.Thread.Sleep(6000); po.OutputType = PpPrintOutputType.ppPrintOutputSlides; po.PrintInBackground = MsoTriState.msoFalse; Slides slides = presentation.Slides; // Set up the document RTDocument rtDoc = new RTDocument(); rtDoc.Identifier = Guid.NewGuid(); rtDoc.Metadata.Title = GetPresentationProperty(ppt.ActivePresentation, "Title"); rtDoc.Metadata.Creator = GetPresentationProperty(ppt.ActivePresentation, "Author"); //Iterate through the pages foreach(Slide s in slides) { // Set the page properties Page p = new Page(); p.Identifier = Guid.NewGuid(); p.Extension = GetSlideSVG(presentation, s); p.MimeType = "image/svg"; // TODO: look up the real value for this rtDoc.Resources.Pages.Add(p.Identifier, p); // Set the TOCNode properties for the page TOCNode tn = new TOCNode(); tn.Title = GetSlideTitle(s); tn.Resource = p; tn.ResourceIdentifier = p.Identifier; // TODO: Insert thumbnail? (tn.thumbnail) rtDoc.Organization.TableOfContents.Add(tn); } // Close PPT presentation.Close(); if (ppt.Presentations.Count == 0) { ppt.Quit(); } ppt = null; tfc.Delete(); return rtDoc; }
public RTPageAdd(Page page) { TOCNode = new TOCNode(); TOCNode.ResourceIdentifier = page.Identifier; TOCNode.Resource = page; TOCNode.Title = "New Page"; // Not adding in here for now to keep out RTDocumentHelper dependency // Should move GetThumbnailFromImage over to another utility library than RTDocumentUtilities... //TOCNode.Thumbnail = RTDocumentHelper.GetThumbnailFromImage(page.Image); Page = page; }
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 void Add( Guid identifier, Page page ) { Dictionary.Add( identifier, page ); }
object ICloneable.Clone() { Page clone = new Page(); clone.Identifier = Identifier; clone.MimeType = MimeType; if (Image != null) { clone.Image = (Image)Image.Clone(); } /*if (Regions != null) { clone.Regions = (Region[])Regions.Clone(); } if (PrivateNotes != null) { if (PrivateNotes is ICloneable) { clone.PrivateNotes = ((ICloneable)PrivateNotes).Clone(); } } if (PublicNotes != null) { if (PublicNotes is ICloneable) { clone.PublicNotes = ((ICloneable)PublicNotes).Clone(); } }*/ if (Extension != null) { if (Extension is ICloneable) { clone.Extension = ((ICloneable)Extension).Clone(); } } return clone; }
/// <summary> /// Handle the reception of a Page object. /// </summary> /// <param name="p">Page received</param> private void PageReceived(Page page) { // Put page in rtDoc TOCNode parentNode = null; int index; for(index = 0; index < rtDoc.Organization.TableOfContents.Count; ++index ) { TOCNode node = rtDoc.Organization.TableOfContents[index]; if( node.ResourceIdentifier == page.Identifier ) { node.Resource = page; parentNode = node; break; } } if( parentNode == null ) throw new InvalidOperationException("Parent TOCNode for Page not found."); // Add page to Resources.Pages if( !rtDoc.Resources.Pages.ContainsKey(page.Identifier) ) { rtDoc.Resources.Pages.Add( page.Identifier, page ); // Insert Page in ON // Instead of finding the previous sibling we just insert it at the end // and assume the page is in order (which it is due to the current // background send implementation of Presenation). We're avoiding using the // "insertAfter" attribute of DataImport becuase it add pages as subpages. // Other, inserted slides, such as captures and new whiteboards will get // inserted as subpages, thus giving them a different look to imply they were // inserted & not originally in the document. this.InsertPageInON( page, parentNode.Title, Guid.Empty ); // If it's the first page, display it Guid pFirst = rtDoc.Organization.TableOfContents[0].ResourceIdentifier; if (page.Identifier == pFirst) { crntPage = pFirst; importer.NavigateToPage( crntONFile, pFirst.ToString("B") ); } } }
/// <summary> /// Does all of the necessary work to create the Xml for a new page & inserts it. /// </summary> private void InsertPageInON( Page page, string title, Guid parentPage ) { // Give the drawing area a background by adding an image to all pages without one if( page.Image == null ) { page.Image = new Bitmap( (int)(constWidthPageSend / 2F), (int)(constHeightPageSend / 2F), System.Drawing.Imaging.PixelFormat.Format16bppRgb555 ); // Add a nice black line around it to make it look good. using( Graphics g = Graphics.FromImage(page.Image) ) { g.Clear( Color.White ); } } // Pri3: Draw a single black line around all images // For unknown reasons, when trying to get a Graphics on a MWF an OutOfMemoryException // is thrown. Thus, we don't draw the black line on all images just yet. StringBuilder importData = new StringBuilder( (page.Image == null) ? 2000 : 1000000 ); XmlTextWriter xml = CreateInitdXml( importData ); // Ensure page verifies that the page exists (and creates it if it doesn't) xml.WriteStartElement( "EnsurePage" ); xml.WriteAttributeString( "path", crntONFile ); xml.WriteAttributeString( "guid", page.Identifier.ToString("B") ); xml.WriteAttributeString( "title", title ); // OneNote request a date in the following format "2003-10-16T17:30:00-08:00" // TODO: Remove the hardcoding of 08:00 and get this value from the local settings xml.WriteAttributeString( "date", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss-08:00")); if( parentPage != Guid.Empty ) { xml.WriteAttributeString( "insertAfter", parentPage.ToString("B") ); } xml.WriteEndElement(); // end EnsurePage // Write the image into the page if( page.Image != null ) { xml.WriteStartElement( "PlaceObjects" ); xml.WriteAttributeString( "pagePath", crntONFile ); xml.WriteAttributeString( "pageGuid", page.Identifier.ToString("B") ); GetImageAsXml( page.Image, xml ); xml.WriteEndElement(); // end PlaceObjects } xml.WriteEndDocument(); string finalData = importData.ToString(); LogAsLastCommand( finalData ); importer.Import( finalData ); }
private void ConsumeObject( ObjectReceivedEventArgs orea ) { // Create RTDoc with one slide & put it in ON if (rtDoc == null && !(orea.Data is RTDocument || orea.Data is RTFrame)) { // Create blank RTDocument rtDoc = new RTDocument(); rtDoc.Identifier = new Guid(constWhiteboardGuid); rtDoc.Metadata.Title = "Whiteboard Session " + DateTime.Now.ToString("u"); rtDoc.Metadata.Creator = Conference.LocalParticipant.Name; // Add a blank page Page pg = new Page(); pg.Identifier = new Guid(constWhiteboardGuid); TOCNode tn = new TOCNode(); tn.Title = "Whiteboard 1"; tn.Resource = pg; tn.ResourceIdentifier = pg.Identifier; tn.Identifier = new Guid(constWhiteboardGuid); rtDoc.Organization.TableOfContents.Add(tn); rtDoc.Resources.Pages.Add(pg.Identifier, pg); // Add the page to the strokes hash strokesPerPage.Add( pg.Identifier, new ArrayList() ); // Init necessary vars this.crntPage = pg.Identifier; // Pri2: re-enable this feature (removed due to PS 2063) //string folderInON = Options.GetFolderForAuthor("Unknown / Whiteboard Session"); //this.crntONFile = folderInON + " " + DateTime.Now.ToString("u").Replace(":", ".").Replace("Z","") + ".one"; this.crntONFile = "Whiteboard - " + DateTime.Now.ToString("u").Replace(":", ".").Replace("Z","") + ".one"; // Import the page this.InsertPageInON( pg, tn.Title, Guid.Empty ); // Show first page System.Threading.Thread.Sleep(50); importer.NavigateToPage( crntONFile, crntPage.ToString("B") ); } if (orea.Data is RTStrokeRemove) { RTStrokeRemoveReceived((RTStrokeRemove)orea.Data); } else if (orea.Data is RTStroke) { RTStrokeReceived((RTStroke)orea.Data); } else if (orea.Data is Page) { PageReceived((Page)orea.Data); } else if (orea.Data is RTPageAdd) { RTPageAddReceived((RTPageAdd)orea.Data); } else if (orea.Data is RTNodeChanged) { RTNodeChangedReceived( (RTNodeChanged)orea.Data); } else if (orea.Data is RTDocument) { RTDocumentReceived((RTDocument)orea.Data); } else if (orea.Data is RTFrame) { RTFrameReceived( (RTFrame)orea.Data ); } }
object ICloneable.Clone() { Page clone = new Page(); clone.Identifier = Identifier; clone.MimeType = MimeType; if (Image != null) { clone.Image = (Image)Image.Clone(); } if (Extension != null) { if (Extension is ICloneable) { clone.Extension = ((ICloneable)Extension).Clone(); } } return clone; }
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> /// Inserts a blank slide immediately after the current slide, syncing any client. /// </summary> private void InsertWhiteboard() { Page page = new Page(); page.Identifier = Guid.NewGuid(); TOCNode tn = rtDocumentHelper.SendPageInsert(page, string.Format(CultureInfo.CurrentCulture, Strings.Whiteboard, (index + 2)), index); statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); // Add page to thumbnails thumbnailsView.InsertThumbnail( page.Image, tn.Title, index+1, tn.Identifier ); this.navigateToIndex( index+1, true ); }
/// <summary> /// This allows initiator to take a snapshot of an application and /// send to all the client(s). /// If a document is open, the snapshot(s) will be append at the /// end of the document. /// </summary> /// <remarks> /// This method is declared as public so we can use it for test automation. /// </remarks> private void InsertSnapshot() { if( window.Minimized ) { RtlAwareMessageBox.Show(this, string.Format(CultureInfo.CurrentCulture, Strings.SnapshotsOfMinimizedWindows, Environment.NewLine), string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } #region Convert the snapshot from an uncompressed bitmap to a Png compressed bitmap MemoryStream ms = new MemoryStream(); try { window.WindowAsBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); } catch { RtlAwareMessageBox.Show(this, Strings.ErrorWhileTakingSnapshot, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0); return; } ms.Position = 0; Image img = Image.FromStream(ms); #endregion #region Bring the PresentationCapability back to the front of the z-order and display the snapshot on the PresentationCapability this.BringToFront(); // Free up the memory of the image if needed and set the // pbRTDoc.Image property with the new snapshot image Image tempImg = this.pbRTDoc.Image; pbRTDoc.Image = (Image)img.Clone(); if( tempImg != null ) tempImg.Dispose(); #endregion #region Create a new RTDocument Page from the snapshot Page page = new Page(); page.Identifier = Guid.NewGuid(); page.Image = img; page.MimeType = "image/png"; #endregion // Send the snapshot page to insert on the remote capabilities TOCNode tn = rtDocumentHelper.SendPageInsert(page, string.Format(CultureInfo.CurrentCulture, Strings.SnapshotOf, window.Text), index); statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); // Add page to thumbnails thumbnailsView.InsertThumbnail( page.Image, tn.Title, index+1, tn.Identifier ); this.navigateToIndex( index+1, true ); }
/// <summary> /// Handle the reception of a Page object. /// </summary> /// <param name="p">Page received</param> private void PageReceived(Page page) { Log("It's a Page object,"); // Store the page object to show later // If it is a "random" page, add it to the RTDoc Log("Structure Before AddPageToRTDocument:"); DisplayRTDocumentStructureInfo(); // Attempt to add the page to the RTDoc try { rtDocumentHelper.AddPageToRTDocument( page ); } catch(InvalidOperationException) { // TOC not received. Cache the page and request the TOC if we haven't already. if( this.cachedPages == null ) { this.cachedPages = Queue.Synchronized(new Queue()); // Pri2: Do we need to send this more often than just once? If so, what should our solution be? rtDocumentHelper.SendTocRequest(); } this.cachedPages.Enqueue(page); return; } // Indicate that you are receiving a page from a RTDocument // Note: The pages are not necessarily sent in order of the pages in the doc ++pageReceivedCounter; if( pageReceivedCounter < rtDocument.Organization.TableOfContents.Count ) { statusBar.StatusMessage = string.Format(CultureInfo.CurrentCulture, Strings.ReceivingPage, (pageReceivedCounter+1), rtDocument.Organization.TableOfContents.Count.ToString(CultureInfo.InvariantCulture)); } else { // On last page, remove receiving message statusBar.SetReadyStatusMessage(); } Log(string.Format(CultureInfo.CurrentCulture, "I just added a Page object with the id: {0},", page.Identifier)); Log(string.Format(CultureInfo.CurrentCulture, "The TOC Node identifier is: {0},", rtDocumentHelper.TOCNodeIdentifierToPageIdentifier(page.Identifier))); Log("Structure After AddPageToRTDocument:"); DisplayRTDocumentStructureInfo(); // Insert the thumbnail for the new page TOCNode node = rtDocumentHelper.PageToTOCNode(page); int pageIndex = rtDocument.Organization.TableOfContents.IndexOf( node ); // If previous slides haven't been recieved, just shove it at the end if( pageIndex > thumbnailsView.Items.Length ) pageIndex = thumbnailsView.Items.Length; thumbnailsView.InsertThumbnail( page.Image, node.Title, pageIndex, node.Identifier ); // If it's the first page, display it // Pri3: Doesn't this fail with a NullRefException if this isn't the first page?? Guid pFirst = rtDocument.Organization.TableOfContents[0].ResourceIdentifier; if( page.Identifier.Equals(pFirst) ) { ShowPage(rtDocument.Organization.TableOfContents[0].Identifier); index = 0; } UpdateNavigationButtonState(); }
/// <summary> /// This allows initiator to take a snapshot of an application and /// send to all the client(s). /// If a document is open, the snapshot(s) will be append at the /// end of the document. /// </summary> /// <remarks> /// This method is declared as public so we can use it for test automation. /// </remarks> private void InsertSnapshot() { if( window.Minimized ) { MessageBox.Show("Snapshots of minimized windows cannot be taken." + Environment.NewLine + "Please restore or maximize the window."); return; } #region Convert the snapshot from an uncompressed bitmap to a Png compressed bitmap MemoryStream ms = new MemoryStream(); try { window.WindowAsBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); } catch { MessageBox.Show("Error while taking snapshot." + Environment.NewLine + "Your target snapshot window may be in an invalid state or closed."); return; } ms.Position = 0; Image img = Image.FromStream(ms); #endregion #region Bring the PresentationCapability back to the front of the z-order and display the snapshot on the PresentationCapability this.BringToFront(); // Free up the memory of the image if needed and set the // pbRTDoc.Image property with the new snapshot image Image tempImg = this.pbRTDoc.Image; pbRTDoc.Image = (Image)img.Clone(); if( tempImg != null ) tempImg.Dispose(); #endregion #region Create a new RTDocument Page from the snapshot Page page = new Page(); page.Identifier = Guid.NewGuid(); page.Image = img; page.MimeType = "image/png"; #endregion // Send the snapshot page to insert on the remote capabilities TOCNode tn = rtDocumentHelper.SendPageInsert(page, "Snapshot of " + window.Text, index); statusBar.SetMaxPage( 1, rtDocument.Organization.TableOfContents.Count ); // Add page to thumbnails thumbnailsView.InsertThumbnail( page.Image, tn.Title, index+1, tn.Identifier ); this.navigateToIndex( index+1, true ); }