public static T GetCustomXmlByTagName <T>(Excel.Workbook workbook, string tagName) where T : class
        {
            if (null == workbook)
            {
                throw new ArgumentNullException("workbook");
            }

            if (string.IsNullOrWhiteSpace(tagName))
            {
                throw new ArgumentNullException("tagName");
            }

            foreach (Office.CustomXMLPart part in workbook.CustomXMLParts)
            {
                if (part.DocumentElement.BaseName == tagName)
                {
                    Office.CustomXMLNode node = part.DocumentElement.FirstChild;
                    string json = node.NodeValue.Trim();

                    return(JsonConvert.DeserializeObject <T>(json));
                }
            }

            return(default(T));
        }
Esempio n. 2
0
 /// <summary>
 /// Refresh the property grid.
 /// </summary>
 /// <param name="cxn">A CustomXMLNode specifying the node whose properties we want to use.</param>
 internal void RefreshProperties(Office.CustomXMLNode cxn)
 {
     listViewProperties.Items.Clear();
     if (cxn != null)
     {
         //refresh properties
         if (show("NodeProperties.Show.Namespace"))
         {
             listViewProperties.Items.Add(new ListViewItem(new string[] { Properties.Resources.Namespace, cxn.NamespaceURI }));
         }
         if (show("NodeProperties.Show.Type"))
         {
             listViewProperties.Items.Add(new ListViewItem(new string[] { Properties.Resources.Type, cxn.NodeType.ToString() }));
         }
         if (show("NodeProperties.Show.XPath"))
         {
             listViewProperties.Items.Add(new ListViewItem(new string[] { Properties.Resources.XPath, cxn.XPath }));
         }
         if (show("NodeProperties.Show.Prefixes"))
         {
             listViewProperties.Items.Add(new ListViewItem(new string[] { Properties.Resources.Prefixes, Utilities.GetPrefixMappingsMxn(cxn) }));
         }
         if (show("NodeProperties.Show.XML"))
         {
             listViewProperties.Items.Add(new ListViewItem(new string[] { Properties.Resources.XML, cxn.XML }));
         }
     }
 }
        public static void replaceXmlDoc(Office.CustomXMLPart cxp, String newContent)
        {
            /* Office.CustomXMLNode node = cxp.SelectSingleNode("/");
             * // gives you #document,
             * // but you can't get the root node from it?
             *
             * //node = cxp.SelectSingleNode("/mypart");
             */

            Office.CustomXMLNode node = cxp.SelectSingleNode("/node()");
            //log.Debug(node.XML);
            //log.Debug(node.XPath);

            Office.CustomXMLNode parent = node.ParentNode;

            log.Debug(parent.BaseName);

            //parent.ReplaceChildNode(node, "mynewnode", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeElement, "");

            parent.ReplaceChildSubtree(newContent, node);

            //parent.RemoveChild(node); //doesn't work

            //parent.AppendChildSubtree("<mynewpart><blagh/></mynewpart>");

            node = cxp.SelectSingleNode("/");
            log.Debug(node.XML);
        }
        public void AddXMLNode(Office.CustomXMLPart TreeviewXMLPart, string id, string wordcount, string pgcount, string text, string bookmark, System.Windows.Media.Color CardColor)// this adds a node for the card in the custom XML file
        {
            string color = CardColor.R.ToString() + "," + CardColor.G.ToString() + "," + CardColor.B.ToString();

            Office.CustomXMLNode node = TreeviewXMLPart.SelectSingleNode("//cardList[1]");//[@xmlns=CARDS]
            Office.CustomXMLNode childNode;
            if (node == null)
            {
                MessageBox.Show("Node = null");
            }
            try
            {
                node.AppendChildNode("node", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeElement, text);
                childNode = node.LastChild;
                childNode.AppendChildNode("id", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute, id);
                childNode.AppendChildNode("words", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute, wordcount);
                childNode.AppendChildNode("Pages", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute, pgcount);
                childNode.AppendChildNode("bookmark", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute, bookmark);
                childNode.AppendChildNode("color", "", Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute, color);
            }
            catch
            {
                MessageBox.Show("problem: " + TreeviewXMLPart.DocumentElement.XML + "\n---------\n" + TreeviewXMLPart.XML);
            }
        }
Esempio n. 5
0
 public static string ReadCustomXmlNode(Excel.Workbook workbook, string xNameSpace,
                                        string xPath)
 {
     Office.CustomXMLNode node = GetCustomXmlNode(workbook, xNameSpace, xPath);
     if (node != null)
     {
         return(node.XML);
     }
     return(string.Empty);
 }
Esempio n. 6
0
 public static string getAttribute(Office.CustomXMLNode node, string attributeName)
 {
     foreach (Office.CustomXMLNode attr in node.Attributes)
     {
         if (attr.BaseName.Equals(attributeName))
         {
             return(attr.NodeValue);
         }
     }
     return(null);
 }
