2040 lines
68 KiB
C#
2040 lines
68 KiB
C#
using Microsoft.Win32;
|
||
using SimPas2_Windows.Managers;
|
||
using System.Diagnostics;
|
||
using System.Globalization;
|
||
using System.Net;
|
||
using System.Xml.Linq;
|
||
using static System.Net.WebRequestMethods;
|
||
|
||
namespace SimPas2_Windows
|
||
{
|
||
public partial class SimPas2 : Form
|
||
{
|
||
private readonly PasswordManager mPassMan;
|
||
private readonly GeneratorManager mGenMan;
|
||
private readonly OtpManager mOtpMan;
|
||
private readonly PinManager mPinMan;
|
||
private readonly NoteManager mNoteMan;
|
||
private readonly QaManager mQaMan;
|
||
private readonly CreditcardManager mCcMan;
|
||
private readonly CryptoManager mCryptoMan;
|
||
|
||
private readonly CultureInfo cultureInfo;
|
||
|
||
private static readonly string mAppDataPath = Path.Combine(
|
||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||
"076Soft", "SimPas");
|
||
private static readonly string mDatabasePath = Path.Combine(mAppDataPath, "SimPas.db");
|
||
private readonly byte[] mEncryptionKey;
|
||
private System.Windows.Forms.Timer otpTimer;
|
||
|
||
private string mPwKeyword;
|
||
private string mOtpKeyword;
|
||
private string mPinKeyword;
|
||
private string mNoteKeyword;
|
||
private string mQaKeyword;
|
||
private string mCcKeyword;
|
||
private string mCryptoKeyword;
|
||
|
||
private string mJpLang;
|
||
|
||
public SimPas2()
|
||
{
|
||
using (MasterPasswordForm masterForm = new MasterPasswordForm(mDatabasePath))
|
||
{
|
||
if (masterForm.ShowDialog() != DialogResult.OK)
|
||
{
|
||
Environment.Exit(0);
|
||
}
|
||
|
||
mEncryptionKey = masterForm.EncryptionKey;
|
||
}
|
||
|
||
cultureInfo = Thread.CurrentThread.CurrentUICulture;
|
||
|
||
InitializeComponent();
|
||
mPassMan = new PasswordManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
mGenMan = new GeneratorManager();
|
||
mOtpMan = new OtpManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
mPinMan = new PinManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
mNoteMan = new NoteManager(mDatabasePath, cultureInfo.Name);
|
||
mQaMan = new QaManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
mCcMan = new CreditcardManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
mCryptoMan = new CryptoManager(mDatabasePath, mEncryptionKey, cultureInfo.Name);
|
||
|
||
mPwKeyword = "";
|
||
mOtpKeyword = "";
|
||
mPinKeyword = "";
|
||
mNoteKeyword = "";
|
||
mQaKeyword = "";
|
||
mCcKeyword = "";
|
||
mCryptoKeyword = "";
|
||
|
||
mJpLang = "ja-JP";
|
||
|
||
InitializeUI();
|
||
ApplySystemTheme();
|
||
LoadPasswords(mPwKeyword);
|
||
LoadOtps(mOtpKeyword);
|
||
LoadPins(mPinKeyword);
|
||
LoadNotes(mNoteKeyword);
|
||
LoadQas(mQaKeyword);
|
||
LoadCcs(mCcKeyword);
|
||
LoadCryptos(mCryptoKeyword);
|
||
|
||
otpTimer = new System.Windows.Forms.Timer { Interval = 1000 };
|
||
otpTimer.Tick += OtpTimer_Tick;
|
||
otpTimer.Start();
|
||
}
|
||
|
||
private void InitializeUI()
|
||
{
|
||
// Window
|
||
this.FormBorderStyle = FormBorderStyle.FixedSingle;
|
||
this.MaximizeBox = false;
|
||
|
||
// Password tab tab order
|
||
pwListbox.TabIndex = 0;
|
||
pwWebsiteTextbox.TabIndex = 1;
|
||
pwUsernameTextbox.TabIndex = 2;
|
||
pwPasswordTextbox.TabIndex = 3;
|
||
pwNotesTextbox.TabIndex = 4;
|
||
pwAddButton.TabIndex = 5;
|
||
pwDeleteButton.TabIndex = 6;
|
||
pwEditButton.TabIndex = 7;
|
||
pwShowButton.TabIndex = 8;
|
||
pwDoneButton.TabIndex = 9;
|
||
pwCopyUsernameButton.TabIndex = 10;
|
||
pwCopyPasswordButton.TabIndex = 11;
|
||
|
||
// OTP tab tab order (otpAddNew)
|
||
otpWebsiteTextbox1.TabIndex = 0;
|
||
otpSecretTextbox.TabIndex = 1;
|
||
otpIssuerTextbox.TabIndex = 2;
|
||
otpAlgorithmCombobox.TabIndex = 3;
|
||
otpDigitsNumeric.TabIndex = 4;
|
||
otpDurationNumeric.TabIndex = 5;
|
||
otpAddButton.TabIndex = 6;
|
||
otpEditButton.TabIndex = 7;
|
||
otpDoneButton.TabIndex = 8;
|
||
|
||
// OTP tab tab order (otpAddOld)
|
||
otpWebsiteTextbox2.TabIndex = 0;
|
||
otpAuthTextbox.TabIndex = 1;
|
||
otpAddLegacyButton.TabIndex = 2;
|
||
|
||
// OTP tab main controls
|
||
otpDeleteButton.TabIndex = 8;
|
||
otpCopyButton.TabIndex = 9;
|
||
otpListbox.TabIndex = 10;
|
||
|
||
// PIN Codes tab tab order
|
||
pinListbox.TabIndex = 0;
|
||
pinWebsiteTextbox.TabIndex = 1;
|
||
pinCodeTextbox.TabIndex = 2;
|
||
pinNoteTextbox.TabIndex = 3;
|
||
pinAddButton.TabIndex = 4;
|
||
pinEditButton.TabIndex = 5;
|
||
pinDeleteButton.TabIndex = 6;
|
||
pinCopyButton.TabIndex = 7;
|
||
pinShowButton.TabIndex = 8;
|
||
pinDoneButton.TabIndex = 9;
|
||
|
||
// Creditcard tab tab order
|
||
ccListbox.TabIndex = 0;
|
||
ccBrandCombobox.TabIndex = 1;
|
||
ccNumberTextbox.TabIndex = 2;
|
||
ccHolderTextbox.TabIndex = 3;
|
||
ccExpirationTextbox.TabIndex = 4;
|
||
ccCvcTextbox.TabIndex = 5;
|
||
ccNotesTextbox.TabIndex = 6;
|
||
ccAddButton.TabIndex = 7;
|
||
ccEditButton.TabIndex = 8;
|
||
ccDeleteButton.TabIndex = 9;
|
||
ccShowButton.TabIndex = 10;
|
||
ccDoneButton.TabIndex = 11;
|
||
|
||
// Crypto tab tab order
|
||
cryptoListbox.TabIndex = 0;
|
||
cryptoCurrencyCombobox.TabIndex = 1;
|
||
cryptoAddressTextbox.TabIndex = 2;
|
||
cryptoSeedTextbox.TabIndex = 3;
|
||
cryptoViewkeyTextbox.TabIndex = 4;
|
||
cryptoSpendkeyTextbox.TabIndex = 5;
|
||
cryptoHeightTextbox.TabIndex = 6;
|
||
cryptoPasswordTextbox.TabIndex = 7;
|
||
cryptoNotesTextbox.TabIndex = 8;
|
||
cryptoAddButton.TabIndex = 9;
|
||
cryptoEditButton.TabIndex = 10;
|
||
cryptoDeleteButton.TabIndex = 11;
|
||
cryptoShowButton.TabIndex = 12;
|
||
cryptoDoneButton.TabIndex = 13;
|
||
|
||
// Set initial button states
|
||
genCopyButton.Enabled = false;
|
||
|
||
pwAddButton.Enabled = true;
|
||
pwEditButton.Enabled = false;
|
||
pwDeleteButton.Enabled = false;
|
||
pwCopyUsernameButton.Enabled = false;
|
||
pwCopyPasswordButton.Enabled = false;
|
||
pwShowButton.Enabled = false;
|
||
pwDoneButton.Enabled = false;
|
||
|
||
otpAddButton.Enabled = true;
|
||
otpAddLegacyButton.Enabled = true;
|
||
otpEditButton.Enabled = false;
|
||
otpDeleteButton.Enabled = false;
|
||
otpCopyButton.Enabled = false;
|
||
otpDoneButton.Enabled = false;
|
||
|
||
pinAddButton.Enabled = true;
|
||
pinEditButton.Enabled = false;
|
||
pinDeleteButton.Enabled = false;
|
||
pinCopyButton.Enabled = false;
|
||
pinShowButton.Enabled = false;
|
||
pinDoneButton.Enabled = false;
|
||
|
||
noteAddEditButton.Enabled = true;
|
||
noteAddEditButton.Text = cultureInfo.Name == mJpLang ? "追加" : "Add";
|
||
noteTextbox.Enabled = false;
|
||
noteDeleteButton.Enabled = false;
|
||
noteSaveButton.Enabled = false;
|
||
noteDoneButton.Enabled = false;
|
||
|
||
qaAddButton.Enabled = true;
|
||
qaDeleteButton.Enabled = false;
|
||
qaEditButton.Enabled = false;
|
||
qaCopyButton.Enabled = false;
|
||
qaShowButton.Enabled = false;
|
||
qaDoneButton.Enabled = false;
|
||
|
||
ccAddButton.Enabled = true;
|
||
ccDeleteButton.Enabled = false;
|
||
ccEditButton.Enabled = false;
|
||
ccShowButton.Enabled = false;
|
||
ccDoneButton.Enabled = false;
|
||
|
||
cryptoAddButton.Enabled = true;
|
||
cryptoDeleteButton.Enabled = false;
|
||
cryptoEditButton.Enabled = false;
|
||
cryptoShowButton.Enabled = false;
|
||
cryptoDoneButton.Enabled = false;
|
||
|
||
// Initialize ComboBox and NumericUpDown
|
||
otpAlgorithmCombobox.SelectedIndex = 0; // SHA1
|
||
otpDigitsNumeric.Value = 6;
|
||
otpDurationNumeric.Value = 30;
|
||
}
|
||
|
||
private void ApplySystemTheme()
|
||
{
|
||
bool isDarkMode = Registry.GetValue(
|
||
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize",
|
||
"AppsUseLightTheme", 1)?.ToString() == "0";
|
||
|
||
Color backColor = isDarkMode ? Color.FromArgb(0x12, 0x0f, 0x12) : Color.FromArgb(0xfc, 0xfc, 0xfc);
|
||
Color disableColor = isDarkMode ? Color.FromArgb(0xbd, 0xb4, 0xbd) : Color.FromArgb(0x74, 0x6c, 0x75);
|
||
Color foreColor = isDarkMode ? Color.FromArgb(0xfc, 0xfc, 0xfc) : Color.FromArgb(0x23, 0x20, 0x23);
|
||
Color tabBackColor = isDarkMode ? Color.FromArgb(0x23, 0x20, 0x23) : Color.FromArgb(0xf6, 0xf6, 0xf6);
|
||
Color tabForeColor = isDarkMode ? Color.FromArgb(0xf6, 0xf6, 0xf6) : Color.FromArgb(0x23, 0x20, 0x23);
|
||
Color elementBackColor = isDarkMode ? Color.FromArgb(0x44, 0x3b, 0x44) : Color.FromArgb(0xcf, 0xcb, 0xcf);
|
||
Color elementForeColor = isDarkMode ? Color.FromArgb(0xcf, 0xcb, 0xcf) : Color.FromArgb(0x44, 0x3b, 0x44);
|
||
|
||
this.BackColor = backColor;
|
||
this.ForeColor = foreColor;
|
||
|
||
foreach (Control control in this.Controls)
|
||
{
|
||
control.BackColor = elementBackColor;
|
||
control.ForeColor = elementForeColor;
|
||
|
||
if (control is TabControl tabControl)
|
||
{
|
||
tabControl.DrawMode = TabDrawMode.OwnerDrawFixed;
|
||
|
||
tabControl.DrawItem += (sender, e) =>
|
||
{
|
||
var tab = tabControl.TabPages[e.Index];
|
||
var g = e.Graphics;
|
||
|
||
using (SolidBrush brush = new SolidBrush(tabBackColor))
|
||
{
|
||
g.FillRectangle(brush, e.Bounds);
|
||
}
|
||
|
||
using (SolidBrush brush = new SolidBrush(tabForeColor))
|
||
{
|
||
g.DrawString(tab.Text, tabControl.Font, brush, e.Bounds.Left + 5, e.Bounds.Top + 5);
|
||
}
|
||
|
||
if (e.State == DrawItemState.Selected)
|
||
{
|
||
using (Pen pen = new Pen(tabForeColor))
|
||
{
|
||
g.DrawRectangle(pen, e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width - 4, e.Bounds.Height - 4);
|
||
}
|
||
}
|
||
};
|
||
|
||
foreach (TabPage tabPage in tabControl.TabPages)
|
||
{
|
||
tabPage.BackColor = backColor;
|
||
tabPage.ForeColor = foreColor;
|
||
|
||
ApplyThemeToControls(tabPage.Controls, tabBackColor, disableColor, tabForeColor);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ApplyThemeToControls(Control.ControlCollection controls, Color backColor, Color disableColor, Color foreColor)
|
||
{
|
||
foreach (Control control in controls)
|
||
{
|
||
if (!(control is Label))
|
||
{
|
||
control.BackColor = backColor;
|
||
}
|
||
control.ForeColor = foreColor;
|
||
|
||
if (control is Button button)
|
||
{
|
||
button.FlatStyle = FlatStyle.Flat;
|
||
button.FlatAppearance.BorderSize = 1;
|
||
button.Paint += (sender, e) =>
|
||
{
|
||
Button btn = (Button)sender;
|
||
e.Graphics.Clear(btn.BackColor);
|
||
|
||
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;
|
||
Color textColor = btn.Enabled ? foreColor : disableColor;
|
||
TextRenderer.DrawText(e.Graphics, btn.Text, btn.Font, btn.ClientRectangle, textColor, flags);
|
||
};
|
||
}
|
||
|
||
if (control.HasChildren)
|
||
{
|
||
ApplyThemeToControls(control.Controls, backColor, disableColor, foreColor);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void genGenerateButton_Click(object sender, EventArgs e)
|
||
{
|
||
genPasswordTextbox.Text = mGenMan.GeneratePassword(genSecureCheckbox.Checked, (int)genNumeric.Value);
|
||
genCopyButton.Enabled = true;
|
||
}
|
||
|
||
private async void genCopyButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(genPasswordTextbox.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(genPasswordTextbox.Text);
|
||
await Task.Delay(45000); // 45秒
|
||
|
||
if (Clipboard.GetText() == genPasswordTextbox.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"パスワードのコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy password: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "コピー出来るパスワードではありません。"
|
||
: "No password to copy.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void pwListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (pwListbox.SelectedItem is Item selected)
|
||
{
|
||
var passwords = mPassMan.GetAll();
|
||
var password = passwords.FirstOrDefault(p => p.Id == selected.Id);
|
||
if (password != default)
|
||
{
|
||
pwWebsiteTextbox.Text = password.Website;
|
||
pwUsernameTextbox.Text = password.Username;
|
||
pwPasswordTextbox.Text = password.Password;
|
||
pwNotesTextbox.Text = password.Note;
|
||
pwAddButton.Enabled = false;
|
||
pwEditButton.Enabled = true;
|
||
pwDeleteButton.Enabled = true;
|
||
pwCopyUsernameButton.Enabled = true;
|
||
pwCopyPasswordButton.Enabled = true;
|
||
pwShowButton.Enabled = true;
|
||
pwDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearPasswordFields();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void pwAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(pwWebsiteTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(pwUsernameTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(pwPasswordTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト、ユーザー名及び、パスワードを御入力下さい。"
|
||
: "Please fill in the website, user/email, and password.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mPassMan.AddPassword(pwWebsiteTextbox.Text, pwUsernameTextbox.Text, pwPasswordTextbox.Text, pwNotesTextbox.Text);
|
||
LoadPasswords(mPwKeyword);
|
||
ClearPasswordFields();
|
||
Debug.WriteLine(cultureInfo.Name);
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "パスワードを追加しました。"
|
||
: "Password added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"パスワードの追加に失敗:{ex.Message}"
|
||
: $"Failed to add password: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void pwDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (pwListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} のパスワードを削除しますか?"
|
||
: $"Are you sure you want to delete the password for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mPassMan.DeletePassword(selected.Id))
|
||
{
|
||
LoadPasswords(mPwKeyword);
|
||
ClearPasswordFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "パスワードの削除に失敗。"
|
||
: "Failed to delete password";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void pwEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (pwListbox.SelectedItem is Item selected)
|
||
{
|
||
try
|
||
{
|
||
if (mPassMan.EditPassword(selected.Id, pwWebsiteTextbox.Text, pwUsernameTextbox.Text, pwPasswordTextbox.Text, pwNotesTextbox.Text))
|
||
{
|
||
LoadPasswords(mPwKeyword);
|
||
ClearPasswordFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "パスワードの変更に成功。"
|
||
: "Password changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "パスワードの変更に失敗。"
|
||
: "Failed to change password.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"パスワードの変更に失敗:{ex.Message}"
|
||
: $"Failed to change password: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private async void pwCopyUsernameButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(pwUsernameTextbox.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(pwUsernameTextbox.Text);
|
||
await Task.Delay(45000); // 45秒
|
||
|
||
if (Clipboard.GetText() == pwUsernameTextbox.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"ユーザー名のコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy user/email: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "コピー出来るユーザー名ではありません。"
|
||
: "No user/email to copy.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private async void pwCopyPasswordButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(pwPasswordTextbox.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(pwPasswordTextbox.Text);
|
||
await Task.Delay(45000); // 45秒
|
||
|
||
if (Clipboard.GetText() == pwPasswordTextbox.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"パスワードのコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy password: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "コピー出来るパスワードではありません。"
|
||
: "No password to copy.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void pwShowButton_Click(object sender, EventArgs e)
|
||
{
|
||
pwPasswordTextbox.UseSystemPasswordChar = !pwPasswordTextbox.UseSystemPasswordChar;
|
||
}
|
||
private void pwDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadPasswords(mPwKeyword);
|
||
ClearPasswordFields();
|
||
}
|
||
|
||
private void pwSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mPwKeyword = pwSearchTextbox.Text;
|
||
LoadPasswords(pwSearchTextbox.Text);
|
||
ClearPasswordFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void otpAddLegacyButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(otpWebsiteTextbox2.Text) ||
|
||
string.IsNullOrWhiteSpace(otpAuthTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト及びOTP Authを御入力下さい。"
|
||
: "Please fill in the website and OTP Auth.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
var (secret, issuer, algorithm, duration, digits) = mOtpMan.ParseOtpAuthUrl(otpAuthTextbox.Text);
|
||
mOtpMan.AddOtp(otpWebsiteTextbox2.Text, secret, issuer, algorithm, duration, digits, "");
|
||
LoadOtps(mOtpKeyword);
|
||
ClearOtpFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "OTPの追加に成功。"
|
||
: "OTP added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"OTPの追加に失敗:{ex.Message}"
|
||
: $"Failed to add OTP: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void otpAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(otpWebsiteTextbox1.Text) ||
|
||
string.IsNullOrWhiteSpace(otpSecretTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(otpIssuerTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト、秘密鍵及び、発行者を御入力下さい。"
|
||
: "Please fill in the website, secret, and issuer.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mOtpMan.AddOtp(
|
||
otpWebsiteTextbox1.Text,
|
||
otpSecretTextbox.Text,
|
||
otpIssuerTextbox.Text,
|
||
otpAlgorithmCombobox.Text,
|
||
(int)otpDurationNumeric.Value,
|
||
(int)otpDigitsNumeric.Value,
|
||
""
|
||
);
|
||
LoadOtps(mOtpKeyword);
|
||
ClearOtpFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "OTPの追加に成功。"
|
||
: "OTP added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"OTPの追加に失敗:{ex.Message}"
|
||
: $"Failed to add OTP: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void otpEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (otpListbox.SelectedItem is Item selected)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(otpWebsiteTextbox1.Text) ||
|
||
string.IsNullOrWhiteSpace(otpSecretTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(otpIssuerTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト、秘密鍵及び、発行者を御入力下さい。"
|
||
: "Please fill in the website, secret, and issuer.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
if (mOtpMan.EditOtp(
|
||
selected.Id,
|
||
otpWebsiteTextbox1.Text,
|
||
otpSecretTextbox.Text,
|
||
otpIssuerTextbox.Text,
|
||
otpAlgorithmCombobox.Text,
|
||
(int)otpDurationNumeric.Value,
|
||
(int)otpDigitsNumeric.Value,
|
||
""
|
||
))
|
||
{
|
||
LoadOtps(mOtpKeyword);
|
||
ClearOtpFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "OTPの変更に成功。"
|
||
: "OTP changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "OTPの更新に失敗。"
|
||
: "Failed to change OTP.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"OTPの更新に失敗:{ex.Message}"
|
||
: $"Failed to change OTP: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void otpDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (otpListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} のOTPを削除しますか?"
|
||
: $"Are you sure you want to delete the OTP for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mOtpMan.DeleteOtp(selected.Id))
|
||
{
|
||
LoadOtps(mOtpKeyword);
|
||
ClearOtpFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "OTPの削除に失敗。"
|
||
: "Failed to delete OTP.";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private async void otpCopyButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(otpCodeLabel.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(otpCodeLabel.Text);
|
||
await Task.Delay(30000); // 30秒
|
||
|
||
if (Clipboard.GetText() == otpCodeLabel.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"OTPのコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy OTP: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
MessageBox.Show($"Failed to copy OTP: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "コピー出来るOTPではありません。"
|
||
: "No OTP to copy.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void otpDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadOtps(mOtpKeyword);
|
||
ClearOtpFields();
|
||
}
|
||
|
||
private void otpSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mOtpKeyword = otpSearchTextbox.Text;
|
||
LoadOtps(otpSearchTextbox.Text);
|
||
ClearOtpFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void otpListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (otpListbox.SelectedItem is Item selected)
|
||
{
|
||
var otps = mOtpMan.GetAll();
|
||
var otp = otps.FirstOrDefault(o => o.Id == selected.Id);
|
||
if (otp != default)
|
||
{
|
||
UpdateOtpCode(otp);
|
||
otpWebsiteTextbox1.Text = otp.Website;
|
||
otpIssuerTextbox.Text = otp.Issuer;
|
||
otpSecretTextbox.Text = otp.Secret;
|
||
otpDigitsNumeric.Value = otp.Digits;
|
||
otpDurationNumeric.Value = otp.Duration;
|
||
otpAlgorithmCombobox.SelectedItem = otp.Algorithm ?? "SHA1";
|
||
otpAddButton.Enabled = false;
|
||
otpAddLegacyButton.Enabled = false;
|
||
otpEditButton.Enabled = true;
|
||
otpDeleteButton.Enabled = true;
|
||
otpCopyButton.Enabled = true;
|
||
otpDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearOtpFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ID {selected.Id} を持つOTPをデータベースに見つけられませんでした。"
|
||
: "OTP with ID {selected.Id} not found in database.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ClearOtpFields();
|
||
}
|
||
}
|
||
|
||
private void pinAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(pinWebsiteTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(pinCodeTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト及び暗証番号を御入力下さい。"
|
||
: "Please fill in the website and pincode.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mPinMan.AddPin(pinWebsiteTextbox.Text, pinCodeTextbox.Text, pinNoteTextbox.Text);
|
||
LoadPins(mPinKeyword);
|
||
ClearPinFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "暗証番号の追加に成功。"
|
||
: "Pincode added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"暗証番号の追加に失敗:{ex.Message}"
|
||
: $"Failed to add pincode: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void pinEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (pinListbox.SelectedItem is Item selected)
|
||
{
|
||
if (mPinMan.EditPin(selected.Id, pinWebsiteTextbox.Text, pinCodeTextbox.Text, pinNoteTextbox.Text))
|
||
{
|
||
LoadPins(mPinKeyword);
|
||
ClearPinFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "暗証番号の変更に成功。"
|
||
: "Pincode changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"暗証番号の変更に失敗。"
|
||
: $"Failed to change pincode.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void pinDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (pinListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} の暗証番号を削除しますか?"
|
||
: $"Are you sure you want to delete the pincode for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mPinMan.DeletePin(selected.Id))
|
||
{
|
||
LoadPins(mPinKeyword);
|
||
ClearPinFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "暗証番号の削除に失敗。"
|
||
: "Failed to delete pincode";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private async void pinCopyButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(pinCodeTextbox.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(pinCodeTextbox.Text);
|
||
await Task.Delay(45000); // 45秒
|
||
|
||
if (Clipboard.GetText() == pinCodeTextbox.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"暗証番号のコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy pincode: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ID {selected.Id} を持つ暗証番号をデータベースに見つけられませんでした。"
|
||
: "Pincode with ID {selected.Id} not found in database.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void pinShowButton_Click(object sender, EventArgs e)
|
||
{
|
||
pinCodeTextbox.UseSystemPasswordChar = !pinCodeTextbox.UseSystemPasswordChar;
|
||
}
|
||
|
||
private void pinDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadPins(mPinKeyword);
|
||
ClearPinFields();
|
||
}
|
||
|
||
private void pinListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (pinListbox.SelectedItem is Item selected)
|
||
{
|
||
var pins = mPinMan.GetAll();
|
||
var pin = pins.FirstOrDefault(o => o.Id == selected.Id);
|
||
if (pin != default)
|
||
{
|
||
pinWebsiteTextbox.Text = pin.Website;
|
||
pinCodeTextbox.Text = pin.Pincode;
|
||
pinNoteTextbox.Text = pin.Note;
|
||
pinAddButton.Enabled = false;
|
||
pinEditButton.Enabled = true;
|
||
pinDeleteButton.Enabled = true;
|
||
pinCopyButton.Enabled = true;
|
||
pinShowButton.Enabled = true;
|
||
pinDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearPinFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"ID {selected.Id} を持つ暗証番号をデータベースに見つけられませんでした。"
|
||
: $"Pincode with ID {selected.Id} not found in database.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ClearPinFields();
|
||
}
|
||
}
|
||
|
||
private void pinSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mPinKeyword = pinSearchTextbox.Text;
|
||
LoadPins(pinSearchTextbox.Text);
|
||
ClearPinFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void noteAddEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (noteListbox.SelectedItem is Item selected)
|
||
{
|
||
try
|
||
{
|
||
mNoteMan.EditNote(selected.Id, noteTitleTextbox.Text);
|
||
LoadNotes(mNoteKeyword);
|
||
ClearNoteFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "メモの変更に成功。"
|
||
: "Note changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"メモの変更に失敗:{ex.Message}"
|
||
: $"Failed to change note: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
try
|
||
{
|
||
mNoteMan.AddNote(noteTitleTextbox.Text);
|
||
LoadNotes(mNoteKeyword);
|
||
ClearNoteFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "メモの追加に成功。"
|
||
: "Note added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"メモの追加に失敗:{ex.Message}"
|
||
: $"Failed to add note: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void noteListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (noteListbox.SelectedItem is Item selected)
|
||
{
|
||
var notes = mNoteMan.GetAll();
|
||
var note = notes.FirstOrDefault(o => o.Id == selected.Id);
|
||
if (note != default)
|
||
{
|
||
noteTitleTextbox.Text = note.Name;
|
||
noteTextbox.Text = note.Text;
|
||
noteTextbox.Enabled = true;
|
||
noteAddEditButton.Text = cultureInfo.Name == mJpLang ? "編集" : "Edit";
|
||
noteDeleteButton.Enabled = true;
|
||
noteDoneButton.Enabled = true;
|
||
noteSaveButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearNoteFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"ID {selected.Id} を持つメモをデータベースに見つけられませんでした。"
|
||
: $"Note with ID {selected.Id} not found in database.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ClearNoteFields();
|
||
}
|
||
}
|
||
|
||
private void noteDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (noteListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} のメモを削除しますか?"
|
||
: $"Are you sure you want to delete the note for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mNoteMan.DeleteNote(selected.Id))
|
||
{
|
||
LoadNotes(mNoteKeyword);
|
||
ClearNoteFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "メモの削除に失敗。"
|
||
: "Failed to delete note";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void NoteSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mNoteKeyword = noteSearchTextbox.Text;
|
||
LoadNotes(noteSearchTextbox.Text);
|
||
ClearNoteFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void noteSaveButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (noteListbox.SelectedItem is Item selected)
|
||
{
|
||
try
|
||
{
|
||
mNoteMan.SaveNote(selected.Id, noteTextbox.Text);
|
||
LoadNotes(mNoteKeyword);
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "メモの保存に成功。"
|
||
: "Note saved successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"メモの保存に失敗:{ex.Message}"
|
||
: $"Failed to save note: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void noteDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadNotes(mNoteKeyword);
|
||
ClearNoteFields();
|
||
}
|
||
|
||
private void qaAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(qaWebsiteTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(qaQuestionTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(qaAnswerTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ウェブサイト、質問及び、回答を御入力下さい。"
|
||
: "Please fill in the website, question, and answer.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mQaMan.AddQa(qaWebsiteTextbox.Text, qaQuestionTextbox.Text, qaAnswerTextbox.Text, qaNoteTextbox.Text);
|
||
LoadQas(mQaKeyword);
|
||
ClearQaFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "秘密質問を追加しました。"
|
||
: "Secret question added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"秘密質問の追加に失敗:{ex.Message}"
|
||
: $"Failed to add secret question: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void qaDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (qaListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} の秘密質問を削除しますか?"
|
||
: $"Are you sure you want to delete the secret question for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mQaMan.DeleteQa(selected.Id))
|
||
{
|
||
LoadQas(mQaKeyword);
|
||
ClearQaFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "秘密質問の削除に失敗。"
|
||
: "Failed to delete secret question";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void qaEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (qaListbox.SelectedItem is Item selected)
|
||
{
|
||
if (mQaMan.EditQa(selected.Id, qaWebsiteTextbox.Text, qaQuestionTextbox.Text, qaAnswerTextbox.Text, qaNoteTextbox.Text))
|
||
{
|
||
LoadQas(mQaKeyword);
|
||
ClearQaFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "秘密質問の変更に成功。"
|
||
: "Secret question changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "秘密質問の変更に失敗。"
|
||
: "Failed to change secret question.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private async void qaCopyButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (!string.IsNullOrEmpty(qaAnswerTextbox.Text))
|
||
{
|
||
try
|
||
{
|
||
Clipboard.SetText(qaAnswerTextbox.Text);
|
||
await Task.Delay(45000); // 45秒
|
||
|
||
if (Clipboard.GetText() == qaAnswerTextbox.Text)
|
||
{
|
||
Clipboard.Clear();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"秘密質問のコピーに失敗:{ex.Message}"
|
||
: $"Failed to copy secret question: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "コピー出来る秘密質問ではありません。"
|
||
: "No secret question to copy.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void qaShowButton_Click(object sender, EventArgs e)
|
||
{
|
||
qaAnswerTextbox.UseSystemPasswordChar = !qaAnswerTextbox.UseSystemPasswordChar;
|
||
}
|
||
|
||
private void qaDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadQas(mQaKeyword);
|
||
ClearQaFields();
|
||
}
|
||
|
||
private void qaListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (qaListbox.SelectedItem is Item selected)
|
||
{
|
||
var qas = mQaMan.GetAll();
|
||
var qa = qas.FirstOrDefault(p => p.Id == selected.Id);
|
||
if (qa != default)
|
||
{
|
||
qaWebsiteTextbox.Text = qa.Website;
|
||
qaQuestionTextbox.Text = qa.Question;
|
||
qaAnswerTextbox.Text = qa.Answer;
|
||
qaNoteTextbox.Text = qa.Note;
|
||
qaAddButton.Enabled = false;
|
||
qaEditButton.Enabled = true;
|
||
qaDeleteButton.Enabled = true;
|
||
qaCopyButton.Enabled = true;
|
||
qaShowButton.Enabled = true;
|
||
qaDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearQaFields();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void qaSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mQaKeyword = qaSearchTextbox.Text;
|
||
LoadNotes(qaSearchTextbox.Text);
|
||
ClearQaFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void ccListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (ccListbox.SelectedItem is Item selected)
|
||
{
|
||
var ccs = mCcMan.GetAll();
|
||
var cc = ccs.FirstOrDefault(p => p.Id == selected.Id);
|
||
if (cc != default)
|
||
{
|
||
ccBrandCombobox.SelectedItem = cc.Brand ?? "Mastercard";
|
||
ccNumberTextbox.Text = cc.Cardnumber;
|
||
ccHolderTextbox.Text = cc.Holdername;
|
||
ccExpirationTextbox.Text = cc.Expiration;
|
||
ccCvcTextbox.Text = cc.Cvc;
|
||
ccNotesTextbox.Text = cc.Note;
|
||
ccAddButton.Enabled = false;
|
||
ccEditButton.Enabled = true;
|
||
ccDeleteButton.Enabled = true;
|
||
ccShowButton.Enabled = true;
|
||
ccDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearCcFields();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ccSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mCcKeyword = ccSearchTextbox.Text;
|
||
LoadCcs(ccSearchTextbox.Text);
|
||
ClearCcFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void ccAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(ccBrandCombobox.Text) ||
|
||
string.IsNullOrWhiteSpace(ccNumberTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(ccExpirationTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(ccCvcTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(ccHolderTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "ブランド、カード番号、氏名、有効期限及び、CVCを御入力下さい。"
|
||
: "Please fill in the brand, card number, full name, expiration, and CVC.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mCcMan.AddCc(ccBrandCombobox.Text, ccNumberTextbox.Text, ccExpirationTextbox.Text, ccCvcTextbox.Text, ccHolderTextbox.Text, ccNotesTextbox.Text);
|
||
LoadCcs(mCcKeyword);
|
||
ClearCcFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "クレジットカードを追加しました。"
|
||
: "Creditcard added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"クレジットカードの追加に失敗:{ex.Message}"
|
||
: $"Failed to add creditcard: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void ccDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (ccListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} のクレジットカードを削除しますか?"
|
||
: $"Are you sure you want to delete the creditcard for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mCcMan.DeleteCc(selected.Id))
|
||
{
|
||
LoadCcs(mCcKeyword);
|
||
ClearCcFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "クレジットカードの削除に失敗。"
|
||
: "Failed to delete creditcard";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ccEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (ccListbox.SelectedItem is Item selected)
|
||
{
|
||
if (mCcMan.EditCc(selected.Id, ccBrandCombobox.Text, ccNumberTextbox.Text, ccExpirationTextbox.Text, ccCvcTextbox.Text, ccHolderTextbox.Text, ccNotesTextbox.Text))
|
||
{
|
||
LoadCcs(mCcKeyword);
|
||
ClearCcFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "クレジットカードの変更に成功。"
|
||
: "Creditcard changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "クレジットカードの変更に失敗。"
|
||
: "Failed to change creditcard.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void ccShowButton_Click(object sender, EventArgs e)
|
||
{
|
||
ccNumberTextbox.UseSystemPasswordChar = !ccNumberTextbox.UseSystemPasswordChar;
|
||
ccCvcTextbox.UseSystemPasswordChar = !ccCvcTextbox.UseSystemPasswordChar;
|
||
}
|
||
|
||
private void ccDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadCcs(mCcKeyword);
|
||
ClearCcFields();
|
||
}
|
||
|
||
private void cryptoListbox_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
if (cryptoListbox.SelectedItem is Item selected)
|
||
{
|
||
var cryptos = mCryptoMan.GetAll();
|
||
var crypto = cryptos.FirstOrDefault(p => p.Id == selected.Id);
|
||
if (crypto != default)
|
||
{
|
||
cryptoCurrencyCombobox.SelectedItem = crypto.Currency ?? "XMR";
|
||
cryptoNameTextbox.Text = crypto.Name;
|
||
cryptoAddressTextbox.Text = crypto.Address;
|
||
cryptoSeedTextbox.Text = crypto.Seed;
|
||
cryptoViewkeyTextbox.Text = crypto.Viewkey;
|
||
cryptoSpendkeyTextbox.Text = crypto.Spendkey;
|
||
cryptoHeightTextbox.Text = crypto.Height;
|
||
cryptoPasswordTextbox.Text = crypto.Password;
|
||
cryptoNotesTextbox.Text = crypto.Note;
|
||
cryptoAddButton.Enabled = false;
|
||
cryptoEditButton.Enabled = true;
|
||
cryptoDeleteButton.Enabled = true;
|
||
cryptoShowButton.Enabled = true;
|
||
cryptoDoneButton.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
ClearCryptoFields();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void cryptoSearchTextbox_KeyPress(object sender, KeyPressEventArgs e)
|
||
{
|
||
if (e.KeyChar == (char)13)
|
||
{
|
||
mCryptoKeyword = cryptoSearchTextbox.Text;
|
||
LoadCryptos(cryptoSearchTextbox.Text);
|
||
ClearCryptoFields();
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
private void cryptoAddButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(cryptoCurrencyCombobox.Text) ||
|
||
string.IsNullOrWhiteSpace(cryptoNameTextbox.Text) ||
|
||
string.IsNullOrWhiteSpace(cryptoAddressTextbox.Text))
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "通貨、ウォレット名及び、住所を御入力下さい。"
|
||
: "Please fill in the currency, wallet name, and address.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
mCryptoMan.AddCrypto(cryptoCurrencyCombobox.Text, cryptoNameTextbox.Text, cryptoAddressTextbox.Text, cryptoSeedTextbox.Text, cryptoViewkeyTextbox.Text, cryptoSpendkeyTextbox.Text, cryptoHeightTextbox.Text, cryptoPasswordTextbox.Text, cryptoNotesTextbox.Text);
|
||
LoadCryptos(mCryptoKeyword);
|
||
ClearCryptoFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "仮想通貨を追加しました。"
|
||
: "Cryptocurrency added successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"仮想通貨の追加に失敗:{ex.Message}"
|
||
: $"Failed to add cryptocurrency: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void cryptoDeleteButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (cryptoListbox.SelectedItem is Item selected)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"本当に {selected.DisplayText} の仮想通貨を削除しますか?"
|
||
: $"Are you sure you want to delete the cryptocurrency for {selected.DisplayText}?";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "削除の確認"
|
||
: "Confirm Delete";
|
||
var res = MessageBox.Show(mes, tit, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||
|
||
if (res == DialogResult.Yes)
|
||
{
|
||
if (mCryptoMan.DeleteCrypto(selected.Id))
|
||
{
|
||
LoadCryptos(mCryptoKeyword);
|
||
ClearCryptoFields();
|
||
}
|
||
else
|
||
{
|
||
mes = cultureInfo.Name == mJpLang
|
||
? "暗号通貨の削除に失敗。"
|
||
: "Failed to delete cryptocurrency";
|
||
tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void cryptoEditButton_Click(object sender, EventArgs e)
|
||
{
|
||
if (cryptoListbox.SelectedItem is Item selected)
|
||
{
|
||
if (mCryptoMan.EditCrypto(selected.Id, cryptoCurrencyCombobox.Text, cryptoNameTextbox.Text, cryptoAddressTextbox.Text, cryptoSeedTextbox.Text, cryptoViewkeyTextbox.Text, cryptoSpendkeyTextbox.Text, cryptoHeightTextbox.Text, cryptoPasswordTextbox.Text, cryptoNotesTextbox.Text))
|
||
{
|
||
LoadCryptos(mCryptoKeyword);
|
||
ClearCryptoFields();
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "暗号通貨の変更に成功。"
|
||
: "Cryptocurrency changed successfully.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "成功"
|
||
: "Success";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
else
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "暗号通貨の変更に失敗。"
|
||
: "Failed to change cryptocurrency.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void cryptoShowButton_Click(object sender, EventArgs e)
|
||
{
|
||
cryptoSeedTextbox.UseSystemPasswordChar = !cryptoSeedTextbox.UseSystemPasswordChar;
|
||
cryptoViewkeyTextbox.UseSystemPasswordChar = !cryptoViewkeyTextbox.UseSystemPasswordChar;
|
||
cryptoSpendkeyTextbox.UseSystemPasswordChar = !cryptoSpendkeyTextbox.UseSystemPasswordChar;
|
||
cryptoHeightTextbox.UseSystemPasswordChar = !cryptoHeightTextbox.UseSystemPasswordChar;
|
||
}
|
||
|
||
private void cryptoDoneButton_Click(object sender, EventArgs e)
|
||
{
|
||
LoadCryptos(mCryptoKeyword);
|
||
ClearCryptoFields();
|
||
}
|
||
|
||
private void OtpTimer_Tick(object sender, EventArgs e)
|
||
{
|
||
if (otpListbox.SelectedItem is Item selected)
|
||
{
|
||
var otps = mOtpMan.GetAll();
|
||
var otp = otps.FirstOrDefault(o => o.Id == selected.Id);
|
||
if (otp != default)
|
||
{
|
||
long currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||
long lastUpdate = currentTime / otp.Duration;
|
||
long nextUpdate = (lastUpdate + 1) * otp.Duration;
|
||
int secondsRemaining = (int)(nextUpdate - currentTime);
|
||
|
||
// Only update if the TOTP code has changed or at the start of a new period
|
||
if (secondsRemaining == otp.Duration || string.IsNullOrEmpty(otpCodeLabel.Text))
|
||
{
|
||
UpdateOtpCode(otp);
|
||
}
|
||
else
|
||
{
|
||
// Update countdown without regenerating TOTP code
|
||
otpCountdownLabel.Text = cultureInfo.Name == mJpLang ? $"{secondsRemaining}秒" : $"{secondsRemaining}s";
|
||
otpCountdownProgress.Value = secondsRemaining;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
otpCodeLabel.Text = string.Empty;
|
||
otpCountdownLabel.Text = string.Empty;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
otpCodeLabel.Text = string.Empty;
|
||
otpCountdownLabel.Text = string.Empty;
|
||
}
|
||
}
|
||
|
||
private void ClearPasswordFields()
|
||
{
|
||
pwWebsiteTextbox.Text = string.Empty;
|
||
pwUsernameTextbox.Text = string.Empty;
|
||
pwPasswordTextbox.Text = string.Empty;
|
||
pwNotesTextbox.Text = string.Empty;
|
||
pwAddButton.Enabled = true;
|
||
pwEditButton.Enabled = false;
|
||
pwDeleteButton.Enabled = false;
|
||
pwCopyUsernameButton.Enabled = false;
|
||
pwCopyPasswordButton.Enabled = false;
|
||
pwShowButton.Enabled = false;
|
||
pwDoneButton.Enabled = false;
|
||
}
|
||
|
||
private void ClearOtpFields()
|
||
{
|
||
otpWebsiteTextbox1.Text = string.Empty;
|
||
otpWebsiteTextbox2.Text = string.Empty;
|
||
otpAuthTextbox.Text = string.Empty;
|
||
otpSecretTextbox.Text = string.Empty;
|
||
otpIssuerTextbox.Text = string.Empty;
|
||
otpAlgorithmCombobox.SelectedIndex = 0;
|
||
otpDigitsNumeric.Value = 6;
|
||
otpDurationNumeric.Value = 30;
|
||
otpCodeLabel.Text = string.Empty;
|
||
otpCountdownLabel.Text = string.Empty;
|
||
otpAddButton.Enabled = true;
|
||
otpAddLegacyButton.Enabled = true;
|
||
otpEditButton.Enabled = false;
|
||
otpDeleteButton.Enabled = false;
|
||
otpCopyButton.Enabled = false;
|
||
otpDoneButton.Enabled = false;
|
||
otpCountdownProgress.Value = 0;
|
||
}
|
||
|
||
private void ClearPinFields()
|
||
{
|
||
pinWebsiteTextbox.Text = string.Empty;
|
||
pinCodeTextbox.Text = string.Empty;
|
||
pinNoteTextbox.Text = string.Empty;
|
||
pinAddButton.Enabled = true;
|
||
pinEditButton.Enabled = false;
|
||
pinDeleteButton.Enabled = false;
|
||
pinCopyButton.Enabled = false;
|
||
pinShowButton.Enabled = false;
|
||
pinDoneButton.Enabled = false;
|
||
}
|
||
|
||
private void ClearNoteFields()
|
||
{
|
||
noteTitleTextbox.Text = string.Empty;
|
||
noteTextbox.Text = string.Empty;
|
||
noteTextbox.Enabled = false;
|
||
noteAddEditButton.Text = cultureInfo.Name == mJpLang ? "追加" : "Add";
|
||
noteDeleteButton.Enabled = false;
|
||
noteDoneButton.Enabled = false;
|
||
noteSaveButton.Enabled = false;
|
||
}
|
||
|
||
private void ClearQaFields()
|
||
{
|
||
qaWebsiteTextbox.Text = string.Empty;
|
||
qaQuestionTextbox.Text = string.Empty;
|
||
qaAnswerTextbox.Text = string.Empty;
|
||
qaNoteTextbox.Text = string.Empty;
|
||
qaAddButton.Enabled = true;
|
||
qaEditButton.Enabled = false;
|
||
qaDeleteButton.Enabled = false;
|
||
qaCopyButton.Enabled = false;
|
||
qaShowButton.Enabled = false;
|
||
qaDoneButton.Enabled = false;
|
||
}
|
||
|
||
private void ClearCcFields()
|
||
{
|
||
ccBrandCombobox.SelectedIndex = 0;
|
||
ccNumberTextbox.Text = string.Empty;
|
||
ccExpirationTextbox.Text = string.Empty;
|
||
ccCvcTextbox.Text = string.Empty;
|
||
ccHolderTextbox.Text = string.Empty;
|
||
ccNotesTextbox.Text = string.Empty;
|
||
ccAddButton.Enabled = true;
|
||
ccEditButton.Enabled = false;
|
||
ccDeleteButton.Enabled = false;
|
||
ccShowButton.Enabled = false;
|
||
ccDoneButton.Enabled = false;
|
||
}
|
||
|
||
private void ClearCryptoFields()
|
||
{
|
||
cryptoCurrencyCombobox.SelectedIndex = 0;
|
||
cryptoNameTextbox.Text = string.Empty;
|
||
cryptoAddressTextbox.Text = string.Empty;
|
||
cryptoSeedTextbox.Text = string.Empty;
|
||
cryptoViewkeyTextbox.Text = string.Empty;
|
||
cryptoSpendkeyTextbox.Text = string.Empty;
|
||
cryptoHeightTextbox.Text = string.Empty;
|
||
cryptoPasswordTextbox.Text = string.Empty;
|
||
cryptoNotesTextbox.Text = string.Empty;
|
||
cryptoAddButton.Enabled = true;
|
||
cryptoEditButton.Enabled = false;
|
||
cryptoDeleteButton.Enabled = false;
|
||
cryptoShowButton.Enabled = false;
|
||
cryptoDoneButton.Enabled = false;
|
||
}
|
||
|
||
private void LoadPasswords(string keyword = "")
|
||
{
|
||
pwListbox.Items.Clear();
|
||
var passwords = mPassMan.GetAll(keyword);
|
||
|
||
foreach (var pwd in passwords)
|
||
{
|
||
pwListbox.Items.Add(new Item(pwd.Id, $"{pwd.Website}/{pwd.Username}"));
|
||
}
|
||
}
|
||
|
||
private void LoadOtps(string keyword = "")
|
||
{
|
||
otpListbox.Items.Clear();
|
||
try
|
||
{
|
||
var otps = mOtpMan.GetAll(keyword);
|
||
foreach (var otp in otps)
|
||
{
|
||
otpListbox.Items.Add(new Item(otp.Id, $"{otp.Website} ({otp.Issuer})"));
|
||
}
|
||
if (otps.Count == 0)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? "データベースにOTPを見つけられませんでした。"
|
||
: "No OTPs found in the database.";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "注意"
|
||
: "Warning";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
string mes = cultureInfo.Name == mJpLang
|
||
? $"OTPの読み込みに失敗:{ex.Message}"
|
||
: $"Failed to load OTPs: {ex.Message}";
|
||
string tit = cultureInfo.Name == mJpLang
|
||
? "エラー"
|
||
: "Error";
|
||
MessageBox.Show(mes, tit, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private void LoadPins(string keyword = "")
|
||
{
|
||
pinListbox.Items.Clear();
|
||
var pins = mPinMan.GetAll(keyword);
|
||
|
||
foreach (var pin in pins)
|
||
{
|
||
pinListbox.Items.Add(new Item(pin.Id, $"{pin.Website}"));
|
||
}
|
||
}
|
||
|
||
private void LoadNotes(string keyword = "")
|
||
{
|
||
noteListbox.Items.Clear();
|
||
var notes = mNoteMan.GetAll(keyword);
|
||
|
||
foreach (var note in notes)
|
||
{
|
||
noteListbox.Items.Add(new Item(note.Id, $"{note.Name}"));
|
||
}
|
||
}
|
||
|
||
private void LoadQas(string keyword = "")
|
||
{
|
||
qaListbox.Items.Clear();
|
||
var qas = mQaMan.GetAll(keyword);
|
||
|
||
foreach (var qa in qas)
|
||
{
|
||
qaListbox.Items.Add(new Item(qa.Id, $"{qa.Website}/{qa.Question}"));
|
||
}
|
||
}
|
||
|
||
private void LoadCcs(string keyword = "")
|
||
{
|
||
ccListbox.Items.Clear();
|
||
var ccs = mCcMan.GetAll(keyword);
|
||
|
||
foreach (var cc in ccs)
|
||
{
|
||
ccListbox.Items.Add(new Item(cc.Id, $"{cc.Brand}/{cc.Holdername} ({cc.Expiration})"));
|
||
}
|
||
}
|
||
|
||
private void LoadCryptos(string keyword = "")
|
||
{
|
||
cryptoListbox.Items.Clear();
|
||
var cryptos = mCryptoMan.GetAll(keyword);
|
||
|
||
foreach (var crypto in cryptos)
|
||
{
|
||
cryptoListbox.Items.Add(new Item(crypto.Id, $"{crypto.Currency}/{crypto.Name}"));
|
||
}
|
||
}
|
||
|
||
private void UpdateOtpCode((int Id, string Website, string Secret, string Issuer, string Algorithm, int Duration, int Digits, string Note) otp)
|
||
{
|
||
try
|
||
{
|
||
var (code, error) = mOtpMan.GenerateTotp(otp.Secret, otp.Digits, otp.Algorithm, otp.Duration);
|
||
if (!string.IsNullOrEmpty(error))
|
||
{
|
||
otpCodeLabel.Text = cultureInfo.Name == mJpLang ? $"エラー:{error}" : $"Error: {error}";
|
||
otpCountdownLabel.Text = string.Empty;
|
||
}
|
||
else
|
||
{
|
||
otpCodeLabel.Text = code;
|
||
long currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||
int secondsRemaining = otp.Duration - (int)(currentTime % otp.Duration);
|
||
otpCountdownLabel.Text = cultureInfo.Name == mJpLang ? $"{secondsRemaining}秒" : $"{secondsRemaining}s";
|
||
otpCountdownProgress.Maximum = otp.Duration;
|
||
otpCountdownProgress.Value = secondsRemaining;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
otpCodeLabel.Text = cultureInfo.Name == mJpLang ? $"エラー:{ex.Message}" : $"Error: {ex.Message}";
|
||
otpCountdownLabel.Text = string.Empty;
|
||
}
|
||
}
|
||
|
||
private class Item
|
||
{
|
||
public int Id { get; }
|
||
public string DisplayText { get; }
|
||
|
||
public Item(int id, string displayText)
|
||
{
|
||
Id = id;
|
||
DisplayText = displayText;
|
||
}
|
||
|
||
public override string ToString() => DisplayText;
|
||
}
|
||
}
|
||
} |