Make current page a subpage

Yesterday I went through the OneNote Newsgroup and I saw this question about making a page a subpage: Make a page a subpage

There were lots of good responses and Josh Einstein (of OneNote Calendar fame) mentioned that he should write a powertoy which does this.  I replied saying that I should do something like this as a fun afternoon project.  Well I am happy to say that I did just write something up and I will be sharing the code with you all.  However I don't think I should release a full powertoy for this.  You want to know why?  Here's why:

  1. For most people it is easier to just use the group command to group pages together.  If you have a page you want to make a subpage then select that page and the page above, right-click and choose group.
  2. If you use this code it will create a subpage but if you try dragging it elsewhere it will not keep the subpage-ness, so that isn't too helpful.
  3. Not that many people know about these powertoys posted on blogs.

Anyhow I did want to share this information on how to write this code and give it to you all:

 using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using OneNote = Microsoft.Office.Interop.OneNote;

namespace MakeSubpageGuts
{
    class Program
    {
        private string strNamespace = "https://schemas.microsoft.com/office/onenote/2007/onenote";
        private OneNote.Application onApp;

        static void Main(string[] args)
        {
            Program p = new Program();
            p.run();
        }

        public void run()
        {
            //create an instanace of OneNote
            onApp = new Microsoft.Office.Interop.OneNote.Application();
            //get the currently viewed page id
            string cur_page_id = findCurrentlyViewedPage();
            //Get the section XML based on the currently viewed page
            string cur_section_xml = getXMLforSection(cur_page_id);
            //Change the section XML so the currently viewed page would a subpage
            string resulting_xml_to_update_for_subpage = parseXMLMakePageSubPage(cur_section_xml, cur_page_id);
            //update OneNote
            updateOneNoteContent(resulting_xml_to_update_for_subpage);

        }

        private void updateOneNoteContent(string in_xml)
        {
            try
            {
                onApp.UpdateHierarchy(in_xml);
            }
            catch (Exception e)
            {
                showError(e);
            }
        }
        
        private string parseXMLMakePageSubPage(string in_section_xml, string cur_page_id)
        {
            //basic XML Doc stuff
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(in_section_xml);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("one", strNamespace);

            //find the currently viewed page
            XmlNode pagetoMove = xmlDoc.SelectSingleNode("//one:Page[@ID=\"" + cur_page_id + "\"]", nsmgr);
            //create a new XmlNode for the isSubPage property on pages
            XmlNode subPageAttr = xmlDoc.CreateNode(XmlNodeType.Attribute, "isSubPage", xmlDoc.NamespaceURI);
            //set the value to true
            subPageAttr.Value = "true";
            //add that to the Page node XML
            pagetoMove.Attributes.SetNamedItem(subPageAttr);
            //return the XML back to the calling method
            return xmlDoc.InnerXml;
        }

        private string getXMLforSection(string in_cur_page_id)
        {
            string sectionID = "";
            try
            {
                onApp.GetHierarchyParent(in_cur_page_id, out sectionID);
            }
            catch (Exception e)
            {
                showError(e);
            }

            string sectionXML = "";

            try
            {
                onApp.GetHierarchy(sectionID, Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, out sectionXML);
            }
            catch (Exception e)
            {
                showError(e);
            }

            return sectionXML;
        }

        private void showError(Exception e)
        {
            Console.WriteLine(e.Message);
            System.Environment.Exit(-99);
        }

        private string findCurrentlyViewedPage()
        {
            string strXML = "";
                                   
            try
            {
                //Get the hierarchy from the root to pages
                onApp.GetHierarchy(null, OneNote.HierarchyScope.hsPages, out strXML);
            }
            catch (Exception e)
            {
                showError(e);
            }

            //Basic XML Doc stuff
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(strXML);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
            nsmgr.AddNamespace("one", strNamespace);

            // Find the page ID of the active page
            XmlElement xmlActivePage = (XmlElement)xmlDoc.SelectSingleNode("//one:Page[@isCurrentlyViewed=\"true\"]", nsmgr);
            return (xmlActivePage.GetAttribute("ID"));
        }
    }
}

 

Take care...also I tip my hat to DStockwell who wrote the Paste from Visual Studio plugin for Windows Live Writer; you can download it here: Paste from Visual Studio.