Esempio n. 7
0
        public static void UpdateCustomXmlNode(Excel.Workbook workbook, string namespaceName, string xmlString, string xPath)
        {
            Office.CustomXMLParts ps = workbook.CustomXMLParts.SelectByNamespace(namespaceName);

            foreach (Office.CustomXMLPart p in ps)
            {
                var nsmgr = p.NamespaceManager;
                nsmgr.AddNamespace("x", namespaceName);

                Office.CustomXMLNode oldNode = p.SelectSingleNode(xPath);
                oldNode.ParentNode.ReplaceChildSubtree(xmlString, oldNode);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Get the prefix mappings needed to evaluate the XPath to a specific custom XML node.
        /// </summary>
        /// <param name="cxn">The corresponding CustomXMLNode.</param>
        /// <returns>A string specifying the prefix mapping list.</returns>
        internal static string GetPrefixMappingsMxn(Office.CustomXMLNode cxn)
        {
            string s = "";

            foreach (Office.CustomXMLPrefixMapping cxpm in cxn.OwnerPart.NamespaceManager)
            {
                //get the string
                if (!String.IsNullOrEmpty(cxpm.Prefix) && cxpm.Prefix != "xml" && cxpm.Prefix != "xmlns")
                {
                    s += "xmlns:" + cxpm.Prefix + "='" + cxpm.NamespaceURI + "' ";
                }
            }
            return(s);
        }
Esempio n. 9
0
        // get DAX query from XML Data based on active rngCell
        public string GetCustomTableQuery(Excel.Range rngCell)
        {
            Excel.Worksheet sheet    = (Excel.Worksheet)rngCell.Parent;
            Excel.Workbook  workbook = (Excel.Workbook)sheet.Parent;

            TabularItems.Measure measure = GetMeasure(rngCell);

            #region measure
            // get referenced measure
            Office.CustomXMLNode node = ExcelHelper.GetCustomXmlNode(workbook, Constants.DaxDrillXmlSchemaSpace,
                                                                     string.Format("{0}[@id='{1}']", Constants.MeasureXpath, measure.Name));

            string measureName = measure.Name;

            if (node != null)
            {
                foreach (Office.CustomXMLNode attr in node.Attributes)
                {
                    if (attr.BaseName == "ref")
                    {
                        // get DAX query by measure id
                        node = ExcelHelper.GetCustomXmlNode(workbook, Constants.DaxDrillXmlSchemaSpace,
                                                            string.Format("{0}[@id='{1}']/x:query", Constants.MeasureXpath, attr.Text));
                        break;
                    }
                }
            }

            #endregion

            #region table

            // get DAX query by table id (if measure not found in XML metadata)
            if (node == null)
            {
                node = ExcelHelper.GetCustomXmlNode(workbook, Constants.DaxDrillXmlSchemaSpace,
                                                    string.Format("{0}[@id='{1}']/x:query", Constants.TableXpath, measure.TableName));
            }

            #endregion

            if (node != null)
            {
                return(node.Text);
            }

            return(string.Empty);
        }
Esempio n. 10
0
        /// <summary>
        /// Create an XmlNode for a CustomXMLNode.
        /// </summary>
        /// <param name="mxnNewNode">The CustomXMLNode to convert.</param>
        /// <param name="xdoc">The XmlDocument for the corresponding XmlNode.</param>
        /// <returns>The newly created XmlNode.</returns>
        internal static XmlNode XnBuildFromMxn(Office.CustomXMLNode mxnNewNode, XmlDocument xdoc)
        {
            XmlNode xn = null;

            switch (mxnNewNode.NodeType)
            {
            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeElement:
                //create a new temp XML document
                XmlDocument xdocElement = new XmlDocument();
                xdocElement.LoadXml(mxnNewNode.XML);

                //import the element back into the main DOM
                xn = xdoc.ImportNode(xdocElement.DocumentElement, true);

                //clean up
                xdocElement = null;
                break;

            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute:
                char[]   cSplitter    = { '=' };
                string[] strAttribute = mxnNewNode.XML.Split(cSplitter);
                xn           = xdoc.CreateAttribute(strAttribute[0], mxnNewNode.NamespaceURI);
                xn.InnerText = mxnNewNode.NodeValue;
                break;

            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeText:
                xn = xdoc.CreateTextNode(mxnNewNode.Text);
                break;

            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeProcessingInstruction:
                xn = xdoc.CreateProcessingInstruction(mxnNewNode.BaseName, mxnNewNode.Text);
                break;

            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeCData:
                xn = xdoc.CreateCDataSection(mxnNewNode.Text);
                break;

            case Office.MsoCustomXMLNodeType.msoCustomXMLNodeComment:
                xn = xdoc.CreateComment(mxnNewNode.Text);
                break;
            }
            return(xn);
        }
Esempio n. 11
0
        /// <summary>
        /// Get an XmlNode in the local XML tree from the corresponding CustomXMLNode.
        /// </summary>
        /// <param name="xdoc">The XmlDocument for the local XML tree.</param>
        /// <param name="mxn">The CustomXMLNode to convert.</param>
        /// <param name="mxnNew">A new CustomXMLNode that's not in the local tree, and therefore should be ignored when trying to find the XmlNode.</param>
        /// <returns>The corresponding XmlNode.</returns>
        internal static XmlNode XnFromMxn(XmlDocument xdoc, Office.CustomXMLNode mxn, Office.CustomXMLNode mxnNew)
        {
            NameTable           nt       = new NameTable();
            XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(nt);
            string  strXPath             = string.Empty;
            XmlNode xn = null;

            strXPath = XpathFromMxn(mxn, xmlnsMgr, mxnNew);
            Debug.Assert(!string.IsNullOrEmpty(strXPath));

            if (xdoc != null)
            {
                xn = xdoc.SelectSingleNode(strXPath, xmlnsMgr);
            }

            Debug.Assert(xn != null);

            return(xn);
        }
Esempio n. 12
0
        public static Office.CustomXMLNode GetCustomXmlNode(Excel.Workbook workbook, string xNameSpace,
                                                            string xPath)
        {
            Office.CustomXMLParts ps = workbook.CustomXMLParts;
            ps = ps.SelectByNamespace(xNameSpace);


            for (int i = 1; i <= ps.Count; i++)
            {
                Office.CustomXMLPart p = ps[i];
                var nsmgr = p.NamespaceManager;
                nsmgr.AddNamespace("x", xNameSpace);

                Office.CustomXMLNode node = p.SelectSingleNode(xPath);
                if (node != null)
                {
                    return(node);
                }
            }
            return(null);
        }
Esempio n. 13
0
        /// <summary>
        /// Get a CustomXMLNode from a TreeNode.
        /// </summary>
        /// <param name="tn">The TreeNode to convert.</param>
        /// <param name="cxp">The CustomXMLPart containing the corresponding CustomXMLNode.</param>
        /// <param name="fRemoveTextNode">True to get the parent XML node, False otherwise.</param>
        /// <returns>The corresponding CustomXMLNode.</returns>
        internal static Office.CustomXMLNode MxnFromTn(TreeNode tn, Office.CustomXMLPart cxp, bool fRemoveTextNode)
        {
            if (tn == null || tn.Text == "/")
            {
                throw new ArgumentNullException("tn");
            }

            //if we hit a null node, bail
            if (((XmlNode)tn.Tag) == null)
            {
                throw new ArgumentNullException("tn");
            }

            //get an nsmgr
            NameTable           nt       = new NameTable();
            XmlNamespaceManager xmlnsMgr = new XmlNamespaceManager(nt);

            //check if we're editing the text node of an attribute, since then we'll want to get the XPath of the attribute
            string xpath;

            if (((XmlNode)tn.Tag).NodeType == XmlNodeType.Text && ((XmlNode)tn.Parent.Tag).NodeType == XmlNodeType.Attribute)
            {
                xpath = XpathFromTn(tn.Parent, fRemoveTextNode, cxp, xmlnsMgr);
            }
            else if (((XmlNode)tn.Tag).NodeType == XmlNodeType.Text)
            {
                xpath = XpathFromTn(tn, fRemoveTextNode, cxp, xmlnsMgr);
            }
            else
            {
                xpath = XpathFromTn(tn, false, cxp, xmlnsMgr);
            }

            Debug.Assert(!String.IsNullOrEmpty(xpath), "ASSERT: empty xpath", "xpathFromTn gave us back nothing!");

            Office.CustomXMLNode selectedNode = cxp.SelectSingleNode(xpath);

            Debug.Assert(selectedNode != null, "ASSERT: null mxn from xpath", "This XPath: " + xpath + " gave us back no node!");
            return(selectedNode);
        }
Esempio n. 14
0
        private String getCandidatePartsNames(List <Office.CustomXMLPart> cxp)
        {
            StringBuilder sb = new StringBuilder();

            bool first = true;

            foreach (Office.CustomXMLPart cp in cxp)
            {
                Office.CustomXMLNode node = cp.SelectSingleNode("/node()");
                if (first)
                {
                    sb.Append(node.BaseName);
                    first = false;
                }
                else
                {
                    sb.Append(", " + node.BaseName);
                }
            }

            return(sb.ToString());
        }
        public static T GetCustomXmlByNamespace <T>(Excel.Workbook workbook, string namespaceStr) where T : class, new()
        {
            if (null == workbook)
            {
                throw new ArgumentNullException("workbook");
            }

            if (string.IsNullOrWhiteSpace(namespaceStr))
            {
                throw new ArgumentNullException("namespaceStr");
            }

            Office.CustomXMLParts parts = workbook.CustomXMLParts.SelectByNamespace(namespaceStr);

            if (0 == parts.Count)
            {
                return(new T());
            }

            Office.CustomXMLNode node = parts[1].DocumentElement.FirstChild;
            string json = node.NodeValue.Trim();

            return(JsonConvert.DeserializeObject <T>(json));
        }
 private void part_NodeAfterDelete(Office.CustomXMLNode mxnDeletedNode, Office.CustomXMLNode mxnDeletedParent, Office.CustomXMLNode mxnDeletedNextSibling, bool bInUndoRedo)
 {
     Debug.WriteLine("Streams.NodeAfterDelete fired.");
     m_cmTaskPane.RefreshControls(Controls.ControlMain.ChangeReason.NodeDeleted, mxnDeletedNode, mxnDeletedParent, mxnDeletedNextSibling, null, null);
 }
        /// <summary>
        /// Handle Word's OnEnter event for content controls, to set the selection in the pane (if the option is set).
        /// </summary>
        /// <param name="ccEntered">A ContentControl object specifying the control that was entered.</param>
        private void doc_ContentControlOnEnter(Word.ContentControl ccEntered)
        {
            log.Debug("Document.ContentControlOnEnter fired.");
            if (ccEntered.XMLMapping.IsMapped)
            {
                log.Debug("control mapped to " + ccEntered.XMLMapping.XPath);
                if (ccEntered.XMLMapping.CustomXMLNode != null)
                {
                    m_cmTaskPane.RefreshControls(Controls.ControlMain.ChangeReason.OnEnter, null, null, null, ccEntered.XMLMapping.CustomXMLNode, null);
                }
                else
                {
                    // Not mapped to anything; probably because the part was replaced?
                    log.Debug(".. but XMLMapping.CustomXMLNode is null");
                    m_cmTaskPane.controlTreeView.DeselectNode();
                    m_cmTaskPane.WarnViaProperties(ccEntered.XMLMapping.XPath);
                }
            }
            else if (ccEntered.Tag != null)
            {
                TagData td      = new TagData(ccEntered.Tag);
                string  xpathid = td.getXPathID();
                if (xpathid == null)
                {
                    xpathid = td.getRepeatID();
                }

                if (xpathid == null)
                {
                    // Visually indicate in the task pane that we're no longer in a mapped control
                    m_cmTaskPane.controlTreeView.DeselectNode();
                    m_cmTaskPane.PropertiesClear();
                }
                else
                {
                    log.Debug("control mapped via tag to " + xpathid);

                    // Repeats, escaped XHTML; we don't show anything for conditions
                    XPathsPartEntry      xppe          = new XPathsPartEntry(m_cmTaskPane.model);
                    xpathsXpath          xx            = xppe.getXPathByID(xpathid);
                    Office.CustomXMLNode customXMLNode = null;
                    if (xx != null)
                    {
                        log.Debug(xx.dataBinding.xpath);
                        customXMLNode = m_currentPart.SelectSingleNode(xx.dataBinding.xpath);
                    }
                    if (customXMLNode == null)
                    {
                        // Not mapped to anything; probably because the part was replaced?
                        m_cmTaskPane.controlTreeView.DeselectNode();
                        if (xx == null)
                        {
                            log.Error("Couldn't find xpath for " + xpathid);
                            m_cmTaskPane.WarnViaProperties("Missing");
                        }
                        else
                        {
                            log.Warn("Couldn't find target node for " + xx.dataBinding.xpath);
                            m_cmTaskPane.WarnViaProperties(xx.dataBinding.xpath);
                        }
                    }
                    else
                    {
                        m_cmTaskPane.RefreshControls(Controls.ControlMain.ChangeReason.OnEnter, null, null, null, customXMLNode, null);
                    }
                }
            }
            Ribbon.buttonEditEnabled   = true;
            Ribbon.buttonDeleteEnabled = true;

            Ribbon.myInvalidate();
        }
        /// <summary>
        /// Refresh the dropdown list.
        /// </summary>
        /// <param name="bRebuildList">True if the list should be rebuilt from the data in the document, False otherwise.</param>
        /// <param name="bSelectFirstPart">True if the first part in the dropdown list should be selected after the refresh.</param>
        /// <param name="bSelectNewestPart">True if the last part in the dropdown list should be selected after the refresh.</param>
        /// <param name="strIdOfPartToSelect">A string specifying the ID of the part to be selected after the refresh.</param>
        /// <param name="strPartToIgnore">A string specifying the ID of a part to be ignored as part of the refresh (because it is being deleted).</param>
        /// <param name="mxnNodeToSelect">A CustomXMLNode specifying the node to be selected after the refresh.</param>
        internal void RefreshPartList(bool bRebuildList, bool bSelectFirstPart, 
            bool bSelectNewestPart, string strIdOfPartToSelect, 
            string strPartToIgnore, Office.CustomXMLNode mxnNodeToSelect)
        {
            this.SuspendLayout();

            // store the location of the deleted item if we're losing one, since we need to reposition the selection afterwards
            int intPositionOfDeletedItem = -1;
            if (!string.IsNullOrEmpty(strPartToIgnore))
            {
                intPositionOfDeletedItem = m_dicCurrentIndices[strPartToIgnore];
            }

            // store the node to select
            m_mxnToSelect = mxnNodeToSelect;

            // only rebuild if we need to
            if (bRebuildList)
            {
                RebuildPartList(strPartToIgnore);
            }

            // get the right selection
            if (bSelectFirstPart)
            {
                comboBoxPartList.SelectedIndex = 0;
            }
            else if (bSelectNewestPart)
            {
                Debug.Assert(m_intLastSelected != comboBoxPartList.Items.Count - 2, "PERF: Double Refresh?", "Why are we refreshing on newest stream index?" + m_intLastSelected.ToString(CultureInfo.InvariantCulture) + " to " + comboBoxPartList.SelectedIndex.ToString(CultureInfo.InvariantCulture));

                // move to the newest item
                // this will implicitly force a tree refresh, because we're switching the index
                Debug.WriteLine("Tree refresh in RefreshPartList w/ selectNewestPart.");
                comboBoxPartList.SelectedIndex = comboBoxPartList.Items.Count - 2;
            }
            else if (!string.IsNullOrEmpty(strIdOfPartToSelect))
            {
                log.Debug("Selecting part by id: " + strIdOfPartToSelect);
                if (comboBoxPartList.SelectedIndex == m_dicCurrentIndices[strIdOfPartToSelect])
                {
                    log.Debug("SelectNodeFromTree");
                    controlMain.SelectNodeFromTree(m_mxnToSelect);
                }
                else
                {
                    comboBoxPartList.SelectedIndex = m_dicCurrentIndices[strIdOfPartToSelect];

                    if (m_intLastSelected != m_dicCurrentIndices[strIdOfPartToSelect])
                    {
                        // refresh the treeview
                        Debug.WriteLine("Tree refresh in RefreshStreamSelect w/ specific stream");
                        log.Debug("Tree refresh in RefreshStreamSelect w/ specific stream");
                        controlMain.RefreshTreeControl(m_mxnToSelect);
                    }
                }
            }
            else
            {
                //we want to keep on the same stream
                if (!string.IsNullOrEmpty(strPartToIgnore) && intPositionOfDeletedItem < m_intLastSelected) //deleting one above, so move the selection up one
                {
                    comboBoxPartList.SelectedIndex = m_intLastSelected - 1;
                }
                else if (m_intLastSelected == intPositionOfDeletedItem) //deleting the one we're on, so go to the top
                {
                    comboBoxPartList.SelectedIndex = 0;
                }
                else if (m_intLastSelected != comboBoxPartList.SelectedIndex) //deleting one below, so do nothing
                {
                    comboBoxPartList.SelectedIndex = m_intLastSelected;
                }
            }

            //set the current selection
            m_intLastSelected = comboBoxPartList.SelectedIndex;

            //clear
            m_mxnToSelect = null;

            this.ResumeLayout();
            this.PerformLayout();
        }
Esempio n. 19
0
        /// <summary>
        /// Find the position of a node at its level in the XML part.
        /// </summary>
        /// <param name="xn">The XmlNode to convert.</param>
        /// <param name="mxnNew">A new CustomXMLNode that's not in the local tree, and therefore should be ignored when trying to find the position.</param>
        /// <returns>The position of the node, in XPath format (i.e. [1]).</returns>
        private static string XpathPosFromMxn(Office.CustomXMLNode xn, Office.CustomXMLNode mxnNew)
        {
            try
            {
                Debug.Assert(xn != null, "cannot create an xpath from a null node");

                long lSib   = 0;
                long lTotal = 0;
                Office.CustomXMLNode xnPrevSib = null;
                string name  = xn.BaseName;
                string nsUri = xn.NamespaceURI;
                Office.MsoCustomXMLNodeType nt = xn.NodeType;

                if (xn == null)
                {
                    Debug.Fail("null node");
                    throw new ArgumentNullException("xn");
                }

                if (xn.ParentNode != null)
                {
                    lTotal = xn.ParentNode.ChildNodes.Count;
                }

                //need to get the mxnNew down all the way to here and NOT increment the count
                //*if* the xnPrevSib == mxnNew, since then the new node is
                //*not* in my DOM, and I should not use it in the XPath(!)
                while ((xnPrevSib = xn.PreviousSibling) != null)
                {
                    if (mxnNew != null)
                    {
                        if (xnPrevSib.NodeType == nt &&
                            xnPrevSib.BaseName.Equals(name) &&
                            xnPrevSib.NamespaceURI.Equals(nsUri) &&
                            xnPrevSib.XPath != mxnNew.XPath)
                        {
                            lSib++;
                        }
                    }
                    else
                    {
                        if (xnPrevSib.NodeType == nt &&
                            xnPrevSib.BaseName.Equals(name) &&
                            xnPrevSib.NamespaceURI.Equals(nsUri))
                        {
                            lSib++;
                        }
                    }

                    xn = xnPrevSib;
                }

                return(lTotal > 0 ? "[" + (lSib + 1).ToString(CultureInfo.InvariantCulture) + "]" : "");
            }
            catch (ArgumentNullException ex)
            {
                Debug.Fail(ex.Source, ex.Message);
            }

            return(string.Empty);
        }
Esempio n. 20
0
 /// <summary>
 /// Refresh the contents of the tree view control.
 /// </summary>
 /// <param name="mxnNodeToSelect">Optional. A CustomXMLNode specifying a node which should be selected after the refresh is completed.</param>
 internal void RefreshTreeControl(Office.CustomXMLNode mxnNodeToSelect)
 {
     controlTreeView.RefreshTree(mxnNodeToSelect);
 }
        // We can't add a tag for a repeat or a condition,
        // unless we know the XPath.  And we can't know that
        // if there is no suitable child to deduce it from.
        // But if they later press the edit button, we
        // would prefer not to have to ask them whether it
        // is a repeat or a condition. We could track the
        // content controls by their ID, but it seems
        // better to just use the Title.

        /// <summary>
        /// Wrap the selection in a Repeat.
        /// The XPath is deduced from plain binds in the contents.
        /// If there are none of these, just insert an empty content control.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void buttonRepeat_Click(Office.IRibbonControl control)
        {
            Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;

            // Workaround for reported Word crash.
            // Can't reproduce with Word 2010 sp1: 14.0.6129.500
            Word.ContentControl currentCC = ContentControlMaker.getActiveContentControl(document, Globals.ThisAddIn.Application.Selection);
            if (currentCC != null && currentCC.Type != Word.WdContentControlType.wdContentControlRichText)
            {
                MessageBox.Show("You can't add a repeat here.");
                return;
            }

            OpenDoPEModel.DesignMode designMode = new OpenDoPEModel.DesignMode(document);
            designMode.Off();

            // Find a content control within the selection
            List <Word.ContentControl> shallowChildren = ContentControlUtilities.getShallowestSelectedContentControls(document, Globals.ThisAddIn.Application.Selection);

            log.Debug(shallowChildren.Count + " shallowChildren found.");

            Word.ContentControl repeatCC = null;
            object missing = System.Type.Missing;

            try
            {
                repeatCC = document.ContentControls.Add(Word.WdContentControlType.wdContentControlRichText, ref missing);
                // Limitation here: you can't make your content control of eg type picture
                log.Debug("New content control added, with id: " + repeatCC.ID);

                designMode.On();
            }
            catch (System.Exception)
            {
                MessageBox.Show("Selection must be either part of a single paragraph, or one or more whole paragraphs");
                designMode.restoreState();
                return;
            }

            repeatCC.Title = "Repeat [unbound]"; // This used if they later click edit

            if (shallowChildren.Count == 0)
            {
                log.Debug("No child control found. So Repeat not set on our new CC");
                //MessageBox.Show("Unbound content control only added. Click the edit button to setup the repeat.");
                editXPath(repeatCC);
                return;
            }
            // For now, just use the tag on the first simple bind we find.
            // Later, we could try parsing a condition or repeat
            Word.ContentControl usableChild = null;
            foreach (Word.ContentControl child in shallowChildren)
            {
                //if (child.Tag.Contains("od:xpath"))
                if (child.XMLMapping.IsMapped)
                {
                    usableChild = child;
                    break;
                }
            }
            if (usableChild == null)
            {
                log.Debug("No usable child found. So Repeat not set on our new CC");
                //MessageBox.Show("Naked content control only added. Click the edit button to setup the repeat.");
                editXPath(repeatCC);
                return;
            }

            string strXPath = null;

            // Need to work out what repeats.  Could be this child,
            // the parent, etc.  If its obvious from this exemplar xml doc,
            // we can do it automatically. Otherwise, we'll ask user.
            // Currently the logic supports repeating ., .., or grandparent.

            // See whether this child repeats in this exemplar.
            Office.CustomXMLNode thisNode        = usableChild.XMLMapping.CustomXMLNode;
            Office.CustomXMLNode thisNodeSibling = usableChild.XMLMapping.CustomXMLNode.NextSibling;
            Office.CustomXMLNode parent          = usableChild.XMLMapping.CustomXMLNode.ParentNode;
            Office.CustomXMLNode parentSibling   = usableChild.XMLMapping.CustomXMLNode.ParentNode.NextSibling;
            if (thisNodeSibling != null &&
                thisNodeSibling.BaseName.Equals(thisNode.BaseName))
            {
                // Looks like this node repeats :-)

                strXPath = usableChild.XMLMapping.XPath;
                // Get XPath. Could use the od xpaths part, but
                // easier here to work with the binding
                log.Debug("Using . as repeat: " + strXPath);
            } // If it doesn't, test parent.
            else if (parentSibling != null &&
                     parentSibling.BaseName.Equals(parent.BaseName))
            {
                strXPath = usableChild.XMLMapping.XPath;
                log.Debug("Using parent for repeat ");
                strXPath = strXPath.Substring(0, strXPath.LastIndexOf("/"));
                log.Debug("Using: " + strXPath);
            }
            else // If that doesn't either, ask user.
            {
                Office.CustomXMLNode grandparent = null;
                if (parent != null)
                {
                    grandparent = parent.ParentNode;
                }

                using (Forms.FormSelectRepeatedElement sr = new Forms.FormSelectRepeatedElement())
                {
                    sr.labelXPath.Text = usableChild.XMLMapping.XPath;
                    sr.listElementNames.Items.Add(thisNode.BaseName);
                    sr.listElementNames.Items.Add(parent.BaseName);
                    if (grandparent != null)
                    {
                        sr.listElementNames.Items.Add(grandparent.BaseName);
                    }
                    sr.listElementNames.SelectedIndex = 0;
                    sr.ShowDialog();
                    if (sr.listElementNames.SelectedIndex == 0)
                    {
                        strXPath = usableChild.XMLMapping.XPath;
                    }
                    else if (sr.listElementNames.SelectedIndex == 1)
                    {
                        strXPath = parent.XPath;
                        log.Debug("Using parent for repeat: " + strXPath);
                    }
                    else
                    {
                        // Grandparent
                        strXPath = grandparent.XPath;
                        log.Debug("Using grandparent for repeat: " + strXPath);
                    }
                }
            }

            // 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(Model.ModelFactory(document));

            // TODO fix usableChild.XMLMapping.PrefixMappings
            xppe.setup("rpt", usableChild.XMLMapping.CustomXMLPart.Id, strXPath, "", false);  // No Q for repeat
            xppe.save();

            repeatCC.Title = "Repeat: " + xppe.xpathId;
            // Write tag
            TagData td = new TagData("");

            td.set("od:repeat", xppe.xpathId);
            repeatCC.Tag = td.asQueryString();
        }
Esempio n. 22
0
 /// <summary>
 /// Refresh the contents of the property grid.
 /// </summary>
 /// <param name="mxn">A CustomXMLNode specifying the node whose properties we want to display.</param>
 internal void RefreshProperties(Office.CustomXMLNode mxn)
 {
     controlProperties.RefreshProperties(mxn);
 }
        public void treeView_ItemDrag(object sender, ItemDragEventArgs e,
                                      ControlTreeView controlTreeView,
                                      ControlMain controlMain,
                                      Word.Document CurrentDocument,
                                      Office.CustomXMLPart CurrentPart, XmlDocument OwnerDocument,
                                      bool _PictureContentControlsReplace)
        {
            object missing = System.Type.Missing;

            TreeNode tn = (TreeNode)e.Item;

            if (tn == null)
            {
                Debug.Fail("no tn");
                return;
            }

            //check if this is something we can drag
            if (((XmlNode)tn.Tag).NodeType == XmlNodeType.ProcessingInstruction ||
                ((XmlNode)tn.Tag).NodeType == XmlNodeType.Comment)
            {
                return;
            }
            if (controlMain.modeControlEnabled == false || // ie always mode bind
                controlMain.controlMode1.isModeBind())
            {
                if (!ControlTreeView.IsLeafNode(tn) ||
                    ((XmlNode)tn.Tag).NodeType == XmlNodeType.Text && !ControlTreeView.IsLeafNode(tn.Parent))
                {
                    return;
                }
            } // repeats and conditions; let them drag any node


            //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("Dragging XPath: " + strXPath);

            string prefixMappings = Utilities.GetPrefixMappings(xmlnsMgr);

            // OpenDoPE
            TagData td  = new TagData("");
            String  val = ((XmlNode)tn.Tag).InnerText;

            DesignMode designMode = new OpenDoPEModel.DesignMode(CurrentDocument);

            // Special case for pictures, since drag/drop does not seem
            // to work properly (the XHTML pasted doesn't do what it should?)
            bool isPicture = ContentDetection.IsBase64Encoded(val);

            if (isPicture && !_PictureContentControlsReplace)
            {
                designMode.Off();
                log.Debug("Special case handling for pictures..");

                // Selection can't be textual content, so ensure it isn't.
                // It is allowed to be a picture, so in the future we could
                // leave the selection alone if it is just a picture.
                Globals.ThisAddIn.Application.Selection.Collapse(ref missing);
                // Are they dragging to an existing picture content control
                Word.ContentControl picCC = ContentControlMaker.getActiveContentControl(CurrentDocument, Globals.ThisAddIn.Application.Selection);
                try
                {
                    if (picCC == null ||
                        (picCC.Type != Word.WdContentControlType.wdContentControlPicture))
                    {
                        picCC = CurrentDocument.ContentControls.Add(
                            Word.WdContentControlType.wdContentControlPicture, ref missing);
                        designMode.restoreState();
                    }
                }
                catch (COMException ce)
                {
                    // Will happen if you try to drag a text node onto an existing image content control
                    log.Debug("Ignoring " + ce.Message);
                    return;
                }
                XPathsPartEntry xppe = new XPathsPartEntry(controlMain.model);
                xppe.setup(null, CurrentPart.Id, strXPath, prefixMappings, false);
                xppe.save();

                td.set("od:xpath", xppe.xpathId);
                picCC.Tag = td.asQueryString();

                picCC.Title = "Data value: " + xppe.xpathId;
                picCC.XMLMapping.SetMappingByNode(Utilities.MxnFromTn(tn, CurrentPart, true));
                return;
            }

            log.Debug("\n\ntreeView_ItemDrag for WdSelectionType " + Globals.ThisAddIn.Application.Selection.Type.ToString());

            bool isXHTML   = false;
            bool isFlatOPC = ContentDetection.IsFlatOPCContent(val);

            if (!isFlatOPC)
            {
                isXHTML = ContentDetection.IsXHTMLContent(val);
            }

            if (Globals.ThisAddIn.Application.Selection.Type
                != Microsoft.Office.Interop.Word.WdSelectionType.wdSelectionIP)
            {
                // ie something is selected, since "inline paragraph selection"
                // just means the cursor is somewhere inside
                // a paragraph, but with nothing selected.

                designMode.Off();

                // Selection types: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.wdselectiontype(v=office.11).aspx
                log.Debug("treeView_ItemDrag fired, but interpreted as gesture for WdSelectionType " + Globals.ThisAddIn.Application.Selection.Type.ToString());

                Word.ContentControl parentCC = ContentControlMaker.getActiveContentControl(CurrentDocument,
                                                                                           Globals.ThisAddIn.Application.Selection);

                // Insert bind | condition | repeat
                // depending on which mode button is pressed.
                if (controlMain.modeControlEnabled == false || // ie always mode bind
                    controlMain.controlMode1.isModeBind())
                {
                    log.Debug("In bind mode");
                    Word.ContentControl cc = null;


                    try
                    {
                        if (isFlatOPC || isXHTML ||
                            (isPicture && _PictureContentControlsReplace))
                        {
                            // Rich text
                            if (parentCC != null &&
                                ContentControlOpenDoPEType.isBound(parentCC))
                            {
                                // Reuse existing cc
                                cc = ContentControlMaker.MakeOrReuse(true, Word.WdContentControlType.wdContentControlRichText, CurrentDocument,
                                                                     Globals.ThisAddIn.Application.Selection);
                            }
                            else
                            {
                                // Make new cc
                                cc = ContentControlMaker.MakeOrReuse(true, Word.WdContentControlType.wdContentControlRichText, CurrentDocument,
                                                                     Globals.ThisAddIn.Application.Selection);
                            }

                            if (isFlatOPC)
                            {
                                log.Debug(".. contains block content ");
                                // 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 if (isXHTML && // and thus not picture
                                     Inline2Block.containsBlockLevelContent(val))
                            {
                                log.Debug(".. contains block content ");
                                // Ensure block level
                                Inline2Block i2b = new Inline2Block();
                                cc = i2b.convertToBlockLevel(cc, false, true);

                                if (cc == null)
                                {
                                    MessageBox.Show("Problems inserting block level XHTML at this location.");
                                    return;
                                }
                            }
                        }
                        else
                        {
                            // Plain text
                            if (parentCC != null &&
                                ContentControlOpenDoPEType.isBound(parentCC))
                            {
                                // Reuse existing cc
                                cc = ContentControlMaker.MakeOrReuse(true, Word.WdContentControlType.wdContentControlText, CurrentDocument,
                                                                     Globals.ThisAddIn.Application.Selection);
                            }
                            else
                            {
                                // Make new cc
                                cc = ContentControlMaker.MakeOrReuse(false, Word.WdContentControlType.wdContentControlText, CurrentDocument,
                                                                     Globals.ThisAddIn.Application.Selection);
                            }
                            cc.MultiLine = true;
                            // Is a text content control always run-level?
                            // No, not if you have a single para selected and you do drag gesture
                            // (or if you remap a rich text control)
                        }
                    }
                    catch (Exception ex)
                    {
                        log.Error("Couldn't add content control: " + ex.Message);
                        return;
                    }

                    XPathsPartEntry xppe = new XPathsPartEntry(controlMain.model);
                    xppe.setup(null, CurrentPart.Id, strXPath, prefixMappings, true);
                    xppe.save();

                    td.set("od:xpath", xppe.xpathId);

                    if (isFlatOPC)
                    {
                        // <?mso-application progid="Word.Document"?>
                        // <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">

                        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; // don't escape it
                    }
                    else if (isPicture)
                    {
                        PictureUtils.setPictureHandler(td);
                        cc.Title = "Image: " + xppe.xpathId;

                        string picContent = CurrentPart.SelectSingleNode(strXPath).Text;
                        PictureUtils.pastePictureIntoCC(cc, Convert.FromBase64String(picContent));
                    }
                    else
                    {
                        cc.XMLMapping.SetMappingByNode(Utilities.MxnFromTn(tn, CurrentPart, true));

                        string nodeXML = cc.XMLMapping.CustomXMLNode.XML;
                        log.Info(nodeXML);
                        cc.Title = "Data value: " + xppe.xpathId;
                    }

                    cc.Tag = td.asQueryString();

                    designMode.restoreState();
                }
                else if (controlMain.controlMode1.isModeCondition())
                {
                    log.Debug("In condition mode");
                    Word.ContentControl cc = null;
                    try
                    {
                        // always make new
                        cc = ContentControlMaker.MakeOrReuse(false, Word.WdContentControlType.wdContentControlRichText, CurrentDocument, Globals.ThisAddIn.Application.Selection);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Couldn't add content control: " + ex.Message);
                        return;
                    }
                    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();

                    designMode.On();
                }
                else if (controlMain.controlMode1.isModeRepeat())
                {
                    log.Debug("In repeat mode");
                    Word.ContentControl cc = null;
                    try
                    {
                        // always make new
                        cc = ContentControlMaker.MakeOrReuse(false, Word.WdContentControlType.wdContentControlRichText, CurrentDocument, Globals.ThisAddIn.Application.Selection);
                    }
                    catch (Exception ex)
                    {
                        log.Error("Couldn't add content control: " + ex.Message);
                        return;
                    }

                    // 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); // no Q for repeat
                    xppe.save();

                    cc.Title = "Repeat: " + xppe.xpathId;
                    // Write tag
                    td.set("od:repeat", xppe.xpathId);
                    cc.Tag = td.asQueryString();

                    designMode.On();
                }

                return;
            } // end if (Globals.ThisAddIn.Application.Selection.Type != Microsoft.Office.Interop.Word.WdSelectionType.wdSelectionIP)

            // Selection.Type: Microsoft.Office.Interop.Word.WdSelectionType.wdSelectionIP
            // ie cursor is somewhere inside a paragraph, but with nothing selected.
            log.Info("In wdSelectionIP specific code.");

            // leave designMode alone here

            // Following processing uses clipboard HTML to implement drag/drop processing
            // Could avoid dealing with that (what's the problem anyway?) if they are dragging onto an existing content control, with:
            //Word.ContentControl existingCC = ContentControlMaker.getActiveContentControl(CurrentDocument, Globals.ThisAddIn.Application.Selection);
            //if (existingCC != null) return;
            // But that stops them from dragging any more content into a repeat.

            string title    = "";
            string tag      = "";
            bool   needBind = false;

            log.Debug(strXPath);
            Office.CustomXMLNode targetNode = CurrentPart.SelectSingleNode(strXPath);
            string nodeContent = targetNode.Text;

            // or ((XmlNode)tn.Tag).InnerXml

            // Insert bind | condition | repeat
            // depending on which mode button is pressed.
            if (controlMain.modeControlEnabled == false || // ie always mode bind
                controlMain.controlMode1.isModeBind())
            {
                log.Debug("In bind mode");
                // OpenDoPE: create w:tag=od:xpath=x1
                // and add XPath to xpaths part
                XPathsPartEntry xppe = new XPathsPartEntry(controlMain.model);
                xppe.setup(null, CurrentPart.Id, strXPath, prefixMappings, false); // Don't setup Q until after drop
                xppe.save();

                // Write tag
                td.set("od:xpath", xppe.xpathId);

                // Does this node contain XHTML?
                // TODO: error handling
                log.Info(nodeContent);


                if (isFlatOPC)
                {
                    // <?mso-application progid="Word.Document"?>
                    // <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">

                    td.set("od:progid", "Word.Document");
                    title    = "Word: " + xppe.xpathId;
                    needBind = false; // make it a rich text control
                }
                else if (isXHTML)
                {
                    td.set("od:ContentType", "application/xhtml+xml");
                    // TODO since this is a run-level sdt,
                    // the XHTML content will need to be run-level.
                    // Help the user with this?
                    // Or in a run-level context, docx4j could convert
                    // p to soft-enter?  But what to do about tables?
                    title = "XHTML: " + xppe.xpathId;

                    needBind = false; // make it a rich text control

                    // Word will only replace our HTML-imported-to-docx with the raw HTML
                    // if we have the bind.
                    // Without this, giving the user visual feedback in Word is a TODO
                }
                else if (isPicture)
                {
                    designMode.Off();
                    log.Debug("NEW Special case handling for pictures..");

                    //object missing = System.Type.Missing;
                    Globals.ThisAddIn.Application.Selection.Collapse(ref missing);
                    // Are they dragging to an existing picture content control
                    Word.ContentControl picCC = ContentControlMaker.getActiveContentControl(CurrentDocument, Globals.ThisAddIn.Application.Selection);
                    try
                    {
                        if (picCC == null ||
                            (picCC.Type != Word.WdContentControlType.wdContentControlPicture))
                        {
                            picCC = CurrentDocument.ContentControls.Add(
                                Word.WdContentControlType.wdContentControlRichText, ref missing);
                            designMode.restoreState();
                        }
                    }
                    catch (COMException ce)
                    {
                        // Will happen if you try to drag a text node onto an existing image content control
                        log.Debug("Ignoring " + ce.Message);
                        return;
                    }
                    PictureUtils.setPictureHandler(td);
                    picCC.Title = "Image: " + xppe.xpathId;

                    picCC.Tag = td.asQueryString();

                    PictureUtils.pastePictureIntoCC(picCC,
                                                    Convert.FromBase64String(nodeContent));

                    return;
                }
                else
                {
                    title    = "Data value: " + xppe.xpathId;
                    needBind = true;
                }
                tag = td.asQueryString();
            }
            else if (controlMain.controlMode1.isModeCondition())
            {
                log.Debug("In condition mode");
                ConditionsPartEntry cpe = new ConditionsPartEntry(controlMain.model);
                cpe.setup(CurrentPart.Id, strXPath, prefixMappings, false);
                cpe.save();

                title = "Conditional: " + cpe.conditionId;
                // Write tag
                td.set("od:condition", cpe.conditionId);
                tag = td.asQueryString();
            }
            else if (controlMain.controlMode1.isModeRepeat())
            {
                log.Debug("In repeat mode");

                // 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();

                title = "Data value: " + xppe.xpathId;
                // Write tag
                td.set("od:repeat", xppe.xpathId);
                tag = td.asQueryString();
            }


            //create the HTML
            string strHTML = string.Empty;

            if (isFlatOPC)
            {
                // <?mso-application progid="Word.Document"?>
                // <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
                nodeContent = ControlTreeView.EscapeXHTML(nodeContent);

                strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, Utilities.GetPrefixMappings(xmlnsMgr), CurrentPart.Id,
                                                                   Utilities.MappingType.RichText, title, tag, nodeContent);
            }
            else if (isXHTML)
            {
                // need to escape eg <span> for it to get through the Clipboard
                nodeContent = ControlTreeView.EscapeXHTML(nodeContent);

                // use a RichText control, and set nodeContent
                strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, Utilities.GetPrefixMappings(xmlnsMgr), CurrentPart.Id,
                                                                   Utilities.MappingType.RichText, title, tag, nodeContent);
                // alternatively, this could be done in DocumentEvents.doc_ContentControlAfterAdd
                // but to do it there, we'd need to manually resolve the XPath to
                // find the value of the CustomXMLNode it pointed to.
            }
            else if (!needBind)
            {
                // For conditions & repeats, we use a RichText control
                strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, Utilities.GetPrefixMappings(xmlnsMgr), CurrentPart.Id,
                                                                   Utilities.MappingType.RichText, title, tag);
            }
            else
            {
                // Normal bind

                if (OwnerDocument.Schemas.Count > 0)
                {
                    switch (Utilities.CheckNodeType((XmlNode)tn.Tag))
                    {
                    case Utilities.MappingType.Date:
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, prefixMappings, CurrentPart.Id, Utilities.MappingType.Date, title, tag);
                        break;

                    case Utilities.MappingType.DropDown:
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, prefixMappings, CurrentPart.Id, Utilities.MappingType.DropDown, title, tag);
                        break;

                    case Utilities.MappingType.Picture:
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, prefixMappings, CurrentPart.Id, Utilities.MappingType.Picture, title, tag);
                        break;

                    default:
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, prefixMappings, CurrentPart.Id, Utilities.MappingType.Text, title, tag);
                        break;
                    }
                }
                else
                {
                    //String val = ((XmlNode)tn.Tag).InnerText;
                    if (ContentDetection.IsBase64Encoded(val))
                    {
                        // Force picture content control
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, Utilities.GetPrefixMappings(xmlnsMgr), CurrentPart.Id,
                                                                           Utilities.MappingType.Picture, title, tag);
                    }
                    else
                    {
                        strHTML = ClipboardUtilities.GenerateClipboardHTML(needBind, strXPath, Utilities.GetPrefixMappings(xmlnsMgr), CurrentPart.Id,
                                                                           Utilities.MappingType.Text, title, tag);
                    }
                }
            }

            // All cases:-

            //notify ourselves of a pending drag/drop
            controlMain.NotifyDragDrop(true);

            //throw it on the clipboard to drag
            DataObject dobj = new DataObject();

            dobj.SetData(DataFormats.Html, strHTML);
            dobj.SetData(DataFormats.Text, tn.Text);
            controlTreeView.DoDragDrop(dobj, DragDropEffects.Move);

            //notify ourselves of a completed drag/drop
            controlMain.NotifyDragDrop(false);

            Clipboard.SetData(DataFormats.Text, ((XmlNode)tn.Tag).InnerXml);
        }
 public TreeViewElements(Office.CustomXMLPart cxpTreeView, Office.CustomXMLNode mxnNodeToSelect)
 {
     m_cxpTreeView = cxpTreeView;
     m_xdocTreeView = new XmlDocument();
     m_mxnNodeToSelect = mxnNodeToSelect;
 }
 private void part_NodeAfterInsert(Office.CustomXMLNode mxnNewNode, bool bInUndoRedo)
 {
     Debug.WriteLine("Streams.NodeAfterInsert fired.");
     m_cmTaskPane.RefreshControls(Controls.ControlMain.ChangeReason.NodeAdded, null, null, null, mxnNewNode, null);
 }
 private void part_NodeAfterReplace(Office.CustomXMLNode mxnOldNode, Office.CustomXMLNode mxnNewNode, bool bInUndoRedo)
 {
     Debug.WriteLine("Streams.NodeAfterReplace fired.");
     m_cmTaskPane.RefreshControls(Controls.ControlMain.ChangeReason.NodeReplaced, mxnOldNode, mxnNewNode.ParentNode, mxnNewNode.NextSibling, mxnNewNode, null);
 }
