protected override bool UpdateTarget(ReceiveContext context) { DeckModel deck = (this.Parent != null && this.Parent.Parent != null) ? this.Parent.Parent.Target as DeckModel : null; ImageSheetModel sheet = this.Target as ImageSheetModel; if(sheet == null) { ///create our imagesheet based on what type of image it is if (image_ != null) { // ImageIt image this.Target = sheet = new ImageSheetModel((Guid)this.TargetId, this.image_, false, this.Bounds.Location, this.Bounds.Size, this.Height); ///make the image visible sheet.Visible = true; } else { // Background image this.Target = sheet = new ImageSheetModel(deck, ((Guid)this.TargetId), this.Disposition | SheetDisposition.Remote, this.Bounds, this.MD5, this.Height); } } if (image_ != null) { using (Synchronizer.Lock(sheet.SyncRoot)) { sheet.Image = this.image_; } } base.UpdateTarget(context); return true; }
private void BuildContentToSlideLookup() { m_ContentToSlideLookup = new Hashtable(); foreach (SlideModel slide in this.m_Slides.Values) { using (Synchronizer.Lock(slide.SyncRoot)) { foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) { continue; } ImageSheetModel ism = ((ImageSheetModel)sm); if (m_ContentToSlideLookup.ContainsKey(ism.MD5)) { m_ContentToSlideLookup[ism.MD5] = null; } else { m_ContentToSlideLookup.Add(ism.MD5, slide); } } } } }
public override object Clone() { Rectangle bounds; using (Synchronizer.Lock(this.SyncRoot)) { bounds = this.Bounds; } ImageSheetModel s = new ImageSheetModel(Guid.NewGuid(), this.image_, this.Disposition, is_editable_, bounds.Location, bounds.Size, this.Height); // Todo: it's not clear why the constructors don't handle visability s.Visible = this.Visible; return(s); }
/// <summary> /// Adds a slide to the deck. /// NOTE: slides have no natural ordering /// </summary> /// <param name="slide">The slide to insert</param> public void InsertSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (m_ContentToSlideLookup == null) { BuildContentToSlideLookup(); } using (Synchronizer.Lock(this)) { // Prevent events from being registered or unregistered. if (this.m_Slides[slide.LocalId] == null || ((SlideModel)this.m_Slides[slide.LocalId]).Id != slide.Id) { this.m_Slides[slide.LocalId] = slide; using (Synchronizer.Lock(slide.SyncRoot)) { foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) { continue; } ImageSheetModel ism = ((ImageSheetModel)sm); Image image = ism.Image; if (image == null) { using (Synchronizer.Lock(ism.Deck.SyncRoot)) image = ism.Deck.GetSlideContent(ism.MD5); } if (image != null) { this.AddSlideContent(ism.MD5, image); } if (!m_ContentToSlideLookup.ContainsKey(ism.MD5)) { m_ContentToSlideLookup.Add(ism.MD5, slide); } } } if (this.m_SlideAddedDelegate != null) { this.m_SlideAddedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, null, slide)); } } } }
public ImageSheetMessage(ImageSheetModel sheet, SheetCollection collection) : base(sheet, collection) { if (sheet.Deck != null) { // we are in background mode // MD5 is not a Published property of ImageSheetModel. using (Synchronizer.Lock(sheet.SyncRoot)) { this.MD5 = sheet.MD5; } // Do NOT try to serialize the ImageContent. That is done by a separate DeckSlideContentMessage. } else { // we are in ImageIt mode using (Synchronizer.Lock(sheet.SyncRoot)) { this.image_ = sheet.Image; } } }
public ImageSheetRenderer(SlideDisplayModel display, ImageSheetModel sheet) : base(display, sheet) { this.m_Sheet = sheet; repaint_dispatcher_ = new EventQueue.PropertyEventDispatcher(this.SlideDisplay.EventQueue, this.Repaint); if (m_Sheet.Image == null) { // we are looking at a background image if (this.m_Sheet.Deck != null) { this.m_Sheet.Deck.SlideContentAdded += new PropertyEventHandler(repaint_dispatcher_.Dispatcher); } else { //FIXME: This happened a couple of times. Ignoring it is not the best fix. Trace.WriteLine("Warning: ImageSheetModel.Deck was found to be null when creating ImageSheetRenderer."); } } else { //we're looking at an ImageIt image this.m_Sheet.Changed["Bounds"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); this.m_Sheet.Changed["Image"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); this.SlideDisplay.Changed["Slide"].Add(new PropertyEventHandler(repaint_dispatcher_.Dispatcher)); } }
/// <summary> /// pre: image_sheet is an image that is to be on the slide (not a background image), /// and therefore it's .Image property is not null /// </summary> /// <param name="image_sheet"></param> /// <param name="viewer"></param> /// <param name="image"></param> public ImageIt(ImageSheetModel image_sheet, MainSlideViewer viewer) : base(image_sheet, viewer) { InitializeComponent(); this.Parent = viewer; //HACK: I'm adding a control that doesn't exist on the ImageIt //because imageit has no control Control c = new Control(); actual_control_ = c; using (Synchronizer.Lock(image_sheet.SyncRoot)) { image_sheet_ = image_sheet; c.Size = image_sheet.Bounds.Size; } image_ratio_ = (float)(c.Width) / (float)(c.Height); Transform(); c.Location = new Point(0, pnlTop.Height); PaintSheet(true); }
public ImageSheetUndoService(EventQueue dispatcher, UndoModel undo, DeckModel deck, SlideModel slide, ImageSheetModel sheet) : base(undo, deck, slide, sheet) { // There are currently no published properties of ImageSheetModel, other than those handled by the base class. }
public static void InsertImage(Image image, SlideModel slide) { int width = image.Width; int height = image.Height; int w = 0, h = 0; using (Synchronizer.Lock(slide.SyncRoot)) { w = slide.Bounds.Width; h = slide.Bounds.Height - 10; } if (width > w) { height = w * height / width; width = w; } if (height > h) { width = h * width / height; height = h; } /// add 4 to the with of image box as padding height = (width + 4) * height / width; width += 4; Point position = new Point(Math.Max((w - width) / 2, 0), Math.Max((h - height) / 2, 10)); ImageSheetModel imagesheet = new ImageSheetModel(Guid.NewGuid(), image, true, position, new Size(width, height), 0); imagesheet.Visible = true; using (Synchronizer.Lock(slide.SyncRoot)) { slide.AnnotationSheets.Add(imagesheet); } }
/// <summary> /// /// </summary> /// <param name="tfc"></param> /// <param name="shapes"></param> /// <param name="range"></param> /// <param name="deck"></param> /// <param name="slide"></param> /// <param name="disposition"></param> /// <param name="emfHeight"></param> /// <param name="startHeight">The starting height to place this sheet at</param> private static void ProcessLayer( List<TaggedShape> layer, TempFileCollection tfc, PowerPoint.Shapes shapes, Model.Presentation.DeckModel deck, Model.Presentation.SlideModel slide, float emfWidthRatio, float emfHeightRatio, int startHeight) { if (layer.Count < 1) return; //Create the image int[] range = PPTDeckIO.BuildIntRange(layer); PowerPoint.ShapeRange sr = shapes.Range(range); PowerPoint.PpShapeFormat format; string fileExt = ""; bool bitmapMode = layer[0].isImage; if (bitmapMode) { format = PowerPoint.PpShapeFormat.ppShapeFormatPNG; fileExt = "png"; } else { format = PowerPoint.PpShapeFormat.ppShapeFormatEMF; fileExt = "emf"; } //Generate a new filename string dirpath = tfc.BasePath; string filename = PPTDeckIO.GenerateFilename(); filename = dirpath + "\\" + filename + "." + fileExt; while (File.Exists(filename)) { filename = PPTDeckIO.GenerateFilename(); filename = dirpath + "\\" + filename + "." + fileExt; } sr.Export(filename, format, 0, 0, PowerPoint.PpExportMode.ppRelativeToSlide); if (bitmapMode) { // Starting with Office 2013, bitmaps may not be exported in the correct size. double version; if (!double.TryParse(((PowerPoint.Application)shapes.Application).Version, out version)) { version = 0.0; } if (version >= 15.0) { ScaleShapeImage(sr, filename); } } tfc.AddFile(filename, false); //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 image = Image.FromStream(fs); if (bitmapMode) image = DisassociateBitmap(image); fs.Close(); //Calculate the geometry int xCoord = 0; int yCoord = 0; int width = 0; int height = 0; PPTDeckIO.CalculateGeometry( image, shapes, range, emfWidthRatio, emfHeightRatio, ref xCoord, ref yCoord, ref width, ref height ); //Create the ImageSheet ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), layer[0].disp, new Rectangle(xCoord, yCoord, width, height), (ByteArray)md5, startHeight); //Add the ImageSheet to the Slide slide.ContentSheets.Add(sheet); //Add the Image+MD5 to the deck deck.AddSlideContent((ByteArray)md5, image); }
/// <summary> /// Create a slide model from a powerpoint slide /// </summary> /// <param name="pageSetup"></param> /// <param name="pptpm"></param> /// <param name="deck"></param> /// <param name="tempFileCollection"></param> /// <param name="dirpath"></param> /// <param name="currentSlide"></param> /// <returns></returns> private static SlideModel CreateSlide(PowerPoint.PageSetup pageSetup, PPTPaneManagement.PPTPaneManager pptpm, DeckModel deck, TempFileCollection tempFileCollection, string dirpath, PowerPoint._Slide currentSlide) { int slideWidth = (int)pageSetup.SlideWidth; //Standard = 720 => 6000 int slideHeight = (int)pageSetup.SlideHeight; //Standard = 540 => 4500 float emfWidth = slideWidth * 25 / 3; float emfHeight = slideHeight * 25 / 3; // Adding an empty textbox in the upper left corner of the the // slide before layers are exported works around a common // issue with shape positioning. Without this, text shapes often get pushed too far // to the right and down due to some extra padding that PPT inserts on // the top and left of the exported images. It doesn't pad the top left of an // empty text box, so the positioning is corrected. // This isn't perfect since the workaround should probably be applied to // every layer with text boxes. currentSlide.Shapes.AddTextbox(Core.MsoTextOrientation.msoTextOrientationHorizontal, 0, 0, 1, 1); PowerPoint.Shapes currentShapes = currentSlide.Shapes; List<TaggedShape> taggedShapeList = PPTDeckIO.BuildTaggedShapeList(currentShapes, pptpm); //Create a new SlideModel SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, slideWidth, slideHeight)); //Lock it using (Synchronizer.Lock(newSlideModel.SyncRoot)) { //Set the slide's title newSlideModel.Title = PPTDeckIO.FindSlideTitle(taggedShapeList, currentSlide); PPTDeckIO.MakeShapesInvisible(currentShapes); //Create the Background image //Generate a new filename string filename = PPTDeckIO.GenerateFilename(); bool bitmapMode = true; if (bitmapMode) { filename = dirpath + "\\" + filename + ".png"; currentSlide.Export(filename, "PNG", 0, 0); // Need to also export as EMF to get the size of the slide in inches currentSlide.Export(filename + "_TEMP", "EMF", 0, 0); tempFileCollection.AddFile( filename + "_TEMP", false ); } else { filename = dirpath + "\\" + filename + ".emf"; currentSlide.Export(filename, "EMF", 0, 0); } tempFileCollection.AddFile(filename, false); //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 image = Image.FromStream(fs); if (bitmapMode) { image = DisassociateBitmap(image); } fs.Close(); // Open the EMF version if we used a bitmap to get the conversion if( bitmapMode ) { FileStream fsEMF = new FileStream( filename + "_TEMP", FileMode.Open, FileAccess.Read ); Image image_emf = Image.FromStream( fsEMF ); emfWidth = image_emf.Width; emfHeight = image_emf.Height; fsEMF.Close(); image_emf.Dispose(); } else { emfWidth = image.Width; emfHeight = image.Height; } //Create the ImageSheet ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), Model.Presentation.SheetDisposition.Background, new Rectangle(0, 0, slideWidth, slideHeight), (ByteArray)md5, 1); //Add the ImageSheet to the Slide newSlideModel.ContentSheets.Add(sheet); //Add the Image+MD5 to the deck deck.AddSlideContent((ByteArray)md5, image); // Restore visibility - this makes everything visible - a bug? PPTDeckIO.MakeShapesVisible(currentShapes); List<List<TaggedShape>> layerList = PPTDeckIO.SeparateIntoLayers(taggedShapeList); int startHeight = 2; foreach (List<TaggedShape> layer in layerList) PPTDeckIO.ProcessLayer( layer, tempFileCollection, currentShapes, deck, newSlideModel, slideWidth/emfWidth, slideHeight/emfHeight, startHeight++ ); //Add SlideModel to the deck deck.InsertSlide(newSlideModel); } return newSlideModel; }
public ImageSheetNetworkService(SendingQueue sender, PresentationModel presentation, DeckModel deck, SlideModel slide, ImageSheetModel sheet, SheetMessage.SheetCollection selector) : base(sender, presentation, deck, slide, sheet, selector) { this.sheet_ = sheet; this.m_SlideModel = slide; }
/// <summary> /// Create a slide model from a powerpoint slide /// </summary> /// <param name="pageSetup"></param> /// <param name="pptpm"></param> /// <param name="deck"></param> /// <param name="tempFileCollection"></param> /// <param name="dirpath"></param> /// <param name="currentSlide"></param> /// <returns></returns> private static SlideModel CreateSlide(PowerPoint.PageSetup pageSetup, PPTPaneManagement.PPTPaneManager pptpm, DeckModel deck, TempFileCollection tempFileCollection, string dirpath, PowerPoint._Slide currentSlide) { int slideWidth = (int)pageSetup.SlideWidth; //Standard = 720 => 6000 int slideHeight = (int)pageSetup.SlideHeight; //Standard = 540 => 4500 float emfWidth = slideWidth * 25 / 3; float emfHeight = slideHeight * 25 / 3; PowerPoint.Shapes currentShapes = currentSlide.Shapes; List<TaggedShape> taggedShapeList = PPTDeckIO.BuildTaggedShapeList(currentShapes, pptpm); //Create a new SlideModel SlideModel newSlideModel = new SlideModel(Guid.NewGuid(), new LocalId(), SlideDisposition.Empty, new Rectangle(0, 0, slideWidth, slideHeight)); //Lock it using (Synchronizer.Lock(newSlideModel.SyncRoot)) { //Set the slide's title newSlideModel.Title = PPTDeckIO.FindSlideTitle(taggedShapeList); PPTDeckIO.MakeShapesInvisible(currentShapes); //Create the Background image //Generate a new filename string filename = PPTDeckIO.GenerateFilename(); bool bitmapMode = true; if (bitmapMode) { filename = dirpath + "\\" + filename + ".JPG"; currentSlide.Export(filename, "JPG", 0, 0); // Need to also export as EMF to get the size of the slide in inches currentSlide.Export(filename + "_TEMP", "EMF", 0, 0); tempFileCollection.AddFile( filename + "_TEMP", false ); } else { filename = dirpath + "\\" + filename + ".emf"; currentSlide.Export(filename, "EMF", 0, 0); } tempFileCollection.AddFile(filename, false); //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 image = Image.FromStream(fs); if (bitmapMode) { image = DisassociateBitmap(image); } fs.Close(); // Open the EMF version if we used a bitmap to get the conversion if( bitmapMode ) { FileStream fsEMF = new FileStream( filename + "_TEMP", FileMode.Open, FileAccess.Read ); Image image_emf = Image.FromStream( fsEMF ); emfWidth = image_emf.Width; emfHeight = image_emf.Height; fsEMF.Close(); image_emf.Dispose(); } else { emfWidth = image.Width; emfHeight = image.Height; } //Create the ImageSheet ImageSheetModel sheet = new ImageSheetModel(deck, Guid.NewGuid(), Model.Presentation.SheetDisposition.Background, new Rectangle(0, 0, slideWidth, slideHeight), (ByteArray)md5, 1); //Add the ImageSheet to the Slide newSlideModel.ContentSheets.Add(sheet); //Add the Image+MD5 to the deck deck.AddSlideContent((ByteArray)md5, image); // Restore visibility - this makes everything visible - a bug? PPTDeckIO.MakeShapesVisible(currentShapes); List<List<TaggedShape>> layerList = PPTDeckIO.SeparateIntoLayers(taggedShapeList); int startHeight = 2; foreach (List<TaggedShape> layer in layerList) PPTDeckIO.ProcessLayer( layer, tempFileCollection, currentShapes, deck, newSlideModel, slideWidth/emfWidth, slideHeight/emfHeight, startHeight++ ); //Add SlideModel to the deck deck.InsertSlide(newSlideModel); } return newSlideModel; }
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; } } } }
/// <summary> /// Adds an image sheet at a point relative to the user's view /// </summary> /// <param name="p">Where we want the image sheet to pop up</param> /// <param name="i_scale_x"></param> /// <param name="i_scale_y"></param> private void AddImageSheet(Point p, float scale_y, float i_scale_x, float i_scale_y) { ImageSheetModel i; //get the image that the user wants to load OpenFileDialog file_dialog = new OpenFileDialog(); file_dialog.Filter = "JPEG files (*.jpg)|*.jpg|BMP files (*.bmp|*.bmp"; if (file_dialog.ShowDialog() == DialogResult.OK) { /// get our image to load Image image = Image.FromFile(file_dialog.FileName); int width, height; using (Synchronizer.Lock(image)) { width = image.Width; height = image.Height; } ///check to see if the image is too large. If it's okay, ///then load the image into an imagesheetmodel and add the sheet if (width > 1600 || height > 1200) { MessageBox.Show("Sorry, image file is too large"); } else { int h = (int)(this.SlideHeight - 20 * scale_y); int w = h * this.SlideWidth / this.SlideHeight; if (width > w) { height = w * height / width; width = w; } if (height > h) { width = h * width / height; height = h; } ///create our image sheet, whose location is inversely transformed. i = new ImageSheetModel(Guid.NewGuid(), image, true, new Point((int)(Math.Min(p.X, SlideWidth - 10 - width) * i_scale_x), (int)(Math.Min(p.Y, SlideHeight - height) * i_scale_y)), new Size((int)(width * i_scale_x), (int)(height * i_scale_y)), 0); ///add the sheet to our annotationsheets. using (Synchronizer.Lock(this.Slide.SyncRoot)) { this.Slide.AnnotationSheets.Add(i); } } } }
/// <summary> /// Removes a slide and its content (if used nowhere else) from the deck /// </summary> /// <param name="slide">The slide to remove</param> public void DeleteSlide(SlideModel slide) { Synchronizer.AssertLockIsHeld(this.SyncRoot); if (!this.m_Slides.Contains(slide.LocalId)) { throw new ArgumentException("The specified slide is not a member of this deck.", "slide"); } else { //Remove the slide from the deck this.m_Slides.Remove(slide.LocalId); //Lock the slide using (Synchronizer.Lock(slide.SyncRoot)) { //Get all the ImageSheets // FIXME: Also get ImageSheetModels from the slide's AnnotationSheets foreach (SheetModel sm in slide.ContentSheets) { if (!(sm is ImageSheetModel)) { continue; } ImageSheetModel ism = ((ImageSheetModel)sm); //Get the MD5 and remove it from the SlideContent if it is not used anywhere else int slideCount = 0; SlideModel uniqueSlide = null; foreach (SlideModel sdm in this.m_Slides.Values) { using (Synchronizer.Lock(sdm.SyncRoot)) { if (sdm.HasHash(ism.MD5)) { //don't remove this sheet slideCount++; uniqueSlide = sdm; } } } if (slideCount == 0) { this.m_SlideContent.Remove(ism.MD5); } if (m_ContentToSlideLookup != null) { if (slideCount == 0) { this.m_ContentToSlideLookup.Remove(ism.MD5); } if (slideCount == 1) { this.m_ContentToSlideLookup[ism.MD5] = uniqueSlide; } } } } using (Synchronizer.Lock(this)) { // Prevent event listeners from being registered or unregistered. if (this.m_SlideRemovedDelegate != null) { this.m_SlideRemovedDelegate(this, new PropertyCollectionEventArgs("Slides", -1, slide, null)); } } } }
public override object Clone() { Rectangle bounds; using (Synchronizer.Lock(this.SyncRoot)) { bounds = this.Bounds; } ImageSheetModel s = new ImageSheetModel(Guid.NewGuid(), this.image_, this.Disposition, is_editable_, bounds.Location, bounds.Size, this.Height); // Todo: it's not clear why the constructors don't handle visability s.Visible = this.Visible; return s; }