/// <summary> /// Create a new CC if not already in one. /// </summary> /// <param name="controlType"></param> /// <param name="docx"></param> /// <param name="selection"></param> /// <returns></returns> public static Word.ContentControl MakeOrReuse(bool tryToReuse, Word.WdContentControlType controlType, Word.Document docx, Word.Selection selection) { // step 1: create content control, if necessary // are we in a content control? Word.ContentControl cc = null; if (tryToReuse) { cc = ContentControlMaker.getActiveContentControl(docx, selection); } object missing = System.Type.Missing; if (cc == null) { // Add one cc = docx.ContentControls.Add(controlType, ref missing); cc.Title = "[New]"; } else { // we're in a content control already. // Have they selected all of it? // If so, is this add or re-map? if (controlType.Equals(Word.WdContentControlType.wdContentControlRichText)) { cc.XMLMapping.Delete(); } cc.Type = controlType; } return(cc); }
private Word.ContentControl AddContentControl(Word.WdContentControlType ct, ref object selection) { object units = Word.WdUnits.wdCharacter; object count = 1; object missing = Type.Missing; Word.ContentControl ContentControl = Globals.ThisDocument.ContentControls.Add(ct, ref selection); ContentControl.Range.Select(); //by default after we inserted the content control the cursion is within the scope of that control,therefore,use Word OM to move the cursor out of the //new control, and ready to insert the next one. Globals.ThisDocument.ThisApplication.Selection.MoveRight(ref units, ref count, ref missing); Globals.ThisDocument.ThisApplication.Selection.TypeParagraph(); selection = Globals.ThisDocument.ThisApplication.Selection.Range; return(ContentControl); }
/// <summary> /// Create a content control mapped to the selected XML node. /// </summary> /// <param name="CCType">A WdContentControlType value specifying the type of control to create.</param> public void CreateMappedControl(Word.WdContentControlType CCType, ControlTreeView.OpenDopeType odType, ControlTreeView controlTreeView, ControlMain controlMain, Word.Document CurrentDocument, Office.CustomXMLPart CurrentPart, //XmlDocument OwnerDocument, bool _PictureContentControlsReplace ) { OpenDoPEModel.DesignMode designMode = new OpenDoPEModel.DesignMode(CurrentDocument); designMode.Off(); try { object missing = Type.Missing; TreeNode tn = controlTreeView.treeView.SelectedNode; if (((XmlNode)tn.Tag).NodeType == XmlNodeType.Text) { tn = tn.Parent; } //get an nsmgr NameTable nt = new NameTable(); //generate the xpath and the ns manager XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(nt); string strXPath = Utilities.XpathFromXn(CurrentPart.NamespaceManager, (XmlNode)tn.Tag, true, xmlnsMgr); log.Info("Right click for XPath: " + strXPath); string prefixMappings = Utilities.GetPrefixMappings(xmlnsMgr); // Insert bind | condition | repeat // depending on which mode button is pressed. TagData td = new TagData(""); if ((controlMain.modeControlEnabled == false && odType == ControlTreeView.OpenDopeType.Unspecified) || // ie always mode bind (controlMain.modeControlEnabled == true && controlMain.controlMode1.isModeBind()) || odType == ControlTreeView.OpenDopeType.Bind) { log.Debug("In bind mode"); String val = ((XmlNode)tn.Tag).InnerText; //bool isXHTML = HasXHTMLContent(tn); bool isPicture = false; bool isXHTML = false; bool isFlatOPC = ContentDetection.IsFlatOPCContent(val); Word.ContentControl cc = null; if (isFlatOPC) { // <?mso-application progid="Word.Document"?> // <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"> log.Debug(".. contains block content "); cc = CurrentDocument.Application.Selection.ContentControls.Add( Word.WdContentControlType.wdContentControlRichText, ref missing); // Ensure block level Inline2Block i2b = new Inline2Block(); cc = i2b.convertToBlockLevel(cc, false, true); if (cc == null) { MessageBox.Show("Problems inserting block level WordML at this location."); return; } } else { isXHTML = ContentDetection.IsXHTMLContent(val); } if (isXHTML) { cc = CurrentDocument.Application.Selection.ContentControls.Add( Word.WdContentControlType.wdContentControlRichText, ref missing); if (Inline2Block.containsBlockLevelContent(val)) { Inline2Block i2b = new Inline2Block(); cc = i2b.convertToBlockLevel(cc, true, true); if (cc == null) { MessageBox.Show("Problems inserting block level XHTML at this location."); designMode.restoreState(); return; } } } else if (ContentDetection.IsBase64Encoded(val)) { isPicture = true; if (_PictureContentControlsReplace) { // Use a rich text control instead cc = CurrentDocument.ContentControls.Add( Word.WdContentControlType.wdContentControlRichText, ref missing); PictureUtils.pastePictureIntoCC(cc, Convert.FromBase64String(val)); } else { // Force picture content control log.Debug("Detected picture"); cc = CurrentDocument.Application.Selection.ContentControls.Add(Word.WdContentControlType.wdContentControlPicture, ref missing); } } else if (!isFlatOPC) { log.Debug("Not picture or XHTML; " + CCType.ToString()); // This formulation seems more susceptible to "locked for editing" //object rng = CurrentDocument.Application.Selection.Range; //cc = CurrentDocument.ContentControls.Add(Word.WdContentControlType.wdContentControlText, ref rng); // so prefer: cc = CurrentDocument.Application.Selection.ContentControls.Add(CCType, ref missing); } XPathsPartEntry xppe = new XPathsPartEntry(controlMain.model); xppe.setup(null, CurrentPart.Id, strXPath, prefixMappings, true); xppe.save(); td.set("od:xpath", xppe.xpathId); if (isFlatOPC) { td.set("od:progid", "Word.Document"); cc.Title = "Word: " + xppe.xpathId; //cc.Range.Text = val; // don't escape it cc.Range.InsertXML(val, ref missing); } else if (isXHTML) { td.set("od:ContentType", "application/xhtml+xml"); cc.Title = "XHTML: " + xppe.xpathId; cc.Range.Text = val; } else if (isPicture) { PictureUtils.setPictureHandler(td); cc.Title = "Image: " + xppe.xpathId; } else { cc.Title = "Data value: " + xppe.xpathId; } cc.Tag = td.asQueryString(); if (cc.Type == Word.WdContentControlType.wdContentControlText) { cc.MultiLine = true; } if (cc.Type != Word.WdContentControlType.wdContentControlRichText) { cc.XMLMapping.SetMappingByNode(Utilities.MxnFromTn(tn, CurrentPart, true)); } designMode.restoreState(); } else if ((controlMain.modeControlEnabled == true && controlMain.controlMode1.isModeCondition()) || odType == ControlTreeView.OpenDopeType.Condition) { log.Debug("In condition mode"); // User can make a condition whatever type they like, // but if they make it text, change it to RichText. if (CCType == Word.WdContentControlType.wdContentControlText) { CCType = Word.WdContentControlType.wdContentControlRichText; } Word.ContentControl cc = CurrentDocument.Application.Selection.ContentControls.Add(CCType, ref missing); ConditionsPartEntry cpe = new ConditionsPartEntry(controlMain.model); cpe.setup(CurrentPart.Id, strXPath, prefixMappings, true); cpe.save(); cc.Title = "Conditional: " + cpe.conditionId; // Write tag td.set("od:condition", cpe.conditionId); cc.Tag = td.asQueryString(); // We want to be in Design Mode, so user can see their gesture take effect designMode.On(); Ribbon.editXPath(cc); } else if ((controlMain.modeControlEnabled == true && controlMain.controlMode1.isModeRepeat()) || odType == ControlTreeView.OpenDopeType.Repeat) { log.Debug("In repeat mode"); // User can make a repeat whatever type they like // (though does it ever make sense for it to be other than RichText?), // but if they make it text, change it to RichText. if (CCType == Word.WdContentControlType.wdContentControlText) { CCType = Word.WdContentControlType.wdContentControlRichText; } Word.ContentControl cc = CurrentDocument.Application.Selection.ContentControls.Add(CCType, ref missing); // Need to drop eg [1] (if any), so BetterForm-based interactive processing works if (strXPath.EndsWith("]")) { strXPath = strXPath.Substring(0, strXPath.LastIndexOf("[")); log.Debug("Having dropped '[]': " + strXPath); } XPathsPartEntry xppe = new XPathsPartEntry(controlMain.model); xppe.setup("rpt", CurrentPart.Id, strXPath, prefixMappings, false); xppe.save(); cc.Title = "Data value: " + xppe.xpathId; // Write tag td.set("od:repeat", xppe.xpathId); cc.Tag = td.asQueryString(); // We want to be in Design Mode, so user can see their gesture take effect designMode.On(); } } catch (COMException cex) { controlTreeView.ShowErrorMessage(cex.Message); designMode.restoreState(); } }