Esempio n. 27
0
        /// <summary>
        /// Get an XPath for a CustomXMLNode.
        /// </summary>
        /// <param name="xn">The CustomXMLNode to convert.</param>
        /// <param name="xnsmgr">The XmlNamespaceManager for the local XML tree.</param>
        /// <param name="mxnNew">A new CustomXMLNode that's not in the local tree, and therefore should be ignored when trying to find the XPath.</param>
        /// <returns>The corresponding XPath.</returns>
        private static string XpathFromMxn(Office.CustomXMLNode xn, XmlNamespaceManager xnsmgr, Office.CustomXMLNode mxnNew)
        {
            try
            {
                Debug.Assert(xn != null, "cannot create an xpath from a null node");

                string strThis     = null;
                string strThisName = null;
                string ns          = "";

                bool fCheckParent = true;

                Office.CustomXMLNode           xnParent = xn.ParentNode;
                Office.CustomXMLPrefixMappings mnsmgr   = xn.OwnerPart.NamespaceManager;

                switch (xn.NodeType)
                {
                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeElement:
                    strThisName = xn.BaseName;

                    if (!string.IsNullOrEmpty(xn.NamespaceURI))
                    {
                        ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":";
                        xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI);
                    }
                    strThis = "/" + ns + strThisName + XpathPosFromMxn(xn, mxnNew);
                    break;

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeAttribute:
                    strThisName = xn.BaseName;
                    if (!string.IsNullOrEmpty(xn.NamespaceURI))
                    {
                        ns = mnsmgr.LookupPrefix(xn.NamespaceURI) + ":";
                        xnsmgr.AddNamespace(mnsmgr.LookupPrefix(xn.NamespaceURI), xn.NamespaceURI);
                    }
                    strThis  = "/@" + ns + strThisName;
                    xnParent = xn.SelectSingleNode("..");

                    break;

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeProcessingInstruction:
                {
                    strThis = "/processing-instruction(";

                    strThis = strThis + ")" + XpathPosFromMxn(xn, mxnNew);
                    break;
                }

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeText:
                    strThis = "/text()" + XpathPosFromMxn(xn, mxnNew);
                    break;

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeComment:
                    strThis = "/comment()" + XpathPosFromMxn(xn, mxnNew);
                    break;

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeDocument:
                    strThis      = "";
                    fCheckParent = false;
                    break;

                case Office.MsoCustomXMLNodeType.msoCustomXMLNodeCData:
                    strThis = "/text()" + XpathPosFromMxn(xn, mxnNew);
                    break;
                }

                return(strThis.Insert(0, fCheckParent ? XpathFromMxn(xnParent, xnsmgr, mxnNew) : ""));
            }
            catch (COMException ex)
            {
                Debug.Fail(ex.Source, ex.Message);
            }

            return(string.Empty);
        }
