mirror of
https://github.com/cyanfish/naps2.git
synced 2024-08-17 11:10:23 +03:00
Use file-scoped namespaces in forms
This commit is contained in:
parent
6731df4789
commit
d1e86b18e3
@ -1,11 +1,10 @@
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public abstract class DialogHelper
|
||||
{
|
||||
public abstract class DialogHelper
|
||||
{
|
||||
public abstract bool PromptToSavePdfOrImage(string defaultPath, out string savePath);
|
||||
public abstract bool PromptToSavePdfOrImage(string defaultPath, out string savePath);
|
||||
|
||||
public abstract bool PromptToSavePdf(string defaultPath, out string savePath);
|
||||
public abstract bool PromptToSavePdf(string defaultPath, out string savePath);
|
||||
|
||||
public abstract bool PromptToSaveImage(string defaultPath, out string savePath);
|
||||
}
|
||||
}
|
||||
public abstract bool PromptToSaveImage(string defaultPath, out string savePath);
|
||||
}
|
@ -2,44 +2,43 @@
|
||||
using System.Windows.Forms;
|
||||
using NAPS2.ImportExport.Email;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class EmailProviderWidget : Button
|
||||
{
|
||||
public partial class EmailProviderWidget : Button
|
||||
public EmailProviderWidget()
|
||||
{
|
||||
public EmailProviderWidget()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public EmailProviderType ProviderType { get; set; }
|
||||
|
||||
public Image ProviderIcon
|
||||
{
|
||||
get => pboxIcon.Image;
|
||||
set => pboxIcon.Image = value;
|
||||
}
|
||||
|
||||
public string ProviderName
|
||||
{
|
||||
get => Text;
|
||||
set => Text = value;
|
||||
}
|
||||
|
||||
public Action? ClickAction { get; set; }
|
||||
|
||||
private void EmailProviderWidget_MouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
BackColor = Color.FromArgb(229, 241, 251);
|
||||
}
|
||||
|
||||
private void EmailProviderWidget_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
BackColor = DefaultBackColor;
|
||||
}
|
||||
|
||||
private void EmailProviderWidget_Click(object sender, EventArgs e)
|
||||
{
|
||||
ClickAction?.Invoke();
|
||||
}
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
public EmailProviderType ProviderType { get; set; }
|
||||
|
||||
public Image ProviderIcon
|
||||
{
|
||||
get => pboxIcon.Image;
|
||||
set => pboxIcon.Image = value;
|
||||
}
|
||||
|
||||
public string ProviderName
|
||||
{
|
||||
get => Text;
|
||||
set => Text = value;
|
||||
}
|
||||
|
||||
public Action? ClickAction { get; set; }
|
||||
|
||||
private void EmailProviderWidget_MouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
BackColor = Color.FromArgb(229, 241, 251);
|
||||
}
|
||||
|
||||
private void EmailProviderWidget_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
BackColor = DefaultBackColor;
|
||||
}
|
||||
|
||||
private void EmailProviderWidget_Click(object sender, EventArgs e)
|
||||
{
|
||||
ClickAction?.Invoke();
|
||||
}
|
||||
}
|
@ -3,60 +3,59 @@ using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using NAPS2.ImportExport.Email.Oauth;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FAuthorize : FormBase
|
||||
{
|
||||
public partial class FAuthorize : FormBase
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private CancellationTokenSource? _cancelTokenSource;
|
||||
|
||||
public FAuthorize(ErrorOutput errorOutput)
|
||||
{
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private CancellationTokenSource? _cancelTokenSource;
|
||||
|
||||
public FAuthorize(ErrorOutput errorOutput)
|
||||
{
|
||||
_errorOutput = errorOutput;
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public OauthProvider? OauthProvider { get; set; }
|
||||
|
||||
private void FAuthorize_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (OauthProvider == null) throw new InvalidOperationException("OauthProvider must be specified");
|
||||
|
||||
MaximumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height);
|
||||
MinimumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height);
|
||||
|
||||
_cancelTokenSource = new CancellationTokenSource();
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
OauthProvider.AcquireToken(_cancelTokenSource.Token);
|
||||
Invoke(() =>
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
});
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorOutput.DisplayError(MiscResources.AuthError, ex);
|
||||
Log.ErrorException("Error acquiring Oauth token", ex);
|
||||
Invoke(() =>
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void FAuthorize_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
_cancelTokenSource?.Cancel();
|
||||
}
|
||||
_errorOutput = errorOutput;
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
public OauthProvider? OauthProvider { get; set; }
|
||||
|
||||
private void FAuthorize_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (OauthProvider == null) throw new InvalidOperationException("OauthProvider must be specified");
|
||||
|
||||
MaximumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height);
|
||||
MinimumSize = new Size(Math.Max(lblWaiting.Width + 142, 272), Height);
|
||||
|
||||
_cancelTokenSource = new CancellationTokenSource();
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
OauthProvider.AcquireToken(_cancelTokenSource.Token);
|
||||
Invoke(() =>
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
});
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_errorOutput.DisplayError(MiscResources.AuthError, ex);
|
||||
Log.ErrorException("Error acquiring Oauth token", ex);
|
||||
Invoke(() =>
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void FAuthorize_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
_cancelTokenSource?.Cancel();
|
||||
}
|
||||
}
|
@ -7,367 +7,366 @@ using NAPS2.Scan;
|
||||
using NAPS2.Scan.Batch;
|
||||
using NAPS2.Scan.Exceptions;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FBatchScan : FormBase
|
||||
{
|
||||
public partial class FBatchScan : FormBase
|
||||
{
|
||||
public const string PATCH_CODE_INFO_URL = "http://www.naps2.com/doc-batch-scan.html#patch-t";
|
||||
public const string PATCH_CODE_INFO_URL = "http://www.naps2.com/doc-batch-scan.html#patch-t";
|
||||
|
||||
private readonly IBatchScanPerformer _batchScanPerformer;
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private readonly DialogHelper _dialogHelper;
|
||||
private readonly IProfileManager _profileManager;
|
||||
private TransactionConfigScope<CommonConfig> _userTransact;
|
||||
private Naps2Config _transactionConfig;
|
||||
private readonly IBatchScanPerformer _batchScanPerformer;
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private readonly DialogHelper _dialogHelper;
|
||||
private readonly IProfileManager _profileManager;
|
||||
private TransactionConfigScope<CommonConfig> _userTransact;
|
||||
private Naps2Config _transactionConfig;
|
||||
|
||||
private bool _batchRunning;
|
||||
private CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private bool _batchRunning;
|
||||
private CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
|
||||
public FBatchScan(IBatchScanPerformer batchScanPerformer, ErrorOutput errorOutput, DialogHelper dialogHelper, IProfileManager profileManager)
|
||||
public FBatchScan(IBatchScanPerformer batchScanPerformer, ErrorOutput errorOutput, DialogHelper dialogHelper, IProfileManager profileManager)
|
||||
{
|
||||
_batchScanPerformer = batchScanPerformer;
|
||||
_errorOutput = errorOutput;
|
||||
_dialogHelper = dialogHelper;
|
||||
_profileManager = profileManager;
|
||||
InitializeComponent();
|
||||
|
||||
RestoreFormState = false;
|
||||
}
|
||||
|
||||
public Action<ProcessedImage> ImageCallback { get; set; }
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(groupboxScanConfig, groupboxOutput,
|
||||
panelSaveSeparator, panelSaveTo, panelSaveType, panelScanDetails, panelScanType,
|
||||
comboProfile, txtFilePath, lblStatus)
|
||||
.WidthToForm()
|
||||
.Bind(btnEditProfile, btnAddProfile, btnStart, btnCancel, btnChooseFolder)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
|
||||
btnAddProfile.Enabled = !(Config.Get(c => c.NoUserProfiles) && _profileManager.Profiles.Any(x => x.IsLocked));
|
||||
|
||||
ConditionalControls.LockHeight(this);
|
||||
|
||||
// TODO: Granular
|
||||
_userTransact = Config.User.BeginTransaction();
|
||||
_transactionConfig = Config.WithTransaction(_userTransact);
|
||||
UpdateUIFromSettings();
|
||||
}
|
||||
|
||||
private void UpdateUIFromSettings()
|
||||
{
|
||||
UpdateProfiles();
|
||||
|
||||
rdSingleScan.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.Single;
|
||||
rdMultipleScansPrompt.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.MultipleWithPrompt;
|
||||
rdMultipleScansDelay.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.MultipleWithDelay;
|
||||
|
||||
// TODO: Verify culture (+ vaildation ofc)
|
||||
txtNumberOfScans.Text = _transactionConfig.Get(c => c.BatchSettings.ScanCount).ToString(CultureInfo.CurrentCulture);
|
||||
txtTimeBetweenScans.Text = _transactionConfig.Get(c => c.BatchSettings.ScanIntervalSeconds).ToString(CultureInfo.CurrentCulture);
|
||||
|
||||
rdLoadIntoNaps2.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.Load;
|
||||
rdSaveToSingleFile.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.SingleFile;
|
||||
rdSaveToMultipleFiles.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.MultipleFiles;
|
||||
|
||||
rdFilePerScan.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.FilePerScan;
|
||||
rdFilePerPage.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.FilePerPage;
|
||||
rdSeparateByPatchT.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.PatchT;
|
||||
|
||||
txtFilePath.Text = _transactionConfig.Get(c => c.BatchSettings.SavePath);
|
||||
}
|
||||
|
||||
private bool ValidateSettings()
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, comboProfile.Text);
|
||||
if (comboProfile.SelectedIndex == -1)
|
||||
{
|
||||
_batchScanPerformer = batchScanPerformer;
|
||||
_errorOutput = errorOutput;
|
||||
_dialogHelper = dialogHelper;
|
||||
_profileManager = profileManager;
|
||||
InitializeComponent();
|
||||
|
||||
RestoreFormState = false;
|
||||
ok = false;
|
||||
comboProfile.Focus();
|
||||
}
|
||||
|
||||
public Action<ProcessedImage> ImageCallback { get; set; }
|
||||
_userTransact.Set(c => c.BatchSettings.ScanType, rdMultipleScansPrompt.Checked ? BatchScanType.MultipleWithPrompt
|
||||
: rdMultipleScansDelay.Checked ? BatchScanType.MultipleWithDelay
|
||||
: BatchScanType.Single);
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
if (rdMultipleScansDelay.Checked)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(groupboxScanConfig, groupboxOutput,
|
||||
panelSaveSeparator, panelSaveTo, panelSaveType, panelScanDetails, panelScanType,
|
||||
comboProfile, txtFilePath, lblStatus)
|
||||
.WidthToForm()
|
||||
.Bind(btnEditProfile, btnAddProfile, btnStart, btnCancel, btnChooseFolder)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
|
||||
btnAddProfile.Enabled = !(Config.Get(c => c.NoUserProfiles) && _profileManager.Profiles.Any(x => x.IsLocked));
|
||||
|
||||
ConditionalControls.LockHeight(this);
|
||||
|
||||
// TODO: Granular
|
||||
_userTransact = Config.User.BeginTransaction();
|
||||
_transactionConfig = Config.WithTransaction(_userTransact);
|
||||
UpdateUIFromSettings();
|
||||
}
|
||||
|
||||
private void UpdateUIFromSettings()
|
||||
{
|
||||
UpdateProfiles();
|
||||
|
||||
rdSingleScan.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.Single;
|
||||
rdMultipleScansPrompt.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.MultipleWithPrompt;
|
||||
rdMultipleScansDelay.Checked = _transactionConfig.Get(c => c.BatchSettings.ScanType) == BatchScanType.MultipleWithDelay;
|
||||
|
||||
// TODO: Verify culture (+ vaildation ofc)
|
||||
txtNumberOfScans.Text = _transactionConfig.Get(c => c.BatchSettings.ScanCount).ToString(CultureInfo.CurrentCulture);
|
||||
txtTimeBetweenScans.Text = _transactionConfig.Get(c => c.BatchSettings.ScanIntervalSeconds).ToString(CultureInfo.CurrentCulture);
|
||||
|
||||
rdLoadIntoNaps2.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.Load;
|
||||
rdSaveToSingleFile.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.SingleFile;
|
||||
rdSaveToMultipleFiles.Checked = _transactionConfig.Get(c => c.BatchSettings.OutputType) == BatchOutputType.MultipleFiles;
|
||||
|
||||
rdFilePerScan.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.FilePerScan;
|
||||
rdFilePerPage.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.FilePerPage;
|
||||
rdSeparateByPatchT.Checked = _transactionConfig.Get(c => c.BatchSettings.SaveSeparator) == SaveSeparator.PatchT;
|
||||
|
||||
txtFilePath.Text = _transactionConfig.Get(c => c.BatchSettings.SavePath);
|
||||
}
|
||||
|
||||
private bool ValidateSettings()
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, comboProfile.Text);
|
||||
if (comboProfile.SelectedIndex == -1)
|
||||
if (!int.TryParse(txtNumberOfScans.Text, out int scanCount) || scanCount <= 0)
|
||||
{
|
||||
ok = false;
|
||||
comboProfile.Focus();
|
||||
scanCount = 0;
|
||||
txtNumberOfScans.Focus();
|
||||
}
|
||||
_userTransact.Set(c => c.BatchSettings.ScanCount, scanCount);
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.ScanType, rdMultipleScansPrompt.Checked ? BatchScanType.MultipleWithPrompt
|
||||
: rdMultipleScansDelay.Checked ? BatchScanType.MultipleWithDelay
|
||||
: BatchScanType.Single);
|
||||
|
||||
if (rdMultipleScansDelay.Checked)
|
||||
{
|
||||
if (!int.TryParse(txtNumberOfScans.Text, out int scanCount) || scanCount <= 0)
|
||||
{
|
||||
ok = false;
|
||||
scanCount = 0;
|
||||
txtNumberOfScans.Focus();
|
||||
}
|
||||
_userTransact.Set(c => c.BatchSettings.ScanCount, scanCount);
|
||||
|
||||
if (!double.TryParse(txtTimeBetweenScans.Text, out double scanInterval) || scanInterval < 0)
|
||||
{
|
||||
ok = false;
|
||||
scanInterval = 0;
|
||||
txtTimeBetweenScans.Focus();
|
||||
}
|
||||
_userTransact.Set(c => c.BatchSettings.ScanIntervalSeconds, scanInterval);
|
||||
}
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.OutputType, rdSaveToSingleFile.Checked ? BatchOutputType.SingleFile
|
||||
: rdSaveToMultipleFiles.Checked ? BatchOutputType.MultipleFiles
|
||||
: BatchOutputType.Load);
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.SaveSeparator, rdFilePerScan.Checked ? SaveSeparator.FilePerScan
|
||||
: rdSeparateByPatchT.Checked ? SaveSeparator.PatchT
|
||||
: SaveSeparator.FilePerPage);
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.SavePath, txtFilePath.Text);
|
||||
if (_transactionConfig.Get(c => c.BatchSettings.OutputType) != BatchOutputType.Load && string.IsNullOrWhiteSpace(_transactionConfig.Get(c => c.BatchSettings.SavePath)))
|
||||
if (!double.TryParse(txtTimeBetweenScans.Text, out double scanInterval) || scanInterval < 0)
|
||||
{
|
||||
ok = false;
|
||||
txtFilePath.Focus();
|
||||
scanInterval = 0;
|
||||
txtTimeBetweenScans.Focus();
|
||||
}
|
||||
|
||||
return ok;
|
||||
_userTransact.Set(c => c.BatchSettings.ScanIntervalSeconds, scanInterval);
|
||||
}
|
||||
|
||||
private void UpdateProfiles()
|
||||
_userTransact.Set(c => c.BatchSettings.OutputType, rdSaveToSingleFile.Checked ? BatchOutputType.SingleFile
|
||||
: rdSaveToMultipleFiles.Checked ? BatchOutputType.MultipleFiles
|
||||
: BatchOutputType.Load);
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.SaveSeparator, rdFilePerScan.Checked ? SaveSeparator.FilePerScan
|
||||
: rdSeparateByPatchT.Checked ? SaveSeparator.PatchT
|
||||
: SaveSeparator.FilePerPage);
|
||||
|
||||
_userTransact.Set(c => c.BatchSettings.SavePath, txtFilePath.Text);
|
||||
if (_transactionConfig.Get(c => c.BatchSettings.OutputType) != BatchOutputType.Load && string.IsNullOrWhiteSpace(_transactionConfig.Get(c => c.BatchSettings.SavePath)))
|
||||
{
|
||||
comboProfile.Items.Clear();
|
||||
comboProfile.Items.AddRange(_profileManager.Profiles.Cast<object>().ToArray());
|
||||
if (!string.IsNullOrEmpty(_transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName)) &&
|
||||
_profileManager.Profiles.Any(x => x.DisplayName == _transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName)))
|
||||
{
|
||||
comboProfile.Text = _transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName);
|
||||
}
|
||||
else if (_profileManager.DefaultProfile != null)
|
||||
{
|
||||
comboProfile.Text = _profileManager.DefaultProfile.DisplayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
comboProfile.Text = "";
|
||||
}
|
||||
ok = false;
|
||||
txtFilePath.Focus();
|
||||
}
|
||||
|
||||
private void rdSingleScan_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(rdFilePerScan, !rdSingleScan.Checked && rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
private void rdMultipleScansDelay_CheckedChanged(object sender, EventArgs e)
|
||||
private void UpdateProfiles()
|
||||
{
|
||||
comboProfile.Items.Clear();
|
||||
comboProfile.Items.AddRange(_profileManager.Profiles.Cast<object>().ToArray());
|
||||
if (!string.IsNullOrEmpty(_transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName)) &&
|
||||
_profileManager.Profiles.Any(x => x.DisplayName == _transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName)))
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelScanDetails, rdMultipleScansDelay.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
comboProfile.Text = _transactionConfig.Get(c => c.BatchSettings.ProfileDisplayName);
|
||||
}
|
||||
|
||||
private void rdLoadIntoNaps2_CheckedChanged(object sender, EventArgs e)
|
||||
else if (_profileManager.DefaultProfile != null)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelSaveTo, !rdLoadIntoNaps2.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
comboProfile.Text = _profileManager.DefaultProfile.DisplayName;
|
||||
}
|
||||
|
||||
private void rdSaveToMultipleFiles_CheckedChanged(object sender, EventArgs e)
|
||||
else
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelSaveSeparator, rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.SetVisible(rdFilePerScan, !rdSingleScan.Checked && rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
comboProfile.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void btnChooseFolder_Click(object sender, EventArgs e)
|
||||
private void rdSingleScan_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(rdFilePerScan, !rdSingleScan.Checked && rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
}
|
||||
|
||||
private void rdMultipleScansDelay_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelScanDetails, rdMultipleScansDelay.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
}
|
||||
|
||||
private void rdLoadIntoNaps2_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelSaveTo, !rdLoadIntoNaps2.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
}
|
||||
|
||||
private void rdSaveToMultipleFiles_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
ConditionalControls.UnlockHeight(this);
|
||||
ConditionalControls.SetVisible(panelSaveSeparator, rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.SetVisible(rdFilePerScan, !rdSingleScan.Checked && rdSaveToMultipleFiles.Checked);
|
||||
ConditionalControls.LockHeight(this);
|
||||
}
|
||||
|
||||
private void btnChooseFolder_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_dialogHelper.PromptToSavePdfOrImage(null, out string savePath))
|
||||
{
|
||||
if (_dialogHelper.PromptToSavePdfOrImage(null, out string savePath))
|
||||
txtFilePath.Text = savePath;
|
||||
}
|
||||
}
|
||||
|
||||
private void linkPatchCodeInfo_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
Process.Start(PATCH_CODE_INFO_URL);
|
||||
}
|
||||
|
||||
private void comboProfile_Format(object sender, ListControlConvertEventArgs e)
|
||||
{
|
||||
e.Value = ((ScanProfile)e.ListItem).DisplayName;
|
||||
}
|
||||
|
||||
private void btnEditProfile_Click(object sender, EventArgs e)
|
||||
{
|
||||
var originalProfile = (ScanProfile) comboProfile.SelectedItem;
|
||||
if (originalProfile != null)
|
||||
{
|
||||
var fedit = FormFactory.Create<FEditProfile>();
|
||||
fedit.ScanProfile = originalProfile;
|
||||
fedit.ShowDialog();
|
||||
if (fedit.Result)
|
||||
{
|
||||
txtFilePath.Text = savePath;
|
||||
}
|
||||
}
|
||||
|
||||
private void linkPatchCodeInfo_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
Process.Start(PATCH_CODE_INFO_URL);
|
||||
}
|
||||
|
||||
private void comboProfile_Format(object sender, ListControlConvertEventArgs e)
|
||||
{
|
||||
e.Value = ((ScanProfile)e.ListItem).DisplayName;
|
||||
}
|
||||
|
||||
private void btnEditProfile_Click(object sender, EventArgs e)
|
||||
{
|
||||
var originalProfile = (ScanProfile) comboProfile.SelectedItem;
|
||||
if (originalProfile != null)
|
||||
{
|
||||
var fedit = FormFactory.Create<FEditProfile>();
|
||||
fedit.ScanProfile = originalProfile;
|
||||
fedit.ShowDialog();
|
||||
if (fedit.Result)
|
||||
{
|
||||
_profileManager.Mutate(new ListMutation<ScanProfile>.ReplaceWith(fedit.ScanProfile), ListSelection.Of(originalProfile));
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, fedit.ScanProfile.DisplayName);
|
||||
UpdateProfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnAddProfile_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!(Config.Get(c => c.NoUserProfiles) && _profileManager.Profiles.Any(x => x.IsLocked)))
|
||||
{
|
||||
var fedit = FormFactory.Create<FEditProfile>();
|
||||
fedit.ScanProfile = Config.Get(c => c.DefaultProfileSettings);
|
||||
fedit.ShowDialog();
|
||||
if (fedit.Result)
|
||||
{
|
||||
_profileManager.Mutate(new ListMutation<ScanProfile>.Append(fedit.ScanProfile), ListSelection.Empty<ScanProfile>());
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, fedit.ScanProfile.DisplayName);
|
||||
UpdateProfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_batchRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!ValidateSettings())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state
|
||||
_batchRunning = true;
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
// Update UI
|
||||
btnStart.Enabled = false;
|
||||
btnCancel.Enabled = true;
|
||||
btnCancel.Text = MiscResources.Cancel;
|
||||
EnableDisableSettings(false);
|
||||
|
||||
// Start the batch
|
||||
DoBatchScan().AssertNoAwait();
|
||||
|
||||
// Save settings for next time (could also do on form close)
|
||||
_userTransact.Commit();
|
||||
}
|
||||
|
||||
private void EnableDisableSettings(bool enabled)
|
||||
{
|
||||
EnableDisable(groupboxScanConfig, enabled);
|
||||
EnableDisable(groupboxOutput, enabled);
|
||||
}
|
||||
|
||||
private void EnableDisable(Control root, bool enabled)
|
||||
{
|
||||
foreach (Control control in root.Controls)
|
||||
{
|
||||
if (control.Controls.Count > 0)
|
||||
{
|
||||
EnableDisable(control, enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
control.Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DoBatchScan()
|
||||
{
|
||||
try
|
||||
{
|
||||
await _batchScanPerformer.PerformBatchScan(Config.Get(c => c.BatchSettings), this,
|
||||
image => SafeInvoke(() => ImageCallback(image)), ProgressCallback, _cts.Token);
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = _cts.IsCancellationRequested
|
||||
? MiscResources.BatchStatusCancelled
|
||||
: MiscResources.BatchStatusComplete;
|
||||
});
|
||||
}
|
||||
catch (ScanDriverException ex)
|
||||
{
|
||||
if (ex is ScanDriverUnknownException)
|
||||
{
|
||||
Log.ErrorException("Error in batch scan", ex);
|
||||
_errorOutput.DisplayError(ex.Message, ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorOutput.DisplayError(ex.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException("Error in batch scan", ex);
|
||||
_errorOutput.DisplayError(MiscResources.BatchError, ex);
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = MiscResources.BatchStatusError;
|
||||
});
|
||||
}
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
_batchRunning = false;
|
||||
_cts = new CancellationTokenSource();
|
||||
btnStart.Enabled = true;
|
||||
btnCancel.Enabled = true;
|
||||
btnCancel.Text = MiscResources.Close;
|
||||
EnableDisableSettings(true);
|
||||
Activate();
|
||||
});
|
||||
}
|
||||
|
||||
private void ProgressCallback(string status)
|
||||
{
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = status;
|
||||
});
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_batchRunning)
|
||||
{
|
||||
if (MessageBox.Show(MiscResources.ConfirmCancelBatch, MiscResources.CancelBatch, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
_cts.Cancel();
|
||||
btnCancel.Enabled = false;
|
||||
lblStatus.Text = MiscResources.BatchStatusCancelling;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void FBatchScan_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (_cts.IsCancellationRequested)
|
||||
{
|
||||
// Keep dialog open while cancel is in progress to avoid concurrency issues
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void linkPlaceholders_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var form = FormFactory.Create<FPlaceholders>();
|
||||
form.FileName = txtFilePath.Text;
|
||||
if (form.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
txtFilePath.Text = form.FileName;
|
||||
_profileManager.Mutate(new ListMutation<ScanProfile>.ReplaceWith(fedit.ScanProfile), ListSelection.Of(originalProfile));
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, fedit.ScanProfile.DisplayName);
|
||||
UpdateProfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnAddProfile_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!(Config.Get(c => c.NoUserProfiles) && _profileManager.Profiles.Any(x => x.IsLocked)))
|
||||
{
|
||||
var fedit = FormFactory.Create<FEditProfile>();
|
||||
fedit.ScanProfile = Config.Get(c => c.DefaultProfileSettings);
|
||||
fedit.ShowDialog();
|
||||
if (fedit.Result)
|
||||
{
|
||||
_profileManager.Mutate(new ListMutation<ScanProfile>.Append(fedit.ScanProfile), ListSelection.Empty<ScanProfile>());
|
||||
_userTransact.Set(c => c.BatchSettings.ProfileDisplayName, fedit.ScanProfile.DisplayName);
|
||||
UpdateProfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_batchRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!ValidateSettings())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update state
|
||||
_batchRunning = true;
|
||||
_cts = new CancellationTokenSource();
|
||||
|
||||
// Update UI
|
||||
btnStart.Enabled = false;
|
||||
btnCancel.Enabled = true;
|
||||
btnCancel.Text = MiscResources.Cancel;
|
||||
EnableDisableSettings(false);
|
||||
|
||||
// Start the batch
|
||||
DoBatchScan().AssertNoAwait();
|
||||
|
||||
// Save settings for next time (could also do on form close)
|
||||
_userTransact.Commit();
|
||||
}
|
||||
|
||||
private void EnableDisableSettings(bool enabled)
|
||||
{
|
||||
EnableDisable(groupboxScanConfig, enabled);
|
||||
EnableDisable(groupboxOutput, enabled);
|
||||
}
|
||||
|
||||
private void EnableDisable(Control root, bool enabled)
|
||||
{
|
||||
foreach (Control control in root.Controls)
|
||||
{
|
||||
if (control.Controls.Count > 0)
|
||||
{
|
||||
EnableDisable(control, enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
control.Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DoBatchScan()
|
||||
{
|
||||
try
|
||||
{
|
||||
await _batchScanPerformer.PerformBatchScan(Config.Get(c => c.BatchSettings), this,
|
||||
image => SafeInvoke(() => ImageCallback(image)), ProgressCallback, _cts.Token);
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = _cts.IsCancellationRequested
|
||||
? MiscResources.BatchStatusCancelled
|
||||
: MiscResources.BatchStatusComplete;
|
||||
});
|
||||
}
|
||||
catch (ScanDriverException ex)
|
||||
{
|
||||
if (ex is ScanDriverUnknownException)
|
||||
{
|
||||
Log.ErrorException("Error in batch scan", ex);
|
||||
_errorOutput.DisplayError(ex.Message, ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
_errorOutput.DisplayError(ex.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.ErrorException("Error in batch scan", ex);
|
||||
_errorOutput.DisplayError(MiscResources.BatchError, ex);
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = MiscResources.BatchStatusError;
|
||||
});
|
||||
}
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
_batchRunning = false;
|
||||
_cts = new CancellationTokenSource();
|
||||
btnStart.Enabled = true;
|
||||
btnCancel.Enabled = true;
|
||||
btnCancel.Text = MiscResources.Close;
|
||||
EnableDisableSettings(true);
|
||||
Activate();
|
||||
});
|
||||
}
|
||||
|
||||
private void ProgressCallback(string status)
|
||||
{
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
lblStatus.Text = status;
|
||||
});
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_batchRunning)
|
||||
{
|
||||
if (MessageBox.Show(MiscResources.ConfirmCancelBatch, MiscResources.CancelBatch, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
_cts.Cancel();
|
||||
btnCancel.Enabled = false;
|
||||
lblStatus.Text = MiscResources.BatchStatusCancelling;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void FBatchScan_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (_cts.IsCancellationRequested)
|
||||
{
|
||||
// Keep dialog open while cancel is in progress to avoid concurrency issues
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void linkPlaceholders_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var form = FormFactory.Create<FPlaceholders>();
|
||||
form.FileName = txtFilePath.Text;
|
||||
if (form.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
txtFilePath.Text = form.FileName;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,230 +2,229 @@ using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
partial class FCrop : ImageForm
|
||||
{
|
||||
partial class FCrop : ImageForm
|
||||
private static CropTransform _lastTransform;
|
||||
private static Size _lastSize;
|
||||
|
||||
private Point _dragStartCoords;
|
||||
private LayoutManager _lm;
|
||||
|
||||
private int _originalWidth, _originalHeight;
|
||||
|
||||
public FCrop(ImageContext imageContext)
|
||||
: base(imageContext)
|
||||
{
|
||||
private static CropTransform _lastTransform;
|
||||
private static Size _lastSize;
|
||||
InitializeComponent();
|
||||
|
||||
private Point _dragStartCoords;
|
||||
private LayoutManager _lm;
|
||||
_lm = new LayoutManager(this)
|
||||
.Bind(tbLeft, tbRight)
|
||||
.WidthTo(() => (int)(GetImageWidthRatio() * pictureBox.Width))
|
||||
.LeftTo(() => (int)((1 - GetImageWidthRatio()) * pictureBox.Width / 2))
|
||||
.Bind(tbTop, tbBottom)
|
||||
.HeightTo(() => (int)(GetImageHeightRatio() * pictureBox.Height))
|
||||
.TopTo(() => (int)((1 - GetImageHeightRatio()) * pictureBox.Height / 2))
|
||||
.Activate();
|
||||
|
||||
private int _originalWidth, _originalHeight;
|
||||
_originalWidth = _originalHeight = 1000;
|
||||
}
|
||||
|
||||
public FCrop(ImageContext imageContext)
|
||||
: base(imageContext)
|
||||
public CropTransform CropTransform { get; private set; }
|
||||
|
||||
protected override IEnumerable<Transform> Transforms => new[] { CropTransform };
|
||||
|
||||
protected override PictureBox PictureBox => pictureBox;
|
||||
|
||||
protected override Bitmap RenderPreview()
|
||||
{
|
||||
var bitmap = new Bitmap(_originalWidth, _originalHeight);
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_lm = new LayoutManager(this)
|
||||
.Bind(tbLeft, tbRight)
|
||||
.WidthTo(() => (int)(GetImageWidthRatio() * pictureBox.Width))
|
||||
.LeftTo(() => (int)((1 - GetImageWidthRatio()) * pictureBox.Width / 2))
|
||||
.Bind(tbTop, tbBottom)
|
||||
.HeightTo(() => (int)(GetImageHeightRatio() * pictureBox.Height))
|
||||
.TopTo(() => (int)((1 - GetImageHeightRatio()) * pictureBox.Height / 2))
|
||||
.Activate();
|
||||
|
||||
_originalWidth = _originalHeight = 1000;
|
||||
}
|
||||
|
||||
public CropTransform CropTransform { get; private set; }
|
||||
|
||||
protected override IEnumerable<Transform> Transforms => new[] { CropTransform };
|
||||
|
||||
protected override PictureBox PictureBox => pictureBox;
|
||||
|
||||
protected override Bitmap RenderPreview()
|
||||
{
|
||||
var bitmap = new Bitmap(_originalWidth, _originalHeight);
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
{
|
||||
g.Clear(Color.Transparent);
|
||||
var attrs = new ImageAttributes();
|
||||
attrs.SetColorMatrix(new ColorMatrix { Matrix33 = 0.5f });
|
||||
g.DrawImage(workingImage2,
|
||||
new Rectangle(0, 0, _originalWidth, _originalHeight),
|
||||
0,
|
||||
0,
|
||||
_originalWidth,
|
||||
_originalHeight,
|
||||
GraphicsUnit.Pixel,
|
||||
attrs);
|
||||
var cropBorderRect = new Rectangle(CropTransform.Left, CropTransform.Top,
|
||||
_originalWidth - CropTransform.Left - CropTransform.Right,
|
||||
_originalHeight - CropTransform.Top - CropTransform.Bottom);
|
||||
g.SetClip(cropBorderRect);
|
||||
g.DrawImage(workingImage2, new Rectangle(0, 0, _originalWidth, _originalHeight));
|
||||
g.ResetClip();
|
||||
g.DrawRectangle(new Pen(Color.Black, 2.0f), cropBorderRect);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
protected override void InitTransform()
|
||||
{
|
||||
_originalWidth = workingImage.Width;
|
||||
_originalHeight = workingImage.Height;
|
||||
if (_lastTransform != null && _lastSize == workingImage.Size)
|
||||
{
|
||||
CropTransform = _lastTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetTransform();
|
||||
}
|
||||
UpdateCropBounds();
|
||||
_lm.UpdateLayout();
|
||||
}
|
||||
|
||||
protected override void ResetTransform()
|
||||
{
|
||||
CropTransform = new CropTransform(0, 0, 0, 0, _originalWidth, _originalHeight);
|
||||
}
|
||||
|
||||
protected override void TransformSaved()
|
||||
{
|
||||
_lastTransform = CropTransform;
|
||||
_lastSize = workingImage.Size;
|
||||
}
|
||||
|
||||
private double GetImageWidthRatio()
|
||||
{
|
||||
if (workingImage == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxAspect = pictureBox.Width / (double)pictureBox.Height;
|
||||
if (imageAspect > pboxAspect)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return imageAspect / pboxAspect;
|
||||
}
|
||||
|
||||
private double GetImageHeightRatio()
|
||||
{
|
||||
if (workingImage == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxAspect = pictureBox.Width / (double)pictureBox.Height;
|
||||
if (pboxAspect > imageAspect)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return pboxAspect / imageAspect;
|
||||
}
|
||||
|
||||
private void UpdateCropBounds()
|
||||
{
|
||||
tbLeft.Maximum = tbRight.Maximum = _originalWidth;
|
||||
tbTop.Maximum = tbBottom.Maximum = _originalHeight;
|
||||
|
||||
tbLeft.Value = CropTransform.Left;
|
||||
tbRight.Value = _originalWidth - CropTransform.Right;
|
||||
tbTop.Value = _originalHeight - CropTransform.Top;
|
||||
tbBottom.Value = CropTransform.Bottom;
|
||||
}
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
CropTransform = new CropTransform
|
||||
(
|
||||
Math.Min(tbLeft.Value, tbRight.Value),
|
||||
_originalWidth - Math.Max(tbLeft.Value, tbRight.Value),
|
||||
_originalHeight - Math.Max(tbTop.Value, tbBottom.Value),
|
||||
Math.Min(tbTop.Value, tbBottom.Value),
|
||||
g.Clear(Color.Transparent);
|
||||
var attrs = new ImageAttributes();
|
||||
attrs.SetColorMatrix(new ColorMatrix { Matrix33 = 0.5f });
|
||||
g.DrawImage(workingImage2,
|
||||
new Rectangle(0, 0, _originalWidth, _originalHeight),
|
||||
0,
|
||||
0,
|
||||
_originalWidth,
|
||||
_originalHeight
|
||||
);
|
||||
UpdatePreviewBox();
|
||||
_originalHeight,
|
||||
GraphicsUnit.Pixel,
|
||||
attrs);
|
||||
var cropBorderRect = new Rectangle(CropTransform.Left, CropTransform.Top,
|
||||
_originalWidth - CropTransform.Left - CropTransform.Right,
|
||||
_originalHeight - CropTransform.Top - CropTransform.Bottom);
|
||||
g.SetClip(cropBorderRect);
|
||||
g.DrawImage(workingImage2, new Rectangle(0, 0, _originalWidth, _originalHeight));
|
||||
g.ResetClip();
|
||||
g.DrawRectangle(new Pen(Color.Black, 2.0f), cropBorderRect);
|
||||
}
|
||||
|
||||
private void tbLeft_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
UpdateTransform();
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private void tbRight_Scroll(object sender, EventArgs e)
|
||||
protected override void InitTransform()
|
||||
{
|
||||
_originalWidth = workingImage.Width;
|
||||
_originalHeight = workingImage.Height;
|
||||
if (_lastTransform != null && _lastSize == workingImage.Size)
|
||||
{
|
||||
UpdateTransform();
|
||||
CropTransform = _lastTransform;
|
||||
}
|
||||
|
||||
private void tbBottom_Scroll(object sender, EventArgs e)
|
||||
else
|
||||
{
|
||||
UpdateTransform();
|
||||
ResetTransform();
|
||||
}
|
||||
UpdateCropBounds();
|
||||
_lm.UpdateLayout();
|
||||
}
|
||||
|
||||
private void tbTop_Scroll(object sender, EventArgs e)
|
||||
protected override void ResetTransform()
|
||||
{
|
||||
CropTransform = new CropTransform(0, 0, 0, 0, _originalWidth, _originalHeight);
|
||||
}
|
||||
|
||||
protected override void TransformSaved()
|
||||
{
|
||||
_lastTransform = CropTransform;
|
||||
_lastSize = workingImage.Size;
|
||||
}
|
||||
|
||||
private double GetImageWidthRatio()
|
||||
{
|
||||
if (workingImage == null)
|
||||
{
|
||||
UpdateTransform();
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxAspect = pictureBox.Width / (double)pictureBox.Height;
|
||||
if (imageAspect > pboxAspect)
|
||||
{
|
||||
_dragStartCoords = TranslatePboxCoords(e.Location);
|
||||
return 1;
|
||||
}
|
||||
return imageAspect / pboxAspect;
|
||||
}
|
||||
|
||||
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
|
||||
private double GetImageHeightRatio()
|
||||
{
|
||||
if (workingImage == null)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
return 1;
|
||||
}
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxAspect = pictureBox.Width / (double)pictureBox.Height;
|
||||
if (pboxAspect > imageAspect)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return pboxAspect / imageAspect;
|
||||
}
|
||||
|
||||
private void UpdateCropBounds()
|
||||
{
|
||||
tbLeft.Maximum = tbRight.Maximum = _originalWidth;
|
||||
tbTop.Maximum = tbBottom.Maximum = _originalHeight;
|
||||
|
||||
tbLeft.Value = CropTransform.Left;
|
||||
tbRight.Value = _originalWidth - CropTransform.Right;
|
||||
tbTop.Value = _originalHeight - CropTransform.Top;
|
||||
tbBottom.Value = CropTransform.Bottom;
|
||||
}
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
CropTransform = new CropTransform
|
||||
(
|
||||
Math.Min(tbLeft.Value, tbRight.Value),
|
||||
_originalWidth - Math.Max(tbLeft.Value, tbRight.Value),
|
||||
_originalHeight - Math.Max(tbTop.Value, tbBottom.Value),
|
||||
Math.Min(tbTop.Value, tbBottom.Value),
|
||||
_originalWidth,
|
||||
_originalHeight
|
||||
);
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
private void tbLeft_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbRight_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbBottom_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbTop_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_dragStartCoords = TranslatePboxCoords(e.Location);
|
||||
}
|
||||
|
||||
private void pictureBox_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
var dragEndCoords = TranslatePboxCoords(e.Location);
|
||||
if (dragEndCoords.X > _dragStartCoords.X)
|
||||
{
|
||||
var dragEndCoords = TranslatePboxCoords(e.Location);
|
||||
if (dragEndCoords.X > _dragStartCoords.X)
|
||||
{
|
||||
tbLeft.Value = _dragStartCoords.X;
|
||||
tbRight.Value = dragEndCoords.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
tbLeft.Value = dragEndCoords.X;
|
||||
tbRight.Value = _dragStartCoords.X;
|
||||
}
|
||||
if (dragEndCoords.Y > _dragStartCoords.Y)
|
||||
{
|
||||
tbTop.Value = _originalHeight - _dragStartCoords.Y;
|
||||
tbBottom.Value = _originalHeight - dragEndCoords.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
tbTop.Value = _originalHeight - dragEndCoords.Y;
|
||||
tbBottom.Value = _originalHeight - _dragStartCoords.Y;
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
|
||||
private Point TranslatePboxCoords(Point point)
|
||||
{
|
||||
double px = point.X - 1;
|
||||
double py = point.Y - 1;
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxWidth = (pictureBox.Width - 2);
|
||||
double pboxHeight = (pictureBox.Height - 2);
|
||||
double pboxAspect = pboxWidth / pboxHeight;
|
||||
if (pboxAspect > imageAspect)
|
||||
{
|
||||
// Empty space on left/right
|
||||
var emptyWidth = ((1 - imageAspect / pboxAspect) / 2 * pboxWidth);
|
||||
px = (pboxAspect / imageAspect * (px - emptyWidth));
|
||||
tbLeft.Value = _dragStartCoords.X;
|
||||
tbRight.Value = dragEndCoords.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty space on top/bottom
|
||||
var emptyHeight = ((1 - pboxAspect / imageAspect) / 2 * pboxHeight);
|
||||
py = (imageAspect / pboxAspect * (py - emptyHeight));
|
||||
tbLeft.Value = dragEndCoords.X;
|
||||
tbRight.Value = _dragStartCoords.X;
|
||||
}
|
||||
double x = px / pboxWidth * _originalWidth;
|
||||
double y = py / pboxHeight * _originalHeight;
|
||||
x = Math.Max(Math.Min(x, _originalWidth), 0);
|
||||
y = Math.Max(Math.Min(y, _originalHeight), 0);
|
||||
return new Point((int)Math.Round(x), (int)Math.Round(y));
|
||||
if (dragEndCoords.Y > _dragStartCoords.Y)
|
||||
{
|
||||
tbTop.Value = _originalHeight - _dragStartCoords.Y;
|
||||
tbBottom.Value = _originalHeight - dragEndCoords.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
tbTop.Value = _originalHeight - dragEndCoords.Y;
|
||||
tbBottom.Value = _originalHeight - _dragStartCoords.Y;
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Point TranslatePboxCoords(Point point)
|
||||
{
|
||||
double px = point.X - 1;
|
||||
double py = point.Y - 1;
|
||||
double imageAspect = _originalWidth / (double)_originalHeight;
|
||||
double pboxWidth = (pictureBox.Width - 2);
|
||||
double pboxHeight = (pictureBox.Height - 2);
|
||||
double pboxAspect = pboxWidth / pboxHeight;
|
||||
if (pboxAspect > imageAspect)
|
||||
{
|
||||
// Empty space on left/right
|
||||
var emptyWidth = ((1 - imageAspect / pboxAspect) / 2 * pboxWidth);
|
||||
px = (pboxAspect / imageAspect * (px - emptyWidth));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty space on top/bottom
|
||||
var emptyHeight = ((1 - pboxAspect / imageAspect) / 2 * pboxHeight);
|
||||
py = (imageAspect / pboxAspect * (py - emptyHeight));
|
||||
}
|
||||
double x = px / pboxWidth * _originalWidth;
|
||||
double y = py / pboxHeight * _originalHeight;
|
||||
x = Math.Max(Math.Min(x, _originalWidth), 0);
|
||||
y = Math.Max(Math.Min(y, _originalHeight), 0);
|
||||
return new Point((int)Math.Round(x), (int)Math.Round(y));
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -5,147 +5,146 @@ using NAPS2.ImportExport.Email.Mapi;
|
||||
using NAPS2.ImportExport.Email.Oauth;
|
||||
using NAPS2.Scan;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FEmailProvider : FormBase
|
||||
{
|
||||
public partial class FEmailProvider : FormBase
|
||||
private readonly GmailOauthProvider _gmailOauthProvider;
|
||||
private readonly OutlookWebOauthProvider _outlookWebOauthProvider;
|
||||
private readonly SystemEmailClients _systemEmailClients;
|
||||
|
||||
private List<EmailProviderWidget> _providerWidgets;
|
||||
private string[] _systemClientNames;
|
||||
private string _defaultSystemClientName;
|
||||
|
||||
public FEmailProvider(GmailOauthProvider gmailOauthProvider, OutlookWebOauthProvider outlookWebOauthProvider, SystemEmailClients systemEmailClients)
|
||||
{
|
||||
private readonly GmailOauthProvider _gmailOauthProvider;
|
||||
private readonly OutlookWebOauthProvider _outlookWebOauthProvider;
|
||||
private readonly SystemEmailClients _systemEmailClients;
|
||||
_gmailOauthProvider = gmailOauthProvider;
|
||||
_outlookWebOauthProvider = outlookWebOauthProvider;
|
||||
_systemEmailClients = systemEmailClients;
|
||||
|
||||
private List<EmailProviderWidget> _providerWidgets;
|
||||
private string[] _systemClientNames;
|
||||
private string _defaultSystemClientName;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public FEmailProvider(GmailOauthProvider gmailOauthProvider, OutlookWebOauthProvider outlookWebOauthProvider, SystemEmailClients systemEmailClients)
|
||||
private void FEmailProvider_Load(object sender, EventArgs e)
|
||||
{
|
||||
_providerWidgets = new List<EmailProviderWidget>();
|
||||
_systemClientNames = _systemEmailClients.GetNames();
|
||||
_defaultSystemClientName = _systemEmailClients.GetDefaultName();
|
||||
|
||||
foreach (var clientName in _systemClientNames.OrderBy(x => x == _defaultSystemClientName ? 0 : 1))
|
||||
{
|
||||
_gmailOauthProvider = gmailOauthProvider;
|
||||
_outlookWebOauthProvider = outlookWebOauthProvider;
|
||||
_systemEmailClients = systemEmailClients;
|
||||
|
||||
InitializeComponent();
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
ProviderType = EmailProviderType.System,
|
||||
ProviderIcon = _systemEmailClients.GetIcon(clientName) ?? Icons.mail_yellow,
|
||||
ProviderName = clientName,
|
||||
ClickAction = () => ChooseSystem(clientName)
|
||||
});
|
||||
}
|
||||
|
||||
private void FEmailProvider_Load(object sender, EventArgs e)
|
||||
if (_gmailOauthProvider.HasClientCreds)
|
||||
{
|
||||
_providerWidgets = new List<EmailProviderWidget>();
|
||||
_systemClientNames = _systemEmailClients.GetNames();
|
||||
_defaultSystemClientName = _systemEmailClients.GetDefaultName();
|
||||
|
||||
foreach (var clientName in _systemClientNames.OrderBy(x => x == _defaultSystemClientName ? 0 : 1))
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
ProviderType = EmailProviderType.System,
|
||||
ProviderIcon = _systemEmailClients.GetIcon(clientName) ?? Icons.mail_yellow,
|
||||
ProviderName = clientName,
|
||||
ClickAction = () => ChooseSystem(clientName)
|
||||
});
|
||||
}
|
||||
|
||||
if (_gmailOauthProvider.HasClientCreds)
|
||||
{
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
ProviderType = EmailProviderType.Gmail,
|
||||
ProviderIcon = Icons.gmail,
|
||||
ProviderName = EmailProviderType.Gmail.Description(),
|
||||
ClickAction = () => ChooseOauth(_gmailOauthProvider)
|
||||
});
|
||||
}
|
||||
|
||||
if (_outlookWebOauthProvider.HasClientCreds)
|
||||
{
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
ProviderType = EmailProviderType.OutlookWeb,
|
||||
ProviderIcon = Icons.outlookweb,
|
||||
ProviderName = EmailProviderType.OutlookWeb.Description(),
|
||||
ClickAction = () => ChooseOauth(_outlookWebOauthProvider)
|
||||
});
|
||||
}
|
||||
|
||||
//providerWidgets.Add(new EmailProviderWidget
|
||||
//{
|
||||
// ProviderType = EmailProviderType.CustomSmtp,
|
||||
// ProviderIcon = Icons.email_setting,
|
||||
// ProviderName = EmailProviderType.CustomSmtp.Description(),
|
||||
// ClickAction = ChooseCustomSmtp
|
||||
//});
|
||||
|
||||
// Put the configured provider at the top
|
||||
var defaultWidget = GetDefaultWidget();
|
||||
if (defaultWidget != null)
|
||||
{
|
||||
_providerWidgets.Remove(defaultWidget);
|
||||
_providerWidgets.Insert(0, defaultWidget);
|
||||
}
|
||||
|
||||
ShowWidgets();
|
||||
ProviderType = EmailProviderType.Gmail,
|
||||
ProviderIcon = Icons.gmail,
|
||||
ProviderName = EmailProviderType.Gmail.Description(),
|
||||
ClickAction = () => ChooseOauth(_gmailOauthProvider)
|
||||
});
|
||||
}
|
||||
|
||||
private void ChooseSystem(string clientName)
|
||||
if (_outlookWebOauthProvider.HasClientCreds)
|
||||
{
|
||||
_providerWidgets.Add(new EmailProviderWidget
|
||||
{
|
||||
ProviderType = EmailProviderType.OutlookWeb,
|
||||
ProviderIcon = Icons.outlookweb,
|
||||
ProviderName = EmailProviderType.OutlookWeb.Description(),
|
||||
ClickAction = () => ChooseOauth(_outlookWebOauthProvider)
|
||||
});
|
||||
}
|
||||
|
||||
//providerWidgets.Add(new EmailProviderWidget
|
||||
//{
|
||||
// ProviderType = EmailProviderType.CustomSmtp,
|
||||
// ProviderIcon = Icons.email_setting,
|
||||
// ProviderName = EmailProviderType.CustomSmtp.Description(),
|
||||
// ClickAction = ChooseCustomSmtp
|
||||
//});
|
||||
|
||||
// Put the configured provider at the top
|
||||
var defaultWidget = GetDefaultWidget();
|
||||
if (defaultWidget != null)
|
||||
{
|
||||
_providerWidgets.Remove(defaultWidget);
|
||||
_providerWidgets.Insert(0, defaultWidget);
|
||||
}
|
||||
|
||||
ShowWidgets();
|
||||
}
|
||||
|
||||
private void ChooseSystem(string clientName)
|
||||
{
|
||||
var emailSetup = Config.Get(c => c.EmailSetup);
|
||||
emailSetup.SystemProviderName = clientName == _defaultSystemClientName ? null : clientName;
|
||||
emailSetup.ProviderType = EmailProviderType.System;
|
||||
Config.User.Set(c => c.EmailSetup, emailSetup);
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ChooseOauth(OauthProvider provider)
|
||||
{
|
||||
var authForm = FormFactory.Create<FAuthorize>();
|
||||
authForm.OauthProvider = provider;
|
||||
if (authForm.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
var emailSetup = Config.Get(c => c.EmailSetup);
|
||||
emailSetup.SystemProviderName = clientName == _defaultSystemClientName ? null : clientName;
|
||||
emailSetup.ProviderType = EmailProviderType.System;
|
||||
Config.User.Set(c => c.EmailSetup, emailSetup);
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void ChooseOauth(OauthProvider provider)
|
||||
private void ShowWidgets()
|
||||
{
|
||||
int heightDiff = Height - panel1.Height;
|
||||
panel1.Height = 0;
|
||||
foreach (var widget in _providerWidgets)
|
||||
{
|
||||
var authForm = FormFactory.Create<FAuthorize>();
|
||||
authForm.OauthProvider = provider;
|
||||
if (authForm.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
panel1.Controls.Add(widget);
|
||||
widget.Top = panel1.Height;
|
||||
widget.Width = panel1.Width;
|
||||
widget.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
panel1.Height += widget.Height - 1;
|
||||
}
|
||||
|
||||
private void ShowWidgets()
|
||||
{
|
||||
int heightDiff = Height - panel1.Height;
|
||||
panel1.Height = 0;
|
||||
foreach (var widget in _providerWidgets)
|
||||
{
|
||||
panel1.Controls.Add(widget);
|
||||
widget.Top = panel1.Height;
|
||||
widget.Width = panel1.Width;
|
||||
widget.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
panel1.Height += widget.Height - 1;
|
||||
}
|
||||
panel1.Height += 1;
|
||||
MaximumSize = new Size(MaximumSize.Width, panel1.Height + heightDiff);
|
||||
MinimumSize = new Size(MinimumSize.Width, panel1.Height + heightDiff);
|
||||
}
|
||||
|
||||
panel1.Height += 1;
|
||||
MaximumSize = new Size(MaximumSize.Width, panel1.Height + heightDiff);
|
||||
MinimumSize = new Size(MinimumSize.Width, panel1.Height + heightDiff);
|
||||
}
|
||||
|
||||
private EmailProviderWidget GetDefaultWidget()
|
||||
private EmailProviderWidget GetDefaultWidget()
|
||||
{
|
||||
var emailSetup = Config.Get(c => c.EmailSetup);
|
||||
foreach (var widget in _providerWidgets)
|
||||
{
|
||||
var emailSetup = Config.Get(c => c.EmailSetup);
|
||||
foreach (var widget in _providerWidgets)
|
||||
if (widget.ProviderType == emailSetup.ProviderType)
|
||||
{
|
||||
if (widget.ProviderType == emailSetup.ProviderType)
|
||||
if (widget.ProviderType == EmailProviderType.System)
|
||||
{
|
||||
if (widget.ProviderType == EmailProviderType.System)
|
||||
{
|
||||
// System providers need additional logic since there may be more than one
|
||||
if (widget.ProviderName == emailSetup.SystemProviderName
|
||||
|| string.IsNullOrEmpty(emailSetup.SystemProviderName) && widget.ProviderName == _defaultSystemClientName)
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
else
|
||||
// System providers need additional logic since there may be more than one
|
||||
if (widget.ProviderName == emailSetup.SystemProviderName
|
||||
|| string.IsNullOrEmpty(emailSetup.SystemProviderName) && widget.ProviderName == _defaultSystemClientName)
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +1,74 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
partial class FHueSaturation : ImageForm
|
||||
{
|
||||
partial class FHueSaturation : ImageForm
|
||||
public FHueSaturation(ImageContext imageContext)
|
||||
: base(imageContext)
|
||||
{
|
||||
public FHueSaturation(ImageContext imageContext)
|
||||
: base(imageContext)
|
||||
{
|
||||
InitializeComponent();
|
||||
ActiveControl = txtHue;
|
||||
}
|
||||
|
||||
public HueTransform HueTransform { get; private set; } = new HueTransform();
|
||||
|
||||
public SaturationTransform SaturationTransform { get; private set; } = new SaturationTransform();
|
||||
|
||||
protected override IEnumerable<Transform> Transforms => new Transform[] { HueTransform, SaturationTransform };
|
||||
|
||||
protected override PictureBox PictureBox => pictureBox;
|
||||
|
||||
protected override void ResetTransform()
|
||||
{
|
||||
HueTransform = new HueTransform();
|
||||
SaturationTransform = new SaturationTransform();
|
||||
tbHue.Value = 0;
|
||||
tbSaturation.Value = 0;
|
||||
txtHue.Text = tbHue.Value.ToString("G");
|
||||
txtSaturation.Text = tbSaturation.Value.ToString("G");
|
||||
}
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
HueTransform = new HueTransform(tbHue.Value);
|
||||
SaturationTransform = new SaturationTransform(tbSaturation.Value);
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
private void txtHue_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (int.TryParse(txtHue.Text, out int value))
|
||||
{
|
||||
if (value >= tbHue.Minimum && value <= tbHue.Maximum)
|
||||
{
|
||||
tbHue.Value = value;
|
||||
}
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbHue_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
txtHue.Text = tbHue.Value.ToString("G");
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void txtSaturation_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (int.TryParse(txtSaturation.Text, out int value))
|
||||
{
|
||||
if (value >= tbSaturation.Minimum && value <= tbSaturation.Maximum)
|
||||
{
|
||||
tbSaturation.Value = value;
|
||||
}
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbSaturation_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
txtSaturation.Text = tbSaturation.Value.ToString("G");
|
||||
UpdateTransform();
|
||||
}
|
||||
InitializeComponent();
|
||||
ActiveControl = txtHue;
|
||||
}
|
||||
}
|
||||
|
||||
public HueTransform HueTransform { get; private set; } = new HueTransform();
|
||||
|
||||
public SaturationTransform SaturationTransform { get; private set; } = new SaturationTransform();
|
||||
|
||||
protected override IEnumerable<Transform> Transforms => new Transform[] { HueTransform, SaturationTransform };
|
||||
|
||||
protected override PictureBox PictureBox => pictureBox;
|
||||
|
||||
protected override void ResetTransform()
|
||||
{
|
||||
HueTransform = new HueTransform();
|
||||
SaturationTransform = new SaturationTransform();
|
||||
tbHue.Value = 0;
|
||||
tbSaturation.Value = 0;
|
||||
txtHue.Text = tbHue.Value.ToString("G");
|
||||
txtSaturation.Text = tbSaturation.Value.ToString("G");
|
||||
}
|
||||
|
||||
private void UpdateTransform()
|
||||
{
|
||||
HueTransform = new HueTransform(tbHue.Value);
|
||||
SaturationTransform = new SaturationTransform(tbSaturation.Value);
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
private void txtHue_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (int.TryParse(txtHue.Text, out int value))
|
||||
{
|
||||
if (value >= tbHue.Minimum && value <= tbHue.Maximum)
|
||||
{
|
||||
tbHue.Value = value;
|
||||
}
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbHue_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
txtHue.Text = tbHue.Value.ToString("G");
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void txtSaturation_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (int.TryParse(txtSaturation.Text, out int value))
|
||||
{
|
||||
if (value >= tbSaturation.Minimum && value <= tbSaturation.Maximum)
|
||||
{
|
||||
tbSaturation.Value = value;
|
||||
}
|
||||
}
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
private void tbSaturation_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
txtSaturation.Text = tbSaturation.Value.ToString("G");
|
||||
UpdateTransform();
|
||||
}
|
||||
}
|
@ -1,92 +1,91 @@
|
||||
using System.Windows.Forms;
|
||||
using NAPS2.Ocr;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FOcrLanguageDownload : FormBase
|
||||
{
|
||||
public partial class FOcrLanguageDownload : FormBase
|
||||
private readonly TesseractLanguageManager _tesseractLanguageManager;
|
||||
|
||||
public FOcrLanguageDownload(TesseractLanguageManager tesseractLanguageManager)
|
||||
{
|
||||
private readonly TesseractLanguageManager _tesseractLanguageManager;
|
||||
_tesseractLanguageManager = tesseractLanguageManager;
|
||||
InitializeComponent();
|
||||
|
||||
public FOcrLanguageDownload(TesseractLanguageManager tesseractLanguageManager)
|
||||
var initialSelection = new HashSet<string>();
|
||||
// TODO: We used to select old installed languages here, maybe we could do it again if we get new lang data
|
||||
if (!_tesseractLanguageManager.InstalledLanguages.Any())
|
||||
{
|
||||
_tesseractLanguageManager = tesseractLanguageManager;
|
||||
InitializeComponent();
|
||||
// Fresh install, so pre-select English as a sensible default
|
||||
initialSelection.Add("ocr-eng");
|
||||
}
|
||||
|
||||
var initialSelection = new HashSet<string>();
|
||||
// TODO: We used to select old installed languages here, maybe we could do it again if we get new lang data
|
||||
if (!_tesseractLanguageManager.InstalledLanguages.Any())
|
||||
// Populate the list of language options
|
||||
// Special case for English: sorted to the top of the list
|
||||
var languageOptions = _tesseractLanguageManager.NotInstalledLanguages
|
||||
.OrderBy(x => x.Code == "eng" ? "AAA" : x.Name);
|
||||
foreach (var languageOption in languageOptions)
|
||||
{
|
||||
var item = new ListViewItem { Text = languageOption.Name, Tag = languageOption.Code };
|
||||
if (initialSelection.Contains($"ocr-{languageOption.Code}"))
|
||||
{
|
||||
// Fresh install, so pre-select English as a sensible default
|
||||
initialSelection.Add("ocr-eng");
|
||||
item.Checked = true;
|
||||
}
|
||||
|
||||
// Populate the list of language options
|
||||
// Special case for English: sorted to the top of the list
|
||||
var languageOptions = _tesseractLanguageManager.NotInstalledLanguages
|
||||
.OrderBy(x => x.Code == "eng" ? "AAA" : x.Name);
|
||||
foreach (var languageOption in languageOptions)
|
||||
{
|
||||
var item = new ListViewItem { Text = languageOption.Name, Tag = languageOption.Code };
|
||||
if (initialSelection.Contains($"ocr-{languageOption.Code}"))
|
||||
{
|
||||
item.Checked = true;
|
||||
}
|
||||
lvLanguages.Items.Add(item);
|
||||
}
|
||||
|
||||
UpdateView();
|
||||
lvLanguages.Items.Add(item);
|
||||
}
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(lvLanguages)
|
||||
.WidthToForm()
|
||||
.HeightToForm()
|
||||
.Bind(labelSizeEstimate, btnCancel, btnDownload)
|
||||
.BottomToForm()
|
||||
.Bind(btnCancel, btnDownload)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
var selectedLanguages = SelectedLanguages;
|
||||
double downloadSize = _tesseractLanguageManager.LanguageComponents.Where(x => selectedLanguages.Contains(x.Id)).Select(x => x.DownloadInfo.Size).Sum();
|
||||
|
||||
labelSizeEstimate.Text = string.Format(MiscResources.EstimatedDownloadSize, downloadSize.ToString("f1"));
|
||||
|
||||
btnDownload.Enabled = lvLanguages.Items.Cast<ListViewItem>().Any(x => x.Checked);
|
||||
}
|
||||
|
||||
private HashSet<string> SelectedLanguages
|
||||
{
|
||||
get { return new HashSet<string>(lvLanguages.Items.Cast<ListViewItem>().Where(x => x.Checked).Select(x => $"ocr-{x.Tag}")); }
|
||||
}
|
||||
|
||||
private void lvLanguages_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnDownload_Click(object sender, EventArgs e)
|
||||
{
|
||||
var progressForm = FormFactory.Create<FDownloadProgress>();
|
||||
|
||||
var selectedLanguages = SelectedLanguages;
|
||||
foreach (var langComponent in _tesseractLanguageManager.LanguageComponents.Where(x => selectedLanguages.Contains(x.Id)))
|
||||
{
|
||||
progressForm.QueueFile(langComponent);
|
||||
}
|
||||
|
||||
Close();
|
||||
progressForm.ShowDialog();
|
||||
}
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(lvLanguages)
|
||||
.WidthToForm()
|
||||
.HeightToForm()
|
||||
.Bind(labelSizeEstimate, btnCancel, btnDownload)
|
||||
.BottomToForm()
|
||||
.Bind(btnCancel, btnDownload)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
var selectedLanguages = SelectedLanguages;
|
||||
double downloadSize = _tesseractLanguageManager.LanguageComponents.Where(x => selectedLanguages.Contains(x.Id)).Select(x => x.DownloadInfo.Size).Sum();
|
||||
|
||||
labelSizeEstimate.Text = string.Format(MiscResources.EstimatedDownloadSize, downloadSize.ToString("f1"));
|
||||
|
||||
btnDownload.Enabled = lvLanguages.Items.Cast<ListViewItem>().Any(x => x.Checked);
|
||||
}
|
||||
|
||||
private HashSet<string> SelectedLanguages
|
||||
{
|
||||
get { return new HashSet<string>(lvLanguages.Items.Cast<ListViewItem>().Where(x => x.Checked).Select(x => $"ocr-{x.Tag}")); }
|
||||
}
|
||||
|
||||
private void lvLanguages_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnDownload_Click(object sender, EventArgs e)
|
||||
{
|
||||
var progressForm = FormFactory.Create<FDownloadProgress>();
|
||||
|
||||
var selectedLanguages = SelectedLanguages;
|
||||
foreach (var langComponent in _tesseractLanguageManager.LanguageComponents.Where(x => selectedLanguages.Contains(x.Id)))
|
||||
{
|
||||
progressForm.QueueFile(langComponent);
|
||||
}
|
||||
|
||||
Close();
|
||||
progressForm.ShowDialog();
|
||||
}
|
||||
}
|
@ -1,37 +1,36 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FPdfPassword : FormBase
|
||||
{
|
||||
public partial class FPdfPassword : FormBase
|
||||
public FPdfPassword()
|
||||
{
|
||||
public FPdfPassword()
|
||||
{
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnOK;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string Password { get; private set; }
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
lblPrompt.Text = string.Format(lblPrompt.Text, FileName);
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
Password = txtPassword.Text;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnOK;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
}
|
||||
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string Password { get; private set; }
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
lblPrompt.Text = string.Format(lblPrompt.Text, FileName);
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
Password = txtPassword.Text;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
@ -1,98 +1,97 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FProgress : FormBase
|
||||
{
|
||||
public partial class FProgress : FormBase
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private readonly OperationProgress _operationProgress;
|
||||
|
||||
private volatile bool _loaded;
|
||||
private volatile bool _background;
|
||||
private IOperation _operation;
|
||||
|
||||
public FProgress(ErrorOutput errorOutput, OperationProgress operationProgress)
|
||||
{
|
||||
private readonly ErrorOutput _errorOutput;
|
||||
private readonly OperationProgress _operationProgress;
|
||||
_errorOutput = errorOutput;
|
||||
_operationProgress = operationProgress;
|
||||
InitializeComponent();
|
||||
|
||||
private volatile bool _loaded;
|
||||
private volatile bool _background;
|
||||
private IOperation _operation;
|
||||
RestoreFormState = false;
|
||||
}
|
||||
|
||||
public FProgress(ErrorOutput errorOutput, OperationProgress operationProgress)
|
||||
public IOperation Operation
|
||||
{
|
||||
get => _operation;
|
||||
set
|
||||
{
|
||||
_errorOutput = errorOutput;
|
||||
_operationProgress = operationProgress;
|
||||
InitializeComponent();
|
||||
|
||||
RestoreFormState = false;
|
||||
_operation = value;
|
||||
_operation.StatusChanged += operation_StatusChanged;
|
||||
_operation.Finished += operation_Finished;
|
||||
btnCancel.Visible = _operation.AllowCancel;
|
||||
}
|
||||
}
|
||||
|
||||
public IOperation Operation
|
||||
void operation_StatusChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_loaded && !_background)
|
||||
{
|
||||
get => _operation;
|
||||
set
|
||||
{
|
||||
_operation = value;
|
||||
_operation.StatusChanged += operation_StatusChanged;
|
||||
_operation.Finished += operation_Finished;
|
||||
btnCancel.Visible = _operation.AllowCancel;
|
||||
}
|
||||
SafeInvoke(DisplayProgress);
|
||||
}
|
||||
}
|
||||
|
||||
void operation_StatusChanged(object sender, EventArgs e)
|
||||
void operation_Finished(object sender, EventArgs e)
|
||||
{
|
||||
if (_loaded && !_background)
|
||||
{
|
||||
if (_loaded && !_background)
|
||||
{
|
||||
SafeInvoke(DisplayProgress);
|
||||
}
|
||||
SafeInvoke(Close);
|
||||
}
|
||||
}
|
||||
|
||||
void operation_Finished(object sender, EventArgs e)
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
_loaded = true;
|
||||
Text = _operation.ProgressTitle;
|
||||
btnRunInBG.Visible = _operation.AllowBackground;
|
||||
|
||||
DisplayProgress();
|
||||
if (_operation.IsFinished)
|
||||
{
|
||||
if (_loaded && !_background)
|
||||
{
|
||||
SafeInvoke(Close);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
_loaded = true;
|
||||
Text = _operation.ProgressTitle;
|
||||
btnRunInBG.Visible = _operation.AllowBackground;
|
||||
|
||||
DisplayProgress();
|
||||
if (_operation.IsFinished)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayProgress()
|
||||
{
|
||||
WinFormsOperationProgress.RenderStatus(Operation, labelStatus, labelNumber, progressBar);
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
TryCancelOp();
|
||||
}
|
||||
|
||||
private void FDownloadProgress_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!_operation.IsFinished && !_background)
|
||||
{
|
||||
TryCancelOp();
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryCancelOp()
|
||||
{
|
||||
if (Operation.AllowCancel)
|
||||
{
|
||||
Operation.Cancel();
|
||||
btnCancel.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnRunInBG_Click(object sender, EventArgs e)
|
||||
{
|
||||
_background = true;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayProgress()
|
||||
{
|
||||
WinFormsOperationProgress.RenderStatus(Operation, labelStatus, labelNumber, progressBar);
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
TryCancelOp();
|
||||
}
|
||||
|
||||
private void FDownloadProgress_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (!_operation.IsFinished && !_background)
|
||||
{
|
||||
TryCancelOp();
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryCancelOp()
|
||||
{
|
||||
if (Operation.AllowCancel)
|
||||
{
|
||||
Operation.Cancel();
|
||||
btnCancel.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnRunInBG_Click(object sender, EventArgs e)
|
||||
{
|
||||
_background = true;
|
||||
Close();
|
||||
}
|
||||
}
|
@ -1,38 +1,37 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FRecover : FormBase
|
||||
{
|
||||
public partial class FRecover : FormBase
|
||||
public FRecover()
|
||||
{
|
||||
public FRecover()
|
||||
{
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnRecover;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
public void SetData(int imageCount, DateTime scannedDateTime)
|
||||
{
|
||||
lblPrompt.Text = string.Format(lblPrompt.Text, imageCount, scannedDateTime.ToShortDateString(), scannedDateTime.ToShortTimeString());
|
||||
}
|
||||
|
||||
private void btnDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.No;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnRecover_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Yes;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnRecover;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetData(int imageCount, DateTime scannedDateTime)
|
||||
{
|
||||
lblPrompt.Text = string.Format(lblPrompt.Text, imageCount, scannedDateTime.ToShortDateString(), scannedDateTime.ToShortTimeString());
|
||||
}
|
||||
|
||||
private void btnDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.No;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnRecover_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Yes;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
@ -1,64 +1,63 @@
|
||||
using System.Windows.Forms;
|
||||
using NAPS2.Scan;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class FSelectDevice : FormBase
|
||||
{
|
||||
public partial class FSelectDevice : FormBase
|
||||
public FSelectDevice()
|
||||
{
|
||||
public FSelectDevice()
|
||||
SaveFormState = false;
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnSelect;
|
||||
CancelButton = btnCancel;
|
||||
}
|
||||
|
||||
public List<ScanDevice> DeviceList { get; set; }
|
||||
|
||||
public ScanDevice? SelectedDevice { get; private set; }
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(listboxDevices)
|
||||
.WidthToForm()
|
||||
.HeightToForm()
|
||||
.Bind(btnSelect, btnCancel)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
|
||||
foreach (var device in DeviceList)
|
||||
{
|
||||
SaveFormState = false;
|
||||
RestoreFormState = false;
|
||||
InitializeComponent();
|
||||
AcceptButton = btnSelect;
|
||||
CancelButton = btnCancel;
|
||||
listboxDevices.Items.Add(device);
|
||||
}
|
||||
|
||||
public List<ScanDevice> DeviceList { get; set; }
|
||||
|
||||
public ScanDevice? SelectedDevice { get; private set; }
|
||||
|
||||
protected override void OnLoad(object sender, EventArgs eventArgs)
|
||||
if (listboxDevices.Items.Count > 0)
|
||||
{
|
||||
new LayoutManager(this)
|
||||
.Bind(listboxDevices)
|
||||
.WidthToForm()
|
||||
.HeightToForm()
|
||||
.Bind(btnSelect, btnCancel)
|
||||
.RightToForm()
|
||||
.Activate();
|
||||
|
||||
foreach (var device in DeviceList)
|
||||
{
|
||||
listboxDevices.Items.Add(device);
|
||||
}
|
||||
if (listboxDevices.Items.Count > 0)
|
||||
{
|
||||
listboxDevices.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void listboxDevices_Format(object sender, ListControlConvertEventArgs e)
|
||||
{
|
||||
e.Value = ((ScanDevice)e.ListItem).Name;
|
||||
}
|
||||
|
||||
private void btnSelect_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listboxDevices.SelectedItem == null)
|
||||
{
|
||||
listboxDevices.Focus();
|
||||
return;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
SelectedDevice = ((ScanDevice) listboxDevices.SelectedItem);
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
listboxDevices.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void listboxDevices_Format(object sender, ListControlConvertEventArgs e)
|
||||
{
|
||||
e.Value = ((ScanDevice)e.ListItem).Name;
|
||||
}
|
||||
|
||||
private void btnSelect_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listboxDevices.SelectedItem == null)
|
||||
{
|
||||
listboxDevices.Focus();
|
||||
return;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
SelectedDevice = ((ScanDevice) listboxDevices.SelectedItem);
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,18 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class ILProfileIcons : Component
|
||||
{
|
||||
public partial class ILProfileIcons : Component
|
||||
public ILProfileIcons()
|
||||
{
|
||||
public ILProfileIcons()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public ILProfileIcons(IContainer container)
|
||||
{
|
||||
container.Add(this);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
public ILProfileIcons(IContainer container)
|
||||
{
|
||||
container.Add(this);
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
@ -3,180 +3,179 @@ using System.Windows.Forms;
|
||||
using NAPS2.Images.Gdi;
|
||||
using Timer = System.Threading.Timer;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class ImageForm : FormBase
|
||||
{
|
||||
public partial class ImageForm : FormBase
|
||||
private readonly ImageContext _imageContext;
|
||||
|
||||
protected Bitmap workingImage, workingImage2;
|
||||
private bool _initComplete;
|
||||
private bool _previewOutOfDate;
|
||||
private bool _working;
|
||||
private Timer _previewTimer;
|
||||
private bool _closed;
|
||||
|
||||
private ImageForm()
|
||||
{
|
||||
private readonly ImageContext _imageContext;
|
||||
// For the designer only
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected Bitmap workingImage, workingImage2;
|
||||
private bool _initComplete;
|
||||
private bool _previewOutOfDate;
|
||||
private bool _working;
|
||||
private Timer _previewTimer;
|
||||
private bool _closed;
|
||||
protected ImageForm(ImageContext imageContext)
|
||||
{
|
||||
_imageContext = imageContext;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private ImageForm()
|
||||
public UiImage Image { get; set; }
|
||||
|
||||
public List<UiImage> SelectedImages { get; set; }
|
||||
|
||||
protected virtual IEnumerable<Transform> Transforms => throw new NotImplementedException();
|
||||
|
||||
protected virtual PictureBox PictureBox => throw new NotImplementedException();
|
||||
|
||||
private bool TransformMultiple => SelectedImages != null && checkboxApplyToSelected.Checked;
|
||||
|
||||
private IEnumerable<UiImage> ImagesToTransform => TransformMultiple ? SelectedImages : Enumerable.Repeat(Image, 1);
|
||||
|
||||
protected virtual Bitmap RenderPreview()
|
||||
{
|
||||
var result = (Bitmap)workingImage.Clone();
|
||||
foreach (var transform in Transforms)
|
||||
{
|
||||
// For the designer only
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected ImageForm(ImageContext imageContext)
|
||||
{
|
||||
_imageContext = imageContext;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public UiImage Image { get; set; }
|
||||
|
||||
public List<UiImage> SelectedImages { get; set; }
|
||||
|
||||
protected virtual IEnumerable<Transform> Transforms => throw new NotImplementedException();
|
||||
|
||||
protected virtual PictureBox PictureBox => throw new NotImplementedException();
|
||||
|
||||
private bool TransformMultiple => SelectedImages != null && checkboxApplyToSelected.Checked;
|
||||
|
||||
private IEnumerable<UiImage> ImagesToTransform => TransformMultiple ? SelectedImages : Enumerable.Repeat(Image, 1);
|
||||
|
||||
protected virtual Bitmap RenderPreview()
|
||||
{
|
||||
var result = (Bitmap)workingImage.Clone();
|
||||
foreach (var transform in Transforms)
|
||||
if (!transform.IsNull)
|
||||
{
|
||||
if (!transform.IsNull)
|
||||
{
|
||||
// TODO: Maybe the working images etc. should be storage
|
||||
result = ((GdiImage)_imageContext.PerformTransform(new GdiImage(result), transform)).Bitmap;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual void InitTransform()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void ResetTransform()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void TransformSaved()
|
||||
{
|
||||
}
|
||||
|
||||
private async void ImageForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
checkboxApplyToSelected.BringToFront();
|
||||
btnRevert.BringToFront();
|
||||
btnCancel.BringToFront();
|
||||
btnOK.BringToFront();
|
||||
if (SelectedImages != null && SelectedImages.Count > 1)
|
||||
{
|
||||
checkboxApplyToSelected.Text = string.Format(checkboxApplyToSelected.Text, SelectedImages.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConditionalControls.Hide(checkboxApplyToSelected, 6);
|
||||
}
|
||||
|
||||
Size = new Size(600, 600);
|
||||
|
||||
var maxDimen = Screen.AllScreens.Max(s => Math.Max(s.WorkingArea.Height, s.WorkingArea.Width));
|
||||
// TODO: Limit to maxDimen * 2
|
||||
using var imageToRender = Image.GetClonedImage();
|
||||
// TODO: More generic or avoid the cast somehow? In general how do we integrate with eto?
|
||||
workingImage = ((GdiImageContext)_imageContext).RenderToBitmap(imageToRender);
|
||||
if (_closed)
|
||||
{
|
||||
workingImage?.Dispose();
|
||||
return;
|
||||
}
|
||||
workingImage2 = (Bitmap)workingImage.Clone();
|
||||
|
||||
InitTransform();
|
||||
lock (this)
|
||||
{
|
||||
_initComplete = true;
|
||||
}
|
||||
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
protected void UpdatePreviewBox()
|
||||
{
|
||||
if (_previewTimer == null)
|
||||
{
|
||||
_previewTimer = new Timer(_ =>
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!_initComplete || !IsHandleCreated || !_previewOutOfDate || _working) return;
|
||||
_working = true;
|
||||
_previewOutOfDate = false;
|
||||
}
|
||||
var bitmap = RenderPreview();
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
PictureBox.Image?.Dispose();
|
||||
PictureBox.Image = bitmap;
|
||||
});
|
||||
lock (this)
|
||||
{
|
||||
_working = false;
|
||||
}
|
||||
}, null, 0, 100);
|
||||
}
|
||||
lock (this)
|
||||
{
|
||||
_previewOutOfDate = true;
|
||||
// TODO: Maybe the working images etc. should be storage
|
||||
result = ((GdiImage)_imageContext.PerformTransform(new GdiImage(result), transform)).Bitmap;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
protected virtual void InitTransform()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void ResetTransform()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void TransformSaved()
|
||||
{
|
||||
}
|
||||
|
||||
private async void ImageForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
checkboxApplyToSelected.BringToFront();
|
||||
btnRevert.BringToFront();
|
||||
btnCancel.BringToFront();
|
||||
btnOK.BringToFront();
|
||||
if (SelectedImages != null && SelectedImages.Count > 1)
|
||||
{
|
||||
Close();
|
||||
checkboxApplyToSelected.Text = string.Format(checkboxApplyToSelected.Text, SelectedImages.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConditionalControls.Hide(checkboxApplyToSelected, 6);
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Transforms.Any(x => !x.IsNull))
|
||||
{
|
||||
foreach (var img in ImagesToTransform)
|
||||
{
|
||||
lock (img)
|
||||
{
|
||||
foreach (var t in Transforms)
|
||||
{
|
||||
img.AddTransform(t);
|
||||
}
|
||||
// Optimize thumbnail rendering for the first (or only) image since we already have it loaded into memory
|
||||
if (img == Image)
|
||||
{
|
||||
var transformed = _imageContext.PerformAllTransforms(new GdiImage(workingImage).Clone(), Transforms);
|
||||
img.SetThumbnail(_imageContext.PerformTransform(transformed, new ThumbnailTransform(Config.Get(c => c.ThumbnailSize))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TransformSaved();
|
||||
Close();
|
||||
}
|
||||
Size = new Size(600, 600);
|
||||
|
||||
private void btnRevert_Click(object sender, EventArgs e)
|
||||
{
|
||||
ResetTransform();
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
private void ImageForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
var maxDimen = Screen.AllScreens.Max(s => Math.Max(s.WorkingArea.Height, s.WorkingArea.Width));
|
||||
// TODO: Limit to maxDimen * 2
|
||||
using var imageToRender = Image.GetClonedImage();
|
||||
// TODO: More generic or avoid the cast somehow? In general how do we integrate with eto?
|
||||
workingImage = ((GdiImageContext)_imageContext).RenderToBitmap(imageToRender);
|
||||
if (_closed)
|
||||
{
|
||||
workingImage?.Dispose();
|
||||
workingImage2?.Dispose();
|
||||
PictureBox.Image?.Dispose();
|
||||
_previewTimer?.Dispose();
|
||||
_closed = true;
|
||||
return;
|
||||
}
|
||||
workingImage2 = (Bitmap)workingImage.Clone();
|
||||
|
||||
InitTransform();
|
||||
lock (this)
|
||||
{
|
||||
_initComplete = true;
|
||||
}
|
||||
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
protected void UpdatePreviewBox()
|
||||
{
|
||||
if (_previewTimer == null)
|
||||
{
|
||||
_previewTimer = new Timer(_ =>
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!_initComplete || !IsHandleCreated || !_previewOutOfDate || _working) return;
|
||||
_working = true;
|
||||
_previewOutOfDate = false;
|
||||
}
|
||||
var bitmap = RenderPreview();
|
||||
SafeInvoke(() =>
|
||||
{
|
||||
PictureBox.Image?.Dispose();
|
||||
PictureBox.Image = bitmap;
|
||||
});
|
||||
lock (this)
|
||||
{
|
||||
_working = false;
|
||||
}
|
||||
}, null, 0, 100);
|
||||
}
|
||||
lock (this)
|
||||
{
|
||||
_previewOutOfDate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Transforms.Any(x => !x.IsNull))
|
||||
{
|
||||
foreach (var img in ImagesToTransform)
|
||||
{
|
||||
lock (img)
|
||||
{
|
||||
foreach (var t in Transforms)
|
||||
{
|
||||
img.AddTransform(t);
|
||||
}
|
||||
// Optimize thumbnail rendering for the first (or only) image since we already have it loaded into memory
|
||||
if (img == Image)
|
||||
{
|
||||
var transformed = _imageContext.PerformAllTransforms(new GdiImage(workingImage).Clone(), Transforms);
|
||||
img.SetThumbnail(_imageContext.PerformTransform(transformed, new ThumbnailTransform(Config.Get(c => c.ThumbnailSize))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TransformSaved();
|
||||
Close();
|
||||
}
|
||||
|
||||
private void btnRevert_Click(object sender, EventArgs e)
|
||||
{
|
||||
ResetTransform();
|
||||
UpdatePreviewBox();
|
||||
}
|
||||
|
||||
private void ImageForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
workingImage?.Dispose();
|
||||
workingImage2?.Dispose();
|
||||
PictureBox.Image?.Dispose();
|
||||
_previewTimer?.Dispose();
|
||||
_closed = true;
|
||||
}
|
||||
}
|
@ -1,74 +1,73 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public partial class OperationProgressNotifyWidget : NotifyWidgetBase
|
||||
{
|
||||
public partial class OperationProgressNotifyWidget : NotifyWidgetBase
|
||||
private readonly OperationProgress _operationProgress;
|
||||
private readonly IOperation _op;
|
||||
|
||||
public OperationProgressNotifyWidget(OperationProgress operationProgress, IOperation op)
|
||||
{
|
||||
private readonly OperationProgress _operationProgress;
|
||||
private readonly IOperation _op;
|
||||
InitializeComponent();
|
||||
|
||||
public OperationProgressNotifyWidget(OperationProgress operationProgress, IOperation op)
|
||||
_operationProgress = operationProgress;
|
||||
_op = op;
|
||||
|
||||
cancelToolStripMenuItem.Visible = op.AllowCancel;
|
||||
op.StatusChanged += Op_StatusChanged;
|
||||
op.Finished += Op_Finished;
|
||||
}
|
||||
|
||||
public override void ShowNotify() => DisplayProgress();
|
||||
|
||||
public override NotifyWidgetBase Clone() => new OperationProgressNotifyWidget(_operationProgress, _op);
|
||||
|
||||
private void DisplayProgress()
|
||||
{
|
||||
var lblNumberRight = lblNumber.Right;
|
||||
WinFormsOperationProgress.RenderStatus(_op, lblTitle, lblNumber, progressBar);
|
||||
if (_op.Status?.IndeterminateProgress != true)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_operationProgress = operationProgress;
|
||||
_op = op;
|
||||
|
||||
cancelToolStripMenuItem.Visible = op.AllowCancel;
|
||||
op.StatusChanged += Op_StatusChanged;
|
||||
op.Finished += Op_Finished;
|
||||
// Don't display the number if the progress bar is precise
|
||||
// Otherwise, the widget will be too cluttered
|
||||
// The number is only shown for OcrOperation at the moment
|
||||
lblNumber.Text = "";
|
||||
}
|
||||
lblNumber.Left = lblNumberRight - lblNumber.Width;
|
||||
Width = Math.Max(Width, lblTitle.Width + lblNumber.Width + 22);
|
||||
Height = Math.Max(Height, lblTitle.Height + 35);
|
||||
}
|
||||
|
||||
public override void ShowNotify() => DisplayProgress();
|
||||
private void DoHideNotify()
|
||||
{
|
||||
_op.StatusChanged -= Op_StatusChanged;
|
||||
_op.Finished -= Op_Finished;
|
||||
InvokeHideNotify();
|
||||
}
|
||||
|
||||
public override NotifyWidgetBase Clone() => new OperationProgressNotifyWidget(_operationProgress, _op);
|
||||
private void Op_StatusChanged(object sender, EventArgs e)
|
||||
{
|
||||
SafeInvoke(DisplayProgress);
|
||||
}
|
||||
|
||||
private void DisplayProgress()
|
||||
{
|
||||
var lblNumberRight = lblNumber.Right;
|
||||
WinFormsOperationProgress.RenderStatus(_op, lblTitle, lblNumber, progressBar);
|
||||
if (_op.Status?.IndeterminateProgress != true)
|
||||
{
|
||||
// Don't display the number if the progress bar is precise
|
||||
// Otherwise, the widget will be too cluttered
|
||||
// The number is only shown for OcrOperation at the moment
|
||||
lblNumber.Text = "";
|
||||
}
|
||||
lblNumber.Left = lblNumberRight - lblNumber.Width;
|
||||
Width = Math.Max(Width, lblTitle.Width + lblNumber.Width + 22);
|
||||
Height = Math.Max(Height, lblTitle.Height + 35);
|
||||
}
|
||||
private void Op_Finished(object sender, EventArgs e)
|
||||
{
|
||||
DoHideNotify();
|
||||
}
|
||||
|
||||
private void DoHideNotify()
|
||||
{
|
||||
_op.StatusChanged -= Op_StatusChanged;
|
||||
_op.Finished -= Op_Finished;
|
||||
InvokeHideNotify();
|
||||
}
|
||||
private void cancelToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
_op.Cancel();
|
||||
cancelToolStripMenuItem.Enabled = false;
|
||||
}
|
||||
|
||||
private void Op_StatusChanged(object sender, EventArgs e)
|
||||
{
|
||||
SafeInvoke(DisplayProgress);
|
||||
}
|
||||
|
||||
private void Op_Finished(object sender, EventArgs e)
|
||||
private void OperationProgressNotifyWidget_Click(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
DoHideNotify();
|
||||
}
|
||||
|
||||
private void cancelToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
_op.Cancel();
|
||||
cancelToolStripMenuItem.Enabled = false;
|
||||
}
|
||||
|
||||
private void OperationProgressNotifyWidget_Click(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
DoHideNotify();
|
||||
_operationProgress.ShowModalProgress(_op);
|
||||
}
|
||||
_operationProgress.ShowModalProgress(_op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,173 +2,172 @@ using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace NAPS2.WinForms
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public class TiffViewer : UserControl
|
||||
{
|
||||
public class TiffViewer : UserControl
|
||||
private readonly Container _components = null;
|
||||
|
||||
private Image _image;
|
||||
private PictureBox _pbox;
|
||||
private double _xzoom;
|
||||
|
||||
public TiffViewer()
|
||||
{
|
||||
private readonly Container _components = null;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private Image _image;
|
||||
private PictureBox _pbox;
|
||||
private double _xzoom;
|
||||
|
||||
public TiffViewer()
|
||||
public Image Image
|
||||
{
|
||||
set
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public Image Image
|
||||
{
|
||||
set
|
||||
if (value != null)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
_image = value;
|
||||
Zoom = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearImage();
|
||||
_image = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ImageWidth => _image?.Width ?? 0;
|
||||
|
||||
public int ImageHeight => _image?.Height ?? 0;
|
||||
|
||||
public double Zoom
|
||||
{
|
||||
set
|
||||
{
|
||||
if (_image != null)
|
||||
{
|
||||
double maxZoom = Math.Sqrt(1e8 / (_image.Width * (double) _image.Height)) * 100;
|
||||
_xzoom = Math.Max(Math.Min(value, maxZoom), 10);
|
||||
double displayWidth = _image.Width * (_xzoom / 100);
|
||||
double displayHeight = _image.Height * (_xzoom / 100);
|
||||
if (_image.HorizontalResolution > 0 && _image.VerticalResolution > 0)
|
||||
{
|
||||
displayHeight *= _image.HorizontalResolution / (double)_image.VerticalResolution;
|
||||
}
|
||||
_pbox.Image = _image;
|
||||
_pbox.BorderStyle = BorderStyle.FixedSingle;
|
||||
_pbox.Width = (int)displayWidth;
|
||||
_pbox.Height = (int)displayHeight;
|
||||
if (ZoomChanged != null)
|
||||
{
|
||||
_pbox.Cursor = HorizontalScroll.Visible || VerticalScroll.Visible ? Cursors.Hand : Cursors.Default;
|
||||
ZoomChanged.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
get => _xzoom;
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ZoomChanged;
|
||||
|
||||
private void ClearImage()
|
||||
{
|
||||
_pbox.Image = Icons.hourglass_grey;
|
||||
_pbox.BorderStyle = BorderStyle.None;
|
||||
_pbox.Width = 32;
|
||||
_pbox.Height = 32;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_components?.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
if (ModifierKeys.HasFlag(Keys.Control))
|
||||
{
|
||||
StepZoom(e.Delta / (double)SystemInformation.MouseWheelScrollDelta);
|
||||
_image = value;
|
||||
Zoom = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
ClearImage();
|
||||
_image = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.OemMinus:
|
||||
if (e.Control)
|
||||
{
|
||||
StepZoom(-1);
|
||||
}
|
||||
break;
|
||||
case Keys.Oemplus:
|
||||
if (e.Control)
|
||||
{
|
||||
StepZoom(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void StepZoom(double steps)
|
||||
{
|
||||
Zoom = Math.Round(Zoom * Math.Pow(1.2, steps));
|
||||
}
|
||||
|
||||
private Point _mousePos;
|
||||
|
||||
private void pbox_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_mousePos = e.Location;
|
||||
}
|
||||
|
||||
private void pbox_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AutoScrollPosition = new Point(-AutoScrollPosition.X + _mousePos.X - e.X, -AutoScrollPosition.Y + _mousePos.Y - e.Y);
|
||||
}
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TiffViewer));
|
||||
this._pbox = new System.Windows.Forms.PictureBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this._pbox)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pbox
|
||||
//
|
||||
resources.ApplyResources(this._pbox, "_pbox");
|
||||
this._pbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this._pbox.Name = "_pbox";
|
||||
this._pbox.TabStop = false;
|
||||
this._pbox.SizeMode = PictureBoxSizeMode.Zoom;
|
||||
this._pbox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pbox_MouseDown);
|
||||
this._pbox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbox_MouseMove);
|
||||
//
|
||||
// TiffViewer
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.BackColor = System.Drawing.Color.LightGray;
|
||||
this.Controls.Add(this._pbox);
|
||||
this.Name = "TiffViewer";
|
||||
((System.ComponentModel.ISupportInitialize)(this._pbox)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
public int ImageWidth => _image?.Width ?? 0;
|
||||
|
||||
public int ImageHeight => _image?.Height ?? 0;
|
||||
|
||||
public double Zoom
|
||||
{
|
||||
set
|
||||
{
|
||||
if (_image != null)
|
||||
{
|
||||
double maxZoom = Math.Sqrt(1e8 / (_image.Width * (double) _image.Height)) * 100;
|
||||
_xzoom = Math.Max(Math.Min(value, maxZoom), 10);
|
||||
double displayWidth = _image.Width * (_xzoom / 100);
|
||||
double displayHeight = _image.Height * (_xzoom / 100);
|
||||
if (_image.HorizontalResolution > 0 && _image.VerticalResolution > 0)
|
||||
{
|
||||
displayHeight *= _image.HorizontalResolution / (double)_image.VerticalResolution;
|
||||
}
|
||||
_pbox.Image = _image;
|
||||
_pbox.BorderStyle = BorderStyle.FixedSingle;
|
||||
_pbox.Width = (int)displayWidth;
|
||||
_pbox.Height = (int)displayHeight;
|
||||
if (ZoomChanged != null)
|
||||
{
|
||||
_pbox.Cursor = HorizontalScroll.Visible || VerticalScroll.Visible ? Cursors.Hand : Cursors.Default;
|
||||
ZoomChanged.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
get => _xzoom;
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ZoomChanged;
|
||||
|
||||
private void ClearImage()
|
||||
{
|
||||
_pbox.Image = Icons.hourglass_grey;
|
||||
_pbox.BorderStyle = BorderStyle.None;
|
||||
_pbox.Width = 32;
|
||||
_pbox.Height = 32;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_components?.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
if (ModifierKeys.HasFlag(Keys.Control))
|
||||
{
|
||||
StepZoom(e.Delta / (double)SystemInformation.MouseWheelScrollDelta);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnMouseWheel(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
switch (e.KeyCode)
|
||||
{
|
||||
case Keys.OemMinus:
|
||||
if (e.Control)
|
||||
{
|
||||
StepZoom(-1);
|
||||
}
|
||||
break;
|
||||
case Keys.Oemplus:
|
||||
if (e.Control)
|
||||
{
|
||||
StepZoom(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void StepZoom(double steps)
|
||||
{
|
||||
Zoom = Math.Round(Zoom * Math.Pow(1.2, steps));
|
||||
}
|
||||
|
||||
private Point _mousePos;
|
||||
|
||||
private void pbox_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
_mousePos = e.Location;
|
||||
}
|
||||
|
||||
private void pbox_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
AutoScrollPosition = new Point(-AutoScrollPosition.X + _mousePos.X - e.X, -AutoScrollPosition.Y + _mousePos.Y - e.Y);
|
||||
}
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TiffViewer));
|
||||
this._pbox = new System.Windows.Forms.PictureBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this._pbox)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// pbox
|
||||
//
|
||||
resources.ApplyResources(this._pbox, "_pbox");
|
||||
this._pbox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this._pbox.Name = "_pbox";
|
||||
this._pbox.TabStop = false;
|
||||
this._pbox.SizeMode = PictureBoxSizeMode.Zoom;
|
||||
this._pbox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pbox_MouseDown);
|
||||
this._pbox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pbox_MouseMove);
|
||||
//
|
||||
// TiffViewer
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.BackColor = System.Drawing.Color.LightGray;
|
||||
this.Controls.Add(this._pbox);
|
||||
this.Name = "TiffViewer";
|
||||
((System.ComponentModel.ISupportInitialize)(this._pbox)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
Loading…
Reference in New Issue
Block a user