mirror of
https://github.com/cyanfish/naps2.git
synced 2024-11-13 06:27:11 +03:00
532 lines
19 KiB
C#
532 lines
19 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using NAPS2.Lang.Resources;
|
|
using NAPS2.Logging;
|
|
using NAPS2.Platform;
|
|
using NAPS2.Remoting.ClientServer;
|
|
using NAPS2.Scan;
|
|
using NAPS2.Scan.Exceptions;
|
|
using NAPS2.Scan.Sane;
|
|
using NAPS2.Scan.Twain;
|
|
using NAPS2.Scan.Wia;
|
|
using NAPS2.Util;
|
|
|
|
namespace NAPS2.WinForms
|
|
{
|
|
public partial class FEditProfile : FormBase
|
|
{
|
|
private readonly IScanPerformer scanPerformer;
|
|
private readonly ErrorOutput errorOutput;
|
|
private readonly ProfileNameTracker profileNameTracker;
|
|
|
|
private ScanProfile scanProfile;
|
|
private ScanDevice currentDevice;
|
|
private bool isDefault;
|
|
private bool useProxy;
|
|
|
|
private int iconID;
|
|
private bool result;
|
|
|
|
private bool suppressChangeEvent;
|
|
|
|
public FEditProfile(IScanPerformer scanPerformer, ErrorOutput errorOutput, ProfileNameTracker profileNameTracker)
|
|
{
|
|
this.scanPerformer = scanPerformer;
|
|
this.errorOutput = errorOutput;
|
|
this.profileNameTracker = profileNameTracker;
|
|
InitializeComponent();
|
|
btnNetwork.Left = btnChooseDevice.Right + 6;
|
|
// TODO: Remove this to reenable
|
|
btnNetwork.Visible = false;
|
|
|
|
AddEnumItems<ScanHorizontalAlign>(cmbAlign);
|
|
AddEnumItems<ScanBitDepth>(cmbDepth);
|
|
AddEnumItems<ScanDpi>(cmbResolution);
|
|
AddEnumItems<ScanScale>(cmbScale);
|
|
AddEnumItems<ScanSource>(cmbSource);
|
|
cmbPage.Format += (sender, e) =>
|
|
{
|
|
var item = (PageSizeListItem)e.ListItem;
|
|
e.Value = item.Label;
|
|
};
|
|
|
|
rdWIA.Visible = PlatformCompat.System.IsWiaDriverSupported;
|
|
rdTWAIN.Visible = PlatformCompat.System.IsTwainDriverSupported;
|
|
rdSANE.Visible = PlatformCompat.System.IsSaneDriverSupported;
|
|
}
|
|
|
|
protected override void OnLoad(object sender, EventArgs e)
|
|
{
|
|
// Don't trigger any onChange events
|
|
suppressChangeEvent = true;
|
|
|
|
pctIcon.Image = ilProfileIcons.IconsList.Images[ScanProfile.IconID];
|
|
txtName.Text = ScanProfile.DisplayName;
|
|
if (CurrentDevice == null)
|
|
{
|
|
CurrentDevice = ScanProfile.Device;
|
|
}
|
|
isDefault = ScanProfile.IsDefault;
|
|
useProxy = ScanProfile.DriverName == DriverNames.PROXY;
|
|
iconID = ScanProfile.IconID;
|
|
|
|
cmbSource.SelectedIndex = (int)ScanProfile.PaperSource;
|
|
cmbDepth.SelectedIndex = (int)ScanProfile.BitDepth;
|
|
cmbResolution.SelectedIndex = (int)ScanProfile.Resolution;
|
|
txtContrast.Text = ScanProfile.Contrast.ToString("G");
|
|
txtBrightness.Text = ScanProfile.Brightness.ToString("G");
|
|
UpdatePageSizeList();
|
|
SelectPageSize();
|
|
cmbScale.SelectedIndex = (int)ScanProfile.AfterScanScale;
|
|
cmbAlign.SelectedIndex = (int)ScanProfile.PageAlign;
|
|
|
|
cbAutoSave.Checked = ScanProfile.EnableAutoSave;
|
|
|
|
// The setter updates the driver selection checkboxes
|
|
DeviceDriverName = useProxy ? ScanProfile.ProxyDriverName : ScanProfile.DriverName;
|
|
|
|
rdbNative.Checked = ScanProfile.UseNativeUI;
|
|
rdbConfig.Checked = !ScanProfile.UseNativeUI;
|
|
|
|
// Start triggering onChange events again
|
|
suppressChangeEvent = false;
|
|
|
|
UpdateEnabledControls();
|
|
|
|
linkAutoSaveSettings.Location = new Point(cbAutoSave.Right, linkAutoSaveSettings.Location.Y);
|
|
new LayoutManager(this)
|
|
.Bind(txtName, txtDevice, panelUI, panel2)
|
|
.WidthToForm()
|
|
.Bind(pctIcon, btnChooseDevice, btnNetwork, btnOK, btnCancel)
|
|
.RightToForm()
|
|
.Bind(cmbAlign, cmbDepth, cmbPage, cmbResolution, cmbScale, cmbSource, trBrightness, trContrast, rdbConfig, rdbNative)
|
|
.WidthTo(() => Width / 2)
|
|
.Bind(rdTWAIN, rdbNative, label3, cmbDepth, label9, cmbAlign, label10, cmbScale, label7, trContrast)
|
|
.LeftTo(() => Width / 2)
|
|
.Bind(txtBrightness)
|
|
.LeftTo(() => trBrightness.Right)
|
|
.Bind(txtContrast)
|
|
.LeftTo(() => trContrast.Right)
|
|
.Activate();
|
|
}
|
|
|
|
private void UpdatePageSizeList()
|
|
{
|
|
cmbPage.Items.Clear();
|
|
|
|
// Defaults
|
|
foreach (ScanPageSize item in Enum.GetValues(typeof(ScanPageSize)))
|
|
{
|
|
cmbPage.Items.Add(new PageSizeListItem
|
|
{
|
|
Type = item,
|
|
Label = item.Description()
|
|
});
|
|
}
|
|
|
|
// Custom Presets
|
|
foreach (var preset in ConfigProvider.Get(c => c.CustomPageSizePresets).OrderBy(x => x.Name))
|
|
{
|
|
cmbPage.Items.Insert(cmbPage.Items.Count - 1, new PageSizeListItem
|
|
{
|
|
Type = ScanPageSize.Custom,
|
|
Label = string.Format(MiscResources.NamedPageSizeFormat, preset.Name, preset.Dimens.Width, preset.Dimens.Height, preset.Dimens.Unit.Description()),
|
|
CustomName = preset.Name,
|
|
CustomDimens = preset.Dimens
|
|
});
|
|
}
|
|
}
|
|
|
|
private void SelectPageSize()
|
|
{
|
|
if (ScanProfile.PageSize == ScanPageSize.Custom)
|
|
{
|
|
SelectCustomPageSize(ScanProfile.CustomPageSizeName, ScanProfile.CustomPageSize);
|
|
}
|
|
else
|
|
{
|
|
cmbPage.SelectedIndex = (int) ScanProfile.PageSize;
|
|
}
|
|
}
|
|
|
|
private void SelectCustomPageSize(string name, PageDimensions dimens)
|
|
{
|
|
for (int i = 0; i < cmbPage.Items.Count; i++)
|
|
{
|
|
var item = (PageSizeListItem) cmbPage.Items[i];
|
|
if (item.Type == ScanPageSize.Custom && item.CustomName == name && item.CustomDimens == dimens)
|
|
{
|
|
cmbPage.SelectedIndex = i;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Not found, so insert a new item
|
|
cmbPage.Items.Insert(cmbPage.Items.Count - 1, new PageSizeListItem
|
|
{
|
|
Type = ScanPageSize.Custom,
|
|
Label = string.IsNullOrEmpty(name)
|
|
? string.Format(MiscResources.CustomPageSizeFormat, dimens.Width, dimens.Height, dimens.Unit.Description())
|
|
: string.Format(MiscResources.NamedPageSizeFormat, name, dimens.Width, dimens.Height, dimens.Unit.Description()),
|
|
CustomName = name,
|
|
CustomDimens = dimens
|
|
});
|
|
cmbPage.SelectedIndex = cmbPage.Items.Count - 2;
|
|
}
|
|
|
|
public bool Result => result;
|
|
|
|
public ScanProfile ScanProfile
|
|
{
|
|
get => scanProfile;
|
|
set => scanProfile = value.Clone();
|
|
}
|
|
|
|
private string DeviceDriverName
|
|
{
|
|
get => rdTWAIN.Checked ? DriverNames.TWAIN
|
|
: rdSANE.Checked ? DriverNames.SANE
|
|
: DriverNames.WIA;
|
|
set
|
|
{
|
|
if (value == DriverNames.TWAIN)
|
|
{
|
|
rdTWAIN.Checked = true;
|
|
}
|
|
else if (value == DriverNames.SANE)
|
|
{
|
|
rdSANE.Checked = true;
|
|
}
|
|
else if (value == DriverNames.WIA || PlatformCompat.System.IsWiaDriverSupported)
|
|
{
|
|
rdWIA.Checked = true;
|
|
}
|
|
else
|
|
{
|
|
rdSANE.Checked = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public ScanDevice CurrentDevice
|
|
{
|
|
get => currentDevice;
|
|
set
|
|
{
|
|
currentDevice = value;
|
|
txtDevice.Text = (value == null ? "" : value.Name);
|
|
}
|
|
}
|
|
|
|
private async Task ChooseDevice()
|
|
{
|
|
try
|
|
{
|
|
ScanDevice device = await scanPerformer.PromptForDevice(ScanProfile, Handle);
|
|
if (device != null)
|
|
{
|
|
if (string.IsNullOrEmpty(txtName.Text) ||
|
|
CurrentDevice != null && CurrentDevice.Name == txtName.Text)
|
|
{
|
|
txtName.Text = device.Name;
|
|
}
|
|
CurrentDevice = device;
|
|
}
|
|
}
|
|
catch (ScanDriverException e)
|
|
{
|
|
if (e is ScanDriverUnknownException)
|
|
{
|
|
Log.ErrorException(e.Message, e.InnerException);
|
|
errorOutput.DisplayError(e.Message, e);
|
|
}
|
|
else
|
|
{
|
|
errorOutput.DisplayError(e.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async void btnChooseDevice_Click(object sender, EventArgs e)
|
|
{
|
|
ScanProfile.DriverName = useProxy ? DriverNames.PROXY : DeviceDriverName;
|
|
ScanProfile.ProxyDriverName = useProxy ? DeviceDriverName : null;
|
|
await ChooseDevice();
|
|
}
|
|
|
|
private void SaveSettings()
|
|
{
|
|
if (ScanProfile.IsLocked)
|
|
{
|
|
if (!ScanProfile.IsDeviceLocked)
|
|
{
|
|
ScanProfile.Device = CurrentDevice;
|
|
}
|
|
return;
|
|
}
|
|
var pageSize = (PageSizeListItem) cmbPage.SelectedItem;
|
|
if (ScanProfile.DisplayName != null)
|
|
{
|
|
profileNameTracker.RenamingProfile(ScanProfile.DisplayName, txtName.Text);
|
|
}
|
|
scanProfile = new ScanProfile
|
|
{
|
|
Version = ScanProfile.CURRENT_VERSION,
|
|
|
|
Device = CurrentDevice,
|
|
IsDefault = isDefault,
|
|
DriverName = useProxy ? DriverNames.PROXY : DeviceDriverName,
|
|
ProxyConfig = ScanProfile.ProxyConfig,
|
|
ProxyDriverName = useProxy ? DeviceDriverName : null,
|
|
DisplayName = txtName.Text,
|
|
IconID = iconID,
|
|
MaxQuality = ScanProfile.MaxQuality,
|
|
UseNativeUI = rdbNative.Checked,
|
|
|
|
AfterScanScale = (ScanScale)cmbScale.SelectedIndex,
|
|
BitDepth = (ScanBitDepth)cmbDepth.SelectedIndex,
|
|
Brightness = trBrightness.Value,
|
|
Contrast = trContrast.Value,
|
|
PageAlign = (ScanHorizontalAlign)cmbAlign.SelectedIndex,
|
|
PageSize = pageSize.Type,
|
|
CustomPageSizeName = pageSize.CustomName,
|
|
CustomPageSize = pageSize.CustomDimens,
|
|
Resolution = (ScanDpi)cmbResolution.SelectedIndex,
|
|
PaperSource = (ScanSource)cmbSource.SelectedIndex,
|
|
|
|
EnableAutoSave = cbAutoSave.Checked,
|
|
AutoSaveSettings = ScanProfile.AutoSaveSettings,
|
|
Quality = ScanProfile.Quality,
|
|
BrightnessContrastAfterScan = ScanProfile.BrightnessContrastAfterScan,
|
|
AutoDeskew = ScanProfile.AutoDeskew,
|
|
WiaOffsetWidth = ScanProfile.WiaOffsetWidth,
|
|
WiaRetryOnFailure = ScanProfile.WiaRetryOnFailure,
|
|
WiaDelayBetweenScans = ScanProfile.WiaDelayBetweenScans,
|
|
WiaDelayBetweenScansSeconds = ScanProfile.WiaDelayBetweenScansSeconds,
|
|
WiaVersion = ScanProfile.WiaVersion,
|
|
ForcePageSize = ScanProfile.ForcePageSize,
|
|
ForcePageSizeCrop = ScanProfile.ForcePageSizeCrop,
|
|
FlipDuplexedPages = ScanProfile.FlipDuplexedPages,
|
|
TwainImpl = ScanProfile.TwainImpl,
|
|
|
|
ExcludeBlankPages = ScanProfile.ExcludeBlankPages,
|
|
BlankPageWhiteThreshold = ScanProfile.BlankPageWhiteThreshold,
|
|
BlankPageCoverageThreshold = ScanProfile.BlankPageCoverageThreshold
|
|
};
|
|
}
|
|
|
|
private void btnOK_Click(object sender, EventArgs e)
|
|
{
|
|
// Note: If CurrentDevice is null, that's fine. A prompt will be shown when scanning.
|
|
|
|
if (txtName.Text == "")
|
|
{
|
|
errorOutput.DisplayError(MiscResources.NameMissing);
|
|
return;
|
|
}
|
|
result = true;
|
|
SaveSettings();
|
|
Close();
|
|
}
|
|
|
|
private void btnCancel_Click(object sender, EventArgs e)
|
|
{
|
|
Close();
|
|
}
|
|
|
|
private void rdbConfig_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateEnabledControls();
|
|
}
|
|
|
|
private void rdbNativeWIA_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
UpdateEnabledControls();
|
|
}
|
|
|
|
private void UpdateEnabledControls()
|
|
{
|
|
if (!suppressChangeEvent)
|
|
{
|
|
suppressChangeEvent = true;
|
|
|
|
bool canUseNativeUi = DeviceDriverName != DriverNames.SANE && !useProxy;
|
|
bool locked = ScanProfile.IsLocked;
|
|
bool deviceLocked = ScanProfile.IsDeviceLocked;
|
|
bool settingsEnabled = !locked && (rdbConfig.Checked || !canUseNativeUi);
|
|
|
|
txtName.Enabled = !locked;
|
|
rdWIA.Enabled = rdTWAIN.Enabled = rdSANE.Enabled = !locked;
|
|
txtDevice.Enabled = !deviceLocked;
|
|
btnChooseDevice.Enabled = !deviceLocked;
|
|
rdbConfig.Enabled = rdbNative.Enabled = !locked;
|
|
|
|
cmbSource.Enabled = settingsEnabled;
|
|
cmbResolution.Enabled = settingsEnabled;
|
|
cmbPage.Enabled = settingsEnabled;
|
|
cmbDepth.Enabled = settingsEnabled;
|
|
cmbAlign.Enabled = settingsEnabled;
|
|
cmbScale.Enabled = settingsEnabled;
|
|
trBrightness.Enabled = settingsEnabled;
|
|
trContrast.Enabled = settingsEnabled;
|
|
txtBrightness.Enabled = settingsEnabled;
|
|
txtContrast.Enabled = settingsEnabled;
|
|
|
|
cbAutoSave.Enabled = !locked && !ConfigProvider.Get(c => c.DisableAutoSave);
|
|
linkAutoSaveSettings.Visible = !locked && !ConfigProvider.Get(c => c.DisableAutoSave);
|
|
|
|
btnAdvanced.Enabled = !locked;
|
|
|
|
ConditionalControls.UnlockHeight(this);
|
|
ConditionalControls.SetVisible(panelUI, canUseNativeUi, 20);
|
|
ConditionalControls.LockHeight(this);
|
|
|
|
suppressChangeEvent = false;
|
|
}
|
|
}
|
|
|
|
private void rdDriver_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (((RadioButton)sender).Checked && !suppressChangeEvent)
|
|
{
|
|
ScanProfile.Device = null;
|
|
CurrentDevice = null;
|
|
UpdateEnabledControls();
|
|
}
|
|
}
|
|
|
|
private void txtBrightness_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (int.TryParse(txtBrightness.Text, out int value))
|
|
{
|
|
if (value >= trBrightness.Minimum && value <= trBrightness.Maximum)
|
|
{
|
|
trBrightness.Value = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void trBrightness_Scroll(object sender, EventArgs e)
|
|
{
|
|
txtBrightness.Text = trBrightness.Value.ToString("G");
|
|
}
|
|
|
|
private void txtContrast_TextChanged(object sender, EventArgs e)
|
|
{
|
|
if (int.TryParse(txtContrast.Text, out int value))
|
|
{
|
|
if (value >= trContrast.Minimum && value <= trContrast.Maximum)
|
|
{
|
|
trContrast.Value = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void trContrast_Scroll(object sender, EventArgs e)
|
|
{
|
|
txtContrast.Text = trContrast.Value.ToString("G");
|
|
}
|
|
|
|
private int lastPageSizeIndex = -1;
|
|
private PageSizeListItem lastPageSizeItem = null;
|
|
|
|
private void cmbPage_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (cmbPage.SelectedIndex == cmbPage.Items.Count - 1)
|
|
{
|
|
// "Custom..." selected
|
|
var form = FormFactory.Create<FPageSize>();
|
|
form.PageSizeDimens = lastPageSizeItem.Type == ScanPageSize.Custom
|
|
? lastPageSizeItem.CustomDimens
|
|
: lastPageSizeItem.Type.PageDimensions();
|
|
if (form.ShowDialog() == DialogResult.OK)
|
|
{
|
|
UpdatePageSizeList();
|
|
SelectCustomPageSize(form.PageSizeName, form.PageSizeDimens);
|
|
}
|
|
else
|
|
{
|
|
cmbPage.SelectedIndex = lastPageSizeIndex;
|
|
}
|
|
}
|
|
lastPageSizeIndex = cmbPage.SelectedIndex;
|
|
lastPageSizeItem = (PageSizeListItem)cmbPage.SelectedItem;
|
|
}
|
|
|
|
private void linkAutoSaveSettings_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
|
{
|
|
if (ConfigProvider.Get(c => c.DisableAutoSave))
|
|
{
|
|
return;
|
|
}
|
|
var form = FormFactory.Create<FAutoSaveSettings>();
|
|
ScanProfile.DriverName = DeviceDriverName;
|
|
form.ScanProfile = ScanProfile;
|
|
form.ShowDialog();
|
|
}
|
|
|
|
private void btnAdvanced_Click(object sender, EventArgs e)
|
|
{
|
|
var form = FormFactory.Create<FAdvancedScanSettings>();
|
|
ScanProfile.DriverName = DeviceDriverName;
|
|
ScanProfile.BitDepth = (ScanBitDepth)cmbDepth.SelectedIndex;
|
|
form.ScanProfile = ScanProfile;
|
|
form.ShowDialog();
|
|
}
|
|
|
|
private void cbAutoSave_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (!suppressChangeEvent)
|
|
{
|
|
if (cbAutoSave.Checked)
|
|
{
|
|
linkAutoSaveSettings.Enabled = true;
|
|
var form = FormFactory.Create<FAutoSaveSettings>();
|
|
form.ScanProfile = ScanProfile;
|
|
form.ShowDialog();
|
|
if (!form.Result)
|
|
{
|
|
cbAutoSave.Checked = false;
|
|
}
|
|
}
|
|
}
|
|
linkAutoSaveSettings.Enabled = cbAutoSave.Checked;
|
|
}
|
|
|
|
private void txtDevice_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.KeyCode == Keys.Delete)
|
|
{
|
|
CurrentDevice = null;
|
|
}
|
|
}
|
|
|
|
private class PageSizeListItem
|
|
{
|
|
public string Label { get; set; }
|
|
|
|
public ScanPageSize Type { get; set; }
|
|
|
|
public string CustomName { get; set; }
|
|
|
|
public PageDimensions CustomDimens { get; set; }
|
|
}
|
|
|
|
private void btnNetwork_Click(object sender, EventArgs e)
|
|
{
|
|
var form = FormFactory.Create<FProxyConfig>();
|
|
form.ProxyConfig = ScanProfile.ProxyConfig;
|
|
form.UseProxy = useProxy;
|
|
if (form.ShowDialog() == DialogResult.OK)
|
|
{
|
|
ScanProfile.ProxyConfig = form.ProxyConfig;
|
|
useProxy = form.UseProxy;
|
|
UpdateEnabledControls();
|
|
}
|
|
}
|
|
}
|
|
}
|