Keyboard shortcut fixes

#228
This commit is contained in:
Ben Olden-Cooligan 2024-04-07 11:19:51 -07:00
parent 5e7748cb32
commit af300170ab
23 changed files with 231 additions and 194 deletions

View File

@ -143,6 +143,22 @@ public class MacEtoPlatform : EtoPlatform
}
}
public override void HandleKeyDown(Control control, Func<Keys, bool> handle)
{
var view = control.ToNative();
var monitor = NSEvent.AddLocalMonitorForEventsMatchingMask(NSEventMask.KeyDown, evt =>
{
if (ReferenceEquals(evt.Window, view.Window) &&
view.HitTest(evt.LocationInWindow) != null!)
{
var args = evt.ToEtoKeyEventArgs();
return handle(args.KeyData) ? null! : evt;
}
return evt;
});
control.UnLoad += (_, _) => NSEvent.RemoveMonitor(monitor);
}
public override void AttachMouseWheelEvent(Control control, EventHandler<MouseEventArgs> eventHandler)
{
var view = control.ToNative();

View File

@ -50,10 +50,6 @@ public class MacDesktopForm : DesktopForm
{
Commands.MoveDown.ToolBarText = "";
Commands.MoveUp.ToolBarText = "";
Commands.SaveAllPdf.Shortcut = Application.Instance.CommonModifier | Keys.S;
Commands.SaveSelectedPdf.Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.S;
Commands.SaveAllImages.Shortcut = Application.Instance.CommonModifier | Keys.M;
Commands.SaveSelectedImages.Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.M;
Menu = new MenuBar
{

View File

@ -9,8 +9,8 @@ public class MacPreviewForm : PreviewForm
private readonly NSSlider _zoomSlider;
public MacPreviewForm(Naps2Config config, DesktopCommands desktopCommands, UiImageList imageList,
IIconProvider iconProvider, KeyboardShortcutManager ksm, ColorScheme colorScheme) : base(config,
desktopCommands, imageList, iconProvider, ksm, colorScheme)
IIconProvider iconProvider, ColorScheme colorScheme) : base(config,
desktopCommands, imageList, iconProvider, colorScheme)
{
_zoomSlider = new NSSlider
{

View File

@ -277,6 +277,9 @@
&lt;OcrDefaultAfterScanning&gt;true&lt;/OcrDefaultAfterScanning&gt;
&lt;ForcePdfCompat&gt;PdfA1B&lt;/ForcePdfCompat&gt;
&lt;EventLogging&gt;None&lt;/EventLogging&gt;
&lt;KeyboardShortcuts&gt;
&lt;ScanDefault&gt;Ctrl+Enter&lt;/ScanDefault&gt;
&lt;/KeyboardShortcuts&gt;
&lt;/AppConfig&gt;</value>
</data>
<data name="NewAppSettings" xml:space="preserve">

View File

@ -127,6 +127,10 @@ public class FileConfigScopeTests : ContextualTests
Assert.False(defaultsScope.Has(c => c.PdfSettings.Compat));
Assert.True(defaultsScope.TryGet(c => c.AlwaysRememberDevice, out var alwaysRememberDevice));
Assert.True(alwaysRememberDevice);
Assert.False(lockedScope.Has(c => c.KeyboardShortcuts.ScanDefault));
Assert.True(defaultsScope.TryGet(c => c.KeyboardShortcuts.ScanDefault, out var scanDefault));
Assert.Equal("Mod+Enter", scanDefault);
}
[Fact]

View File

@ -268,6 +268,11 @@ public class WinFormsEtoPlatform : EtoPlatform
return SD.Icon.ExtractAssociatedIcon(exePath)?.ToBitmap().ToEto();
}
public override void HandleKeyDown(Control control, Func<Keys, bool> handle)
{
control.ToNative().KeyDown += (_, args) => args.Handled = handle(args.KeyData.ToEto());
}
public override void AttachMouseWheelEvent(Control control, EventHandler<MouseEventArgs> eventHandler)
{
if (control is Scrollable scrollable)

View File

@ -124,7 +124,7 @@ public class ConfigSerializer : VersionedSerializer<ConfigStorage<CommonConfig>>
storage.Set(x => x.EsclSecurityPolicy, c.EsclSecurityPolicy);
storage.Set(x => x.EsclServerCertificatePath, c.EsclServerCertificatePath);
storage.Set(x => x.EventLogging, c.EventLogging);
storage.Set(x => x.KeyboardShortcuts, c.KeyboardShortcuts ?? new KeyboardShortcuts());
storage.Set(x => x.KeyboardShortcuts, MapKeyboardShortcuts(c.KeyboardShortcuts ?? new KeyboardShortcuts()));
return storage;
}
@ -191,6 +191,18 @@ public class ConfigSerializer : VersionedSerializer<ConfigStorage<CommonConfig>>
return flags;
}
private KeyboardShortcuts MapKeyboardShortcuts(KeyboardShortcuts keyboardShortcuts)
{
// To be platform-independent, replace "Ctrl+" with "Mod+", which means "Ctrl" on Window/Linux and "Cmd" on Mac
var serializer = new XmlSerializer<KeyboardShortcuts>();
var doc = serializer.SerializeToXDocument(keyboardShortcuts);
foreach (var node in doc.Root!.Elements())
{
node.Value = node.Value.Replace("Ctrl+", "Mod+");
}
return serializer.DeserializeFromXDocument(doc)!;
}
private static ConfigStorage<CommonConfig> UserConfigV0ToCommonConfig(UserConfigV0 c)
{
var storage = new ConfigStorage<CommonConfig>();

View File

@ -129,7 +129,7 @@ public static class InternalDefaults
},
KeyboardShortcuts = new KeyboardShortcuts
{
ScanDefault = "Ctrl+Enter",
ScanDefault = "Mod+Enter",
ScanProfile1 = "F2",
ScanProfile2 = "F3",
ScanProfile3 = "F4",
@ -142,21 +142,25 @@ public static class InternalDefaults
ScanProfile10 = "F11",
ScanProfile11 = "F12",
ScanProfile12 = "",
NewProfile = "",
BatchScan = "Ctrl+B",
Profiles = "",
Ocr = "",
Import = "Ctrl+O",
SavePDF = "Ctrl+S",
SavePDFAll = "",
SavePDFSelected = "",
NewProfile = "Mod+N",
BatchScan = "Mod+B",
Profiles = "Mod+L",
ScannerSharing = "Mod+G",
Ocr = "Mod+Alt+O",
Import = "Mod+O",
SavePDF = "",
SavePDFAll = "Mod+S",
SavePDFSelected = "Mod+Shift+S",
PDFSettings = "Mod+Alt+P",
SaveImages = "",
SaveImagesAll = "",
SaveImagesSelected = "",
SaveImagesAll = "Mod+I",
SaveImagesSelected = "Mod+Shift+I",
ImageSettings = "Mod+Alt+I",
EmailPDF = "",
EmailPDFAll = "",
EmailPDFSelected = "",
Print = "Ctrl+P",
EmailPDFAll = "Mod+E",
EmailPDFSelected = "Mod+Shift+E",
EmailSettings = "Mod+Alt+E",
Print = "Mod+P",
ImageView = "",
ImageBlackWhite = "",
ImageBrightness = "",
@ -166,12 +170,12 @@ public static class InternalDefaults
ImageReset = "",
ImageSaturation = "",
ImageSharpen = "",
RotateLeft = "",
RotateRight = "",
RotateFlip = "",
RotateLeft = "Mod+Shift+Left",
RotateRight = "Mod+Shift+Right",
RotateFlip = "Mod+Shift+Down",
RotateCustom = "",
MoveUp = "Ctrl+Up",
MoveDown = "Ctrl+Down",
MoveUp = "Mod+Up",
MoveDown = "Mod+Down",
ReorderInterleave = "",
ReorderDeinterleave = "",
ReorderAltInterleave = "",
@ -179,10 +183,10 @@ public static class InternalDefaults
ReorderReverseAll = "",
ReorderReverseSelected = "",
Delete = "",
Clear = "Ctrl+Shift+Del",
Clear = "Mod+Shift+Del",
About = "F1",
ZoomIn = "Ctrl+Oemplus",
ZoomOut = "Ctrl+OemMinus"
ZoomIn = "Mod+Oemplus",
ZoomOut = "Mod+OemMinus"
},
DefaultProfileSettings = new ScanProfile { Version = ScanProfile.CURRENT_VERSION }
};

