2022-05-12 13:35:08 -04:00

199 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AudibleApi;
using AudibleUtilities;
namespace LibationWinForms.Dialogs
{
public partial class AccountsDialog : Form
{
private const string COL_Delete = nameof(DeleteAccount);
private const string COL_LibraryScan = nameof(LibraryScan);
private const string COL_AccountId = nameof(AccountId);
private const string COL_AccountName = nameof(AccountName);
private const string COL_Locale = nameof(Locale);
public AccountsDialog()
{
InitializeComponent();
dataGridView1.Columns[COL_AccountName].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
populateDropDown();
populateGridValues();
this.SetLibationIcon();
}
private void populateDropDown()
=> (dataGridView1.Columns[COL_Locale] as DataGridViewComboBoxColumn).DataSource
= Localization.Locales
.Select(l => l.Name)
.OrderBy(a => a).ToList();
private void populateGridValues()
{
// WARNING: accounts persister will write ANY EDIT to object immediately to file
// here: copy strings and dispose of persister
// only persist in 'save' step
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var accounts = persister.AccountsSettings.Accounts;
if (!accounts.Any())
return;
foreach (var account in accounts)
dataGridView1.Rows.Add(
"X",
account.LibraryScan,
account.AccountId,
account.Locale.Name,
account.AccountName);
}
private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
{
e.Row.Cells[COL_Delete].Value = "X";
e.Row.Cells[COL_LibraryScan].Value = true;
}
private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var dgv = (DataGridView)sender;
var col = dgv.Columns[e.ColumnIndex];
if (col is DataGridViewButtonColumn && e.RowIndex >= 0)
{
var row = dgv.Rows[e.RowIndex];
switch (col.Name)
{
case COL_Delete:
// if final/edit row: do nothing
if (e.RowIndex < dgv.RowCount - 1)
dgv.Rows.Remove(row);
break;
//case COL_MoveUp:
// // if top: do nothing
// if (e.RowIndex < 1)
// break;
// dgv.Rows.Remove(row);
// dgv.Rows.Insert(e.RowIndex - 1, row);
// break;
//case COL_MoveDown:
// // if final/edit row or bottom filter row: do nothing
// if (e.RowIndex >= dgv.RowCount - 2)
// break;
// dgv.Rows.Remove(row);
// dgv.Rows.Insert(e.RowIndex + 1, row);
// break;
}
}
}
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private class AccountDto
{
public string AccountId { get; set; }
public string AccountName { get; set; }
public string LocaleName { get; set; }
public bool LibraryScan { get; set; }
}
private void saveBtn_Click(object sender, EventArgs e)
{
try
{
if (!inputIsValid())
return;
// without transaction, accounts persister will write ANY EDIT immediately to file
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
persister.BeginTransation();
persist(persister.AccountsSettings);
persister.CommitTransation();
this.DialogResult = DialogResult.OK;
this.Close();
}
catch (Exception ex)
{
MessageBoxLib.ShowAdminAlert("Error attempting to save accounts", "Error saving accounts", ex);
}
}
private bool inputIsValid()
{
var dtos = getRowDtos();
foreach (var dto in dtos)
{
if (string.IsNullOrWhiteSpace(dto.AccountId))
{
MessageBox.Show("Account id cannot be blank. Please enter an account id for all accounts.", "Blank account", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (string.IsNullOrWhiteSpace(dto.LocaleName))
{
MessageBox.Show("Please select a locale (i.e.: country or region) for all accounts.", "Blank region", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
return true;
}
private void persist(AccountsSettings accountsSettings)
{
var existingAccounts = accountsSettings.Accounts;
var dtos = getRowDtos();
// editing account id is a special case. an account is defined by its account id, therefore this is really a different account. the user won't care about this distinction though.
// these will be caught below by normal means and re-created minus the convenience of persisting identity tokens
// delete
for (var i = existingAccounts.Count - 1; i >= 0; i--)
{
var existing = existingAccounts[i];
if (!dtos.Any(dto =>
dto.AccountId?.ToLower().Trim() == existing.AccountId.ToLower()
&& dto.LocaleName == existing.Locale?.Name))
{
accountsSettings.Delete(existing);
}
}
// upsert each. validation occurs through Account and AccountsSettings
foreach (var dto in dtos)
{
var acct = accountsSettings.Upsert(dto.AccountId, dto.LocaleName);
acct.LibraryScan = dto.LibraryScan;
acct.AccountName
= string.IsNullOrWhiteSpace(dto.AccountName)
? $"{dto.AccountId} - {dto.LocaleName}"
: dto.AccountName.Trim();
}
}
private List<AccountDto> getRowDtos()
=> dataGridView1.Rows
.Cast<DataGridViewRow>()
.Where(r => !r.IsNewRow)
.Select(r => new AccountDto
{
AccountId = (string)r.Cells[COL_AccountId].Value,
AccountName = (string)r.Cells[COL_AccountName].Value,
LocaleName = (string)r.Cells[COL_Locale].Value,
LibraryScan = (bool)r.Cells[COL_LibraryScan].Value
})
.ToList();
}
}