public void QuickDialog() { IQuickFilingDialog qfDialog; qfDialog = OneNote.Instance().QuickFiling(); if (_hierarchyType == HierarchyType.Sections) { qfDialog.TreeDepth = HierarchyElement.heSections; qfDialog.Title = "Import Section to mindmanager"; qfDialog.ParentWindowHandle = _windowHandle; qfDialog.AddButton("Import Section", HierarchyElement.heSections, HierarchyElement.heSections, true); } else if (_hierarchyType == HierarchyType.Pages) { qfDialog.TreeDepth = HierarchyElement.hePages; qfDialog.Title = "Select Page "; qfDialog.ParentWindowHandle = _windowHandle; qfDialog.AddButton("Add page Link to Topic", HierarchyElement.hePages, HierarchyElement.hePages, true); } qfDialog.Run(new Callback(_hierarchyType, ref _mindManager)); }
public override async Task Execute(params object[] args) { var scope = args[0] as string; using (one = new OneNote()) { bookScope = scope == "notebook"; hierarchy = bookScope ? one.GetNotebook(one.CurrentNotebookId, OneNote.Scope.Pages) : one.GetSection(one.CurrentSectionId); var ns = one.GetNamespace(hierarchy); totalCount = hierarchy.Descendants(ns + "Page").Count(); if (totalCount == 0) { UIHelper.ShowMessage(Resx.ArchiveCommand_noPages); return; } var topName = hierarchy.Attribute("name").Value; zipPath = await SingleThreaded.Invoke(() => { // OpenFileDialog must run in STA thread return(ChooseLocation(topName)); }); if (zipPath == null) { return; } var progressDialog = new UI.ProgressDialog(Execute); await progressDialog.RunModeless(); } }
private bool Refresh() { using (one = new OneNote(out page, out ns)) { // find linked references content block... var meta = page.Root.Descendants(ns + "Meta") .FirstOrDefault(e => e.Attribute("name").Value == LinkRefsMeta); if (meta == null) { return(false); } if (!Enum.TryParse(meta.Attribute("content").Value, out scope)) { scope = OneNote.Scope.Pages; } // TODO: deprecated; determine options... if not on refresh URI if (!synopses && !unindexed) { var meta2 = meta.Parent.Elements(ns + "Meta") .FirstOrDefault(e => e.Attribute("name").Value == SynopsisMeta); if (meta2 != null) { bool.TryParse(meta2.Attribute("content").Value, out synopses); } } // remove the containing OE so it can be regenerated meta.Parent.Remove(); return(true); } }
public override async Task Execute(params object[] args) { using (var one = new OneNote()) { var section = one.GetSection(); var ns = one.GetNamespace(section); // find all level 1 pages not collapsed and immediately followed by level 2 page var pages = from e in section.Elements(ns + "Page") let n = e.NextNode where n != null && e.Attribute("pageLevel").Value.Equals("1") && !e.Attributes("isCollapsed").Any(x => x.Value.Equals("true")) && n.NodeType == XmlNodeType.Element && ((XElement)n).Attribute("pageLevel").Value.Equals("2") select e; if (pages?.Count() > 0) { logger.WriteLine($"found {pages.Count()} expanded pages"); foreach (var page in pages) { page.Add(new XAttribute("isCollapsed", "true")); } one.UpdateHierarchy(section); } else { logger.WriteLine($"found 0 expanded pages"); } } await Task.Yield(); }
private async Task Callback(string sectionId) { if (string.IsNullOrEmpty(sectionId)) { // cancelled return; } var action = copying ? "copying" : "moving"; logger.Start($"..{action} {pageIds.Count} pages"); try { using (var one = new OneNote()) { var service = new SearchServices(owner, one, sectionId); if (copying) { await service.CopyPages(pageIds); } else { await service.MovePages(pageIds); } } } catch (Exception exc) { logger.WriteLine(exc); } finally { logger.End(); } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Invoked by the ProgressDialog OnShown callback private async Task Execute(UI.ProgressDialog progress, CancellationToken token) { logger.Start(); logger.StartClock(); using (one = new OneNote()) { var hierarchy = GetHierarchy(); if (token.IsCancellationRequested) { logger.WriteLine("cancelled"); return; } try { var hyperlinks = await GetHyperlinks(progress, token); if (token.IsCancellationRequested) { logger.WriteLine("cancelled"); return; } var elements = hierarchy.Descendants(ns + "Page").ToList(); var titles = new Dictionary <string, string>(); logger.WriteLine($"building map for {elements.Count} pages"); progress.SetMaximum(elements.Count); progress.SetMessage($"Building map for {elements.Count} pages"); foreach (var element in elements) { progress.Increment(); if (token.IsCancellationRequested) { return; } var parentId = element.Attribute("ID").Value; var xml = one.GetPageXml(parentId); var matches = regex.Matches(xml); if (matches.Count == 0) { element.Remove(); continue; } var parent = new Page(XElement.Parse(xml)); var name = element.Parent.Attribute("name").Value; progress.SetMessage($"Scanning {name}/{parent.Title}"); // prevent duplicates var refs = new List <string>(); foreach (Match match in matches) { var pid = match.Groups[1].Value; if (refs.Contains(pid)) { // already captured this pid continue; } if (!hyperlinks.ContainsKey(pid)) { logger.WriteLine($"not found in scope: {pid} on {name}/{parent.Title}"); continue; } var hyperlink = hyperlinks[pid]; if (hyperlink.PageID != parentId) { string title; if (titles.ContainsKey(hyperlink.PageID)) { title = titles[hyperlink.PageID]; } else { var p = one.GetPage(hyperlink.PageID, OneNote.PageDetail.Basic); title = p.Title; titles.Add(hyperlink.PageID, title); } element.Add(new XElement("Ref", new XAttribute("title", title), new XAttribute("ID", hyperlink.PageID) )); //logger.WriteLine($" - {title}"); refs.Add(pid); } } } if (titles.Count == 0) { UIHelper.ShowMessage("No linked pages were found"); return; } if (token.IsCancellationRequested) { return; } Prune(hierarchy); await BuildMapPage(hierarchy); } catch (Exception exc) { logger.WriteLine(exc); } } logger.WriteTime("map complete"); logger.End(); }
private void FetchRecentTags() { using (var one = new OneNote()) { // builds a hierarchy of all notebooks with notebook/section/page nodes // and each Page has a Meta of tags var root = one.SearchMeta(string.Empty, Page.TaggingMetaName); var ns = root.GetNamespaceOfPrefix("one"); var pages = root.Descendants(ns + "Page") .OrderByDescending(e => e.Attribute("lastModifiedTime").Value); var tags = new Dictionary <string, string>(); var count = 0; foreach (var page in pages) { var meta = page.Elements(ns + "Meta") .FirstOrDefault(e => e.Attribute("name").Value == Page.TaggingMetaName); if (meta != null) { // tags are entered in user's language so split on their separator var parts = meta.Attribute("content").Value.Split( new string[] { AddIn.Culture.TextInfo.ListSeparator }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts) { var p = part.Trim(); var key = p.ToLower(); if (!tags.ContainsKey(key)) { tags.Add(key, p); count++; if (count >= PoolSize) { break; } } } } if (count >= PoolSize) { break; } } if (tags.Count > 0) { //var sorted = tags.OrderBy(k => k.Key.StartsWith("#") ? k.Key.Substring(1) : k.Key); //foreach (var s in sorted) //{ // recentFlow.Controls.Add(MakeLabel(s.Value, s.Value)); //} // keep order of most recent first foreach (var value in tags.Values) { recentFlow.Controls.Add(MakeLabel(value, value)); } } } }
public override async Task Execute(params object[] args) { using (var one = new OneNote()) { var section = one.GetSection(); ns = one.GetNamespace(section); // find first selected - active page var active = section.Elements(ns + "Page") .FirstOrDefault(e => e.Attributes("isCurrentlyViewed").Any(a => a.Value.Equals("true"))); if (active == null) { UIHelper.ShowInfo(one.Window, "At least two pages must be selected to merge"); return; } var selections = section.Elements(ns + "Page") .Where(e => !e.Attributes("isCurrentlyViewed").Any() && e.Attributes("selected").Any(a => a.Value.Equals("all"))); if (active == null) { UIHelper.ShowInfo(one.Window, "At least two pages must be selected to merge"); return; } // get first selected (active) page and reference its quick styles, outline, size page = one.GetPage(active.Attribute("ID").Value); quickmap = page.GetQuickStyleMap(); var offset = GetPageBottomOffset(); // track running bottom as we add new outlines var maxOffset = offset; // find maximum z-offset var z = page.Root.Elements(ns + "Outline").Elements(ns + "Position") .Attributes("z").Max(a => int.Parse(a.Value)) + 1; // merge each of the subsequently selected pages into the active page foreach (var selection in selections.ToList()) { var childPage = one.GetPage(selection.Attribute("ID").Value); var map = page.MergeQuickStyles(childPage); var childOutlines = childPage.Root.Elements(ns + "Outline"); if (childOutlines == null || !childOutlines.Any()) { break; } var topOffset = childOutlines.Elements(ns + "Position") .Min(p => double.Parse(p.Attribute("y").Value, CultureInfo.InvariantCulture)); foreach (var childOutline in childOutlines) { // adjust position relative to new parent page outlines var position = childOutline.Elements(ns + "Position").FirstOrDefault(); var y = double.Parse(position.Attribute("y").Value, CultureInfo.InvariantCulture) - topOffset + offset + OutlineMargin; position.Attribute("y").Value = y.ToString("#0.0", CultureInfo.InvariantCulture); // keep track of lowest bottom var size = childOutline.Elements(ns + "Size").FirstOrDefault(); var bottom = y + double.Parse(size.Attribute("height").Value, CultureInfo.InvariantCulture); if (bottom > maxOffset) { maxOffset = bottom; } position.Attribute("z").Value = z.ToString(); z++; // remove its IDs so the page can apply its own childOutline.Attributes("objectID").Remove(); childOutline.Descendants().Attributes("objectID").Remove(); page.ApplyStyleMapping(map, childOutline); page.Root.Add(childOutline); } if (maxOffset > offset) { offset = maxOffset; } } // update page and section hierarchy await one.Update(page); foreach (var selection in selections) { one.DeleteHierarchy(selection.Attribute("ID").Value); } } }
private async Task Callback(string targetId) { if (string.IsNullOrEmpty(targetId)) { // cancelled return; } logger.Start($"target folder {targetId}"); try { using (var one = new OneNote()) { var target = one.GetSection(targetId); if (target == null) { logger.WriteLine("invalid target section"); return; } var notebook = one.GetNotebook(OneNote.Scope.Pages); var ns = one.GetNamespace(notebook); // use current page to ascend back to closest folder to handle nesting... var element = notebook.Descendants(ns + "Page") .FirstOrDefault(e => e.Attribute("ID").Value == one.CurrentPageId); var folder = element.FirstAncestor(ns + "SectionGroup"); if (folder == null) { logger.WriteLine("error finding ancestor folder"); return; } // TODO: this needs to be a recursive search if (folder.Attribute("ID").Value == targetId) { logger.WriteLine("cannot copy a folder into itself"); return; } logger.WriteLine( $"copying folder {folder.Attribute("name").Value} " + $"to {target.Attribute("name").Value}"); target.Add(folder); await CopyPages(one, folder, ns); one.UpdateHierarchy(target); } } catch (Exception exc) { logger.WriteLine(exc); } finally { logger.End(); } }
private async Task UpdateTableReport(string guid) { using (one = new OneNote(out page, out ns, OneNote.PageDetail.Basic)) { var meta = page.Root.Descendants(ns + "Meta") .FirstOrDefault(e => e.Attribute("name").Value == TableMeta && e.Attribute("content").Value == guid && e.Parent.Elements(ns + "Table").Any()); if (meta == null) { UIHelper.ShowInfo("Outlook task table not found. It may have been deleted"); return; } var table = new Table(meta.Parent.Elements(ns + "Table").First()); var taskIDs = table.Root.Descendants(ns + "OutlookTask") .Select(e => e.Attribute("guidTask").Value) // ref by list so they're not disposed when we clear the table XElement .ToList(); if (!taskIDs.Any()) { UIHelper.ShowInfo("Table contains no Outlook tasks. Rows may have been deleted"); return; } PrepareTableContext(); using (var outlook = new Outlook()) { var tasks = outlook.LoadTasksByID(taskIDs); foreach (var task in tasks) { var row = table.Rows.FirstOrDefault(r => r.Root .Element(ns + "Cell") .Element(ns + "OEChildren") .Element(ns + "OE") .Element(ns + "OutlookTask")? .Attribute("guidTask").Value == task.OneNoteTaskID); if (row != null) { PopulateRow(row, task, false); } } } // update "Last updated..." line... var stamp = page.Root.Descendants(ns + "Meta") .Where(e => e.Attribute("name").Value == RefreshMeta && e.Attribute("content").Value == guid) .Select(e => e.Parent.Elements(ns + "T").FirstOrDefault()) .FirstOrDefault(); if (stamp != null) { stamp.GetCData().Value = $"{Resx.ReminderReport_LastUpdated} {DateTime.Now.ToShortFriendlyString()} " + $"(<a href=\"onemore://ImportOutlookTasksCommand/refresh/{guid}\">{Resx.word_Refresh}</a>)"; } await one.Update(page); } }
public override async Task Execute(params object[] args) { bool jumplinks; bool alignlinks; if (args.Length > 0 && args[0] is string refresh && refresh == "refresh") { jumplinks = args.Any(a => a as string == "links"); alignlinks = args.Any(a => a as string == "align"); if (await RefreshToc(jumplinks, alignlinks)) { // successfully updated return; } } OneNote.Scope scope; bool withPreviews; bool withPages; using (var dialog = new InsertTocDialog()) { if (dialog.ShowDialog(owner) == DialogResult.Cancel) { return; } scope = dialog.Scope; jumplinks = dialog.TopLinks; alignlinks = dialog.RightAlignTopLinks; withPreviews = dialog.PreviewPages; withPages = dialog.SectionPages; } try { using (one = new OneNote()) { switch (scope) { case OneNote.Scope.Self: await InsertToc(one.GetPage(), jumplinks, alignlinks); break; case OneNote.Scope.Pages: await InsertPagesTable(withPreviews); break; case OneNote.Scope.Sections: await InsertSectionsTable(withPages, withPreviews); break; } } } catch (Exception exc) { logger.WriteLine($"error executing {nameof(InsertTocCommand)}", exc); } }
private async Task Callback(string targetId) { if (string.IsNullOrEmpty(targetId)) { // cancelled return; } logger.Start($"..target folder {targetId}"); try { using (var one = new OneNote()) { // user might choose a sectiongroup or a notebook; GetSection will get either var target = one.GetSection(targetId); if (target == null) { logger.WriteLine("invalid target section"); return; } // source folder will be in current notebook var notebook = await one.GetNotebook(OneNote.Scope.Pages); var ns = one.GetNamespace(notebook); // use current page to ascend back to closest folder to handle nesting... var element = notebook.Descendants(ns + "Page") .FirstOrDefault(e => e.Attribute("ID").Value == one.CurrentPageId); var folder = element.FirstAncestor(ns + "SectionGroup"); if (folder == null) { logger.WriteLine("error finding ancestor folder"); return; } if (folder.DescendantsAndSelf().Any(e => e.Attribute("ID").Value == targetId)) { logger.WriteLine("cannot copy a folder into itself or one of its children"); MessageBox.Show( Resx.CopyFolderCommand_InvalidTarget, Resx.OneMoreTab_Label, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return; } logger.WriteLine( $"copying folder {folder.Attribute("name").Value} " + $"to {target.Attribute("name").Value}"); // clone structure of folder; this does not assign ID values var clone = CloneFolder(folder, ns); // update target so OneNote will apply new ID values target.Add(clone); one.UpdateHierarchy(target); // re-fetch target to find newly assigned ID values var upTarget = one.GetSection(targetId); var cloneID = upTarget.Elements() .Where(e => !e.Attributes().Any(a => a.Name == "isRecycleBin")) .Select(e => e.Attribute("ID").Value) .Except( target.Elements() .Where(e => e.Attributes().Any(a => a.Name == "ID") && !e.Attributes().Any(a => a.Name == "isRecycleBin")) .Select(e => e.Attribute("ID").Value) ).FirstOrDefault(); clone = upTarget.Elements().FirstOrDefault(e => e.Attribute("ID").Value == cloneID); using (progress = new UI.ProgressDialog()) { progress.SetMaximum(folder.Descendants(ns + "Page").Count()); progress.Show(owner); // now with a new SectionGroup with a valid ID, copy all pages into it await CopyPages(folder, clone, one, ns); } } } catch (Exception exc) { logger.WriteLine(exc); } finally { logger.End(); } }
// async event handlers should be be declared 'async void' private async void Search(object sender, EventArgs e) { checkAllLabel.Enabled = false; clearAllLabel.Enabled = false; resultTree.Nodes.Clear(); var text = filterBox.Text.ToLower(); if (string.IsNullOrEmpty(text)) { return; } var filters = FormatFilter(filterBox.Text.ToLower()) .Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries) .Select(v => v.Trim()) .ToList(); var includedTags = filters.Where(f => f[0] != '-').ToList(); var excludedTags = filters.Where(f => f[0] == '-').Select(f => f.Substring(1)).ToList(); XElement results; XNamespace ns; var scopeId = string.Empty; using (var one = new OneNote()) { switch (scopeBox.SelectedIndex) { case 1: scopeId = one.CurrentNotebookId; break; case 2: scopeId = one.CurrentSectionId; break; } results = await one.SearchMeta(scopeId, MetaNames.TaggingLabels); ns = one.GetNamespace(results); } // remove recyclebin nodes results.Descendants() .Where(n => n.Name.LocalName == "UnfiledNotes" || n.Attribute("isRecycleBin") != null || n.Attribute("isInRecycleBin") != null) .Remove(); // filter var metas = results.Descendants(ns + "Meta") .Where(m => m.Attribute("name").Value == MetaNames.TaggingLabels); if (metas == null) { return; } // filter out unmatched pages, keep track in separate list because metas can't be // modified while enumerating var dead = new List <XElement>(); foreach (var meta in metas) { var content = meta.Attribute("content").Value; if (string.IsNullOrEmpty(content)) { // meta content may be empty because it's no longer used on a page; // empty metas exist because page-level metas cannot be removed! dead.Add(meta.Parent); } else { var tags = content.ToLower() .Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries) .Select(v => v.Trim()) .ToList(); if (tags.Count > 0) { if (excludedTags.Count > 0 && tags.Any(t => excludedTags.Contains(t))) { dead.Add(meta.Parent); } else if (includedTags.Count > 0) { var exclude = opBox.SelectedIndex == 0 // All ? !includedTags.All(t => tags.Contains(t)) : !includedTags.Any(t => tags.Contains(t)); if (exclude) { dead.Add(meta.Parent); } } } } } // remove unmatched pages from results XElement dead.ForEach(d => d.Remove()); // remove empty leaf nodes var pruning = true; while (pruning) { var elements = results.Descendants() .Where(d => d.Name.LocalName != "Meta" && !d.HasElements); pruning = elements.Any(); if (pruning) { elements.Remove(); } } if (results.HasElements) { resultTree.Populate(results, ns); checkAllLabel.Enabled = true; clearAllLabel.Enabled = true; } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #region InsertHeadingsTable /// <summary> /// Inserts a table of contents at the top of the current page, /// of all headings on the page /// </summary> /// <param name="addTopLinks"></param> /// <param name="one"></param> private async Task InsertHeadingsTable(OneNote one, bool addTopLinks) { var page = one.GetPage(); var ns = page.Namespace; var headings = page.GetHeadings(one); var top = page.Root.Element(ns + "Outline")?.Element(ns + "OEChildren"); if (top == null) { return; } var title = page.Root.Elements(ns + "Title").Elements(ns + "OE").FirstOrDefault(); if (title == null) { return; } var titleLink = one.GetHyperlink(page.PageId, title.Attribute("objectID").Value); var titleLinkText = $"<a href=\"{titleLink}\"><span style='font-style:italic'>{Resx.InsertTocCommand_Top}</span></a>"; var dark = page.GetPageColor(out _, out _).GetBrightness() < 0.5; var textColor = dark ? "#FFFFFF" : "#000000"; var toc = new List <XElement> { // "Table of Contents" new XElement(ns + "OE", new XAttribute("style", $"font-size:16.0pt;color:{textColor}"), new XElement(ns + "T", new XCData($"<span style='font-weight:bold'>{Resx.InsertTocCommand_TOC}</span>") ) ) }; // use the minimum intent level var minlevel = headings.Min(e => e.Style.Index); foreach (var heading in headings) { var text = new StringBuilder(); var count = minlevel; while (count < heading.Style.Index) { text.Append(". . "); count++; } if (!string.IsNullOrEmpty(heading.Link)) { var linkColor = dark ? " style='color:#5B9BD5'" : string.Empty; text.Append($"<a href=\"{heading.Link}\"{linkColor}>{heading.Text}</a>"); } else { text.Append(heading.Text); } toc.Add(new XElement(ns + "OE", new XAttribute("style", $"color:{textColor}"), new XElement(ns + "T", new XCData(text.ToString())) )); if (addTopLinks) { var table = new Table(ns); table.AddColumn(400, true); table.AddColumn(100, true); var row = table.AddRow(); row.Cells.ElementAt(0).SetContent(heading.Root); row.Cells.ElementAt(1).SetContent( new XElement(ns + "OE", new XAttribute("alignment", "right"), new XElement(ns + "T", new XCData(titleLinkText))) ); // heading.Root is the OE heading.Root.ReplaceNodes(table.Root); } } // empty line after the TOC toc.Add(new XElement(ns + "OE", new XElement(ns + "T", new XCData(string.Empty)))); top.AddFirst(toc); await one.Update(page); }
private void BuildSectionTable( OneNote one, XNamespace ns, XElement container, IEnumerable <XElement> elements, bool includePages, int level) { foreach (var element in elements) { var notBin = element.Attribute("isRecycleBin") == null; if (element.Name.LocalName == "SectionGroup" && notBin) { // SectionGroup var name = element.Attribute("name").Value; var indent = new XElement(ns + "OEChildren"); indent.Add(new XElement(ns + "OE", new XElement(ns + "T", new XCData($"<span style='font-weight:bold'>{name}</span>")) )); BuildSectionTable( one, ns, indent, element.Elements(), includePages, level + 1); container.Add( new XElement(ns + "OE", new XElement(ns + "T", new XCData(string.Empty))), new XElement(ns + "OE", indent) ); } else if (element.Name.LocalName == "Section" && notBin) { // Section var link = one.GetHyperlink(element.Attribute("ID").Value, string.Empty); var name = element.Attribute("name").Value; var pages = element.Elements(ns + "Page"); if (includePages && pages.Any()) { var indent = new XElement(ns + "OEChildren"); foreach (var page in pages) { var text = new StringBuilder(); var plevel = int.Parse(page.Attribute("pageLevel").Value); while (plevel > 0) { text.Append(". . "); plevel--; } var plink = one.GetHyperlink(element.Attribute("ID").Value, string.Empty); var pname = page.Attribute("name").Value; text.Append($"<a href=\"{plink}\">{pname}</a>"); indent.Add(new XElement(ns + "OE", new XElement(ns + "T", new XCData(text.ToString()) ))); } container.Add(new XElement(ns + "OE", new XElement(ns + "T", new XCData($"<a href=\"{link}\">{name}</a>")), indent )); } else { container.Add(new XElement(ns + "OE", new XElement(ns + "T", new XCData($"<a href=\"{link}\">{name}</a>") ))); } } } }
public override async Task Execute(params object[] args) { logger.StartDiagnostic(); logger.WriteLine("Diagnostics.Execute()"); logger.WriteLine(new string('-', 80)); var processes = Process.GetProcessesByName("ONENOTE"); var moduledesc = "unknown"; if (processes.Length > 0) { var module = processes[0].MainModule; moduledesc = $"{module.FileName} ({module.FileVersionInfo.ProductVersion})"; } logger.WriteLine($"ONENOTE...: {moduledesc}"); logger.WriteLine($"Addin path: {Assembly.GetExecutingAssembly().Location}"); logger.WriteLine($"Data path.: {PathFactory.GetAppDataPath()}"); logger.WriteLine($"Log path..: {logger.LogPath}"); logger.WriteLine(); using (var one = new OneNote()) { var(backupFolder, defaultFolder, unfiledFolder) = one.GetFolders(); logger.WriteLine($"Default path: {defaultFolder}"); logger.WriteLine($"Backup path: {backupFolder}"); logger.WriteLine($"Unfiled path: {unfiledFolder}"); logger.WriteLine(); var info = one.GetPageInfo(); logger.WriteLine($"Page name: {info.Name}"); logger.WriteLine($"Page path: {info.Path}"); logger.WriteLine($"Page link: {info.Link}"); logger.WriteLine(); info = one.GetSectionInfo(); logger.WriteLine($"Section name: {info.Name}"); logger.WriteLine($"Section path: {info.Path}"); logger.WriteLine($"Section link: {info.Link}"); logger.WriteLine(); var notebook = await one.GetNotebook(); var notebookId = one.CurrentNotebookId; logger.WriteLine($"Notebook name: {notebook.Attribute("name").Value}"); logger.WriteLine($"Notebook link: {one.GetHyperlink(notebookId, null)}"); logger.WriteLine(); one.ReportWindowDiagnostics(logger); logger.WriteLine(); var page = one.GetPage(); var pageColor = page.GetPageColor(out _, out _); var pageBrightness = pageColor.GetBrightness(); logger.WriteLine($"Page background: {pageColor.ToRGBHtml()}"); logger.WriteLine($"Page brightness: {pageBrightness}"); logger.WriteLine($"Page is dark...: {pageBrightness < 0.5}"); (float dpiX, float dpiY) = UIHelper.GetDpiValues(); logger.WriteLine($"Screen DPI.....: horizontal/X:{dpiX} vertical/Y:{dpiY}"); (float scalingX, float scalingY) = UIHelper.GetScalingFactors(); logger.WriteLine($"Scaling factors: horizontal/X:{scalingX} vertical/Y:{scalingY}"); RemindCommand.ReportDiagnostics(logger); RemindScheduler.ReportDiagnostics(logger); logger.WriteLine(new string('-', 80)); using (var dialog = new DiagnosticsDialog(logger.LogPath)) { dialog.ShowDialog(owner); } } // turn headers back on logger.End(); await Task.Yield(); }
public SearchServices(IWin32Window owner, OneNote one, string sectionId) { this.owner = owner; this.one = one; this.sectionId = sectionId; }
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Pages private void SortPages(SortDialog.Sortings sorting, SortDialog.Directions direction) { #region Notes /* * <one:Page ID="" name="Notes" pageLevel="1" /> * * Pages within a section are stored as a flat list of elements with * indented pages indicated by pageLevel only - they are not recursive children. * So the code below must group child pages with their parent so all parents * can be sorted correctly. Children are not sorted. */ #endregion Notes logger.StartClock(); using (var one = new OneNote()) { var root = one.GetSection(); var ns = one.GetNamespace(root); var pages = new List <PageNode>(); foreach (var child in root.Elements(ns + "Page")) { if (child.Attribute("pageLevel").Value == "1") { // found the next parent page pages.Add(new PageNode(child)); } else { // grouping child pages with the top parent pages[pages.Count - 1].Children.Add(child); } } if (direction == SortDialog.Directions.Descending) { if (sorting == SortDialog.Sortings.ByName) { pages = pages.OrderByDescending( p => AddTitleIconDialog.RemoveEmojis(p.Page.Attribute("name").Value)).ToList(); } else { var key = sorting == SortDialog.Sortings.ByCreated ? "dateTime" : "lastModifiedTime"; pages = pages.OrderByDescending( p => p.Page.Attribute(key).Value).ToList(); } } else { if (sorting == SortDialog.Sortings.ByName) { pages = pages.OrderBy( p => AddTitleIconDialog.RemoveEmojis(p.Page.Attribute("name").Value)).ToList(); } else { var key = sorting == SortDialog.Sortings.ByCreated ? "dateTime" : "lastModifiedTime"; pages = pages.OrderBy( p => p.Page.Attribute(key).Value).ToList(); } } root.RemoveNodes(); // recreate flat list foreach (var page in pages) { root.Add(page.Page); foreach (var child in page.Children) { root.Add(child); } } //logger.WriteLine(root); one.UpdateHierarchy(root); } logger.WriteTime(nameof(SortPages)); }
private async Task PowerPointImporter(string filepath, bool append, bool split) { string outpath; using (var powerpoint = new PowerPoint()) { outpath = powerpoint.ConvertFileToImages(filepath); } if (outpath == null) { logger.WriteLine($"failed to create output path"); return; } if (split) { using (var one = new OneNote()) { var section = await one.CreateSection(Path.GetFileNameWithoutExtension(filepath)); var sectionId = section.Attribute("ID").Value; var ns = one.GetNamespace(section); await one.NavigateTo(sectionId); int i = 1; foreach (var file in Directory.GetFiles(outpath, "*.jpg")) { one.CreatePage(sectionId, out var pageId); var page = one.GetPage(pageId); page.Title = $"Slide {i}"; var container = page.EnsureContentContainer(); LoadImage(container, ns, file); await one.Update(page); i++; } logger.WriteLine("created section"); } } else { using (var one = new OneNote()) { Page page; if (append) { page = one.GetPage(); } else { one.CreatePage(one.CurrentSectionId, out var pageId); page = one.GetPage(pageId); page.Title = Path.GetFileName(filepath); } var container = page.EnsureContentContainer(); foreach (var file in Directory.GetFiles(outpath, "*.jpg")) { using (var image = Image.FromFile(file)) { LoadImage(container, page.Namespace, file); } } await one.Update(page); if (!append) { await one.NavigateTo(page.PageId); } } } try { Directory.Delete(outpath, true); } catch (Exception exc) { logger.WriteLine($"error cleaning up {outpath}", exc); } }
public Archivist(OneNote one, string home) { this.one = one; this.home = Path.GetDirectoryName(home); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Invoked by the ProgressDialog OnShown callback private async Task Execute(UI.ProgressDialog progress, CancellationToken token) { logger.Start(); logger.StartClock(); using (one = new OneNote()) { if (page == null) { page = one.GetPage(); ns = page.Namespace; } PageNamespace.Set(ns); var title = Unstamp(page.Title); string startId = string.Empty; switch (scope) { case OneNote.Scope.Sections: startId = one.CurrentNotebookId; break; case OneNote.Scope.Pages: startId = one.CurrentSectionId; break; } logger.WriteLine($"searching for '{title}'"); var results = one.Search(startId, title, unindexed); if (token.IsCancellationRequested) { logger.WriteLine("cancelled"); return; } //logger.WriteLine(results); var referals = FlattenPages(results, page.PageId); var total = referals.Count(); if (total == 0) { UIHelper.ShowInfo(Resx.LinkReferencesCommand_noref); return; } // initialize search-and-replace editor... var whatText = $@"\b{SearchAndReplaceEditor.EscapeEscapes(title)}\b"; var pageLink = one.GetHyperlink(page.PageId, string.Empty); var withElement = new XElement("A", new XAttribute("href", pageLink), page.Title ); var editor = new SearchAndReplaceEditor(whatText, withElement, useRegex: true, caseSensitive: false ); // process pages... progress.SetMaximum(total); progress.SetMessage($"Linking for {total} pages"); var updates = 0; foreach (var referal in referals) { progress.Increment(); progress.SetMessage(referal.Attribute(NameAttr).Value); var refpage = one.GetPage(referal.Attribute("ID").Value, OneNote.PageDetail.Basic); logger.WriteLine($"searching for '{whatText}' on {refpage.Title}"); var count = editor.SearchAndReplace(refpage); if (count > 0) { await one.Update(refpage); referal.SetAttributeValue(LinkedAttr, "true"); referal.SetAttributeValue(SynopsisAttr, GetSynopsis(refpage)); updates++; } else { logger.WriteLine($"search not found on {referal.Attribute(NameAttr).Value}"); } if (token.IsCancellationRequested) { logger.WriteLine("cancelled"); break; } } if (updates > 0) { // even if cancellation is request, must update page with referals that were // modified, otherwise, there will be referal pages that link to this page // without this page referring back! AppendReferalBlock(page, referals); await one.Update(page); } } logger.WriteTime("linking complete"); logger.End(); }
/* * <one:OE quickStyleIndex="1"> * <one:T><![CDATA[. .Heading 2]]></one:T> * </one:OE> */ public List <Heading> GetHeadings(OneNote one) { quickStyles = GetQuickStyles(); customStyles = new StyleProvider().GetStyles() .Where(e => e.StyleType == StyleType.Heading) .OrderBy(e => e.Index) .ToList(); var headings = new List <Heading>(); // Find all OE blocks with text, e.g., containing at least one T var blocks = from e in Root.Elements(Namespace + "Outline").Descendants(Namespace + "OE") let c = e.Elements(Namespace + "T").DescendantNodes() .FirstOrDefault(p => p.NodeType == XmlNodeType.CDATA) as XCData where c?.Value.Length > 0 && !Regex.IsMatch(c.Value, @"[\s\b]+<span[\s\b]+style=") && (e.Attribute("quickStyleIndex") != null || e.Attribute("style") != null) select e; if (blocks?.Any() == true) { GetPageColor(); foreach (var block in blocks) { // concat text from each T in block; handles when cursor bisects heading var text = block.Elements(Namespace + "T") .Select(e => e.Value).Aggregate((x, y) => $"{x}{y}"); if (text == null) { continue; } Heading heading = null; if (block.ReadAttributeValue("quickStyleIndex", out var quickStyleIndex, -1)) { var style = quickStyles .Find(s => s.StyleType == StyleType.Heading && s.Index == quickStyleIndex); if (style != null) { // found standard heading heading = new Heading { Root = block, // text might include <style... Text = text, Link = GetHyperlink(block, one), Style = style }; headings.Add(heading); } } if (heading == null) { // custom heading? var style = FindCustomStyle(block); if (style != null) { // found standard heading heading = new Heading { Root = block, // text might include <style... Text = text, Link = GetHyperlink(block, one), Style = style }; headings.Add(heading); } } } } // style.Index is used for TOC indenting, regardless of heading level ResetHeadingStyleIndexes(); // Level is used as the intended Heading level, e.g. Heading4 level is 4 foreach (var heading in headings) { heading.Level = heading.Style.Index; } return(headings); }
public Archivist(OneNote one) : this(one, null) { }
public override async Task Execute(params object[] args) { using (one = new OneNote(out var page, out var ns)) { // make sure cursor is positioned in a target table... var targetRoot = GetTargetTableRoot(page, ns); if (targetRoot == null) { IsCancelled = true; return; } var table = new Table(targetRoot); // anchor is the upper-left cell into which pasting will begin var anchor = table.GetSelectedCells(out _).FirstOrDefault(); if (anchor == null) { logger.WriteLine("could not find anchor cell"); UIHelper.ShowInfo(one.Window, "could not find anchor cell; this shouldn't happen!"); IsCancelled = true; return; } // get the content to paste... var spage = await GetSourcePage(); if (spage == null) { UIHelper.ShowInfo(one.Window, Resx.PasteCellsCommand_NoContent); IsCancelled = true; return; } var source = GetSourceTable(spage); if (source == null) { UIHelper.ShowInfo(one.Window, Resx.PasteCellsCommand_NoContent); IsCancelled = true; return; } var mapping = page.MergeQuickStyles(spage); EnsureRoom(table, anchor, source); // paste... for (int r = 0, row = anchor.RowNum - 1; r < source.RowCount; r++, row++) { for (int c = 0, col = anchor.ColNum - 1; c < source.ColumnCount; c++, col++) { table[row][col].SetContent(source[r][c].GetContent()); page.ApplyStyleMapping(mapping, table[row][col].Root); var shading = source[r][c].ShadingColor; if (shading != null) { table[row][col].ShadingColor = shading; } } } await one.Update(page); } }
public override async Task Execute(params object[] args) { using (one = new OneNote(out var page, out var ns)) { // Find first selected cell as anchor point to locate table into which // the formula should be inserted; By filtering on selected=all, we avoid // including the parent table of a selected nested table. var anchor = page.Root.Descendants(ns + "Cell") // first dive down to find the selected T .Elements(ns + "OEChildren").Elements(ns + "OE") .Elements(ns + "T") .Where(e => e.Attribute("selected")?.Value == "all") // now move back up to the Cell .Select(e => e.Parent.Parent.Parent) .FirstOrDefault(); if (anchor == null) { UIHelper.ShowInfo(one.Window, Resx.FormulaCommand_SelectOne); return; } var table = new Table(anchor.FirstAncestor(ns + "Table")); var cells = table.GetSelectedCells(out var range).ToList(); if (range == TableSelectionRange.Rectangular) { UIHelper.ShowInfo(one.Window, Resx.FormulaCommand_Linear); return; } using (var dialog = new FormulaDialog()) { // display selected cell names dialog.SetCellNames( string.Join(", ", cells.Select(c => c.Coordinates))); // + $" ({rangeType})"); var cell = cells.First(); // display formula of first cell if any var formula = new Formula(cell); if (formula.Valid) { dialog.Format = formula.Format; dialog.Formula = formula.Expression; dialog.DecimalPlaces = formula.DecimalPlaces; } var tagIndex = page.GetTagDefIndex(BoltSymbol); if (!string.IsNullOrEmpty(tagIndex)) { if (cell.HasTag(tagIndex)) { dialog.Tagged = true; } } if (dialog.ShowDialog(owner) != DialogResult.OK) { return; } if (dialog.Tagged) { tagIndex = page.AddTagDef(BoltSymbol, Resx.AddFormulaCommand_Calculated); } StoreFormula(cells, dialog.Formula, dialog.Format, dialog.DecimalPlaces, range, tagIndex); var processor = new Processor(table); processor.Execute(cells); await one.Update(page); } } }
/* * <one:OE > * <one:T><![CDATA[<span * style='font-family:Calibri'>This is the third </span><span style='font-weight: * bold;font-style:italic;text-decoration:underline line-through;font-family:Consolas; * color:#70AD47'>li</span>]]></one:T> * <one:T selected="all" style="font-family:Consolas;font-size:12.0pt;color:#70AD47"><![CDATA[]]></one:T> * <one:T style="font-family:Consolas;font-size:12.0pt;color:#70AD47"><![CDATA[<span style='font-weight:bold;font-style:italic; * text-decoration:underline line-through'>ne </span>]]></one:T> * </one:OE> */ /// <summary> /// Infer styles from the context at the position of the text cursor on the current page. /// </summary> private static Style CollectStyleFromContext() { // infer contextual style Page page = null; using (var one = new OneNote()) { page = one.GetPage(); } if (page == null) { return(null); } var ns = page.Namespace; var selection = (from e in page.Root.Descendants(ns + "T") where e.Attributes("selected").Any(a => a.Value.Equals("all")) select e).FirstOrDefault(); if (selection != null) { var analyzer = new StyleAnalyzer(page.Root, inward: false); var cdata = selection.GetCData(); if (cdata.IsEmpty()) { // inside a word, adjacent to a word, or somewhere in whitespace? if ((selection.PreviousNode is XElement prev) && !prev.GetCData().EndsWithWhitespace()) { selection = prev; if ((selection.DescendantNodes()? .OfType <XCData>() .LastOrDefault() is XCData data) && !string.IsNullOrEmpty(data?.Value)) { var wrapper = data.GetWrapper(); // if last node is text then skip the cdata and examine the parent T // otherwise if last node is a span then start with its style var last = wrapper.Nodes().Reverse().First(n => n.NodeType == XmlNodeType.Text || ((n is XElement ne) && ne.Name.LocalName == "span")); if (last?.NodeType == XmlNodeType.Element) { var wspan = last as XElement; if (wspan.Attribute("style") != null) { analyzer.CollectStyleProperties(wspan); } } } } else { if ((selection.NextNode is XElement next) && !next.GetCData().StartsWithWhitespace()) { selection = next; if ((selection.DescendantNodes()? .OfType <XCData>() .FirstOrDefault() is XCData data) && !string.IsNullOrEmpty(data?.Value)) { var wrapper = data.GetWrapper(); // if first node is text then skip the cdata and examine the parent T // otherwise if first node is a span then start with its style var last = wrapper.Nodes().First(n => n.NodeType == XmlNodeType.Text || ((n is XElement ne) && ne.Name.LocalName == "span")); if (last?.NodeType == XmlNodeType.Element) { var wspan = last as XElement; if (wspan.Attribute("style") != null) { analyzer.CollectStyleProperties(wspan); } } } } } } var properties = analyzer.CollectStyleProperties(selection); var style = new Style(properties) { Name = "Style-" + new Random().Next(1000, 9999).ToString() }; return(style); }
private void GridResult_PreviewMouseDown(object sender, MouseButtonEventArgs e) { if (ArticleButton.IsChecked == true) { var currentArticle = (Model.Article)((Grid)sender).Tag; int? id = currentArticle.ArticleId; OneArticle one = new OneArticle(); OneArticle.articleId = (int)id; one.Title.Text = currentArticle.Title; one.Text.Text = currentArticle.Text; if (currentArticle.Image != null) { one.Source.Source = Pima.ViewModel.Converter.ConvertByteArrayToImage(currentArticle.Image); } else { one.Source.Visibility = Visibility.Collapsed; } CurrentPage.Navigate(one); } else if (NoteButton.IsChecked == true) { var currentArticle = (Model.Notes)((Grid)sender).Tag; int? id = currentArticle.NotesId; OneNote one = new OneNote(); OneNote.articleId = (int)id; one.Name.Text = currentArticle.Name; //one.Text.Text = currentArticle.Text; if (currentArticle.Note != null) { one.Source.Source = Pima.ViewModel.Converter.ConvertByteArrayToImage(currentArticle.Note); } else { one.Source.Visibility = Visibility.Collapsed; } CurrentPage.Navigate(one); } else if (SongButton.IsChecked == true) { var currentSong = (Model.Songs)((Grid)sender).Tag; int? id = currentSong.SongsId; OneSong one = new OneSong(); OneSong.songID = (int)id; one.Name.Text = currentSong.Name; //one.Text.Text = currentArticle.Text; if (currentSong.Image != null) { one.Source.Source = Pima.ViewModel.Converter.ConvertByteArrayToImage(currentSong.Image); } else { one.Source.Visibility = Visibility.Collapsed; } CurrentPage.Navigate(one); } else if (ChordButton.IsChecked == true) { var currentChord = (Model.Chords)((Grid)sender).Tag; int? id = currentChord.ChordsId; OneChord one = new OneChord(); OneChord.ChordId = (int)id; one.Name.Text = currentChord.Name; //one.Text.Text = currentArticle.Text; if (currentChord.Chord != null) { one.Source.Source = Pima.ViewModel.Converter.ConvertByteArrayToImage(currentChord.Chord); } else { one.Source.Visibility = Visibility.Collapsed; } CurrentPage.Navigate(one); } }
public override async Task Execute(params object[] args) { using (one = new OneNote()) { (backupPath, defaultPath, _) = one.GetFolders(); if (!Directory.Exists(backupPath)) { UIHelper.ShowError(owner, Resx.AnalyzeCommand_NoBackups); return; } using (var dialog = new AnalyzeDialog()) { if (dialog.ShowDialog(owner) != DialogResult.OK) { return; } showNotebookSummary = dialog.IncludeNotebookSummary; showSectionSummary = dialog.IncludeSectionSummary; pageDetail = dialog.Detail; thumbnailSize = dialog.ThumbnailSize; } one.CreatePage(one.CurrentSectionId, out var pageId); var page = one.GetPage(pageId); page.Title = Resx.AnalyzeCommand_Title; page.SetMeta(MetaNames.AnalysisReport, "true"); ns = page.Namespace; PageNamespace.Set(ns); heading1Index = page.GetQuickStyle(Styles.StandardStyles.Heading1).Index; heading2Index = page.GetQuickStyle(Styles.StandardStyles.Heading2).Index; using (progress = new UI.ProgressDialog()) { progress.SetMaximum(5); progress.Show(owner); var container = page.EnsureContentContainer(); var notebooks = await one.GetNotebooks(); var prev = false; if (showNotebookSummary) { ReportNotebooks(container, notebooks); ReportOrphans(container, notebooks); ReportCache(container); prev = true; } if (showSectionSummary) { if (prev) { WriteHorizontalLine(page, container); } await ReportSections(container, notebooks); prev = true; } if (pageDetail == AnalysisDetail.Current) { if (prev) { WriteHorizontalLine(page, container); } ReportPages(container, one.GetSection(), null, pageId); } else if (pageDetail == AnalysisDetail.All) { if (prev) { WriteHorizontalLine(page, container); } ReportAllPages(container, await one.GetNotebook(), null, pageId); } progress.SetMessage("Updating report..."); await one.Update(page); } await one.NavigateTo(pageId); } }
public static async Task <Dictionary <string, string> > FetchRecentTags(OneNote.Scope scope, int poolSize) { using (var one = new OneNote()) { // builds a hierarchy of all notebooks with notebook/section/page nodes // and each Page has a Meta of tags var scopeId = string.Empty; switch (scope) { case OneNote.Scope.Sections: scopeId = one.CurrentNotebookId; break; case OneNote.Scope.Pages: scopeId = one.CurrentSectionId; break; } var root = await one.SearchMeta(scopeId, Page.TaggingMetaName); var ns = root.GetNamespaceOfPrefix("one"); var pages = root.Descendants(ns + "Page") .OrderByDescending(e => e.Attribute("lastModifiedTime").Value); var tags = new Dictionary <string, string>(); var count = 0; foreach (var page in pages) { var meta = page.Elements(ns + "Meta") .FirstOrDefault(e => e.Attribute("name").Value == Page.TaggingMetaName); if (meta != null) { // tags are entered in user's language so split on their separator var parts = meta.Attribute("content").Value.Split( new string[] { AddIn.Culture.TextInfo.ListSeparator }, StringSplitOptions.RemoveEmptyEntries); foreach (var part in parts) { var p = part.Trim(); var key = p.ToLower(); if (!tags.ContainsKey(key)) { tags.Add(key, p); count++; if (count >= poolSize) { break; } } } } if (count >= poolSize) { break; } } return(tags); } }
// https://github.com/LanderVe/WPF_PDFDocument/blob/master/WPF_PDFDocument/WPF_PDFDocument.csproj // https://blogs.u2u.be/lander/post/2018/01/23/Creating-a-PDF-Viewer-in-WPF-using-Windows-10-APIs // https://docs.microsoft.com/en-us/uwp/api/windows.data.pdf.pdfdocument.getpage?view=winrt-20348 private async Task ImportImages(ProgressDialog progress, CancellationToken token) { logger.Start(); logger.StartClock(); progress.SetMaximum(4); progress.SetMessage($"Importing {address}..."); var pdfFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); // WebView2 needs to run in an STA thread await SingleThreaded.Invoke(() => { // WebView2 needs a message pump so host in its own invisible worker dialog using (var form = new WebViewWorkerDialog( new WebViewWorker(async(webview) => { webview.Source = new Uri(address); progress.Increment(); await Task.Yield(); return(true); }), new WebViewWorker(async(webview) => { progress.Increment(); await Task.Delay(2000); await webview.CoreWebView2.PrintToPdfAsync(pdfFile); progress.Increment(); return(true); }))) { form.ShowDialog(progress); } }); if (token.IsCancellationRequested) { return; } if (!File.Exists(pdfFile)) { logger.WriteLine($"PDF file not found, {pdfFile}"); return; } // convert PDF pages to images... logger.WriteLine("rendering images"); try { Page page = null; using (var one = new OneNote()) { page = target == ImportWebTarget.Append ? one.GetPage() : await CreatePage(one, target == ImportWebTarget.ChildPage?one.GetPage() : null, address); } var ns = page.Namespace; var container = page.EnsureContentContainer(); var file = await StorageFile.GetFileFromPathAsync(pdfFile); var doc = await Windows.Data.Pdf.PdfDocument.LoadFromFileAsync(file); await file.DeleteAsync(); progress.SetMaximum((int)doc.PageCount); for (int i = 0; i < doc.PageCount; i++) { progress.SetMessage($"Rasterizing image {i} of {doc.PageCount}"); progress.Increment(); //logger.WriteLine($"rasterizing page {i}"); var pdfpage = doc.GetPage((uint)i); using (var stream = new InMemoryRandomAccessStream()) { await pdfpage.RenderToStreamAsync(stream); using (var image = new Bitmap(stream.AsStream())) { var data = Convert.ToBase64String( (byte[])new ImageConverter().ConvertTo(image, typeof(byte[])) ); container.Add(new XElement(ns + "OE", new XElement(ns + "Image", new XAttribute("format", "png"), new XElement(ns + "Size", new XAttribute("width", $"{image.Width}.0"), new XAttribute("height", $"{image.Height}.0")), new XElement(ns + "Data", data) )), new Paragraph(ns, " ") ); } } } progress.SetMessage($"Updating page"); using (var one = new OneNote()) { await one.Update(page); } } catch (Exception exc) { logger.WriteLine(exc.Message, exc); } logger.WriteTime("import complete"); logger.End(); }