OneNote: changed the behavior for the default destination, we create a new page in the unfiled section. Also changed the names of the destination, included the Notebook & Section

This commit is contained in:
RKrom 2014-07-29 15:34:19 +02:00
commit 0f63bf837f
3 changed files with 202 additions and 42 deletions

View file

@ -69,7 +69,7 @@ namespace GreenshotOfficePlugin {
if (page == null) {
return "Microsoft OneNote";
} else {
return page.PageName;
return page.DisplayName;
}
}
}
@ -110,20 +110,20 @@ namespace GreenshotOfficePlugin {
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(this.Designation, this.Description);
if (page != null) {
// No page selected, take the current
List<OneNotePage> pages = OneNoteExporter.GetPages();
if(pages == null || pages.Count == 0) {
return exportInformation;
if (page == null) {
try {
exportInformation.ExportMade = OneNoteExporter.ExportToNewPage(surface);
} catch(Exception ex) {
exportInformation.ErrorMessage = ex.Message;
LOG.Error(ex);
}
} else {
try {
exportInformation.ExportMade = OneNoteExporter.ExportToPage(surface, page);
} catch(Exception ex) {
exportInformation.ErrorMessage = ex.Message;
LOG.Error(ex);
}
page = pages[0];
}
try {
OneNoteExporter.ExportToPage(surface, page);
exportInformation.ExportMade = true;
} catch (Exception ex) {
exportInformation.ErrorMessage = ex.Message;
LOG.Error(ex);
}
return exportInformation;
}

View file

@ -18,25 +18,16 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Greenshot.Interop;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace Greenshot.Interop.Office {
public class OneNotePage {
public string PageName { get; set; }
public string PageID { get; set; }
public bool IsCurrentlyViewed { get; set; }
}
public class OneNoteExporter {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OneNoteExporter));
private const string XML_IMAGE_CONTENT = "<one:Image format=\"png\"><one:Size width=\"{1}.0\" height=\"{2}.0\" isSetByUser=\"true\" /><one:Data>{0}</one:Data></one:Image>";
@ -44,23 +35,129 @@ namespace Greenshot.Interop.Office {
private const string ONENOTE_NAMESPACE_2007 = "http://schemas.microsoft.com/office/onenote/2007/onenote";
private const string ONENOTE_NAMESPACE_2010 = "http://schemas.microsoft.com/office/onenote/2010/onenote";
public static void ExportToPage(ISurface surfaceToUpload, OneNotePage page) {
/// <summary>
/// Create a new page in the "unfiled notes section", with the title of the capture, and export the capture there.
/// </summary>
/// <param name="surfaceToUpload">ISurface</param>
/// <returns>bool true if export worked</returns>
public static bool ExportToNewPage(ISurface surfaceToUpload) {
using(IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance<IOneNoteApplication>()) {
OneNotePage newPage = new OneNotePage();
string unfiledNotesSectionID = GetSectionID(oneNoteApplication, SpecialLocation.slUnfiledNotesSection);
if(unfiledNotesSectionID != null) {
string pageId = "";
oneNoteApplication.CreateNewPage(unfiledNotesSectionID, out pageId, NewPageStyle.npsDefault);
newPage.ID = pageId;
// Set the new name, this is automatically done in the export to page
newPage.Name = surfaceToUpload.CaptureDetails.Title;
return ExportToPage(oneNoteApplication, surfaceToUpload, newPage);
}
}
return false;
}
/// <summary>
/// Can be used to change the title of a page
/// </summary>
/// <param name="oneNoteApplication"></param>
/// <param name="pageId"></param>
/// <param name="title"></param>
private static void UpdatePageTitle(IOneNoteApplication oneNoteApplication, string pageId, string title) {
try {
string pageXML = "";
oneNoteApplication.GetPageContent(pageId, out pageXML, PageInfo.piAll, XMLSchema.xsCurrent);
XmlDocument doc = new XmlDocument();
doc.LoadXml(pageXML);
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.NameTable);
namespaceManager.AddNamespace("one", ONENOTE_NAMESPACE_2010);
doc.SelectSingleNode("//one:T", namespaceManager).InnerText = title;
// Update the page
oneNoteApplication.UpdatePageContent(doc.OuterXml, DateTime.MinValue, XMLSchema.xs2010, true);
} catch(Exception ex) {
LOG.Warn("Couldn't set page title.", ex);
}
}
/// <summary>
/// Export the capture to the specified page
/// </summary>
/// <param name="surfaceToUpload">ISurface</param>
/// <param name="page">OneNotePage</param>
/// <returns>bool true if everything worked</returns>
public static bool ExportToPage(ISurface surfaceToUpload, OneNotePage page) {
using(IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance<IOneNoteApplication>()) {
return ExportToPage(oneNoteApplication, surfaceToUpload, page);
}
}
/// <summary>
/// Export the capture to the specified page
/// </summary>
/// <param name="oneNoteApplication">IOneNoteApplication</param>
/// <param name="surfaceToUpload">ISurface</param>
/// <param name="page">OneNotePage</param>
/// <returns>bool true if everything worked</returns>
private static bool ExportToPage(IOneNoteApplication oneNoteApplication, ISurface surfaceToUpload, OneNotePage page) {
if(oneNoteApplication == null) {
return false;
}
using (MemoryStream pngStream = new MemoryStream()) {
SurfaceOutputSettings pngOutputSettings = new SurfaceOutputSettings(OutputFormat.png, 100, false);
ImageOutput.SaveToStream(surfaceToUpload, pngStream, pngOutputSettings);
string base64String = Convert.ToBase64String(pngStream.GetBuffer());
string imageXmlStr = string.Format(XML_IMAGE_CONTENT, base64String, surfaceToUpload.Image.Width, surfaceToUpload.Image.Height);
string pageChangesXml = string.Format(XML_OUTLINE, new object[] { imageXmlStr, page.PageID, ONENOTE_NAMESPACE_2010, page.PageName });
using (IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance<IOneNoteApplication>()) {
LOG.InfoFormat("Sending XML: {0}", pageChangesXml);
oneNoteApplication.UpdatePageContent(pageChangesXml, DateTime.MinValue, XMLSchema.xs2010, false);
try {
oneNoteApplication.NavigateTo(page.PageID, null, false);
} catch(Exception ex) {
LOG.Warn("Unable to navigate to the target page", ex);
string pageChangesXml = string.Format(XML_OUTLINE, new object[] { imageXmlStr, page.ID, ONENOTE_NAMESPACE_2010, page.Name });
LOG.InfoFormat("Sending XML: {0}", pageChangesXml);
oneNoteApplication.UpdatePageContent(pageChangesXml, DateTime.MinValue, XMLSchema.xs2010, false);
try {
oneNoteApplication.NavigateTo(page.ID, null, false);
} catch(Exception ex) {
LOG.Warn("Unable to navigate to the target page", ex);
}
return true;
}
}
/// <summary>
/// Retrieve the Section ID for the specified special location
/// </summary>
/// <param name="oneNoteApplication"></param>
/// <param name="specialLocation">SpecialLocation</param>
/// <returns>string with section ID</returns>
private static string GetSectionID(IOneNoteApplication oneNoteApplication, SpecialLocation specialLocation) {
if(oneNoteApplication == null) {
return null;
}
string unfiledNotesPath = "";
oneNoteApplication.GetSpecialLocation(specialLocation, out unfiledNotesPath);
string notebookXml = "";
oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
if(!string.IsNullOrEmpty(notebookXml)) {
LOG.Debug(notebookXml);
StringReader reader = null;
try {
reader = new StringReader(notebookXml);
using(XmlTextReader xmlReader = new XmlTextReader(reader)) {
while(xmlReader.Read()) {
if("one:Section".Equals(xmlReader.Name)) {
string id = xmlReader.GetAttribute("ID");
string path = xmlReader.GetAttribute("path");
if(unfiledNotesPath.Equals(path)) {
return id;
}
}
}
}
} finally {
if(reader != null) {
reader.Dispose();
}
}
}
return null;
}
/// <summary>
@ -81,16 +178,36 @@ namespace Greenshot.Interop.Office {
reader = new StringReader(notebookXml);
using (XmlTextReader xmlReader = new XmlTextReader(reader)) {
reader = null;
OneNoteSection currentSection = null;
OneNoteNotebook currentNotebook = null;
while (xmlReader.Read()) {
if("one:Notebook".Equals(xmlReader.Name)) {
string id = xmlReader.GetAttribute("ID");
if(id != null && (currentNotebook == null || !id.Equals(currentNotebook.ID))) {
currentNotebook = new OneNoteNotebook();
currentNotebook.ID = xmlReader.GetAttribute("ID");
currentNotebook.Name = xmlReader.GetAttribute("name");
}
}
if("one:Section".Equals(xmlReader.Name)) {
string id = xmlReader.GetAttribute("ID");
if(id != null && (currentSection == null || !id.Equals(currentSection.ID))) {
currentSection = new OneNoteSection();
currentSection.ID = xmlReader.GetAttribute("ID");
currentSection.Name = xmlReader.GetAttribute("name");
currentSection.Parent = currentNotebook;
}
}
if ("one:Page".Equals(xmlReader.Name)) {
// Skip deleted items
if("true".Equals(xmlReader.GetAttribute("isInRecycleBin"))) {
continue;
}
OneNotePage page = new OneNotePage();
page.PageName = xmlReader.GetAttribute("name");
page.PageID = xmlReader.GetAttribute("ID");
if(page.PageID == null || page.PageName == null) {
page.Parent = currentSection;
page.Name = xmlReader.GetAttribute("name");
page.ID = xmlReader.GetAttribute("ID");
if(page.ID == null || page.Name == null) {
continue;
}
page.IsCurrentlyViewed = "true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"));
@ -113,7 +230,7 @@ namespace Greenshot.Interop.Office {
if(p1.IsCurrentlyViewed || p2.IsCurrentlyViewed) {
return p2.IsCurrentlyViewed.CompareTo(p1.IsCurrentlyViewed);
}
return p1.PageName.CompareTo(p2.PageName);
return p1.DisplayName.CompareTo(p2.DisplayName);
});
return pages;
}

View file

@ -18,6 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace Greenshot.Interop.Office {
@ -27,13 +28,15 @@ namespace Greenshot.Interop.Office {
[ComProgId("OneNote.Application")]
public interface IOneNoteApplication : ICommon {
/// <summary>
/// Make sure that the notebookXml is of type string, e.g. "", otherwise a type error occurs.
/// Make sure that the out variables are filled with a string, e.g. "", otherwise a type error occurs.
/// For more info on the methods: http://msdn.microsoft.com/en-us/library/gg649853.aspx
/// </summary>
void GetHierarchy(string startNode, HierarchyScope scope, out string notebookXml, XMLSchema schema);
void GetSpecialLocation(SpecialLocation specialLocation, out string specialLocationPath);
void UpdatePageContent(string pageChangesXml, DateTime dateExpectedLastModified, XMLSchema schema, bool force);
void GetPageContent(string pageId, out string pageXml, PageInfo pageInfoToExport, XMLSchema schema);
void NavigateTo(string hierarchyObjectID, string objectId, bool newWindow);
void CreateNewPage(string sectionID, out string pageID, NewPageStyle newPageStyle);
}
public enum PageInfo {
@ -57,4 +60,44 @@ namespace Greenshot.Interop.Office {
xs2010 = 1,
xsCurrent= xs2010
}
public enum SpecialLocation : int {
slBackupFolder = 0,
slUnfiledNotesSection = 1,
slDefaultNotebookFolder = 2
}
public enum NewPageStyle {
npsDefault = 0,
npsBlankPageWithTitle = 1,
npsBlankPageNoTitle = 2
}
public class OneNotePage {
public OneNoteSection Parent { get; set; }
public string Name { get; set; }
public string ID { get; set; }
public bool IsCurrentlyViewed { get; set; }
public string DisplayName {
get {
OneNoteNotebook notebook = Parent.Parent;
if(string.IsNullOrEmpty(notebook.Name)) {
return string.Format("{0} / {1}", Parent.Name, Name);
} else {
return string.Format("{0} / {1} / {2}", Parent.Parent.Name, Parent.Name, Name);
}
}
}
}
public class OneNoteSection {
public OneNoteNotebook Parent { get; set; }
public string Name { get; set; }
public string ID { get; set; }
}
public class OneNoteNotebook {
public string Name { get; set; }
public string ID { get; set; }
}
}