Ejemplo n.º 1
0
        public void buttonEdit_Click(Office.IRibbonControl control)
        {
            Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;

            // Get the content control
            Word.ContentControl cc = ContentControlMaker.getActiveContentControl(document, Globals.ThisAddIn.Application.Selection);
            if (cc == null)
            {
                // Shouldn't happen
                MessageBox.Show("Which content control?");
                return;
            }
            editXPath(cc);
        }
Ejemplo n.º 2
0
        public void buttonDelete_Click(Office.IRibbonControl control)
        {
            Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;

            // Get the content control
            Word.ContentControl cc = ContentControlMaker.getActiveContentControl(document, Globals.ThisAddIn.Application.Selection);
            if (cc == null)
            {
                // Shouldn't happen
                MessageBox.Show("Which content control?");
                return;
            }
            // Delete the content control, but keep the contents
            log.Warn("Deleting control with tag " + cc.Tag);
            cc.Delete(false);
        }
Ejemplo n.º 3
0
        public void buttonBind_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 data value here.");
                return;
            }

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

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

            try
            {
                cc = document.ContentControls.Add(Word.WdContentControlType.wdContentControlText, ref missing);
                // Later, we'll change it to type picture if necessary
                cc.MultiLine = true;

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

            cc.Title = "Data Value [unbound]"; // // This used if they later click edit

            // Now just launch the edit button
            editXPath(cc);
        }
Ejemplo n.º 4
0
        public bool toggleButtonMappingEnabled = false; // TODO REVIEW

        public bool isContextMenuStylesOverridden(Office.IRibbonControl control)
        {
            if (!buttonEditEnabled)
            {
                log.Debug("edit disabled");
                return(false); // outside any cc
            }
            // we should be in a content control
            Word.Document       document = Globals.ThisAddIn.Application.ActiveDocument;
            Word.ContentControl cc       = ContentControlMaker.getActiveContentControl(document, Globals.ThisAddIn.Application.Selection);
            if (cc == null)
            {
                log.Debug("cc null");
                return(false);
            }
            // we are in a cc. is it an XHTML one?
            log.Debug(cc.Title);
            log.Debug(cc.Tag);
            return((cc.Title != null && cc.Title.StartsWith("XHTML")) ||
                   (cc.Tag != null && cc.Tag.Contains("ContentType=application/xhtml+xml")));
        }
        public FormStyleChooser()
        {
            InitializeComponent();

            styleDefaultPFont = Globals.ThisAddIn.Application.ActiveDocument.Styles[Word.WdBuiltinStyle.wdStyleDefaultParagraphFont];

            cc = ContentControlMaker.getActiveContentControl(Globals.ThisAddIn.Application.ActiveDocument, Globals.ThisAddIn.Application.Selection);
            if (cc == null)
            {
                // Shouldn't happen
                log.Error("Which content control?");
                this.Close();
            }


            dynamic d = cc.get_DefaultTextStyle(); // actually returns the PARAGRAPH style!

            if (d == null)
            {
                // Nothing selected
                log.Error("No current style!");
            }
            else
            {
                //log.Debug(((Object)d).GetType().FullName);
                // System.__ComObject

                //string typeName = ComHelper.GetTypeName(d);
                //log.Debug(typeName);
                //Marshal.ReleaseComObject(selection);

                existingStyle = d as Word.Style;
                log.Debug(existingStyle.NameLocal); // eg Heading 6 ie the PARAGRAPH style!
            }



            foreach (Word.Style s in Globals.ThisAddIn.Application.ActiveDocument.Styles)
            {
                try
                {
                    if (s.Type.Equals(Word.WdStyleType.wdStyleTypeParagraph) && s.Linked)
                    {
                        //log.Debug(s.NameLocal);
                        //log.Debug(".. linked to " + linkedS.NameLocal);

                        WrappedStyle wrapped = new WrappedStyle(s);
                        listBox1.Items.Add(wrapped);

                        if (existingStyle != null &&
                            wrapped.ToString().Equals(existingStyle.NameLocal))
                        {
                            //log.Debug(" found  " + existingStyle.NameLocal);

                            listBox1.SelectedItem = wrapped;
                        }
                    }
                }
                catch (System.Runtime.InteropServices.COMException) { }
            }



            // events click, doubleclick, mouseXXX
            //this.listBox1.SelectedIndexChanged += new System.EventHandler(listBox1_SelectedIndexChanged);
            this.listBox1.SelectedValueChanged += new System.EventHandler(listBox1_SelectedValueChanged);
        }
        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);
        }
Ejemplo n.º 7
0
        // 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();
        }
Ejemplo n.º 8
0
        public void buttonCondition_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 condition 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 conditionCC = null;
            object missing = System.Type.Missing;

            try
            {
                if (Globals.ThisAddIn.Application.Selection.Type == Microsoft.Office.Interop.Word.WdSelectionType.wdSelectionIP)
                {
                    // Nothing is selected, so type "condition"
                    document.Windows[1].Selection.Text = "condition";
                }
                object range = Globals.ThisAddIn.Application.Selection.Range;
                conditionCC = document.ContentControls.Add(Word.WdContentControlType.wdContentControlRichText, ref range);

                // Limitation here: you can't make your content control of eg type picture
                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;
            }

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

            if (shallowChildren.Count == 0)
            {
                log.Debug("No child control found. So Condition not set on our new CC");
                //MessageBox.Show("Unbound content control only added. Click the edit button to setup the condition.");
                editXPath(conditionCC);
                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 Condition not set on our new CC");
                //MessageBox.Show("Naked content control only added. Click the edit button to setup the condition.");
                editXPath(conditionCC);
                return;
            }

            // Get XPath. Could use the od xpaths part, but
            // easier here to get it from the binding
            string strXPath = usableChild.XMLMapping.XPath;

            log.Debug("Getting count condition from " + strXPath);
            strXPath = "count(" + strXPath + ")>0";
            log.Debug(strXPath);

            ConditionsPartEntry cpe = new ConditionsPartEntry(Model.ModelFactory(document));

            // TODO fix usableChild.XMLMapping.PrefixMappings
            cpe.setup(usableChild.XMLMapping.CustomXMLPart.Id, strXPath, "", true);
            cpe.save();

            conditionCC.Title = "Conditional: " + cpe.conditionId;
            // Write tag
            TagData td = new TagData("");

            td.set("od:condition", cpe.conditionId);
            conditionCC.Tag = td.asQueryString();

            editXPath(conditionCC);
        }