Esempio n. 28
0
 /// <summary>
 /// Select a node within the tree view.
 /// </summary>
 /// <param name="mxnToSelect">A CustomXMLNode specifying a node which should be selected after the refresh is completed.</param>
 internal void SelectNodeFromTree(Office.CustomXMLNode mxnToSelect)
 {
     //select the node (happens on the calling thread)
     controlTreeView.SelectNodeFromTree(mxnToSelect);
 }
Esempio n. 29
0
        /// <summary>
        /// Refresh the dropdown list.
        /// </summary>
        /// <param name="bRebuildList">True if the list should be rebuilt from the data in the document, False otherwise.</param>
        /// <param name="bSelectFirstPart">True if the first part in the dropdown list should be selected after the refresh.</param>
        /// <param name="bSelectNewestPart">True if the last part in the dropdown list should be selected after the refresh.</param>
        /// <param name="strIdOfPartToSelect">A string specifying the ID of the part to be selected after the refresh.</param>
        /// <param name="strPartToIgnore">A string specifying the ID of a part to be ignored as part of the refresh (because it is being deleted).</param>
        /// <param name="mxnNodeToSelect">A CustomXMLNode specifying the node to be selected after the refresh.</param>
        internal void RefreshPartList(bool bRebuildList, bool bSelectFirstPart, bool bSelectNewestPart, string strIdOfPartToSelect, string strPartToIgnore, Office.CustomXMLNode mxnNodeToSelect)
        {
            this.SuspendLayout();

            // store the location of the deleted item if we're losing one, since we need to reposition the selection afterwards
            int intPositionOfDeletedItem = -1;

            if (!string.IsNullOrEmpty(strPartToIgnore))
            {
                intPositionOfDeletedItem = m_dicCurrentIndices[strPartToIgnore];
            }

            // store the node to select
            m_mxnToSelect = mxnNodeToSelect;

            // only rebuild if we need to
            if (bRebuildList)
            {
                RebuildPartList(strPartToIgnore);
            }

            // get the right selection
            if (bSelectFirstPart)
            {
                comboBoxPartList.SelectedIndex = 0;
            }
            else if (bSelectNewestPart)
            {
                Debug.Assert(m_intLastSelected != comboBoxPartList.Items.Count - 2, "PERF: Double Refresh?", "Why are we refreshing on newest stream index?" + m_intLastSelected.ToString(CultureInfo.InvariantCulture) + " to " + comboBoxPartList.SelectedIndex.ToString(CultureInfo.InvariantCulture));

                // move to the newest item
                // this will implicitly force a tree refresh, because we're switching the index
                Debug.WriteLine("Tree refresh in RefreshPartList w/ selectNewestPart.");
                comboBoxPartList.SelectedIndex = comboBoxPartList.Items.Count - 2;
            }
            else if (!string.IsNullOrEmpty(strIdOfPartToSelect))
            {
                if (comboBoxPartList.SelectedIndex == m_dicCurrentIndices[strIdOfPartToSelect])
                {
                    ((ControlMain)Parent).SelectNodeFromTree(m_mxnToSelect);
                }
                else
                {
                    comboBoxPartList.SelectedIndex = m_dicCurrentIndices[strIdOfPartToSelect];

                    if (m_intLastSelected != m_dicCurrentIndices[strIdOfPartToSelect])
                    {
                        // refresh the treeview
                        Debug.WriteLine("Tree refresh in RefreshStreamSelect w/ specific stream");
                        ((ControlMain)Parent).RefreshTreeControl(m_mxnToSelect);
                    }
                }
            }
            else
            {
                //we want to keep on the same stream
                if (!string.IsNullOrEmpty(strPartToIgnore) && intPositionOfDeletedItem < m_intLastSelected) //deleting one above, so move the selection up one
                {
                    comboBoxPartList.SelectedIndex = m_intLastSelected - 1;
                }
                else if (m_intLastSelected == intPositionOfDeletedItem) //deleting the one we're on, so go to the top
                {
                    comboBoxPartList.SelectedIndex = 0;
                }
                else if (m_intLastSelected != comboBoxPartList.SelectedIndex) //deleting one below, so do nothing
                {
                    comboBoxPartList.SelectedIndex = m_intLastSelected;
                }
            }

            //set the current selection
            m_intLastSelected = comboBoxPartList.SelectedIndex;

            //clear
            m_mxnToSelect = null;

            this.ResumeLayout();
            this.PerformLayout();
        }