View File

@ -19,22 +19,24 @@ public class KeyboardShortcuts
public string? BatchScan { get; set; }
public string? Profiles { get; set; }
public string? ScannerSharing { get; set; }
public string? Ocr { get; set; }
public string? Import { get; set; }
public string? SavePDF { get; set; }
public string? SavePDFAll { get; set; }
public string? SavePDFSelected { get; set; }
public string? PDFSettings { get; set; }
public string? SaveImages { get; set; }
public string? SaveImagesAll { get; set; }
public string? SaveImagesSelected { get; set; }
public string? ImageSettings { get; set; }
public string? EmailPDF { get; set; }
public string? EmailPDFAll { get; set; }
public string? EmailPDFSelected { get; set; }
public string? EmailSettings { get; set; }
public string? Print { get; set; }

View File

@ -16,28 +16,20 @@ public class DesktopKeyboardShortcuts
public void Assign(DesktopCommands commands)
{
// Defaults
_ksm.Assign("Ctrl+Enter", commands.Scan);
_ksm.Assign("Ctrl+B", commands.BatchScan);
_ksm.Assign("Ctrl+O", commands.Import);
_ksm.Assign("Ctrl+S", commands.SavePdf);
_ksm.Assign("Ctrl+P", commands.Print);
_ksm.Assign("Ctrl+Up", commands.MoveUp);
_ksm.Assign("Ctrl+Left", commands.MoveUp);
_ksm.Assign("Ctrl+Down", commands.MoveDown);
_ksm.Assign("Ctrl+Right", commands.MoveDown);
_ksm.Assign("Ctrl+Shift+Del", commands.ClearAll);
_ksm.Assign("F1", commands.About);
_ksm.Assign("Ctrl+OemMinus", commands.ZoomOut);
_ksm.Assign("Ctrl+Oemplus", commands.ZoomIn);
// Unconfigurable defaults
_ksm.Assign("Mod+.", commands.Scan);
_ksm.Assign("Mod+Up", commands.MoveUp);
_ksm.Assign("Mod+Left", commands.MoveUp);
_ksm.Assign("Mod+Down", commands.MoveDown);
_ksm.Assign("Mod+Right", commands.MoveDown);
_ksm.Assign("Del", commands.Delete);
_ksm.Assign("Ctrl+A", commands.SelectAll);
_ksm.Assign("Ctrl+C", commands.Copy);
_ksm.Assign("Ctrl+V", commands.Paste);
_ksm.Assign("Ctrl+Z", commands.Undo);
_ksm.Assign(EtoPlatform.Current.IsGtk ? "Ctrl+Shift+Z" : "Ctrl+Y", commands.Redo);
_ksm.Assign("Mod+A", commands.SelectAll);
_ksm.Assign("Mod+C", commands.Copy);
_ksm.Assign("Mod+V", commands.Paste);
_ksm.Assign("Mod+Z", commands.Undo);
_ksm.Assign(EtoPlatform.Current.IsWinForms ? "Mod+Y" : "Mod+Shift+Z", commands.Redo);
// Configured
// Configured defaults
var ks = _config.Get(c => c.KeyboardShortcuts);
@ -50,6 +42,7 @@ public class DesktopKeyboardShortcuts
_ksm.Assign(ks.EmailPDF, commands.EmailPdf);
_ksm.Assign(ks.EmailPDFAll, commands.EmailAll);
_ksm.Assign(ks.EmailPDFSelected, commands.EmailSelected);
_ksm.Assign(ks.EmailSettings, commands.EmailSettings);
}
_ksm.Assign(ks.ImageBlackWhite, commands.BlackWhite);
_ksm.Assign(ks.ImageBrightness, commands.BrightCont);
@ -84,13 +77,24 @@ public class DesktopKeyboardShortcuts
_ksm.Assign(ks.RotateFlip, commands.Flip);
_ksm.Assign(ks.RotateLeft, commands.RotateLeft);
_ksm.Assign(ks.RotateRight, commands.RotateRight);
_ksm.Assign(ks.SaveImages, commands.SaveImages);
_ksm.Assign(ks.SaveImagesAll, commands.SaveAllImages);
_ksm.Assign(ks.SaveImagesSelected, commands.SaveSelectedImages);
_ksm.Assign(ks.SavePDF, commands.SavePdf);
_ksm.Assign(ks.SavePDFAll, commands.SaveAllPdf);
_ksm.Assign(ks.SavePDFSelected, commands.SaveSelectedPdf);
if (PlatformCompat.System.CombinedPdfAndImageSaving)
{
_ksm.Assign(ks.SavePDFAll, commands.SaveAll);
_ksm.Assign(ks.SavePDFSelected, commands.SaveSelected);
}
else
{
_ksm.Assign(ks.SaveImages, commands.SaveImages);
_ksm.Assign(ks.SaveImagesAll, commands.SaveAllImages);
_ksm.Assign(ks.SaveImagesSelected, commands.SaveSelectedImages);
_ksm.Assign(ks.SavePDF, commands.SavePdf);
_ksm.Assign(ks.SavePDFAll, commands.SaveAllPdf);
_ksm.Assign(ks.SavePDFSelected, commands.SaveSelectedPdf);
}
_ksm.Assign(ks.PDFSettings, commands.PdfSettings);
_ksm.Assign(ks.ImageSettings, commands.ImageSettings);
_ksm.Assign(ks.ScanDefault, commands.Scan);
_ksm.Assign(ks.ScannerSharing, commands.ScannerSharing);
_ksm.Assign(ks.ZoomIn, commands.ZoomIn);
_ksm.Assign(ks.ZoomOut, commands.ZoomOut);

