First, I need to develop a better name for this addin. Highlighted Text Extractor? Get Highlighted Text? Sum the highlights? I'm open to suggestions.
There was a bug with the first iteration of this powertoy I sent out. The OneNote user who had asked for this was the first to get the "beta" version, and it had an easy to understand bug. Simply put, if there was text highlighted within a table, the text was duplicated on the new page.
In "Reproducible Test Steps", it can be summed up like this:
Only one instance of the text from step 3
The text is duplicated.
Simple to understand, anyone should be able to follow the (minimal) steps to reproduce the bug, and the expected results are compared to the actual results. This is pretty much exactly the way we log bugs internally as well.
Anyway, a little knowledge of our schema can explain why this was happening, and suggest a way to fix the error.
Within the schema, a "text range" is stored inside of an Outline Element (OE) which is all documented here. So what I was doing was looking at an OE and checking to see if there was highlighted text in it. If so, I used that text on the new page.
This worked well except within a table. According to the schema reference, and OE can contain, among other things, these two children:
That second item can be thought of as "An OE can have a set of other OutlineElements (OEs) within them, and those OEs can also have more OEs inside of them, and so on…"
That's the root of the problem. What I was doing was looking inside the OE to see if there was highlighted text. If there was, I added it to the new page. Since the child OE had the highlighting applied, I copied it for both the parent and the child OE, since all I looked for was if ANY text in the OE had highlighting. What I really needed to do was make sure I was "at the bottom" of the OE set - that the OE I was currently examining had no further OE elements in it.
The original code looked like this:
if (oeList[i].ChildNodes[j].InnerXml.Contains("span") && oeList[i].ChildNodes[j].InnerXml.Contains("style") && oeList[i].ChildNodes[j].InnerXml.Contains("background") &&)
And the fix was pretty easy:
if (oeList[i].ChildNodes[j].InnerXml.Contains("span") && oeList[i].ChildNodes[j].InnerXml.Contains("style") && oeList[i].ChildNodes[j].InnerXml.Contains("background") && !oeList[i].ChildNodes[j].InnerXml.Contains("one:OE"))
Now as long as the XML of the OE the code is examining does not have another OE in it, it will work.
Yes, I was doing all of this checking with strings rather than using the XML Attribute collection.
That suggests another change - moving away from the string manipulation I was doing and changing the code to use the XML DOM. No functionality would be expected to change by this refactoring, so from a test point of view I would only need to wait for a new version to test, then run my tests one more time. This is a topic for a whole new article since it leads to estimating how long testing will take and the benefits of automation, so I'll just leave it here for now.
Another item I'll point out is my tablet system I used to create this addin. I've always thought that having two separate monitors made using Visual Studio much easier than one large monitor would, so I recently got an external monitor for my tablet. It is a USB based MIMO, and it's great. I put OneNote on it and step through the code on my tablet PC monitor. Here's what it looks like:
Even though that monitor is only 800x600, it makes a huge difference - less window management, lets me see the code and the UI for the application at the same time and gives me more room on the primary monitor.
One last item is that this addin only works for the English language right now. I'm investigating the fix for this and will update it when ready.
If anyone wants the code, shoot me an email (link at the upper right). Edit 3-22-2012: the code is now posted at http://blogs.msdn.com/b/johnguin/archive/2012/03/22/source-code-for-the-onenote-text-highlighting-extractor-powertoy.aspx
Questions, comments, concerns and criticisms always welcome,