Compare commits
18 Commits
v3.1-beta.
...
v3.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79e0a8fba7 | ||
|
|
8497987967 | ||
|
|
717fefd2c0 | ||
|
|
066cae8e33 | ||
|
|
9083574a77 | ||
|
|
6b1ab9c777 | ||
|
|
3be7c87c8e | ||
|
|
8694d3206b | ||
|
|
f67f3805c6 | ||
|
|
612dd41b4b | ||
|
|
13378a482d | ||
|
|
352b498c23 | ||
|
|
3a652cfb70 | ||
|
|
93e9ce31ba | ||
|
|
69ed7767b2 | ||
|
|
6fcaa8d551 | ||
|
|
15ece43463 | ||
|
|
25f5f0ed14 |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 100 KiB |
90
LibationWinForms/Properties/Resources.Designer.cs
generated
@@ -109,5 +109,95 @@ namespace LibationWinForms.Properties {
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_green {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_green", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_green_pdf_no {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_green_pdf_no", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_green_pdf_yes {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_green_pdf_yes", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_red {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_red", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_red_pdf_no {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_red_pdf_no", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_red_pdf_yes {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_red_pdf_yes", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_yellow {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_yellow", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_yellow_pdf_no {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_yellow_pdf_no", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap liberate_yellow_pdf_yes {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("liberate_yellow_pdf_yes", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,4 +133,31 @@
|
||||
<data name="edit_tags_50x50" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\edit-tags-50x50.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_green" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_green.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_green_pdf_no" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_green_pdf_no.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_green_pdf_yes" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_green_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_red" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_red.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_red_pdf_no" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_red_pdf_no.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_red_pdf_yes" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_red_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_yellow" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_yellow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_yellow_pdf_no" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_yellow_pdf_no.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="liberate_yellow_pdf_yes" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\liberate_yellow_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow.ico
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_128.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_16.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_256.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_32.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_512.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
LibationWinForms/Resources/Libation icon/glass-with-glow_64.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
@@ -1,6 +1,6 @@
|
||||
how to create the app's icon
|
||||
============================
|
||||
https://www.flaticon.com/free-icon/glass-with-wine_33529#term=wine&page=1&position=59
|
||||
orig from (no longer available) https://www.flaticon.com/free-icon/glass-with-wine_33529
|
||||
get this image, color=black, at each of these sizes: 16,32,64,128,256
|
||||
|
||||
from this answer: https://stackoverflow.com/a/16922387
|
||||
|
||||
BIN
LibationWinForms/Resources/download-arrow.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 100 KiB |
BIN
LibationWinForms/Resources/liberate and pdf icons.pdn
Normal file
BIN
LibationWinForms/Resources/liberate icons.pdn
Normal file
BIN
LibationWinForms/Resources/liberate_green.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
LibationWinForms/Resources/liberate_green_pdf_no.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
LibationWinForms/Resources/liberate_green_pdf_yes.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
LibationWinForms/Resources/liberate_red.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
LibationWinForms/Resources/liberate_red_pdf_no.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
LibationWinForms/Resources/liberate_red_pdf_yes.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
LibationWinForms/Resources/liberate_yellow.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
LibationWinForms/Resources/liberate_yellow_pdf_no.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
LibationWinForms/Resources/liberate_yellow_pdf_yes.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
2
LibationWinForms/Resources/pdf source.url
Normal file
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=https://www.flaticon.com/free-icon/pdf-file-format-symbol_29099
|
||||
2
LibationWinForms/Resources/stoplight source.url
Normal file
@@ -0,0 +1,2 @@
|
||||
[InternetShortcut]
|
||||
URL=https://www.flaticon.com/free-icon/semaphore_55291
|
||||
@@ -26,44 +26,19 @@ namespace LibationWinForms
|
||||
[Browsable(false)]
|
||||
public IEnumerable<string> TagsEnumerated => book.UserDefinedItem.TagsEnumerated;
|
||||
|
||||
public enum LiberatedState { NotDownloaded, DRM, Liberated }
|
||||
[Browsable(false)]
|
||||
public string Download_Status
|
||||
{
|
||||
get
|
||||
{
|
||||
var print
|
||||
= FileManager.AudibleFileStorage.Audio.Exists(book.AudibleProductId) ? "Liberated"
|
||||
: FileManager.AudibleFileStorage.AAX.Exists(book.AudibleProductId) ? "DRM"
|
||||
: "NOT d/l'ed";
|
||||
public LiberatedState Liberated_Status
|
||||
=> FileManager.AudibleFileStorage.Audio.Exists(book.AudibleProductId) ? LiberatedState.Liberated
|
||||
: FileManager.AudibleFileStorage.AAX.Exists(book.AudibleProductId) ? LiberatedState.DRM
|
||||
: LiberatedState.NotDownloaded;
|
||||
|
||||
if (!book.Supplements.Any())
|
||||
return print;
|
||||
|
||||
print += "\r\n";
|
||||
|
||||
var downloadStatuses = book.Supplements
|
||||
.Select(d => FileManager.AudibleFileStorage.PDF.Exists(book.AudibleProductId))
|
||||
// break delayed execution right now!
|
||||
.ToList();
|
||||
var count = downloadStatuses.Count;
|
||||
if (count == 1)
|
||||
{
|
||||
print += downloadStatuses[0]
|
||||
? "PDF d/l'ed"
|
||||
: "PDF NOT d/l'ed";
|
||||
}
|
||||
else
|
||||
{
|
||||
var downloadedCount = downloadStatuses.Count(s => s);
|
||||
print
|
||||
+= downloadedCount == count ? $"{count} PDFs d/l'ed"
|
||||
: downloadedCount == 0 ? $"{count} PDFs NOT d/l'ed"
|
||||
: $"{downloadedCount} of {count} PDFs d/l'ed";
|
||||
}
|
||||
|
||||
return print;
|
||||
}
|
||||
}
|
||||
public enum PdfState { NoPdf, Downloaded, NotDownloaded }
|
||||
[Browsable(false)]
|
||||
public PdfState Pdf_Status
|
||||
=> !book.Supplements.Any() ? PdfState.NoPdf
|
||||
: FileManager.AudibleFileStorage.PDF.Exists(book.AudibleProductId) ? PdfState.Downloaded
|
||||
: PdfState.NotDownloaded;
|
||||
|
||||
// displayValues is what gets displayed
|
||||
// the value that gets returned from the property is the cell's value
|
||||
|
||||
@@ -74,8 +74,16 @@ namespace LibationWinForms
|
||||
private void replaceFormatted(object sender, DataGridViewCellFormattingEventArgs e)
|
||||
{
|
||||
var col = ((DataGridView)sender).Columns[e.ColumnIndex];
|
||||
if (col is DataGridViewTextBoxColumn textCol && GetGridEntry(e.RowIndex).TryDisplayValue(textCol.Name, out string value))
|
||||
if (col is DataGridViewTextBoxColumn textCol && getGridEntry(e.RowIndex).TryDisplayValue(textCol.Name, out string value))
|
||||
{
|
||||
// DO NOT DO THIS: getCell(e).Value = value;
|
||||
// it's the wrong way and will infinitely call CellFormatting on each assign
|
||||
|
||||
// this is the correct way. will actually set FormattedValue (and EditedFormattedValue) while leaving Value as-is for sorting
|
||||
e.Value = value;
|
||||
|
||||
getCell(e).ToolTipText = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void hiddenFormatting(object sender, DataGridViewCellFormattingEventArgs e)
|
||||
@@ -85,9 +93,9 @@ namespace LibationWinForms
|
||||
if (e.RowIndex < 0 || dgv.Columns[e.ColumnIndex] is DataGridViewButtonColumn)
|
||||
return;
|
||||
|
||||
var isHidden = GetGridEntry(e.RowIndex).TagsEnumerated.Contains("hidden");
|
||||
var isHidden = getGridEntry(e.RowIndex).TagsEnumerated.Contains("hidden");
|
||||
|
||||
dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Style
|
||||
getCell(e).Style
|
||||
= isHidden
|
||||
? new DataGridViewCellStyle { ForeColor = Color.LightGray }
|
||||
: dgv.DefaultCellStyle;
|
||||
@@ -105,22 +113,66 @@ namespace LibationWinForms
|
||||
|
||||
private void liberate_Paint(object sender, DataGridViewCellPaintingEventArgs e)
|
||||
{
|
||||
var dgv = (DataGridView)sender;
|
||||
|
||||
if (!isColumnValid(dgv, e.RowIndex, e.ColumnIndex, LIBERATE))
|
||||
if (!isColumnValid(e, LIBERATE))
|
||||
return;
|
||||
|
||||
dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = GetGridEntry(e.RowIndex).Download_Status;
|
||||
var cell = getCell(e);
|
||||
var gridEntry = getGridEntry(e.RowIndex);
|
||||
var liberatedStatus = gridEntry.Liberated_Status;
|
||||
var pdfStatus = gridEntry.Pdf_Status;
|
||||
|
||||
// mouseover text
|
||||
{
|
||||
var libState = liberatedStatus switch
|
||||
{
|
||||
GridEntry.LiberatedState.Liberated => "Liberated",
|
||||
GridEntry.LiberatedState.DRM => "Downloaded but needs DRM removed",
|
||||
GridEntry.LiberatedState.NotDownloaded => "Book NOT downloaded",
|
||||
_ => throw new Exception("Unexpected liberation state")
|
||||
};
|
||||
|
||||
var pdfState = pdfStatus switch
|
||||
{
|
||||
GridEntry.PdfState.Downloaded => "\r\nPDF downloaded",
|
||||
GridEntry.PdfState.NotDownloaded => "\r\nPDF NOT downloaded",
|
||||
GridEntry.PdfState.NoPdf => "",
|
||||
_ => throw new Exception("Unexpected PDF state")
|
||||
};
|
||||
|
||||
var text = libState + pdfState;
|
||||
|
||||
if (liberatedStatus == GridEntry.LiberatedState.NotDownloaded ||
|
||||
liberatedStatus == GridEntry.LiberatedState.DRM ||
|
||||
pdfStatus == GridEntry.PdfState.NotDownloaded)
|
||||
text += "\r\nClick to complete";
|
||||
|
||||
//DEBUG//cell.Value = text;
|
||||
cell.ToolTipText = text;
|
||||
}
|
||||
|
||||
// draw img
|
||||
{
|
||||
var image_lib
|
||||
= liberatedStatus == GridEntry.LiberatedState.NotDownloaded ? "red"
|
||||
: liberatedStatus == GridEntry.LiberatedState.DRM ? "yellow"
|
||||
: liberatedStatus == GridEntry.LiberatedState.Liberated ? "green"
|
||||
: throw new Exception("Unexpected liberation state");
|
||||
var image_pdf
|
||||
= pdfStatus == GridEntry.PdfState.NoPdf ? ""
|
||||
: pdfStatus == GridEntry.PdfState.NotDownloaded ? "_pdf_no"
|
||||
: pdfStatus == GridEntry.PdfState.Downloaded ? "_pdf_yes"
|
||||
: throw new Exception("Unexpected PDF state");
|
||||
var image = (Bitmap)Properties.Resources.ResourceManager.GetObject($"liberate_{image_lib}{image_pdf}");
|
||||
drawImage(e, image);
|
||||
}
|
||||
}
|
||||
|
||||
private async void liberate_Click(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
var dgv = (DataGridView)sender;
|
||||
|
||||
if (!isColumnValid(dgv, e.RowIndex, e.ColumnIndex, LIBERATE))
|
||||
if (!isColumnValid(e, LIBERATE))
|
||||
return;
|
||||
|
||||
var productId = GetGridEntry(e.RowIndex).GetBook().AudibleProductId;
|
||||
var productId = getGridEntry(e.RowIndex).GetBook().AudibleProductId;
|
||||
|
||||
// if liberated, open explorer to file
|
||||
if (FileManager.AudibleFileStorage.Audio.Exists(productId))
|
||||
@@ -139,7 +191,7 @@ namespace LibationWinForms
|
||||
|
||||
public void RefreshRow(string productId)
|
||||
{
|
||||
var rowId = GetRowId((ge) => ge.GetBook().AudibleProductId == productId);
|
||||
var rowId = getRowId((ge) => ge.GetBook().AudibleProductId == productId);
|
||||
|
||||
// update cells incl Liberate button text
|
||||
dataGridView.InvalidateRow(rowId);
|
||||
@@ -160,33 +212,21 @@ namespace LibationWinForms
|
||||
{
|
||||
// DataGridView Image for Button Column: https://stackoverflow.com/a/36253883
|
||||
|
||||
var dgv = (DataGridView)sender;
|
||||
|
||||
if (!isColumnValid(dgv, e.RowIndex, e.ColumnIndex, EDIT_TAGS))
|
||||
if (!isColumnValid(e, EDIT_TAGS))
|
||||
return;
|
||||
|
||||
var displayTags = GetGridEntry(e.RowIndex).TagsEnumerated.ToList();
|
||||
var cell = getCell(e);
|
||||
var gridEntry = getGridEntry(e.RowIndex);
|
||||
|
||||
var cell = dgv.Rows[e.RowIndex].Cells[e.ColumnIndex];
|
||||
var displayTags = gridEntry.TagsEnumerated.ToList();
|
||||
|
||||
if (displayTags.Any())
|
||||
cell.Value = string.Join("\r\n", displayTags);
|
||||
else // no tags: use image
|
||||
else
|
||||
{
|
||||
// clear tag text
|
||||
// if removing all tags: clear previous tag text
|
||||
cell.Value = "";
|
||||
|
||||
var image = Properties.Resources.edit_tags_25x25;
|
||||
|
||||
e.Paint(e.CellBounds, DataGridViewPaintParts.All);
|
||||
|
||||
var w = image.Width;
|
||||
var h = image.Height;
|
||||
var x = e.CellBounds.Left + (e.CellBounds.Width - w) / 2;
|
||||
var y = e.CellBounds.Top + (e.CellBounds.Height - h) / 2;
|
||||
|
||||
e.Graphics.DrawImage(image, new Rectangle(x, y, w, h));
|
||||
e.Handled = true;
|
||||
drawImage(e, Properties.Resources.edit_tags_25x25);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,10 +236,10 @@ namespace LibationWinForms
|
||||
|
||||
var dgv = (DataGridView)sender;
|
||||
|
||||
if (!isColumnValid(dgv, e.RowIndex, e.ColumnIndex, EDIT_TAGS))
|
||||
if (!isColumnValid(e, EDIT_TAGS))
|
||||
return;
|
||||
|
||||
var liveGridEntry = GetGridEntry(e.RowIndex);
|
||||
var liveGridEntry = getGridEntry(e.RowIndex);
|
||||
|
||||
// EditTagsDialog should display better-formatted title
|
||||
liveGridEntry.TryDisplayValue(nameof(liveGridEntry.Title), out string value);
|
||||
@@ -221,10 +261,25 @@ namespace LibationWinForms
|
||||
}
|
||||
#endregion
|
||||
|
||||
private static bool isColumnValid(DataGridView dgv, int rowIndex, int colIndex, string colName)
|
||||
private static void drawImage(DataGridViewCellPaintingEventArgs e, Bitmap image)
|
||||
{
|
||||
var col = dgv.Columns[colIndex];
|
||||
return rowIndex >= 0 && col.HeaderText == colName && col is DataGridViewButtonColumn;
|
||||
e.Paint(e.CellBounds, DataGridViewPaintParts.All);
|
||||
|
||||
var w = image.Width;
|
||||
var h = image.Height;
|
||||
var x = e.CellBounds.Left + (e.CellBounds.Width - w) / 2;
|
||||
var y = e.CellBounds.Top + (e.CellBounds.Height - h) / 2;
|
||||
|
||||
e.Graphics.DrawImage(image, new Rectangle(x, y, w, h));
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private bool isColumnValid(DataGridViewCellEventArgs e, string colName) => isColumnValid(e.RowIndex, e.ColumnIndex, colName);
|
||||
private bool isColumnValid(DataGridViewCellPaintingEventArgs e, string colName) => isColumnValid(e.RowIndex, e.ColumnIndex, colName);
|
||||
private bool isColumnValid(int rowIndex, int colIndex, string colName)
|
||||
{
|
||||
var col = dataGridView.Columns[colIndex];
|
||||
return rowIndex >= 0 && col.Name == colName && col is DataGridViewButtonColumn;
|
||||
}
|
||||
|
||||
private void formatColumns()
|
||||
@@ -243,6 +298,7 @@ namespace LibationWinForms
|
||||
|
||||
col.Width = col.Name switch
|
||||
{
|
||||
LIBERATE => 70,
|
||||
nameof(GridEntry.Cover) => 80,
|
||||
nameof(GridEntry.Title) => col.Width * 2,
|
||||
nameof(GridEntry.Misc) => (int)(col.Width * 1.35),
|
||||
@@ -263,7 +319,7 @@ namespace LibationWinForms
|
||||
=> dataGridView.UIThread(() => updateRowImage(pictureId));
|
||||
private void updateRowImage(string pictureId)
|
||||
{
|
||||
var rowId = GetRowId((ge) => ge.GetBook().PictureId == pictureId);
|
||||
var rowId = getRowId((ge) => ge.GetBook().PictureId == pictureId);
|
||||
if (rowId > -1)
|
||||
dataGridView.InvalidateRow(rowId);
|
||||
}
|
||||
@@ -331,7 +387,7 @@ namespace LibationWinForms
|
||||
currencyManager.SuspendBinding();
|
||||
{
|
||||
for (var r = dataGridView.RowCount - 1; r >= 0; r--)
|
||||
dataGridView.Rows[r].Visible = productIds.Contains(GetGridEntry(r).GetBook().AudibleProductId);
|
||||
dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).GetBook().AudibleProductId);
|
||||
}
|
||||
currencyManager.ResumeBinding();
|
||||
VisibleCountChanged?.Invoke(this, dataGridView.AsEnumerable().Count(r => r.Visible));
|
||||
@@ -340,8 +396,14 @@ namespace LibationWinForms
|
||||
}
|
||||
#endregion
|
||||
|
||||
private int GetRowId(Func<GridEntry, bool> func) => dataGridView.GetRowIdOfBoundItem(func);
|
||||
private int getRowId(Func<GridEntry, bool> func) => dataGridView.GetRowIdOfBoundItem(func);
|
||||
|
||||
private GridEntry GetGridEntry(int rowIndex) => dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
||||
}
|
||||
private GridEntry getGridEntry(int rowIndex) => dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
||||
|
||||
private DataGridViewCell getCell(DataGridViewCellFormattingEventArgs e) => getCell(e.RowIndex, e.ColumnIndex);
|
||||
|
||||
private DataGridViewCell getCell(DataGridViewCellPaintingEventArgs e) => getCell(e.RowIndex, e.ColumnIndex);
|
||||
|
||||
private DataGridViewCell getCell(int rowIndex, int columnIndex) => dataGridView.Rows[rowIndex].Cells[columnIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 100 KiB |
40
README.md
@@ -16,6 +16,8 @@
|
||||
- [Searches](#searches)
|
||||
- [Search examples](#search-examples)
|
||||
- [Filters](#filters)
|
||||
4. [Advanced](#advanced)
|
||||
- [Files and folders](#files-and-folders)
|
||||
|
||||
## Audible audiobook manager
|
||||
|
||||
@@ -36,6 +38,7 @@
|
||||
|
||||
* Windows only
|
||||
* Several known speed/performance issues
|
||||
* Large file size
|
||||
* Made by a programmer, not a designer so the goals are function rather than beauty. And it shows
|
||||
|
||||
### The ugly
|
||||
@@ -68,10 +71,22 @@ Success! We see how many new titles are imported:
|
||||
|
||||
Automatically download some or all of your audible books. This shows you how much of your library is not yet downloaded and decrypted:
|
||||
|
||||
The stoplights will tell you a title's status:
|
||||
|
||||
* Green: downloaded and decrypted
|
||||
* Yellow: downloaded but still encrypted with DRM
|
||||
* Red: not downloaded
|
||||
* PDF icon without arrow: downloaded
|
||||
* PDF with arrow: not downloaded
|
||||
|
||||
Or hover over the button to see the status.
|
||||
|
||||

|
||||
|
||||
Select Liberate > Begin Book Backups
|
||||
|
||||
You can also click on the stop light to download only that title and its PDF
|
||||
|
||||

|
||||
|
||||
First the original book with DRM is downloaded
|
||||
@@ -86,12 +101,12 @@ And voila! If you have multiple books not yet liberated, Libation will automatic
|
||||
|
||||

|
||||
|
||||
The Audible id must be somewhere in the book's file or folder name for Libation to detect your downloaded book.
|
||||
|
||||
### Download PDF attachments
|
||||
|
||||
For books which include PDF downloads, Libation can download these for you as well and will attempt to store them with the book. "Book backup" will already download an available PDF. This additional option is useful when Audible adds a PDF to your book after you've already backed it up.
|
||||
|
||||

|
||||
|
||||
Select Liberate > Begin PDF Backups
|
||||
|
||||

|
||||
@@ -100,10 +115,6 @@ The downloads work just like with books, only with no additional decryption need
|
||||
|
||||

|
||||
|
||||
Ta da!
|
||||
|
||||

|
||||
|
||||
### Details of downloaded files
|
||||
|
||||

|
||||
@@ -156,11 +167,12 @@ If you only want to see Harry Potter
|
||||
|
||||

|
||||
|
||||
If you only want to see potter except for Harry Potter
|
||||
If you only want to see potter except for Harry Potter. You can also use "-" instead of "NOT"
|
||||
|
||||

|
||||

|
||||
|
||||
Only books written by Neil Gaiman where he also narrates his own book. (If you don't include AND, you'll see everything written by Neil Gaiman and also all books in your library which are self-narrated.)
|
||||
To see only books written by Neil Gaiman where he also narrates his own book. (If you don't include AND, you'll see everything written by Neil Gaiman and also all books in your library which are self-narrated.)
|
||||
|
||||

|
||||
|
||||
@@ -178,3 +190,15 @@ To edit this list go to Quick Filters > Edit quick filters. Here you can re-orde
|
||||
Check "Quick Filters > Start Libation with 1st filter Default" to have your top filter automatically applied when Libation starts. In this top example, I want to always start without these: at books I've tagged hidden, books I've tagged as free_audible_originals, and books which I have rated.
|
||||
|
||||

|
||||
|
||||
## Advanced
|
||||
|
||||
### Files and folders
|
||||
|
||||
To make upgrades and reinstalls easier, Libation separates all of its responsibilities to a few different folders. If you don't want to mess with this stuff: ignore it. Read on if you like a little more control over your files.
|
||||
|
||||
* In Libation's initial folder are the files that make up the program. Since nothing else is here, just copy new files here to upgrade the program. Delete this folder to delete Libation.
|
||||
|
||||
* In a separate folder, Libation keeps track of all of the files it creates like settings and downloaded images. After an upgrade, Libation might think that's its being run for the first time. Just click ADVANCED SETUP and point to this folder. Libation will reload your library and settings.
|
||||
|
||||
* The last important folder is the "books location." This is where Libation looks for your downloaded and decrypted books. This is how it knows which books still need to be downloaded. The Audible id must be somewhere in the book's file or folder name for Libation to detect your downloaded book.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
-- begin VERSIONING ---------------------------------------------------------------------------------------------------------------------
|
||||
https://github.com/rmcrackan/Libation/releases
|
||||
|
||||
v3.1.0 : FIRST PUBLIC RELEASE
|
||||
v3.1-beta.11 : Improved configuration and settings file management. Configurable logging
|
||||
v3.1-beta.10 : New feature: clicking Liberate button on a liberated item navigates to that audio file
|
||||
v3.1-beta.9 : New feature: liberate individual book
|
||||
|
||||
|
Before Width: | Height: | Size: 314 B |
|
Before Width: | Height: | Size: 573 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |
BIN
images/SearchExamplePotterNotHarry2.png
Normal file
|
After Width: | Height: | Size: 21 KiB |