View File

@ -16,6 +16,11 @@ public abstract class EtoDialogBase : Dialog, IFormBase
ShowInTaskbar = true;
LayoutController.Bind(this);
LayoutController.Invalidated += (_, _) => FormStateController.UpdateLayoutSize(LayoutController);
if (EtoPlatform.Current.IsMac)
{
// Always have a basic menu on Mac, otherwise system keyboard shortcuts like Copy/Paste don't work
Menu = new MenuBar();
}
}
protected abstract void BuildLayout();

View File

@ -131,6 +131,11 @@ public abstract class EtoPlatform
public virtual Bitmap? ExtractAssociatedIcon(string exePath) => throw new NotSupportedException();
public virtual void HandleKeyDown(Control control, Func<Keys, bool> handle)
{
control.KeyDown += (_, args) => args.Handled = handle(args.KeyData);
}
public virtual void AttachMouseWheelEvent(Control control, EventHandler<MouseEventArgs> eventHandler)
{
control.MouseWheel += eventHandler;

View File

@ -1,6 +1,6 @@
using Eto.Forms;
namespace NAPS2.EtoForms.Desktop;
namespace NAPS2.EtoForms;
/// <summary>
/// A helper class to assign keyboard shortcuts to commands.
@ -12,12 +12,16 @@ public class KeyboardShortcutManager
private readonly Dictionary<string, Keys> _customMap = new()
{
{ "mod", Application.Instance.CommonModifier },
{ "cmd", Keys.Application },
{ "ctrl", Keys.Control },
{ "del", Keys.Delete },
{ "ins", Keys.Insert },
{ "break", Keys.Pause },
{ "oemplus", Keys.Equal },
{ "oemminus", Keys.Minus },
{ "esc", Keys.Escape },
{ ".", Keys.Period },
{ "0", Keys.D0 },
{ "1", Keys.D1 },
{ "2", Keys.D2 },

View File

@ -32,56 +32,47 @@ public class DesktopCommands
Scan = new ActionCommand(desktopScanController.ScanDefault)
{
Text = UiStrings.Scan,
Image = iconProvider.GetIcon("control_play_blue"),
Shortcut = Application.Instance.CommonModifier | Keys.Period
Image = iconProvider.GetIcon("control_play_blue")
};
NewProfile = new ActionCommand(desktopScanController.ScanWithNewProfile)
{
Text = UiStrings.NewProfile,
Image = iconProvider.GetIcon("add_small"),
Shortcut = Application.Instance.CommonModifier | Keys.N
Image = iconProvider.GetIcon("add_small")
};
BatchScan = new ActionCommand(desktopSubFormController.ShowBatchScanForm)
{
Text = UiStrings.BatchScan,
Image = iconProvider.GetIcon("application_cascade"),
Shortcut = Application.Instance.CommonModifier | Keys.B
Image = iconProvider.GetIcon("application_cascade")
};
ScannerSharing = new ActionCommand(desktopSubFormController.ShowScannerSharingForm)
{
Text = UiStrings.ScannerSharing,
Image = iconProvider.GetIcon("wireless16"),
Shortcut = Application.Instance.CommonModifier | Keys.G
Image = iconProvider.GetIcon("wireless16")
};
Profiles = new ActionCommand(desktopSubFormController.ShowProfilesForm)
{
Text = UiStrings.Profiles,
Image = iconProvider.GetIcon("blueprints"),
Shortcut = Application.Instance.CommonModifier | Keys.L
Image = iconProvider.GetIcon("blueprints")
};
Ocr = new ActionCommand(desktopSubFormController.ShowOcrForm)
{
Text = UiStrings.Ocr,
Image = iconProvider.GetIcon("text"),
Shortcut = Application.Instance.CommonModifier | Keys.Alt | Keys.O
Image = iconProvider.GetIcon("text")
};
Import = new ActionCommand(desktopController.Import)
{
Text = UiStrings.Import,
Image = iconProvider.GetIcon("folder_picture"),
Shortcut = Application.Instance.CommonModifier | Keys.O
Image = iconProvider.GetIcon("folder_picture")
};
SaveAll = new ActionCommand(_imageListActions.SaveAllAsPdfOrImages)
{
Text = UiStrings.SaveAll,
Image = iconProvider.GetIcon("diskette"),
Shortcut = Application.Instance.CommonModifier | Keys.S
Image = iconProvider.GetIcon("diskette")
};
SaveSelected = new ActionCommand(_imageListActions.SaveSelectedAsPdfOrImages)
{
Text = UiStrings.SaveSelected,
Image = iconProvider.GetIcon("diskette"),
Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.S
Image = iconProvider.GetIcon("diskette")
};
SavePdf = new ActionCommand(desktopController.SavePdf)
{
@ -98,8 +89,7 @@ public class DesktopCommands
};
PdfSettings = new ActionCommand(desktopSubFormController.ShowPdfSettingsForm)
{
Text = UiStrings.PdfSettings,
Shortcut = Application.Instance.CommonModifier | Keys.Alt | Keys.P
Text = UiStrings.PdfSettings
};
SaveImages = new ActionCommand(desktopController.SaveImages)
{
@ -116,8 +106,7 @@ public class DesktopCommands
};
ImageSettings = new ActionCommand(desktopSubFormController.ShowImageSettingsForm)
{
Text = UiStrings.ImageSettings,
Shortcut = Application.Instance.CommonModifier | Keys.Alt | Keys.I
Text = UiStrings.ImageSettings
};
EmailPdf = new ActionCommand(desktopController.EmailPdf)
{
@ -126,24 +115,20 @@ public class DesktopCommands
};
EmailAll = new ActionCommand(imageListActions.EmailAllAsPdf)
{
Text = UiStrings.EmailAll,
Shortcut = Application.Instance.CommonModifier | Keys.E
Text = UiStrings.EmailAll
};
EmailSelected = new ActionCommand(imageListActions.EmailSelectedAsPdf)
{
Text = UiStrings.EmailSelected,
Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.E
Text = UiStrings.EmailSelected
};
EmailSettings = new ActionCommand(desktopSubFormController.ShowEmailSettingsForm)
{
Text = UiStrings.EmailSettings,
Shortcut = Application.Instance.CommonModifier | Keys.Alt | Keys.E
Text = UiStrings.EmailSettings
};
Print = new ActionCommand(desktopController.Print)
{
Text = UiStrings.Print,
Image = iconProvider.GetIcon("printer"),
Shortcut = Application.Instance.CommonModifier | Keys.P
Image = iconProvider.GetIcon("printer")
};
ImageMenu = new ActionCommand
{
@ -274,15 +259,13 @@ public class DesktopCommands
Delete = new ActionCommand(desktopController.Delete)
{
Text = UiStrings.Delete,
Image = iconProvider.GetIcon("cross"),
Shortcut = Keys.Delete
Image = iconProvider.GetIcon("cross")
};
ClearAll = new ActionCommand(desktopController.Clear)
{
ToolBarText = UiStrings.Clear,
MenuText = UiStrings.ClearAll,
Image = iconProvider.GetIcon("cancel"),
Shortcut = Application.Instance.CommonModifier | Keys.Shift | Keys.Delete
Image = iconProvider.GetIcon("cancel")
};
LanguageMenu = new ActionCommand
{
@ -313,34 +296,27 @@ public class DesktopCommands
};
SelectAll = new ActionCommand(imageListActions.SelectAll)
{
Text = UiStrings.SelectAll,
Shortcut = Application.Instance.CommonModifier | Keys.A
Text = UiStrings.SelectAll
};
Copy = new ActionCommand(desktopController.Copy)
{
Text = UiStrings.Copy,
Image = iconProvider.GetIcon("copy"),
Shortcut = Application.Instance.CommonModifier | Keys.C
Image = iconProvider.GetIcon("copy")
};
Paste = new ActionCommand(desktopController.Paste)
{
Text = UiStrings.Paste,
Image = iconProvider.GetIcon("paste"),
Shortcut = Application.Instance.CommonModifier | Keys.V
Image = iconProvider.GetIcon("paste")
};
Undo = new ActionCommand(imageListActions.Undo)
{
Text = UiStrings.Undo,
Image = iconProvider.GetIcon("undo"),
Shortcut = Application.Instance.CommonModifier | Keys.Z
Image = iconProvider.GetIcon("undo")
};
Redo = new ActionCommand(imageListActions.Redo)
{
Text = UiStrings.Redo,
Image = iconProvider.GetIcon("redo"),
Shortcut = EtoPlatform.Current.IsWinForms
? Application.Instance.CommonModifier | Keys.Y
: Application.Instance.CommonModifier | Keys.Shift | Keys.Z
Image = iconProvider.GetIcon("redo")
};
}

View File

@ -69,12 +69,7 @@ public abstract class DesktopForm : EtoFormBase
_desktopSubFormController = desktopSubFormController;
Commands = commands;
if (!EtoPlatform.Current.IsMac)
{
// For Mac the menu shortcuts work without needing manual hooks
// Maybe at some point we can support custom assignment on Mac, though we'll need to fix Ctrl vs Command
_keyboardShortcuts.Assign(Commands);
}
_keyboardShortcuts.Assign(Commands);
CreateToolbarsAndMenus();
UpdateScanButton();
UpdateProfilesToolbar();
@ -91,10 +86,10 @@ public abstract class DesktopForm : EtoFormBase
// TODO: Fix Eto so that we don't need to set an item here (otherwise the first time we right click nothing happens)
_contextMenu.Items.Add(Commands.SelectAll);
_contextMenu.Opening += OpeningContextMenu;
KeyDown += OnKeyDown;
_listView.Control.KeyDown += OnKeyDown;
_listView.Control.MouseWheel += ListViewMouseWheel;
_listView.Control.MouseMove += ListViewMouseMove;
EtoPlatform.Current.HandleKeyDown(this, _keyboardShortcuts.Perform);
EtoPlatform.Current.HandleKeyDown(_listView.Control, _keyboardShortcuts.Perform);
//
// Shown += FDesktop_Shown;
@ -527,11 +522,6 @@ public abstract class DesktopForm : EtoFormBase
_scanMenuCommands.Value = commandList;
}
private void OnKeyDown(object? sender, KeyEventArgs e)
{
e.Handled = _keyboardShortcuts.Perform(e.KeyData);
}
protected virtual void UpdateTitle(ScanProfile? defaultProfile)
{
Title = string.Format(UiStrings.Naps2TitleFormat, defaultProfile?.DisplayName ?? UiStrings.Naps2FullName);

View File

@ -9,19 +9,18 @@ public class PreviewForm : EtoDialogBase
{
private readonly DesktopCommands _desktopCommands;
private readonly IIconProvider _iconProvider;
private readonly KeyboardShortcutManager _ksm;
private readonly KeyboardShortcutManager _previewKsm;
private readonly ButtonToolItem _pageNumberButton = new();
private readonly ButtonToolItem _zoomPercentButton = new();
private UiImage? _currentImage;
public PreviewForm(Naps2Config config, DesktopCommands desktopCommands, UiImageList imageList,
IIconProvider iconProvider, KeyboardShortcutManager ksm, ColorScheme colorScheme) : base(config)
IIconProvider iconProvider, ColorScheme colorScheme) : base(config)
{
_desktopCommands = desktopCommands;
ImageList = imageList;
_iconProvider = iconProvider;
_ksm = ksm;
ImageViewer.ColorScheme = colorScheme;
ImageViewer.ZoomChanged += ImageViewerZoomChanged;
@ -63,6 +62,9 @@ public class PreviewForm : EtoDialogBase
Text = UiStrings.Delete,
Image = iconProvider.GetIcon("cross")
};
_previewKsm = new KeyboardShortcutManager();
EtoPlatform.Current.HandleKeyDown(this, _previewKsm.Perform);
}
private void ImageList_ImagesUpdated(object? sender, ImageListEventArgs e)
@ -313,65 +315,59 @@ public class PreviewForm : EtoDialogBase
}
}
protected override async void OnKeyDown(KeyEventArgs e)
{
if (!(e.Control || e.Shift || e.Alt))
{
switch (e.Key)
{
case Keys.Escape:
Close();
return;
// TODO: Left/right should maybe not change page if we're not at max zoom out (i.e. if we can pan)
case Keys.PageDown:
case Keys.Right:
case Keys.Down:
await GoTo(ImageIndex + 1);
return;
case Keys.PageUp:
case Keys.Left:
case Keys.Up:
await GoTo(ImageIndex - 1);
return;
}
}
e.Handled = _ksm.Perform(e.KeyData);
}
private void AssignKeyboardShortcuts()
{
// Defaults
// Unconfigurable defaults
_ksm.Assign("Del", DeleteCurrentImageCommand);
_ksm.Assign("Ctrl+Oemplus", ZoomInCommand);
_ksm.Assign("Ctrl+OemMinus", ZoomOutCommand);
_ksm.Assign("Ctrl+0", ZoomActualCommand);
_ksm.Assign("Ctrl+Z", Commands.Undo);
_ksm.Assign(EtoPlatform.Current.IsGtk ? "Ctrl+Shift+Z" : "Ctrl+Y", Commands.Redo);
_previewKsm.Assign("Esc", Close);
_previewKsm.Assign("Del", DeleteCurrentImageCommand);
_previewKsm.Assign("Mod+0", ZoomActualCommand);
_previewKsm.Assign("Mod+Z", Commands.Undo);
_previewKsm.Assign(EtoPlatform.Current.IsWinForms ? "Mod+Y" : "Mod+Shift+Z", Commands.Redo);
// Configured
_previewKsm.Assign("PageDown", () => _ = GoTo(ImageIndex + 1));
_previewKsm.Assign("Right", () => _ = GoTo(ImageIndex + 1));
_previewKsm.Assign("Down", () => _ = GoTo(ImageIndex + 1));
_previewKsm.Assign("PageUp", () => _ = GoTo(ImageIndex - 1));
_previewKsm.Assign("Left", () => _ = GoTo(ImageIndex - 1));
_previewKsm.Assign("Up", () => _ = GoTo(ImageIndex - 1));
// Configured defaults
var ks = Config.Get(c => c.KeyboardShortcuts);
_ksm.Assign(ks.Delete, DeleteCurrentImageCommand);
_ksm.Assign(ks.ImageBlackWhite, Commands.BlackWhite);
_ksm.Assign(ks.ImageBrightness, Commands.BrightCont);
_ksm.Assign(ks.ImageContrast, Commands.BrightCont);
_ksm.Assign(ks.ImageCrop, Commands.Crop);
_ksm.Assign(ks.ImageHue, Commands.HueSat);
_ksm.Assign(ks.ImageSaturation, Commands.HueSat);
_ksm.Assign(ks.ImageSharpen, Commands.Sharpen);
_ksm.Assign(ks.ImageDocumentCorrection, Commands.DocumentCorrection);
_ksm.Assign(ks.ImageSplit, Commands.Split);
_ksm.Assign(ks.ImageCombine, Commands.Combine);
_previewKsm.Assign(ks.Delete, DeleteCurrentImageCommand);
_previewKsm.Assign(ks.ImageBlackWhite, Commands.BlackWhite);
_previewKsm.Assign(ks.ImageBrightness, Commands.BrightCont);
_previewKsm.Assign(ks.ImageContrast, Commands.BrightCont);
_previewKsm.Assign(ks.ImageCrop, Commands.Crop);
_previewKsm.Assign(ks.ImageHue, Commands.HueSat);
_previewKsm.Assign(ks.ImageSaturation, Commands.HueSat);
_previewKsm.Assign(ks.ImageSharpen, Commands.Sharpen);
_previewKsm.Assign(ks.ImageDocumentCorrection, Commands.DocumentCorrection);
_previewKsm.Assign(ks.ImageSplit, Commands.Split);
_previewKsm.Assign(ks.ImageCombine, Commands.Combine);
_ksm.Assign(ks.RotateCustom, Commands.CustomRotate);
_ksm.Assign(ks.RotateFlip, Commands.Flip);
_ksm.Assign(ks.RotateLeft, Commands.RotateLeft);
_ksm.Assign(ks.RotateRight, Commands.RotateRight);
_ksm.Assign(ks.SaveImages, Commands.SaveSelectedImages);
_ksm.Assign(ks.SavePDF, Commands.SaveSelectedPdf);
_previewKsm.Assign(ks.RotateCustom, Commands.CustomRotate);
_previewKsm.Assign(ks.RotateFlip, Commands.Flip);
_previewKsm.Assign(ks.RotateLeft, Commands.RotateLeft);
_previewKsm.Assign(ks.RotateRight, Commands.RotateRight);
if (PlatformCompat.System.CombinedPdfAndImageSaving)
{
_previewKsm.Assign(ks.SavePDFAll, Commands.SaveSelected);
}
else
{
_previewKsm.Assign(ks.SavePDF, Commands.SaveSelectedPdf);
_previewKsm.Assign(ks.SaveImages, Commands.SaveSelectedImages);
_previewKsm.Assign(ks.SavePDFAll, Commands.SaveSelectedPdf);
_previewKsm.Assign(ks.SaveImagesAll, Commands.SaveSelectedImages);
}
_previewKsm.Assign(ks.ZoomIn, ZoomInCommand);
_previewKsm.Assign(ks.ZoomOut, ZoomOutCommand);
}
protected override void Dispose(bool disposing)

