Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PTRun][OneNote] Improve the OneNote plugin #36813

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
Move user facing strings to resources
  • Loading branch information
Odotocodot committed Jan 18, 2025
commit 925db784cbb07b1d3db4ae92d45a2d3f6318d00a
Original file line number Diff line number Diff line change
@@ -2,7 +2,10 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Globalization;
using System.Text;
using System.Windows.Controls;
using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using Microsoft.PowerToys.Settings.UI.Library;
using Wox.Plugin;

@@ -11,6 +14,8 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote.Components
public class OneNoteSettings : ISettingProvider
{
private bool coloredIcons;
private static readonly CompositeFormat ShowEncryptedSectionsDescription = CompositeFormat.Parse(Resources.ShowEncryptedSectionsDescription);
private static readonly CompositeFormat ShowRecycleBinDescription = CompositeFormat.Parse(Resources.ShowRecycleBinDescription);

internal bool ShowUnreadItems { get; private set; }

@@ -39,32 +44,32 @@ private set
{
Key = nameof(ShowUnreadItems),
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Checkbox,
DisplayLabel = string.Empty,
DisplayDescription = string.Empty,
DisplayLabel = Resources.DisplayUnreadIcon,
DisplayDescription = Resources.DisplayUnreadIconDescription,
Value = true,
},
new PluginAdditionalOption()
{
Key = nameof(ShowEncryptedSections),
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Checkbox,
DisplayLabel = string.Empty,
DisplayDescription = string.Empty,
DisplayLabel = Resources.ShowEncryptedSections,
DisplayDescription = string.Format(CultureInfo.CurrentCulture, ShowEncryptedSectionsDescription, Keywords.NotebookExplorer),
Value = true,
},
new PluginAdditionalOption()
{
Key = nameof(ShowRecycleBins),
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Checkbox,
DisplayLabel = string.Empty,
DisplayDescription = string.Empty,
DisplayLabel = Resources.ShowRecycleBin,
DisplayDescription = string.Format(CultureInfo.CurrentCulture, ShowRecycleBinDescription, Keywords.NotebookExplorer),
Value = true,
},
new PluginAdditionalOption()
{
Key = nameof(ComObjectTimeout),
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Numberbox,
DisplayLabel = "Test",
DisplayDescription = "Test",
DisplayLabel = Resources.OneNoteComObjectTimeout,
DisplayDescription = Resources.OneNoteComObjectTimeoutDescription,
NumberValue = 10000,
NumberBoxMin = 1000,
NumberBoxMax = 120000,
@@ -75,7 +80,7 @@ private set
{
Key = nameof(ColoredIcons),
PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Checkbox,
DisplayLabel = string.Empty,
DisplayLabel = Resources.CreateColoredIconsForNotebooksSections,
DisplayDescription = string.Empty,
Value = true,
},
Original file line number Diff line number Diff line change
@@ -3,8 +3,11 @@
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Windows.Input;
using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using Odotocodot.OneNote.Linq;
using Wox.Infrastructure;
using Wox.Plugin;
@@ -21,6 +24,18 @@ public class ResultCreator
private const string PathSeparator = " > ";
private static readonly string _oldSeparator = OneNoteApplication.RelativePathSeparator.ToString();

private static readonly CompositeFormat ViewNotebookExplorerDescription = CompositeFormat.Parse(Resources.ViewNotebookExplorerDescription);
private static readonly CompositeFormat ViewRecentPagesDescription = CompositeFormat.Parse(Resources.ViewRecentPagesDescription);
private static readonly CompositeFormat CreatePage = CompositeFormat.Parse(Resources.CreatePage);
private static readonly CompositeFormat CreateSection = CompositeFormat.Parse(Resources.CreateSection);
private static readonly CompositeFormat CreateSectionGroup = CompositeFormat.Parse(Resources.CreateSectionGroup);
private static readonly CompositeFormat CreateNotebook = CompositeFormat.Parse(Resources.CreateNotebook);
private static readonly CompositeFormat Location = CompositeFormat.Parse(Resources.Location);
private static readonly CompositeFormat Path = CompositeFormat.Parse(Resources.Path);
private static readonly CompositeFormat SectionNamesCannotContain = CompositeFormat.Parse(Resources.SectionNamesCannotContain);
private static readonly CompositeFormat SectionGroupNamesCannotContain = CompositeFormat.Parse(Resources.SectionGroupNamesCannotContain);
private static readonly CompositeFormat NotebookNamesCannotContain = CompositeFormat.Parse(Resources.NotebookNamesCannotContain);

internal ResultCreator(PluginInitContext context, OneNoteSettings settings, IconProvider iconProvider)
{
_settings = settings;
@@ -94,15 +109,14 @@ internal List<Result> EmptyQuery(Query query)
{
new Result
{
Title = "Search OneNote pages",
QueryTextDisplay = string.Empty,
Title = Resources.SearchOneNotePages,
IcoPath = _iconProvider.Search,
Score = 5000,
},
new Result
{
Title = "View notebook explorer",
SubTitle = $"Type \"{Keywords.NotebookExplorer}\" or select this option to search by notebook structure ",
Title = Resources.ViewNotebookExplorer,
SubTitle = string.Format(CultureInfo.CurrentCulture, ViewNotebookExplorerDescription, Keywords.NotebookExplorer),
QueryTextDisplay = Keywords.NotebookExplorer,
IcoPath = _iconProvider.NotebookExplorer,
Score = 2000,
@@ -114,8 +128,8 @@ internal List<Result> EmptyQuery(Query query)
},
new Result
{
Title = "See recent pages",
SubTitle = $"Type \"{Keywords.RecentPages}\" or select this option to see recently modified pages",
Title = Resources.ViewRecentPages,
SubTitle = string.Format(CultureInfo.CurrentCulture, ViewRecentPagesDescription, Keywords.RecentPages),
QueryTextDisplay = Keywords.RecentPages,
IcoPath = _iconProvider.Recent,
Score = -1000,
@@ -127,7 +141,7 @@ internal List<Result> EmptyQuery(Query query)
},
new Result
{
Title = "New quick note",
Title = Resources.NewQuickNote,
IcoPath = _iconProvider.QuickNote,
Score = -4000,
Action = ResultAction(() =>
@@ -138,7 +152,7 @@ internal List<Result> EmptyQuery(Query query)
},
new Result
{
Title = "Open and sync notebooks",
Title = Resources.OpenSyncNotebooks,
IcoPath = _iconProvider.Sync,
Score = int.MinValue,
Action = ResultAction(() =>
@@ -189,7 +203,7 @@ internal Result CreateOneNoteItemResult(IOneNoteItem item, bool actionIsAutoComp
if (section.Encrypted)
{
// potentially replace with glyphs if supported
title += $" [Encrypted] {(section.Locked ? "[Locked]" : "[Unlocked]")}";
title += $" [Encrypted] {(section.Locked ? "[Locked]" : "[Unlocked]")} \uE72E";
}

toolTip =
@@ -254,8 +268,8 @@ internal Result CreateNewPageResult(string newPageName, OneNoteSection section)
newPageName = newPageName.Trim();
return new Result
{
Title = $"Create page: \"{newPageName}\"",
SubTitle = $"Path: {GetNicePath(section)}{PathSeparator}{newPageName}",
Title = string.Format(CultureInfo.CurrentCulture, CreatePage, newPageName),
SubTitle = string.Format(CultureInfo.CurrentCulture, Path, GetNicePath(section) + PathSeparator + newPageName),
QueryTextDisplay = $"{GetQueryTextDisplay}{newPageName}",
IcoPath = _iconProvider.NewPage,
Action = ResultAction(() =>
@@ -273,10 +287,10 @@ internal Result CreateNewSectionResult(string newSectionName, IOneNoteItem paren

return new Result
{
Title = $"Create section: \"{newSectionName}\"",
Title = string.Format(CultureInfo.CurrentCulture, CreateSection, newSectionName),
SubTitle = validTitle
? $"Path: {GetNicePath(parent)}{PathSeparator}{newSectionName}"
: $"Section names cannot contain: {string.Join(' ', OneNoteApplication.InvalidSectionChars)}",
? string.Format(CultureInfo.CurrentCulture, Path, GetNicePath(parent) + PathSeparator + newSectionName)
: string.Format(CultureInfo.CurrentCulture, SectionNamesCannotContain, string.Join(' ', OneNoteApplication.InvalidSectionChars)),
QueryTextDisplay = $"{GetQueryTextDisplay}{newSectionName}",
IcoPath = _iconProvider.NewSection,
Action = ResultAction(() =>
@@ -311,10 +325,10 @@ internal Result CreateNewSectionGroupResult(string newSectionGroupName, IOneNote

return new Result
{
Title = $"Create section group: \"{newSectionGroupName}\"",
Title = string.Format(CultureInfo.CurrentCulture, CreateSectionGroup, newSectionGroupName),
SubTitle = validTitle
? $"Path: {GetNicePath(parent)}{PathSeparator}{newSectionGroupName}"
: $"Section group names cannot contain: {string.Join(' ', OneNoteApplication.InvalidSectionGroupChars)}",
? string.Format(CultureInfo.CurrentCulture, Path, GetNicePath(parent) + PathSeparator + newSectionGroupName)
: string.Format(CultureInfo.CurrentCulture, SectionGroupNamesCannotContain, string.Join(' ', OneNoteApplication.InvalidSectionGroupChars)),
QueryTextDisplay = $"{GetQueryTextDisplay}{newSectionGroupName}",
IcoPath = _iconProvider.NewSectionGroup,
Action = ResultAction(() =>
@@ -349,10 +363,10 @@ internal Result CreateNewNotebookResult(string newNotebookName)

return new Result
{
Title = $"Create notebook: \"{newNotebookName}\"",
Title = string.Format(CultureInfo.CurrentCulture, CreateNotebook, newNotebookName),
SubTitle = validTitle
? $"Location: {OneNoteApplication.GetDefaultNotebookLocation()}"
: $"Notebook names cannot contain: {string.Join(' ', OneNoteApplication.InvalidNotebookChars)}",
? string.Format(CultureInfo.CurrentCulture, Location, OneNoteApplication.GetDefaultNotebookLocation())
: string.Format(CultureInfo.CurrentCulture, NotebookNamesCannotContain, string.Join(' ', OneNoteApplication.InvalidNotebookChars)),
QueryTextDisplay = $"{GetQueryTextDisplay}{newNotebookName}",
IcoPath = _iconProvider.NewNotebook,
Action = ResultAction(() =>
@@ -377,7 +391,7 @@ internal List<ContextMenuResult> LoadContextMenu(Result selectedResult)
results.Add(new ContextMenuResult
{
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
Title = "Open and sync",
Title = Resources.OpenAndSync,
Glyph = "\xE8A7",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = Key.Enter,
@@ -395,7 +409,7 @@ internal List<ContextMenuResult> LoadContextMenu(Result selectedResult)
results.Add(new ContextMenuResult
{
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
Title = "Open in notebook explorer",
Title = Resources.OpenInNotebookExplorer,
Glyph = "\xEC50",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = Key.Enter,
@@ -414,7 +428,7 @@ internal List<ContextMenuResult> LoadContextMenu(Result selectedResult)
results.Add(new ContextMenuResult
{
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
Title = "Visit the Microsoft Store",
Title = Resources.VisitMicrosoftStore,
Glyph = "\xE8A7",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = Key.Enter,
@@ -446,14 +460,14 @@ internal List<Result> NoItemsInCollection(IOneNoteItem? parent, List<Result> res
case OneNoteNotebook:
case OneNoteSectionGroup:
// Can create section/section group
results.Add(NoItemsInCollectionResult("section", _iconProvider.NewSection, "(unencrypted) section"));
results.Add(NoItemsInCollectionResult("section group", _iconProvider.NewSectionGroup));
results.Add(NoItemsInCollectionResult(Resources.CreateSection, _iconProvider.NewSection));
results.Add(NoItemsInCollectionResult(Resources.CreateSectionGroup, _iconProvider.NewSectionGroup));
break;
case OneNoteSection section:
// Can create page
if (!section.Locked)
{
results.Add(NoItemsInCollectionResult("page", _iconProvider.NewPage));
results.Add(NoItemsInCollectionResult(Resources.CreatePage, _iconProvider.NewPage));
}

break;
@@ -463,24 +477,23 @@ internal List<Result> NoItemsInCollection(IOneNoteItem? parent, List<Result> res

return results;

static Result NoItemsInCollectionResult(string title, string iconPath, string? subTitle = null)
static Result NoItemsInCollectionResult(string title, string iconPath)
{
return new Result
{
Title = $"Create {title}: \"\"",
SubTitle = $"No {subTitle ?? title}s found. Type a valid title to create one",
Title = title,
SubTitle = Resources.NoItemsFoundTypeValidName,
IcoPath = iconPath,
};
}
}

// TODO Localize
internal List<Result> NoMatchesFound(bool show)
{
return show
? SingleResult(
"No matches found",
"Try searching something else, or syncing your notebooks.",
Resources.NoMatchesFound,
Resources.NoMatchesFoundDescription,
_iconProvider.Search)
: [];
}
@@ -489,17 +502,17 @@ internal List<Result> InvalidQuery(bool show)
{
return show
? SingleResult(
"Invalid query",
"The first character of the search must be a letter or a digit",
Resources.InvalidQuery,
Resources.InvalidQueryDescription,
_iconProvider.Warning)
: [];
}

internal List<Result> OneNoteNotInstalled()
{
var results = SingleResult(
"OneNote is not installed",
"Please install OneNote to use this plugin",
Resources.OneNoteNotInstalled,
Resources.OneNoteNotInstalledDescription,
_iconProvider.Warning);

results[0].ContextData = "https://apps.microsoft.com/store/detail/XPFFZHVGQWWLHB?ocid=pdpshare";
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Globalization;
using System.Text;
using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using Odotocodot.OneNote.Linq;
using Wox.Plugin;

@@ -13,6 +16,10 @@ private sealed class NotebookExplorer
{
private readonly SearchManager _searchManager;
private readonly ResultCreator _resultCreator;
private static readonly CompositeFormat OpenXInOneNote = CompositeFormat.Parse(Resources.OpenXInOneNote);
private static readonly CompositeFormat SearchingByTitleInX = CompositeFormat.Parse(Resources.SearchingByTitleInX);
private static readonly CompositeFormat SearchingPagesInX = CompositeFormat.Parse(Resources.SearchingPagesInX);
private static readonly CompositeFormat SearchInItemInfo = CompositeFormat.Parse(Resources.SearchInItemInfo);

internal NotebookExplorer(SearchManager searchManager, ResultCreator resultCreator)
{
@@ -70,16 +77,16 @@ string search when search.StartsWith(Keywords.ScopedSearch, StringComparison.Ord
if (parent != null)
{
var result = _resultCreator.CreateOneNoteItemResult(parent, false, score: 4000);
result.Title = $"Open \"{parent.Name}\" in OneNote";
result.Title = string.Format(CultureInfo.CurrentCulture, OpenXInOneNote, parent.Name);
result.SubTitle = lastSearch switch
{
string search when search.StartsWith(Keywords.TitleSearch, StringComparison.Ordinal)
=> $"Now search by title in \"{parent.Name}\"",
=> string.Format(CultureInfo.CurrentCulture, SearchingByTitleInX, parent.Name),

string search when search.StartsWith(Keywords.ScopedSearch, StringComparison.Ordinal)
=> $"Now searching all pages in \"{parent.Name}\"",
=> string.Format(CultureInfo.CurrentCulture, SearchingPagesInX, parent.Name),

_ => $"Use \'{Keywords.ScopedSearch}\' to search this item. Use \'{Keywords.TitleSearch}\' to search by title in this item",
_ => string.Format(CultureInfo.CurrentCulture, SearchInItemInfo, Keywords.ScopedSearch, Keywords.TitleSearch),
};

results.Add(result);
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using Odotocodot.OneNote.Linq;
using Wox.Infrastructure;
using Wox.Plugin;
@@ -68,7 +69,7 @@ private List<Result> TitleSearch(string query, IOneNoteItem? parent, IEnumerable
{
if (query.Length == Keywords.TitleSearch.Length && parent == null)
{
return ResultCreator.SingleResult($"Now searching by title.", null, _iconProvider.Search);
return ResultCreator.SingleResult(Resources.SearchingByTitle, null, _iconProvider.Search);
}

List<int>? highlightData = null;
Loading
Oops, something went wrong.