mirror of
https://github.com/rmcrackan/Libation.git
synced 2025-12-23 22:17:52 -05:00
Make winforms book details and search syntax dialogs nonmodal
Match Chardonnay behavior
This commit is contained in:
@@ -18,6 +18,18 @@ namespace LibationWinForms
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectionStart
|
||||
{
|
||||
get => textBox1.SelectionStart;
|
||||
set => textBox1.SelectionStart = value;
|
||||
}
|
||||
|
||||
protected override void OnGotFocus(EventArgs e)
|
||||
{
|
||||
base.OnGotFocus(e);
|
||||
textBox1.Focus();
|
||||
}
|
||||
|
||||
public ClearableTextBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -20,8 +20,7 @@ namespace LibationWinForms.Dialogs
|
||||
public LiberatedStatus BookLiberatedStatus { get; private set; }
|
||||
public LiberatedStatus? PdfLiberatedStatus { get; private set; }
|
||||
|
||||
private LibraryBook _libraryBook { get; }
|
||||
private Book Book => _libraryBook.Book;
|
||||
private Book Book => LibraryBook.Book;
|
||||
|
||||
public BookDetailsDialog()
|
||||
{
|
||||
@@ -29,16 +28,23 @@ namespace LibationWinForms.Dialogs
|
||||
this.SetLibationIcon();
|
||||
audibleLink.SetLinkLabelColors();
|
||||
}
|
||||
public BookDetailsDialog(LibraryBook libraryBook) : this()
|
||||
|
||||
public LibraryBook LibraryBook
|
||||
{
|
||||
_libraryBook = ArgumentValidator.EnsureNotNull(libraryBook, nameof(libraryBook));
|
||||
initDetails();
|
||||
initTags();
|
||||
initLiberated();
|
||||
get => field;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
initDetails();
|
||||
initTags();
|
||||
initLiberated();
|
||||
}
|
||||
}
|
||||
|
||||
// 1st draft: lazily cribbed from GridEntry.ctor()
|
||||
private void initDetails()
|
||||
{
|
||||
audibleLink.LinkVisited = false;
|
||||
this.Text = Book.TitleWithSubtitle;
|
||||
dolbyAtmosPb.Visible = Book.IsSpatial;
|
||||
dolbyAtmosPb.Image = Application.IsDarkModeEnabled ? Properties.Resources.Dolby_Atmos_Vertical_80_dark : Properties.Resources.Dolby_Atmos_Vertical_80;
|
||||
@@ -53,7 +59,7 @@ namespace LibationWinForms.Dialogs
|
||||
Narrator(s): {Book.NarratorNames}
|
||||
Length: {(Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min")}
|
||||
Category: {string.Join(", ", Book.LowestCategoryNames())}
|
||||
Purchase Date: {_libraryBook.DateAdded:d}
|
||||
Purchase Date: {LibraryBook.DateAdded:d}
|
||||
Language: {Book.Language}
|
||||
Audible ID: {Book.AudibleProductId}
|
||||
""";
|
||||
@@ -137,7 +143,7 @@ namespace LibationWinForms.Dialogs
|
||||
|
||||
private void audibleLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
var locale = AudibleApi.Localization.Get(_libraryBook.Book.Locale);
|
||||
var locale = AudibleApi.Localization.Get(Book.Locale);
|
||||
var link = $"https://www.audible.{locale.TopDomain}/pd/{Book.AudibleProductId}";
|
||||
Go.To.Url(link);
|
||||
e.Link.Visited = true;
|
||||
|
||||
@@ -149,6 +149,7 @@ namespace LibationWinForms.Dialogs
|
||||
|
||||
templateTb.Text = text.Insert(selStart, itemText);
|
||||
templateTb.SelectionStart = selStart + itemText.Length;
|
||||
templateTb.Focus();
|
||||
}
|
||||
|
||||
private void llblGoToWiki_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
label3.Location = new System.Drawing.Point(4, 18);
|
||||
label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(218, 120);
|
||||
label3.Size = new System.Drawing.Size(218, 150);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = resources.GetString("label3.Text");
|
||||
//
|
||||
@@ -155,6 +155,7 @@
|
||||
lboxIdFields.Name = "lboxIdFields";
|
||||
lboxIdFields.Size = new System.Drawing.Size(220, 305);
|
||||
lboxIdFields.TabIndex = 0;
|
||||
lboxIdFields.DoubleClick += lboxFields_DoubleClick;
|
||||
//
|
||||
// label9
|
||||
//
|
||||
@@ -194,6 +195,7 @@
|
||||
lboxBoolFields.Name = "lboxBoolFields";
|
||||
lboxBoolFields.Size = new System.Drawing.Size(220, 365);
|
||||
lboxBoolFields.TabIndex = 0;
|
||||
lboxBoolFields.DoubleClick += lboxFields_DoubleClick;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
@@ -229,10 +231,11 @@
|
||||
//
|
||||
lboxNumberFields.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
lboxNumberFields.FormattingEnabled = true;
|
||||
lboxNumberFields.Location = new System.Drawing.Point(3, 141);
|
||||
lboxNumberFields.Location = new System.Drawing.Point(3, 171);
|
||||
lboxNumberFields.Name = "lboxNumberFields";
|
||||
lboxNumberFields.Size = new System.Drawing.Size(220, 275);
|
||||
lboxNumberFields.Size = new System.Drawing.Size(220, 245);
|
||||
lboxNumberFields.TabIndex = 0;
|
||||
lboxNumberFields.DoubleClick += lboxFields_DoubleClick;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
@@ -272,6 +275,7 @@
|
||||
lboxStringFields.Name = "lboxStringFields";
|
||||
lboxStringFields.Size = new System.Drawing.Size(220, 350);
|
||||
lboxStringFields.TabIndex = 0;
|
||||
lboxStringFields.DoubleClick += lboxFields_DoubleClick;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using LibationSearchEngine;
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace LibationWinForms.Dialogs
|
||||
{
|
||||
public partial class SearchSyntaxDialog : Form
|
||||
{
|
||||
public event EventHandler<string> TagDoubleClicked;
|
||||
public SearchSyntaxDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -23,5 +24,13 @@ namespace LibationWinForms.Dialogs
|
||||
base.OnFormClosing(e);
|
||||
this.SaveSizeAndLocation(LibationFileManager.Configuration.Instance);
|
||||
}
|
||||
|
||||
private void lboxFields_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ListBox { SelectedItem: string tagName })
|
||||
{
|
||||
TagDoubleClicked?.Invoke(this, tagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace LibationWinForms
|
||||
{
|
||||
protected void Configure_Filter() { }
|
||||
|
||||
private void filterHelpBtn_Click(object sender, EventArgs e) => new SearchSyntaxDialog().ShowDialog();
|
||||
private void filterHelpBtn_Click(object sender, EventArgs e) => ShowSearchSyntaxDialog();
|
||||
|
||||
private void filterSearchTb_TextCleared(object sender, EventArgs e)
|
||||
{
|
||||
@@ -45,5 +45,32 @@ namespace LibationWinForms
|
||||
performFilter(lastGoodFilter);
|
||||
}
|
||||
}
|
||||
|
||||
public SearchSyntaxDialog ShowSearchSyntaxDialog()
|
||||
{
|
||||
var dialog = new SearchSyntaxDialog();
|
||||
dialog.TagDoubleClicked += Dialog_TagDoubleClicked;
|
||||
dialog.FormClosed += Dialog_Closed;
|
||||
filterHelpBtn.Enabled = false;
|
||||
dialog.Show(this);
|
||||
return dialog;
|
||||
|
||||
void Dialog_Closed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
dialog.TagDoubleClicked -= Dialog_TagDoubleClicked;
|
||||
filterHelpBtn.Enabled = true;
|
||||
}
|
||||
void Dialog_TagDoubleClicked(object sender, string tag)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tag)) return;
|
||||
|
||||
var text = filterSearchTb.Text;
|
||||
var selStart = Math.Min(Math.Max(0, filterSearchTb.SelectionStart), text.Length);
|
||||
|
||||
filterSearchTb.Text = text.Insert(selStart, tag);
|
||||
filterSearchTb.SelectionStart = selStart + tag.Length;
|
||||
filterSearchTb.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace LibationWinForms.GridView
|
||||
{
|
||||
public partial class ProductsDisplay : UserControl
|
||||
@@ -68,7 +69,7 @@ namespace LibationWinForms.GridView
|
||||
PictureStorage.PictureCached -= PictureCached;
|
||||
|
||||
if (!imageDisplay.Visible)
|
||||
imageDisplay.Show(null);
|
||||
imageDisplay.Show(this);
|
||||
}
|
||||
|
||||
private void productsGrid_DescriptionClicked(GridEntry liveGridEntry, Rectangle cellRectangle)
|
||||
@@ -90,11 +91,27 @@ namespace LibationWinForms.GridView
|
||||
displayWindow.Show(this);
|
||||
}
|
||||
|
||||
private async void productsGrid_DetailsClicked(LibraryBookEntry liveGridEntry)
|
||||
private BookDetailsDialog bookDetailsForm;
|
||||
private void productsGrid_DetailsClicked(LibraryBookEntry liveGridEntry)
|
||||
{
|
||||
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
|
||||
if (bookDetailsForm.ShowDialog() == DialogResult.OK)
|
||||
await liveGridEntry.LibraryBook.UpdateUserDefinedItemAsync(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
|
||||
if (bookDetailsForm is null || bookDetailsForm.IsDisposed || !bookDetailsForm.Visible)
|
||||
{
|
||||
bookDetailsForm = new();
|
||||
bookDetailsForm.RestoreSizeAndLocation(Configuration.Instance);
|
||||
bookDetailsForm.FormClosed += bookDetailsForm_FormClosed;
|
||||
}
|
||||
|
||||
bookDetailsForm.LibraryBook = liveGridEntry.LibraryBook;
|
||||
if (!bookDetailsForm.Visible)
|
||||
bookDetailsForm.Show(this);
|
||||
|
||||
async void bookDetailsForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
bookDetailsForm.FormClosed -= bookDetailsForm_FormClosed;
|
||||
bookDetailsForm.SaveSizeAndLocation(Configuration.Instance);
|
||||
if (e.CloseReason is CloseReason.UserClosing && bookDetailsForm.DialogResult is DialogResult.OK)
|
||||
await liveGridEntry.LibraryBook.UpdateUserDefinedItemAsync(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -144,19 +144,10 @@ namespace LibationWinForms
|
||||
LibraryCommands.ScanEnd += LibraryCommands_ScanEnd;
|
||||
await tcs.Task;
|
||||
LibraryCommands.ScanEnd -= LibraryCommands_ScanEnd;
|
||||
MainForm.productsDisplay.VisibleCountChanged -= productsDisplay_VisibleCountChanged;
|
||||
|
||||
return true;
|
||||
|
||||
void LibraryCommands_ScanEnd(object sender, int newCount)
|
||||
{
|
||||
//if we imported new books, wait for the grid to update before proceeding.
|
||||
if (newCount > 0)
|
||||
MainForm.productsDisplay.VisibleCountChanged += productsDisplay_VisibleCountChanged;
|
||||
else
|
||||
tcs.SetResult();
|
||||
}
|
||||
void productsDisplay_VisibleCountChanged(object sender, int e) => tcs.SetResult();
|
||||
void LibraryCommands_ScanEnd(object _, int __) => tcs.SetResult();
|
||||
}
|
||||
|
||||
private async Task<bool> ShowSearching()
|
||||
@@ -189,9 +180,10 @@ namespace LibationWinForms
|
||||
|
||||
await displayControlAsync(MainForm.filterHelpBtn);
|
||||
|
||||
using var filterHelp = MainForm.Invoke(() => new SearchSyntaxDialog());
|
||||
MainForm.Invoke(filterHelp.ShowDialog);
|
||||
|
||||
using var filterHelp = MainForm.Invoke(MainForm.ShowSearchSyntaxDialog);
|
||||
var tcs = new TaskCompletionSource();
|
||||
filterHelp.FormClosed += (_, _) => tcs.SetResult();
|
||||
await tcs.Task;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user