}// recognizeText #endregion #region delete /// <summary> /// Deletes the last object added to the slide /// </summary> /// <param name="allShapes">A list of all shapes on the slide</param> private void deleteLastObject(List <PowerPoint.Shape> allShapes) { if (allShapes.Count == 0) { setFeedback("There is no shape to be deleted"); } else { int rangeLength = allShapes.Count; PowerPoint.Shape shape = allShapes[rangeLength - 1]; // find the last added shape to the slide if (shape.Type == MsoShapeType.msoTextBox) { // for each textbox, get rid of the button / listbox associated with it ListBox listboxToDelete = findListboxFromTextbox(shape.Name); listboxToDelete.Hide(); stackDeleteTextbox(shape, listboxToDelete); // push both shape and the listbox onto the stack this.Controls.Remove(listboxToDelete); alternateList.Remove(listboxToDelete); clearButtons(); } else { stackDeleteShape(shape); } shape.Delete(); // if found, then this gesture deletes that shape setFeedback("Last added object deleted"); } }//deleteLastObject()
private void addFirstSlide() { PowerPoint.Slide firstSlide = Globals.ThisAddIn.Application.ActivePresentation.Slides[1]; PowerPoint.Shape textBox2 = firstSlide.Shapes.AddTextbox( Office.MsoTextOrientation.msoTextOrientationHorizontal, 50, 50, 500, 500); textBox2.TextFrame.TextRange.InsertAfter("firstSlide"); }
/// <summary> /// try to delete some word from an existing textbox /// </summary> /// <param name="shape"></param> private void deleteWordIfTextbox(PowerPoint.Shape shape) { TextBox box = new TextBox(); box.Text = shape.TextFrame.TextRange.Text; box.Font = new System.Drawing.Font(shape.TextFrame.TextRange.Font.Name, shape.TextFrame.TextRange.Font.Size, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); box.Width = (int)shape.TextFrame.TextRange.BoundWidth + 10; shape.TextFrame.TextRange.Text = deleteWholeWord(box, shape.Left); shape.Width = shape.TextFrame.TextRange.BoundWidth + 10; ShapeAttributes clone1 = new ShapeAttributes(shape); undoStack.Push(clone1); undoStack.Push("deleteWord"); setFeedback("Word deleted"); basicOverlay.Ink.DeleteStrokes(); Panel.Invalidate(); if (shape.TextFrame.TextRange.Text.Length == 0) { DialogResult dr = System.Windows.Forms.MessageBox.Show( "Textbox is now empty. Do you wish to delete it?", "PowerPoint", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); if (dr == DialogResult.OK) // only go ahead and delete if OK button is pressed { deleteChosenObject(shape); } } }
// Test driver. public static bool Test() { bool passed = true; PowerPoint.Application app = new PowerPoint.Application(); //PowerPoint.Application app = new PowerPoint.ApplicationClass(); app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue; PowerPoint.Presentation presentation = app.Presentations.Add(Core.MsoTriState.msoFalse); PowerPoint.Slide slide = presentation.Slides.Add(1, PowerPoint.PpSlideLayout.ppLayoutBlank); PowerPoint.Shape shape = slide.Shapes.AddLine(0, 0, 100, 100); Console.WriteLine("Test on presentation."); passed = passed && TestTags(presentation.Tags); Console.WriteLine("Test on slide."); passed = passed && TestTags(slide.Tags); Console.WriteLine("Test on shape."); passed = passed && TestTags(shape.Tags); app = null; return(passed); }
private void updateListbox(PowerPoint.Shape s) { ListBox lb = findListboxFromTextbox(s.Name); int x = (int)s.Left; int y = (int)(s.Top + s.Height); lb.Location = new System.Drawing.Point(x + 8, y + 15); }
private void stackDeleteTextbox(PowerPoint.Shape shape, ListBox lb) { ShapeAttributes clone = new ShapeAttributes(shape); undoStack.Push(""); undoStack.Push(lb); undoStack.Push(clone); undoStack.Push("DeleteTextBox"); }
private void stackDeleteShape(PowerPoint.Shape shape) { ShapeAttributes clone = new ShapeAttributes(shape); undoStack.Push(""); undoStack.Push(""); undoStack.Push(clone); undoStack.Push("DeleteObject"); }
private void stackAddShape(PowerPoint.Shape s) { ShapeAttributes clone = new ShapeAttributes(s); undoStack.Push(""); // placeholder undoStack.Push(""); // placeholder undoStack.Push(clone); // object to be added undoStack.Push("AddObject"); // action }
private void stackOrderChange(PowerPoint.Shape shape, string order) { ShapeAttributes clone = new ShapeAttributes(shape); undoStack.Push(""); undoStack.Push(order); undoStack.Push(clone); undoStack.Push("ChangeOrder"); }
/// <summary> /// paste acts just like the real paste. It adds a shape of the specified MsoAutoShapeType at /// the specified location with the specified dimension. This is implemented because there /// is no built in paste for the Shape object that we are interested in /// </summary> /// <param name="type">the type of the shape</param> /// <param name="x">x coordinate</param> /// <param name="y">y coordinate</param> /// <param name="width">width of the shape</param> /// <param name="height">height of the shape</param> /// <returns></returns> public PowerPoint.Shape paste(Microsoft.Office.Core.MsoAutoShapeType type, int x, int y, float width, float height, int color, float angle) { int XCORRECTION = 5; PowerPoint.Slide slide = pptApp.ActivePresentation.Slides[getCurSlide()]; PowerPoint.Shape shape = slide.Shapes.AddShape(type, (float)(x + XCORRECTION), y, (int)width, (int)height); shape.Fill.ForeColor.RGB = color; shape.Rotation = angle; return(shape); }
/// <summary> /// Selects the passed shape. If clearSelection is true, clears the current selection first, else adds the shape to current selection. /// /// </summary> /// <param name="shape">Shape to select; if null, will just not select it.</param> /// <param name="clearSelection">true = clear the current selection first; false = leave it be</param> internal void selectShape(PowerPoint.Shape shape, bool clearSelection) { if (clearSelection) { PowerPoint.Selection selection = pptController.pptApp.ActiveWindow.Selection; selection.Unselect(); } if (shape != null) { shape.Select(Microsoft.Office.Core.MsoTriState.msoTrue); } }//selectShape
/// <summary> /// rightClick is only called when a right click is recognized AND when there is a current /// selection on the slide. /// </summary> /// <param name="shapes">a collection of shapes</param> internal void rightClick(PowerPoint.ShapeRange shapes) { PowerPoint.Shape clickedShape = null; try { clickedShape = pptController.findShape(X, Y); } catch (Exception e) { debugExceptionMessage("right click", e); return; } // If the click wasn't on any shape, just return if (clickedShape == null) { PowerPoint.Selection selection = pptController.pptApp.ActiveWindow.Selection; selection.Unselect(); return; } // Then, if it falls on an unselected shape, select that and return //if(shapes. bool inRange = false; // first assume the cursor is NOT in range of any of the shapes try { foreach (PowerPoint.Shape shape in shapes) { // if the cursor falls within the range of ANY of the shape selected if (clickedShape.Equals(shape)) { inRange = true; } } if (inRange == false) // if the cursor does not fall within the range of any shapes currently selected { // then try to see if it falls on top of a shape that is not currently selected, // if so, select that one PowerPoint.Shape shape = pptController.findShape(X, Y); shape.Select(Microsoft.Office.Core.MsoTriState.msoTrue); } } catch (Exception e) { // this exception should only be thrown when the right click does NOT fall on top of any // shapes, so the select method complains. In that case, this does not need to do anything // However, it's now checked for above so we should know when it happens debugExceptionMessage("rightclick", e); } }
/// <summary> /// update the location of the button after the text of the textbox has changed /// </summary> /// <param name="shapeToChange"></param> private void updateButton(PowerPoint.Shape shapeToChange) { int MARGIN = 20; foreach (Button b in buttons) { if (b.Name == shapeToChange.Name) { int x = (int)(shapeToChange.Left + shapeToChange.Width + MARGIN); int y = (int)(shapeToChange.Top + shapeToChange.Height); b.Location = new Point(x, y); } } }
} // lasso() internal void tryLasso(int x, int y) { try { PowerPoint.Shape shapeInCursorRange = pptController.findShape(x, y); if (shapeInCursorRange == null) { lasso(); } lassoAllowed = false; } catch (Exception e) { debugExceptionMessage("tryLasso", e); } }
/// <summary> /// display a button beside the given shape, giving the user the ability /// to call up a list of alternative recognition results /// </summary> /// <param name="shape"></param> private void displayButton(PowerPoint.Shape shape) { int MARGIN = 20; int x = (int)(shape.Left + shape.Width + MARGIN); int y = (int)(shape.Top + shape.Height); Button dropdown = new Button(); this.Controls.Add(dropdown); dropdown.BringToFront(); dropdown.Location = new Point(x, y); dropdown.Height = 15; dropdown.Width = 15; dropdown.Text = "v"; dropdown.Click += new EventHandler(dropdown_Click); dropdown.Name = shape.Name; buttons.Add(dropdown); updateListbox(shape); }
/// <summary> /// try to insert new text into an existing textbox /// </summary> /// <param name="shape"></param> private void insertIfTextbox(PowerPoint.Shape shape) { shape.TextFrame.WordWrap = MsoTriState.msoFalse; TextBox box = new TextBox(); // need some functions withint TextBox class box.Text = shape.TextFrame.TextRange.Text; box.Font = new System.Drawing.Font(shape.TextFrame.TextRange.Font.Name, shape.TextFrame.TextRange.Font.Size, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); box.Width = (int)shape.TextFrame.TextRange.BoundWidth + 10; shape.TextFrame.TextRange.Text = insertText(box, shape.Left); shape.Width = shape.TextFrame.TextRange.BoundWidth + buttonForm.BOUND; // adjust width accordingly ShapeAttributes clone = new ShapeAttributes(shape); undoStack.Push(clone); // keep track of name so for undo's sake undoStack.Push("insert"); setFeedback("Text inserted"); basicOverlay.Ink.DeleteStrokes(); Panel.Invalidate(); }
public ShapeAttributes(PowerPoint.Shape shape) { Left = shape.Left; Top = shape.Top; Width = shape.Width; Height = shape.Height; Rotation = shape.Rotation; Type = shape.AutoShapeType; Color = shape.Fill.ForeColor.RGB; Name = shape.Name; // FIXME: This doesn't work when you add text to an AutoShape if (shape.Type == MsoShapeType.msoTextBox) { Text = shape.TextFrame.TextRange.Text; Font = shape.TextFrame.TextRange.Font.Name; Size = shape.TextFrame.TextRange.Font.Size; } }
}//end paste() #endregion #region Misc /// <summary> /// add the object on which the gesture started to the current selection /// </summary> /// <param name="allShapes">a list of all shapes on the current slide</param> private void multiSelect(List <PowerPoint.Shape> allShapes) { PowerPoint.Shape shape = pptController.findShape(X, Y); if (shape.Equals(null)) { setFeedback("No shape selected - nothing added to selection"); return; } PowerPoint.Selection selection; try { // if the selection is empty, add the shape anyways if (!fillCurrentSelection(out selection)) { shape.Select(MsoTriState.msoTrue); setFeedback("Added object to previously empty selection"); } else { //else, get the selected shapes. I don't know what's the deal with ChildShapeRange. selection = pptController.pptApp.ActiveWindow.Selection; PowerPoint.ShapeRange shapes = selection.HasChildShapeRange ? selection.ChildShapeRange : selection.ShapeRange; //allShapes = selection.HasChildShapeRange ? selection.ChildShapeRange : selection.ShapeRange; // TODO: FIX: why do we need to reselect everything? Figure out why and replace if possible foreach (PowerPoint.Shape s in shapes) { s.Select(MsoTriState.msoFalse); // why does FALSE actually select the object?!? } shape.Select(MsoTriState.msoFalse); setFeedback("New object added to selection"); } } catch (Exception ex) { debugExceptionMessage("case right, for removing exception", ex); shape.Select(MsoTriState.msoFalse); setFeedback("Added object to previously empty selection"); // setFeedback("No currently selection, please select at least one object first"); } }//multiSelect()
}//multiSelect() /// <summary> /// add a line to the current slide /// </summary> private void addLine() { if (secondPoint == false) // if this is the first endpoint of the line { firstX = X; firstY = Y; secondPoint = true; setFeedback("Line started -- draw another \"RightDown\" at endpoint"); } else { int secondX = X; int secondY = Y; secondPoint = false; PowerPoint.Shape line = pptController.addLineToCurrSlide((float)firstX, (float)firstY, (float)secondX, (float)secondY); stackAddShape(line); setFeedback("Line added"); } }//addLine()
/// <summary> /// called by the selectedIndexChanged event handler when the user selects an alternative /// in any of the listboxes. It then replace the text in the original textbox with the /// selected alternative. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void lb_SelectedIndexChanged(object sender, EventArgs e) { ListBox lb = (ListBox)sender; PowerPoint.Shape shapeToChange = findTextboxFromListbox(lb.Name); string original = shapeToChange.TextFrame.TextRange.Text; shapeToChange.TextFrame.TextRange.Text = lb.SelectedItem.ToString(); shapeToChange.Width = shapeToChange.TextFrame.TextRange.BoundWidth + 10; ShapeAttributes sa = new ShapeAttributes(shapeToChange); updateButton(shapeToChange); lb.Hide(); undoStack.Push(""); undoStack.Push(original); undoStack.Push(sa); undoStack.Push("SelectedIndexChanged"); }
/// <summary> /// becaused on information given about a button, find the corresponding listbox. /// This is mainly based on position and name /// </summary> /// <param name="x">x position</param> /// <param name="y">y position</param> /// <param name="name">name of textbox / button</param> /// <returns></returns> internal ListBox findListboxFromButton(int x, int y, string name) { List <PowerPoint.Shape> all = pptController.allShapes(); PowerPoint.Shape textbox = null; // first find the textbox associated with this button foreach (PowerPoint.Shape s in all) { if (s.Name == name) // they should have the same name because button is initialized so { textbox = s; } } foreach (ListBox lb in alternateList) // then from the textbox, we can easily find the listbox { if (textbox.Name == lb.Name) { return(lb); } } System.Windows.Forms.MessageBox.Show("Should never get here! " + alternateList.Count); return(null); }
}//fillSelection() #endregion /// <summary> /// Returns true if the point falls on the rotate-marker of the passed shape; otherwise false. /// WARNING: Makes excessive use of hardcoded numbers. /// </summary> /// <param name="potentialShapes"></param> /// <returns></returns> private bool onRotateMarker(PowerPoint.Shape testShape, fPoint cursor) { float hDisp = 0; // the horizontal displacement from the center of the shape float vDisp = 15; // the height above the top of the bounding box that the center of the marker is. float margin = 8; // the margin (as radius, but like a square) around the center of the marker that we will accept hits on. // the coords (unrotated) of the marker's center. fPoint markCenter = new fPoint(testShape.Left + (testShape.Width / 2) + hDisp, testShape.Top - vDisp); // get the coords of the point fPoint rotCursor = rotatePointWithShape(cursor, testShape); //FIXME TEST DEBUG -- adds a shape to the (unrotated) location of where it thinks the marker is //pptController.addShapeToCurrSlide(MsoAutoShapeType.msoShapeRectangle, markCenter.x - margin, markCenter.y - margin, margin * 2, margin * 2); // see if they're close if ((Math.Abs(rotCursor.x - markCenter.x) <= margin) && (Math.Abs(rotCursor.y - markCenter.y) <= margin)) { return(true); } return(false); }
}//deleteLastObject() /// <summary> /// delete the object chose /// </summary> /// <param name="shape">the shape to be deleted</param> private void deleteChosenObject(PowerPoint.Shape shape) { if (shape == null) { setFeedback("No shape deleted - gesture must START on the shape to be deleted"); return; } if (shape.Type == MsoShapeType.msoTextBox) { // for each textbox, get rid of the button / listbox associated with it ListBox listboxToDelete = findListboxFromTextbox(shape.Name); listboxToDelete.Hide(); stackDeleteTextbox(shape, listboxToDelete); // push both shape and the listbox onto the stack this.Controls.Remove(listboxToDelete); alternateList.Remove(listboxToDelete); clearButtons(); } else { stackDeleteShape(shape); } shape.Delete(); setFeedback("Shape deleted"); }
/// <summary> /// Checks whether the input fPoint is "on" the passed shape, with error SHAPEMARGIN (should we pass in margin?) /// </summary> /// <param name="curPoint">a fPoint with the x and y values in PowerPoint coordinates</param> /// <param name="shape">the PowerPoint shape. May be rotated (but not yet flipped)/</param> /// <returns>true if the point and shape coincide, false else</returns> internal bool pointOnShape(BasicForm.fPoint curPoint, PowerPoint.Shape shape) { BasicForm.fPoint p = BasicForm.rotatePointWithShape(curPoint, shape); return(shape.Left - SHAPEMARGIN < p.x && p.x < shape.Width + shape.Left + SHAPEMARGIN && shape.Top - SHAPEMARGIN < p.y && p.y < shape.Top + shape.Height + SHAPEMARGIN); }
public PowerPoint.Shape addLineToCurrSlide(float x1, float y1, float x2, float y2) { PowerPoint.Shape line = pptApp.ActivePresentation.Slides[getCurSlide()].Shapes.AddLine( x1, y1, x2, y2); return(line); }//addLineCurrSlide