View File

@ -65,8 +65,7 @@ public class ProfilesForm : EtoDialogBase
_deleteCommand = new ActionCommand(DoDelete)
{
MenuText = UiStrings.Delete,
Image = Icons.cross_small.ToEtoImage(),
Shortcut = Keys.Delete
Image = Icons.cross_small.ToEtoImage()
};
_setDefaultCommand = new ActionCommand(DoSetDefault)
{
@ -75,13 +74,11 @@ public class ProfilesForm : EtoDialogBase
};
_copyCommand = new ActionCommand(DoCopy)
{
MenuText = UiStrings.Copy,
Shortcut = Application.Instance.CommonModifier | Keys.C
MenuText = UiStrings.Copy
};
_pasteCommand = new ActionCommand(DoPaste)
{
MenuText = UiStrings.Paste,
Shortcut = Application.Instance.CommonModifier | Keys.V
MenuText = UiStrings.Paste
};
_scannerSharingCommand = new ActionCommand(OpenScannerSharingForm)
{
@ -89,6 +86,12 @@ public class ProfilesForm : EtoDialogBase
Image = Icons.wireless16.ToEtoImage()
};
var profilesKsm = new KeyboardShortcutManager();
profilesKsm.Assign("Del", _deleteCommand);
profilesKsm.Assign("Mod+C", _copyCommand);
profilesKsm.Assign("Mod+V", _pasteCommand);
EtoPlatform.Current.HandleKeyDown(_listView.Control, profilesKsm.Perform);
_listView.ImageSize = 48;
_listView.ItemClicked += ItemClicked;
_listView.SelectionChanged += SelectionChanged;