Esempio n. 30
0
        /// <summary>
        /// Refresh the task pane based on some event.
        /// </summary>
        /// <param name="ehReason">A ChangeReason value specifying the reason for the refresh request.</param>
        /// <param name="mxnOldNode">A CustomXMLNode specifying the deleted node (if applicable).</param>
        /// <param name="mxnOldParent">A CustomXMLNode specifying the former parent node of the deleted node (if applicable).</param>
        /// <param name="mxnOldNextSibling">A CustomXMLNode specifying the former next sibling node of the affected node (if applicable).</param>
        /// <param name="mxnNewNode">A CustomXMLNode specifying the new node (if applicable).</param>
        /// <param name="cxpOldPart">A CustomXMLPart specifying the XML part being deleted (if applicable).</param>
        internal void RefreshControls(ChangeReason ehReason, Office.CustomXMLNode mxnOldNode, Office.CustomXMLNode mxnOldParent, Office.CustomXMLNode mxnOldNextSibling, Office.CustomXMLNode mxnNewNode, Office._CustomXMLPart cxpOldPart)
        {
            // determine why we've been asked to refresh the pane
            switch (ehReason)
            {
            case ChangeReason.DocumentChanged:
                Debug.WriteLine("UI refresh for document change.");
                if (!Globals.ThisAddIn.Application.ShowWindowsInTaskbar)
                {
                    EventHandler.ChangeCurrentDocument();
                }
                controlPartList.RefreshPartList(true, true, false, string.Empty, null, null);
                break;

            case ChangeReason.PartAdded:
                Debug.WriteLine("UI refresh for stream addition.");
                controlPartList.RefreshPartList(true, false, false, string.Empty, null, null);
                break;

            case ChangeReason.PartDeleted:
                Debug.WriteLine("UI refresh for stream deletion.");
                Debug.Assert(cxpOldPart != null, "We were handed a NULL cxp?");
                controlPartList.RefreshPartList(true, false, false, string.Empty, cxpOldPart.Id, null);
                break;

            case ChangeReason.PartLoaded:
                Debug.WriteLine("UI refresh for stream load.");
                controlPartList.RefreshPartList(true, false, false, string.Empty, null, null);
                break;

            case ChangeReason.NodeAdded:
                Debug.WriteLine("UI refresh for node addition.");
                controlTreeView.AddMxnToTree(mxnNewNode);
                break;

            case ChangeReason.NodeDeleted:
                Debug.WriteLine("UI refresh for node deletion.");
                controlTreeView.RemoveMxnFromTree(mxnOldNode, mxnOldParent, mxnOldNextSibling, null);
                break;

            case ChangeReason.NodeReplaced:
                Debug.WriteLine("UI refresh for node replacement.");
                controlTreeView.ReplaceMxnInTree(mxnOldNode, mxnNewNode);
                break;

            case ChangeReason.DragDrop:
                Debug.WriteLine("UI refresh for drag/drop of XML.");
                controlPartList.RefreshPartList(true, false, true, string.Empty, null, null);
                break;

            case ChangeReason.OnEnter:
                Debug.WriteLine("UI refresh for BB enter.");
                Debug.Assert(mxnNewNode != null, "No mxn for CC?");
                if ((controlTreeView.Options & ControlTreeView.cOptionsAutoSelectNode) != 0)
                {
                    controlPartList.RefreshPartList(false, false, false, mxnNewNode.OwnerPart.Id, null, mxnNewNode);
                }
                break;

            default:
                Debug.Assert(false, "Unknown refresh event", "We got called on a refresh event that doesn't exist??");
                break;
            }
        }
        private void launchTaskPane()
        {
            //set the cursor to wait
            Globals.ThisAddIn.Application.System.Cursor = Word.WdCursorType.wdCursorWait;

            //set up the task pane
            CustomTaskPane ctpPaneForThisWindow
                = Globals.ThisAddIn.CustomTaskPanes.Add(
                      new Controls.ControlMain(),
                      Properties.Resources.TaskPaneName);

            ctpPaneForThisWindow.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoHorizontal;

            //store it for later
            if (Globals.ThisAddIn.Application.ShowWindowsInTaskbar)
            {
                Globals.ThisAddIn.TaskPaneList.Add(Globals.ThisAddIn.Application.ActiveWindow, ctpPaneForThisWindow);
            }

            //connect task pane events
            Globals.ThisAddIn.ConnectTaskPaneEvents(ctpPaneForThisWindow);

            //get the control we hosted
            Controls.ControlMain ccm = (Controls.ControlMain)ctpPaneForThisWindow.Control;

            ccm.formPartList.ccm = ccm;

            // OK, OpenDoPE parts should exist
            Model model = Model.ModelFactory(Globals.ThisAddIn.Application.ActiveDocument);

            // hand the OpenDoPE model to the control
            ccm.model = model;


            //hand the eventing class to the control
            DocumentEvents de = new DocumentEvents(ccm);

            de.Ribbon = this; // so de can enable/disable stuff on ribbon


            ccm.EventHandlerAndOnChildren = de;

            // following is no good for us, since it selects first part
            //ccm.RefreshControls(Controls.ControlMain.ChangeReason.DocumentChanged, null, null, null, null, null);

            // The current cxp is stored in the DocumentEvents object
            // (which in turn is a field in ControlBase).
            // The user custom xml part is to current in DocumentEvents.
            // But we also need:
            string requiredRoot = System.Configuration.ConfigurationManager.AppSettings["RootElement"];

            Office.CustomXMLPart userPart   = model.getUserPart(requiredRoot);
            Office.CustomXMLNode mxnNewNode = userPart.DocumentElement;

            log.Debug("DocumentElement of user part: " + mxnNewNode.BaseName);
            ccm.formPartList.controlPartList.RefreshPartList(true, false, false, mxnNewNode.OwnerPart.Id, null, mxnNewNode);

            //ccm.RefreshControls(Controls.ControlMain.ChangeReason.OnEnter, null, null, null, mxnNewNode, null);
            // would also work, but is more opaque

            //show it
            ctpPaneForThisWindow.Visible = true;

            this.buttonBindEnabled      = true;
            this.buttonConditionEnabled = true;
            this.buttonRepeatEnabled    = true;

            this.menuAdvancedEnabled = true;

            this.buttonReplaceXMLEnabled = true;
            this.buttonClearAllEnabled   = true;

            myInvalidate();

            //reset the cursor
            Globals.ThisAddIn.Application.System.Cursor = Word.WdCursorType.wdCursorNormal;
        }