Skip to content

Commit

Permalink
1398 quick palette (stevencohn#1399)
Browse files Browse the repository at this point in the history
* quick palette
stevencohn#1398
  • Loading branch information
stevencohn authored and weissm committed May 25, 2024
1 parent b04d443 commit 06b3aa9
Show file tree
Hide file tree
Showing 20 changed files with 1,005 additions and 60 deletions.
6 changes: 6 additions & 0 deletions OneMore/AddInCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@ public async Task PronunciateCmd(IRibbonControl control)
=> await factory.Run<PronunciateCommand>();


[IgnorePalette]
[Command("ribQuickPaletteButton_Label", Keys.Control | Keys.Oemcomma)]
public async Task QuickPaletteCmd(IRibbonControl control)
=> await factory.Run<QuickPaletteCommand>(factory);


[Command("ribRecalculateFormulaButton_Label", Keys.Shift | Keys.F5, "ribTableMenu")]
public async Task RecalculateFormulaCmd(IRibbonControl control)
=> await factory.Run<RecalculateFormulaCommand>();
Expand Down
27 changes: 27 additions & 0 deletions OneMore/Commands/CommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,33 @@ public CommandFactory(
}


/// <summary>
/// Make an instance of the given command type with internal properties set so
/// the command is ready for use.
/// </summary>
/// <typeparam name="T">The Command type to instantiate</typeparam>
/// <returns>An instance of T</returns>
public async Task<Command> Make<T>() where T : Command, new()
{
var command = new T();

// need to rediscover active OneNote window for each command instantiation
// otherwise closing the primary or last-used active window will leave owner
// set to an invalid window handle
await using var one = new OneNote();
// convert the ulong to a IWin32Window which will be used by ShowDialog calls
var owner = new Win32WindowHandle(new IntPtr((long)one.WindowHandle));

command.SetFactory(this)
.SetLogger(logger)
.SetRibbon(ribbon)
.SetOwner(owner)
.SetTrash(trash);

return command;
}


/// <summary>
/// Instantiates and executes the specified command with optional arguments.
/// Provides catch-all exception handling - logging and a generic message to the user
Expand Down
79 changes: 60 additions & 19 deletions OneMore/Commands/Styles/ApplyStyleCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//************************************************************************************************
// Copyright © 2016 Steven M Cohn. All rights reserved.
// Copyright © 2016 Steven M Cohn. All rights reserved.
//************************************************************************************************

#pragma warning disable S125 // Sections of code should not be commented out
Expand Down Expand Up @@ -30,6 +30,12 @@ public ApplyStyleCommand()
}


/// <summary>
/// Applies the specified custom style.
/// This is called from the My Styles control.
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public override async Task Execute(params object[] args)
{
var selectedIndex = (int)args[0];
Expand All @@ -43,36 +49,71 @@ public override async Task Execute(params object[] args)
return;
}

logger.StartClock();
await ExecuteWithStyle(style, false);
}


/// <summary>
/// Applies the given style and, optionally, merges it with the existing style
/// of the selected content.
/// </summary>
/// <param name="style">The style to apply.</param>
/// <param name="merge">
/// True to merge the given style with the existing style of the selected text.
/// Otherwise, the style is applied completely as if selected from My Styles.
/// </param>
/// <returns></returns>
public async Task ExecuteWithStyle(Style style, bool merge = true)
{
await using var one = new OneNote(out page, out ns);
if (page != null)
if (page is null)
{
logger.WriteTime($"loaded page; applying style {style.Name}", true);
logger.WriteLine("could not load current page");
return;
}

stylizer = new Stylizer(style);
var actual = style;

if (merge)
{
var analyzer = new StyleAnalyzer(page.Root);
actual = analyzer.CollectFromSelection();
if (actual is not null)
{
if (style.IsBold) actual.IsBold = !actual.IsBold;
if (style.IsItalic) actual.IsItalic = !actual.IsItalic;
if (style.IsUnderline) actual.IsUnderline = !actual.IsUnderline;
if (style.IsStrikethrough) actual.IsStrikethrough = !actual.IsStrikethrough;
if (style.IsSubscript) actual.IsSubscript = !actual.IsSubscript;
if (style.IsSuperscript) actual.IsSuperscript = !actual.IsSuperscript;

if (!string.IsNullOrWhiteSpace(style.Color) &&
!style.Color.Equals(Style.Automatic))
{
actual.Color = style.Color;
}

bool success = style.StyleType == StyleType.Character
? StylizeWords()
: StylizeParagraphs();
if (!string.IsNullOrWhiteSpace(style.Highlight) &&
!style.Highlight.Equals(Style.Automatic))
{
actual.Highlight = style.Highlight;
}
}
}

if (success)
{
logger.WriteTime("applied style; saving page", true);
stylizer = new Stylizer(actual);

await one.Update(page);
bool success = actual.StyleType == StyleType.Character
? StylizeWords()
: StylizeParagraphs();

logger.WriteTime("saved page");
}
else
{
logger.WriteTime("styles not applied");
}
if (success)
{
await one.Update(page);
}
else
{
logger.WriteTime("could not load page");
logger.WriteLine("styles not applied");
}
}