View File

@ -43,10 +43,13 @@ public class ScannerSharingForm : EtoDialogBase
_deleteCommand = new ActionCommand(DoDelete)
{
MenuText = UiStrings.Delete,
Image = Icons.cross_small.ToEtoImage(),
Shortcut = Keys.Delete
Image = Icons.cross_small.ToEtoImage()
};
var profilesKsm = new KeyboardShortcutManager();
profilesKsm.Assign("Del", _deleteCommand);
EtoPlatform.Current.HandleKeyDown(_listView.Control, profilesKsm.Perform);
// TODO: Enable
// _shareAsService.Checked = _osServiceManager.IsRegistered;
// _shareAsService.CheckedChanged += ShareAsServiceCheckedChanged;

View File

@ -26,6 +26,8 @@ internal interface ISystemCompat
bool CanPrint { get; }
bool CombinedPdfAndImageSaving { get; }
bool ShouldRememberBackgroundOperations { get; }
bool RenderInWorker { get; }

View File

@ -32,6 +32,8 @@ internal class LinuxSystemCompat : ISystemCompat
public bool CanPrint => true;
public bool CombinedPdfAndImageSaving => false;
public bool ShouldRememberBackgroundOperations => true;
public bool RenderInWorker => false;

View File

@ -32,6 +32,8 @@ internal class MacSystemCompat : ISystemCompat
public bool CanPrint => true;
public bool CombinedPdfAndImageSaving => true;
public bool ShouldRememberBackgroundOperations => true;
public bool RenderInWorker => false;

