Skip to content

Commit c84c2c5

Browse files
committed
Add "Mine primary spelling button" and "Mine button" options (Closes #114)
Fix popup scrolling that happens when mining button is clicked Don't expose "Selected Reading" field for kanji dictionaries
1 parent 6bf61d6 commit c84c2c5

10 files changed

+179
-181
lines changed

JL.Core/Dicts/DictUtils.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ public static class DictUtils
454454
DictType.NonspecificNazeka
455455
];
456456

457-
internal static readonly DictType[] s_kanjiDictTypes =
457+
public static readonly DictType[] KanjiDictTypes =
458458
[
459459
DictType.Kanjidic,
460460
DictType.NonspecificKanjiYomichan,

JL.Core/Mining/JLFieldUtils.cs

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public static class JLFieldUtils
4848
public static readonly JLField[] JLFieldsForKanjiDicts =
4949
[
5050
JLField.Nothing,
51-
JLField.SelectedSpelling,
5251
JLField.PrimarySpelling,
5352
JLField.Readings,
5453
JLField.KunReadings,

JL.Core/Mining/MiningUtils.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,9 @@ private static Dictionary<JLField, string> GetMiningParameters(LookupResult[] lo
688688
{
689689
dictTypes = DictUtils.s_wordDictTypes;
690690
}
691-
else if (DictUtils.s_kanjiDictTypes.Contains(selectedLookupResult.Dict.Type))
691+
else if (DictUtils.KanjiDictTypes.Contains(selectedLookupResult.Dict.Type))
692692
{
693-
dictTypes = DictUtils.s_kanjiDictTypes;
693+
dictTypes = DictUtils.KanjiDictTypes;
694694
}
695695
else if (DictUtils.s_nameDictTypes.Contains(selectedLookupResult.Dict.Type))
696696
{
@@ -1055,7 +1055,7 @@ public static async Task MineToFile(LookupResult[] lookupResults, int currentLoo
10551055
filePath = Path.Join(Utils.ResourcesPath, "mined_names.txt");
10561056
jlFields = JLFieldUtils.JLFieldsForNameDicts;
10571057
}
1058-
else if (DictUtils.s_kanjiDictTypes.Contains(lookupResult.Dict.Type))
1058+
else if (DictUtils.KanjiDictTypes.Contains(lookupResult.Dict.Type))
10591059
{
10601060
filePath = Path.Join(Utils.ResourcesPath, "mined_kanjis.txt");
10611061
jlFields = JLFieldUtils.JLFieldsForKanjiDicts;
@@ -1118,7 +1118,7 @@ public static async Task MineToFile(LookupResult[] lookupResults, int currentLoo
11181118
{
11191119
_ = ankiConfigDict.TryGetValue(MineType.Word, out ankiConfig);
11201120
}
1121-
else if (DictUtils.s_kanjiDictTypes.Contains(dictType))
1121+
else if (DictUtils.KanjiDictTypes.Contains(dictType))
11221122
{
11231123
_ = ankiConfigDict.TryGetValue(MineType.Kanji, out ankiConfig);
11241124
}
@@ -1194,7 +1194,7 @@ public static async Task Mine(LookupResult[] lookupResults, int currentLookupRes
11941194
{
11951195
_ = ankiConfigDict.TryGetValue(MineType.Word, out ankiConfig);
11961196
}
1197-
else if (DictUtils.s_kanjiDictTypes.Contains(lookupResult.Dict.Type))
1197+
else if (DictUtils.KanjiDictTypes.Contains(lookupResult.Dict.Type))
11981198
{
11991199
_ = ankiConfigDict.TryGetValue(MineType.Kanji, out ankiConfig);
12001200
}

JL.Windows/ConfigManager.cs

+28
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ internal sealed class ConfigManager
132132
public bool AutoLookupFirstTermWhenTextIsCopiedFromClipboard { get; private set; } // = false;
133133
public bool AutoLookupFirstTermWhenTextIsCopiedFromWebSocket { get; private set; } // = false;
134134
public bool AutoLookupFirstTermOnTextChangeOnlyWhenMainWindowIsMinimized { get; private set; } = true;
135+
public MouseButton MineMouseButton { get; private set; } = MouseButton.Left;
136+
public MouseButton MinePrimarySpellingMouseButton { get; private set; } = MouseButton.Middle;
135137

136138
#endregion
137139

@@ -282,6 +284,24 @@ public void ApplyPreferences(SqliteConnection connection)
282284

283285
LookupOnClickMouseButton = ConfigDBManager.GetValueFromConfig(connection, LookupOnClickMouseButton, nameof(LookupOnClickMouseButton), Enum.TryParse);
284286
MiningModeMouseButton = ConfigDBManager.GetValueFromConfig(connection, MiningModeMouseButton, nameof(MiningModeMouseButton), Enum.TryParse);
287+
288+
MouseButton mineMouseButton = ConfigDBManager.GetValueFromConfig(connection, MineMouseButton, nameof(MineMouseButton), Enum.TryParse);
289+
MouseButton minePrimarySpellingMouseButton = ConfigDBManager.GetValueFromConfig(connection, MinePrimarySpellingMouseButton, nameof(MinePrimarySpellingMouseButton), Enum.TryParse);
290+
if (mineMouseButton == minePrimarySpellingMouseButton)
291+
{
292+
if (minePrimarySpellingMouseButton == MouseButton.Left)
293+
{
294+
minePrimarySpellingMouseButton = MouseButton.Middle;
295+
}
296+
else
297+
{
298+
mineMouseButton = MouseButton.Left;
299+
}
300+
}
301+
302+
MineMouseButton = mineMouseButton;
303+
MinePrimarySpellingMouseButton = minePrimarySpellingMouseButton;
304+
285305
MainWindowTextVerticalAlignment = ConfigDBManager.GetValueFromConfig(connection, MainWindowTextVerticalAlignment, nameof(MainWindowTextVerticalAlignment), Enum.TryParse);
286306
mainWindow.MainTextBox.VerticalContentAlignment = MainWindowTextVerticalAlignment;
287307

@@ -962,6 +982,8 @@ public void LoadPreferenceWindow(PreferencesWindow preferenceWindow)
962982

963983
preferenceWindow.LookupOnClickMouseButtonComboBox.SelectedValue = LookupOnClickMouseButton.ToString();
964984
preferenceWindow.MiningModeMouseButtonComboBox.SelectedValue = MiningModeMouseButton.ToString();
985+
preferenceWindow.MineMouseButtonComboBox.SelectedValue = MineMouseButton.ToString();
986+
preferenceWindow.MinePrimarySpellingMouseButtonComboBox.SelectedValue = MinePrimarySpellingMouseButton.ToString();
965987

966988
preferenceWindow.ShowMiningModeReminderCheckBox.IsChecked = ShowMiningModeReminder;
967989
preferenceWindow.DisableLookupsForNonJapaneseCharsInPopupsCheckBox.IsChecked = DisableLookupsForNonJapaneseCharsInPopups;
@@ -1395,6 +1417,12 @@ public async Task SavePreferences(PreferencesWindow preferenceWindow)
13951417
ConfigDBManager.UpdateSetting(connection, nameof(MiningModeMouseButton),
13961418
preferenceWindow.MiningModeMouseButtonComboBox.SelectedValue.ToString()!);
13971419

1420+
ConfigDBManager.UpdateSetting(connection, nameof(MineMouseButton),
1421+
preferenceWindow.MineMouseButtonComboBox.SelectedValue.ToString()!);
1422+
1423+
ConfigDBManager.UpdateSetting(connection, nameof(MinePrimarySpellingMouseButton),
1424+
preferenceWindow.MinePrimarySpellingMouseButtonComboBox.SelectedValue.ToString()!);
1425+
13981426
MainWindow mainWindow = MainWindow.Instance;
13991427
DpiScale dpi = WindowsUtils.Dpi;
14001428
ConfigDBManager.UpdateSetting(connection, "MainWindowTopPosition",

JL.Windows/GUI/MiningSelectionWindow.xaml.cs

+10-74
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using JL.Core.Lookup;
66
using JL.Core.Mining;
77
using JL.Windows.Utilities;
8-
using Rectangle = System.Drawing.Rectangle;
98

109
namespace JL.Windows.GUI;
1110

@@ -18,24 +17,20 @@ internal sealed partial class MiningSelectionWindow
1817
private readonly LookupResult[] _lookupResults;
1918
private readonly int _currentLookupResultIndex;
2019
private readonly string _currentSourceText;
21-
private readonly string? _formattedDefinitions;
22-
private readonly string? _selectedDefinitions;
2320
private readonly int _currentSourceTextCharPosition;
2421

2522
private nint _windowHandle;
2623

2724
private static MiningSelectionWindow? s_instance;
2825

29-
private MiningSelectionWindow(PopupWindow owner, LookupResult[] lookupResults, int currentLookupResultIndex, string currentSourceText, string? formattedDefinitions, string? selectedDefinitions, int currentSourceTextCharPosition)
26+
private MiningSelectionWindow(PopupWindow owner, LookupResult[] lookupResults, int currentLookupResultIndex, string currentSourceText, int currentSourceTextCharPosition)
3027
{
3128
InitializeComponent();
3229
Owner = owner;
3330
_popupWindow = owner;
3431
_lookupResults = lookupResults;
3532
_currentLookupResultIndex = currentLookupResultIndex;
3633
_currentSourceText = currentSourceText;
37-
_formattedDefinitions = formattedDefinitions;
38-
_selectedDefinitions = selectedDefinitions;
3934
_currentSourceTextCharPosition = currentSourceTextCharPosition;
4035
}
4136

@@ -44,9 +39,9 @@ public static bool IsItVisible()
4439
return s_instance?.IsVisible ?? false;
4540
}
4641

47-
internal static void Show(PopupWindow owner, LookupResult[] lookupResults, int currentLookupResultIndex, string currentSourceText, string? formattedDefinitions, string? selectedDefinitions, int currentSourceTextCharPosition)
42+
internal static void Show(PopupWindow owner, LookupResult[] lookupResults, int currentLookupResultIndex, string currentSourceText, int currentSourceTextCharPosition)
4843
{
49-
MiningSelectionWindow currentInstance = s_instance ??= new MiningSelectionWindow(owner, lookupResults, currentLookupResultIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition);
44+
MiningSelectionWindow currentInstance = s_instance ??= new MiningSelectionWindow(owner, lookupResults, currentLookupResultIndex, currentSourceText, currentSourceTextCharPosition);
5045
ConfigManager configManager = ConfigManager.Instance;
5146

5247
ListViewItem[] listViewItem;
@@ -73,7 +68,7 @@ internal static void Show(PopupWindow owner, LookupResult[] lookupResults, int c
7368
currentInstance.FontFamily = configManager.PopupFont;
7469
currentInstance.Owner = owner;
7570
currentInstance.Show();
76-
currentInstance.UpdatePosition(WinApi.GetMousePosition());
71+
WindowsUtils.UpdatePositionForSelectionWindows(currentInstance, currentInstance._windowHandle, WinApi.GetMousePosition());
7772

7873
if (configManager.Focusable)
7974
{
@@ -105,81 +100,22 @@ protected override void OnActivated(EventArgs e)
105100
// ReSharper disable once AsyncVoidMethod
106101
private async void MiningListView_PreviewMouseUp(object sender, MouseButtonEventArgs e)
107102
{
103+
TextBox? definitionsTextBox = _popupWindow.GetDefinitionTextBox(_currentLookupResultIndex);
104+
string? formattedDefinitions = definitionsTextBox?.Text;
105+
string? selectedDefinitions = PopupWindowUtils.GetSelectedDefinitions(definitionsTextBox);
106+
108107
string selectedSpelling = (string)((ListViewItem)sender).Content;
109108
_popupWindow.HidePopup();
110109

111110
ConfigManager configManager = ConfigManager.Instance;
112111
if (configManager.MineToFileInsteadOfAnki)
113112
{
114-
await MiningUtils.MineToFile(_lookupResults, _currentLookupResultIndex, _currentSourceText, _formattedDefinitions, _selectedDefinitions, _currentSourceTextCharPosition, selectedSpelling).ConfigureAwait(false);
115-
}
116-
else
117-
{
118-
await MiningUtils.Mine(_lookupResults, _currentLookupResultIndex, _currentSourceText, _formattedDefinitions, _selectedDefinitions, _currentSourceTextCharPosition, selectedSpelling).ConfigureAwait(false);
119-
}
120-
}
121-
122-
private void UpdatePosition(Point cursorPosition)
123-
{
124-
double mouseX = cursorPosition.X;
125-
double mouseY = cursorPosition.Y;
126-
127-
DpiScale dpi = WindowsUtils.Dpi;
128-
double currentWidth = ActualWidth * dpi.DpiScaleX;
129-
double currentHeight = ActualHeight * dpi.DpiScaleY;
130-
131-
double dpiAwareXOffSet = 5 * dpi.DpiScaleX;
132-
double dpiAwareYOffset = 15 * dpi.DpiScaleY;
133-
134-
Rectangle bounds = WindowsUtils.ActiveScreen.Bounds;
135-
bool needsFlipX = mouseX + currentWidth > bounds.Right;
136-
bool needsFlipY = mouseY + currentHeight > bounds.Bottom;
137-
138-
double newLeft;
139-
double newTop;
140-
141-
if (needsFlipX)
142-
{
143-
// flip Leftwards while preventing -OOB
144-
newLeft = mouseX - currentWidth - dpiAwareXOffSet;
145-
if (newLeft < bounds.X)
146-
{
147-
newLeft = bounds.X;
148-
}
113+
await MiningUtils.MineToFile(_lookupResults, _currentLookupResultIndex, _currentSourceText, formattedDefinitions, selectedDefinitions, _currentSourceTextCharPosition, selectedSpelling).ConfigureAwait(false);
149114
}
150115
else
151116
{
152-
// no flip
153-
newLeft = mouseX - dpiAwareXOffSet;
117+
await MiningUtils.Mine(_lookupResults, _currentLookupResultIndex, _currentSourceText, formattedDefinitions, selectedDefinitions, _currentSourceTextCharPosition, selectedSpelling).ConfigureAwait(false);
154118
}
155-
156-
if (needsFlipY)
157-
{
158-
// flip Upwards while preventing -OOB
159-
newTop = mouseY - (currentHeight + dpiAwareYOffset);
160-
if (newTop < bounds.Y)
161-
{
162-
newTop = bounds.Y;
163-
}
164-
}
165-
else
166-
{
167-
// no flip
168-
newTop = mouseY + dpiAwareYOffset;
169-
}
170-
171-
// stick to edges if +OOB
172-
if (newLeft + currentWidth > bounds.Right)
173-
{
174-
newLeft = bounds.Right - currentWidth;
175-
}
176-
177-
if (newTop + currentHeight > bounds.Bottom)
178-
{
179-
newTop = bounds.Bottom - currentHeight;
180-
}
181-
182-
WinApi.MoveWindowToPosition(_windowHandle, newLeft, newTop);
183119
}
184120

185121
public static void CloseWindow()

JL.Windows/GUI/PopupWindow.xaml.cs

+44-34
Original file line numberDiff line numberDiff line change
@@ -1287,53 +1287,63 @@ private async void TextBox_MouseMove(object sender, MouseEventArgs e)
12871287

12881288
// ReSharper disable once AsyncVoidMethod
12891289
private async void AudioButton_Click(object sender, RoutedEventArgs e)
1290+
{
1291+
await HandleAudioButtonClick().ConfigureAwait(false);
1292+
}
1293+
1294+
private Task HandleAudioButtonClick()
12901295
{
12911296
LookupResult lookupResult = LastLookupResults[_listViewItemIndex];
12921297
if (lookupResult.Readings is null || lookupResult.Readings.Length is 1)
12931298
{
1294-
await PopupWindowUtils.PlayAudio(lookupResult.PrimarySpelling, lookupResult.Readings?[0]).ConfigureAwait(false);
1299+
return PopupWindowUtils.PlayAudio(lookupResult.PrimarySpelling, lookupResult.Readings?[0]);
12951300
}
12961301
else
12971302
{
12981303
ReadingSelectionWindow.Show(this, lookupResult.PrimarySpelling, lookupResult.Readings);
1304+
return Task.CompletedTask;
12991305
}
13001306
}
13011307

1302-
// ReSharper disable once AsyncVoidMethod
1303-
private async void MiningButton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
1308+
private Task HandleMining(bool minePrimarySpelling)
13041309
{
1305-
if (!MiningMode || e.ChangedButton is MouseButton.Right)
1306-
{
1307-
return;
1308-
}
1309-
13101310
int listViewItemIndex = _listViewItemIndex;
1311-
TextBox? definitionsTextBox = GetDefinitionTextBox(listViewItemIndex);
1312-
string? formattedDefinitions = definitionsTextBox?.Text;
1313-
string? selectedDefinitions = PopupWindowUtils.GetSelectedDefinitions(definitionsTextBox);
13141311
string currentSourceText = _currentSourceText;
13151312
int currentSourceTextCharPosition = _currentSourceTextCharPosition;
13161313
LookupResult[] lookupResults = LastLookupResults;
13171314

13181315
LookupResult lookupResult = lookupResults[listViewItemIndex];
1319-
if (lookupResult.Readings is null)
1316+
if (minePrimarySpelling
1317+
|| lookupResult.Readings is null
1318+
|| DictUtils.KanjiDictTypes.Contains(lookupResult.Dict.Type))
13201319
{
1320+
TextBox? definitionsTextBox = GetDefinitionTextBox(listViewItemIndex);
1321+
string? formattedDefinitions = definitionsTextBox?.Text;
1322+
string? selectedDefinitions = PopupWindowUtils.GetSelectedDefinitions(definitionsTextBox);
1323+
13211324
HidePopup();
13221325

1323-
ConfigManager configManager = ConfigManager.Instance;
1324-
if (configManager.MineToFileInsteadOfAnki)
1325-
{
1326-
await MiningUtils.MineToFile(lookupResults, listViewItemIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition, lookupResult.PrimarySpelling).ConfigureAwait(false);
1327-
}
1328-
else
1329-
{
1330-
await MiningUtils.Mine(lookupResults, listViewItemIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition, lookupResult.PrimarySpelling).ConfigureAwait(false);
1331-
}
1326+
return ConfigManager.Instance.MineToFileInsteadOfAnki
1327+
? MiningUtils.MineToFile(lookupResults, listViewItemIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition, lookupResult.PrimarySpelling)
1328+
: MiningUtils.Mine(lookupResults, listViewItemIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition, lookupResult.PrimarySpelling);
13321329
}
1333-
else
1330+
1331+
MiningSelectionWindow.Show(this, lookupResults, listViewItemIndex, currentSourceText, currentSourceTextCharPosition);
1332+
return Task.CompletedTask;
1333+
}
1334+
1335+
// ReSharper disable once AsyncVoidMethod
1336+
private async void MiningButton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
1337+
{
1338+
ConfigManager configManager = ConfigManager.Instance;
1339+
bool minePrimarySpelling = e.ChangedButton == configManager.MinePrimarySpellingMouseButton;
1340+
if (!MiningMode
1341+
|| (!minePrimarySpelling && e.ChangedButton != configManager.MineMouseButton))
13341342
{
1335-
MiningSelectionWindow.Show(this, lookupResults, listViewItemIndex, currentSourceText, formattedDefinitions, selectedDefinitions, currentSourceTextCharPosition);
1343+
return;
13361344
}
1345+
1346+
await HandleMining(minePrimarySpelling).ConfigureAwait(false);
13371347
}
13381348

13391349
private void ShowAddNameWindow()
@@ -1842,7 +1852,8 @@ private void OnMouseEnter(object sender, MouseEventArgs e)
18421852
// ReSharper disable once AsyncVoidMethod
18431853
private async void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
18441854
{
1845-
_lastInteractedTextBox = (TextBox)sender;
1855+
TextBox textBox = (TextBox)sender;
1856+
_lastInteractedTextBox = textBox;
18461857
LastSelectedText = _lastInteractedTextBox.SelectedText;
18471858

18481859
ConfigManager configManager = ConfigManager.Instance;
@@ -1854,20 +1865,19 @@ private async void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
18541865
return;
18551866
}
18561867

1868+
await HandleTextBoxMouseUp(textBox).ConfigureAwait(false);
1869+
}
1870+
1871+
private Task HandleTextBoxMouseUp(TextBox textBox)
1872+
{
18571873
ChildPopupWindow ??= new PopupWindow
18581874
{
18591875
Owner = this
18601876
};
18611877

1862-
if (configManager.LookupOnSelectOnly)
1863-
{
1864-
await ChildPopupWindow.LookupOnSelect((TextBox)sender).ConfigureAwait(false);
1865-
}
1866-
1867-
else
1868-
{
1869-
await ChildPopupWindow.LookupOnMouseMoveOrClick((TextBox)sender, true).ConfigureAwait(false);
1870-
}
1878+
return ConfigManager.Instance.LookupOnSelectOnly
1879+
? ChildPopupWindow.LookupOnSelect(textBox)
1880+
: ChildPopupWindow.LookupOnMouseMoveOrClick(textBox, true);
18711881
}
18721882

18731883
private void OnMouseLeave(object sender, MouseEventArgs e)
@@ -2124,7 +2134,7 @@ private void PopupListView_MouseLeave(object sender, MouseEventArgs e)
21242134
}
21252135
}
21262136

2127-
private TextBox? GetDefinitionTextBox(int listViewIndex)
2137+
public TextBox? GetDefinitionTextBox(int listViewIndex)
21282138
{
21292139
PopupListView.Items.Filter = null;
21302140
return ((StackPanel)((StackPanel)PopupListView.Items[listViewIndex]!).Children[1]).GetChildByName<TextBox>(nameof(LookupResult.FormattedDefinitions));

0 commit comments

Comments
 (0)