Expand Down
8 changes: 7 additions & 1 deletion OneMore/Commands/Tools/CommandPaletteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public override async Task Execute(params object[] args)
{
using var dialog = new CommandPaletteDialog();
dialog.RequestData += PopulateCommands;
PopulateCommands(dialog, EventArgs.Empty);
PopulateCommands(dialog, null);

if (dialog.ShowDialog(owner) == DialogResult.OK &&
dialog.Index >= 0)
Expand Down Expand Up @@ -71,6 +71,12 @@ private void PopulateCommands(object sender, EventArgs e)
var dialog = sender as CommandPaletteDialog;

var provider = new CommandProvider();

if (e is not null)
{
provider.ClearMRU();
}

commands = provider.LoadPaletteCommands().OrderBy(c => c.Name).ToList();
recent = provider.LoadMRU(commands).OrderBy(c => c.Name).ToList();
logger.WriteLine($"discovered {commands.Count} commands, {recent.Count} mru");
Expand Down
45 changes: 31 additions & 14 deletions OneMore/Commands/Tools/CommandPaletteDialog.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//************************************************************************************************
// Copyright © 2022 Steven M Cohn. All rights reserved.
// Copyright © 2022 Steven M Cohn. All rights reserved.
//************************************************************************************************

namespace River.OneMoreAddIn.Commands
Expand All @@ -10,7 +10,8 @@ namespace River.OneMoreAddIn.Commands
using System.Windows.Forms;
using Resx = Properties.Resources;

internal partial class CommandPaletteDialog : UI.MoreForm

internal partial class CommandPaletteDialog : MoreForm
{
private readonly MoreAutoCompleteList palette;
private string[] commands;
Expand All @@ -19,6 +20,12 @@ internal partial class CommandPaletteDialog : UI.MoreForm


public CommandPaletteDialog()
: this(Resx.CommandPalette_Title, Resx.CommandPaletteDialog_introLabel_Text, true)
{
}


public CommandPaletteDialog(string title, string intro, bool showClearOption)
{
InitializeComponent();

Expand All @@ -29,13 +36,19 @@ public CommandPaletteDialog()

palette.SetAutoCompleteList(cmdBox);

if (NeedsLocalizing())
{
Text = Resx.CommandPalette_Title;
Text = title;
introLabel.Text = intro;

if (!showClearOption)
{
clearLink.Visible = false;
cmdBox.Top -= clearLink.Height;
Height -= clearLink.Height;
}
else if (NeedsLocalizing())
{
Localize(new string[]
{
"introLabel",
"clearLink"
});
}
Expand Down Expand Up @@ -74,8 +87,7 @@ private void ClearRecentCommands(object sender, LinkLabelLinkClickedEventArgs e)
Resx.CommandPalette_clear,
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
new CommandProvider().ClearMRU();
RequestData?.Invoke(this, EventArgs.Empty);
RequestData?.Invoke(this, e);
}
}

Expand All @@ -84,22 +96,27 @@ private void ValidateCommand(object sender, EventArgs e)
{
var text = cmdBox.Text.Trim();

errorProvider.SetError(cmdBox,
string.IsNullOrWhiteSpace(text) || palette.HasMatches
? String.Empty
errorProvider.SetError(cmdBox,
string.IsNullOrWhiteSpace(text) || palette.HasMatches
? string.Empty
: Resx.CommandPalette_unrecognized);
}


private void InvokeCommand(object sender, EventArgs e)
{
var text = cmdBox.Text.Trim();
var regex = new Regex($"^{text}($|\\|.+$)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

Index = commands.IndexOf(c => regex.IsMatch(c));
var pattern = new Regex(
@$"(?:(?<cat>[^{palette.CategoryDivider}]+){palette.CategoryDivider})?" +
text +
$@"(?:\{palette.KeyDivider}(?<seq>.*))?",
RegexOptions.IgnoreCase | RegexOptions.Compiled);

Index = commands.IndexOf(c => pattern.IsMatch(c));
if (Index < 0)
{
Index = recentNames.IndexOf(c => regex.IsMatch(c));
Index = recentNames.IndexOf(c => pattern.IsMatch(c));
Recent = Index >= 0;
}

Expand Down
Loading

0 comments on commit 06b3aa9

Please sign in to comment.