View File

@ -29,6 +29,8 @@ internal abstract class WindowsSystemCompat : ISystemCompat
public bool CanPrint => true;
public bool CombinedPdfAndImageSaving => false;
public bool ShouldRememberBackgroundOperations => true;
public bool RenderInWorker => true;

View File

@ -98,20 +98,21 @@
<ScanProfile10>F11</ScanProfile10>
<ScanProfile11>F12</ScanProfile11>
<ScanProfile12></ScanProfile12>
<NewProfile></NewProfile>
<NewProfile>Ctrl+N</NewProfile>
<BatchScan>Ctrl+B</BatchScan>
<Profiles></Profiles>
<Ocr></Ocr>
<Profiles>Ctrl+L</Profiles>
<ScannerSharing>Ctrl+G</ScannerSharing>
<Ocr>Ctrl+Alt+O</Ocr>
<Import>Ctrl+O</Import>
<SavePDF>Ctrl+S</SavePDF>
<SavePDFAll></SavePDFAll>
<SavePDFSelected></SavePDFSelected>
<SaveImages></SaveImages>
<SaveImagesAll></SaveImagesAll>
<SaveImagesSelected></SaveImagesSelected>
<EmailPDF></EmailPDF>
<EmailPDFAll></EmailPDFAll>
<EmailPDFSelected></EmailPDFSelected>
<SavePDFAll>Ctrl+S</SavePDFAll>
<SavePDFSelected>Ctrl+Shift+S</SavePDFSelected>
<PDFSettings>Ctrl+Alt+P</PDFSettings>
<SaveImagesAll>Ctrl+I</SaveImagesAll>
<SaveImagesSelected>Ctrl+Shift+I</SaveImagesSelected>
<ImageSettings>Ctrl+Alt+I</ImageSettings>
<EmailPDFAll>Ctrl+E</EmailPDFAll>
<EmailPDFSelected>Ctrl+Shift+E</EmailPDFSelected>
<EmailSettings>Ctrl+Alt+E</EmailSettings>
<Print>Ctrl+P</Print>
<ImageView></ImageView>
<ImageBlackWhite></ImageBlackWhite>
@ -122,9 +123,9 @@
<ImageSaturation></ImageSaturation>
<ImageSharpen></ImageSharpen>
<ImageReset></ImageReset>
<RotateLeft></RotateLeft>
<RotateRight></RotateRight>
<RotateFlip></RotateFlip>
<RotateLeft>Ctrl+Shift+Left</RotateLeft>
<RotateRight>Ctrl+Shift+Right</RotateRight>
<RotateFlip>Ctrl+Shift+Down</RotateFlip>
<RotateCustom></RotateCustom>
<MoveUp>Ctrl+Up</MoveUp>
<MoveDown>Ctrl+Down</MoveDown>